| 1 | ## our_shell: ysh
 | 
| 2 | ## oils_failures_allowed: 1
 | 
| 3 | 
 | 
| 4 | #### fastlex: NUL byte not allowed inside char literal #' '
 | 
| 5 | 
 | 
| 6 | echo $'var x = #\'\x00\'; echo x=$x' > tmp.oil
 | 
| 7 | $SH tmp.oil
 | 
| 8 | 
 | 
| 9 | echo $'var x = #\' ' > incomplete.oil
 | 
| 10 | $SH incomplete.oil
 | 
| 11 | 
 | 
| 12 | ## status: 2
 | 
| 13 | ## STDOUT:
 | 
| 14 | ## END
 | 
| 15 | 
 | 
| 16 | #### fastlex: NUL byte inside shebang line
 | 
| 17 | 
 | 
| 18 | # Hm this test doesn't really tickle the bug
 | 
| 19 | 
 | 
| 20 | echo $'#! /usr/bin/env \x00 sh \necho hi' > tmp.oil
 | 
| 21 | env OILS_HIJACK_SHEBANG=1 $SH tmp.oil
 | 
| 22 | 
 | 
| 23 | ## STDOUT:
 | 
| 24 | hi
 | 
| 25 | ## END
 | 
| 26 | 
 | 
| 27 | #### Tea keywords don't interfere with YSH expressions
 | 
| 28 | 
 | 
| 29 | var d = {data: 'foo'}
 | 
| 30 | 
 | 
| 31 | echo $[d.data]
 | 
| 32 | 
 | 
| 33 | var e = {enum: 1, class: 2, import: 3, const: 4, var: 5, set: 6}
 | 
| 34 | echo $[len(e)]
 | 
| 35 | 
 | 
| 36 | ## STDOUT:
 | 
| 37 | foo
 | 
| 38 | 6
 | 
| 39 | ## END
 | 
| 40 | 
 | 
| 41 | #### Catch AttributeError
 | 
| 42 | 
 | 
| 43 | var s = 'foo'
 | 
| 44 | echo s=$s
 | 
| 45 | var t = s.bad()
 | 
| 46 | echo 'should not get here'
 | 
| 47 | 
 | 
| 48 | ## status: 3
 | 
| 49 | ## STDOUT:
 | 
| 50 | s=foo
 | 
| 51 | ## END
 | 
| 52 | 
 | 
| 53 | 
 | 
| 54 | #### Command sub paren parsing bug (#1387)
 | 
| 55 | 
 | 
| 56 | write $(if (true) { write true })
 | 
| 57 | 
 | 
| 58 | const a = $(write $[len('foo')])
 | 
| 59 | echo $a
 | 
| 60 | 
 | 
| 61 | const b = $(write $[5 ** 3])
 | 
| 62 | echo $b
 | 
| 63 | 
 | 
| 64 | const c = $(
 | 
| 65 |   write $[6 + 7]
 | 
| 66 | )
 | 
| 67 | echo $c
 | 
| 68 | 
 | 
| 69 | ## STDOUT:
 | 
| 70 | true
 | 
| 71 | 3
 | 
| 72 | 125
 | 
| 73 | 13
 | 
| 74 | ## END
 | 
| 75 | 
 | 
| 76 | 
 | 
| 77 | #### More Command sub paren parsing
 | 
| 78 | 
 | 
| 79 | write $( var mylist = ['for']; for x in (mylist) { echo $x } )
 | 
| 80 | 
 | 
| 81 | write $( echo while; while (false) { write hi } )
 | 
| 82 | 
 | 
| 83 | write $( if (true) { write 'if' } )
 | 
| 84 | 
 | 
| 85 | write $( if (false) { write 'if' } elif (true) { write 'elif' } )
 | 
| 86 | 
 | 
| 87 | ## STDOUT:
 | 
| 88 | for
 | 
| 89 | while
 | 
| 90 | if
 | 
| 91 | elif
 | 
| 92 | ## END
 | 
| 93 | 
 | 
| 94 | #### don't execute empty command
 | 
| 95 | 
 | 
| 96 | shopt --set ysh:all
 | 
| 97 | 
 | 
| 98 | set -x
 | 
| 99 | 
 | 
| 100 | try {
 | 
| 101 |   type -a ''
 | 
| 102 | }
 | 
| 103 | echo "type -a returned $_status"
 | 
| 104 | 
 | 
| 105 | $(true)
 | 
| 106 | echo nope
 | 
| 107 | 
 | 
| 108 | ## status: 127
 | 
| 109 | ## STDOUT:
 | 
| 110 | type -a returned 1
 | 
| 111 | ## END
 | 
| 112 | 
 | 
| 113 | 
 | 
| 114 | #### && || with YSH constructs ?
 | 
| 115 | 
 | 
| 116 | 
 | 
| 117 | var x = []
 | 
| 118 | true && call x->append(42)
 | 
| 119 | false && call x->append(43)
 | 
| 120 | pp line (x)
 | 
| 121 | 
 | 
| 122 | 
 | 
| 123 | func amp() {
 | 
| 124 |   true && return (42)
 | 
| 125 | }
 | 
| 126 | 
 | 
| 127 | func pipe() {
 | 
| 128 |   false || return (42)
 | 
| 129 | }
 | 
| 130 | 
 | 
| 131 | pp line (amp())
 | 
| 132 | pp line (pipe())
 | 
| 133 | 
 | 
| 134 | ## STDOUT:
 | 
| 135 | ## END
 | 
| 136 | 
 | 
| 137 | 
 | 
| 138 | #### shvar then replace - bug #1986 context manager crash
 | 
| 139 | 
 | 
| 140 | shvar FOO=bar {
 | 
| 141 |   for x in (1 .. 500) {
 | 
| 142 |     var Q = "hello"
 | 
| 143 |     setvar Q = Q=>replace("hello","world")
 | 
| 144 |   }
 | 
| 145 | }
 | 
| 146 | echo $Q
 | 
| 147 | 
 | 
| 148 | ## STDOUT:
 | 
| 149 | world
 | 
| 150 | ## END
 | 
| 151 | 
 |