OILS / spec / ysh-blocks.test.sh View on Github | oilshell.org

291 lines, 175 significant
1#### cd accepts a block, runs it in different dir
2shopt -s ysh:all
3
4const saved = "$PWD"
5
6# OLDPWD is NOT defined
7cd / { echo $PWD; echo OLDPWD=${OLDPWD:-} }; echo done
8
9if ! test "$saved" = $PWD; then
10 echo FAIL
11fi
12
13cd /tmp {
14 write PWD=$PWD
15 write --sep ' ' pwd builtin: $(pwd)
16}
17
18if ! test "$saved" = $PWD; then
19 echo FAIL
20fi
21
22## STDOUT:
23/
24OLDPWD=
25done
26PWD=/tmp
27pwd builtin: /tmp
28## END
29
30#### cd with block: requires explicit command
31shopt --set ysh:upgrade
32
33cd /tmp { echo $PWD }
34
35HOME=~
36cd { echo $PWD }
37
38## status: 2
39## STDOUT:
40/tmp
41## END
42
43#### cd passed block with return 1
44shopt -s ysh:all
45
46f() {
47 cd / {
48 echo block
49 return 1
50 echo 'not reached'
51 }
52}
53f
54echo 'not reached'
55
56## status: 1
57## STDOUT:
58block
59## END
60
61#### block doesn't have its own scope
62shopt -s ysh:all
63var x = 1
64echo "x=$x"
65cd / {
66 #set y = 5 # This would be an error because set doesn't do dynamic lookup
67 var x = 42
68 echo "x=$x"
69}
70echo "x=$x"
71## STDOUT:
72x=1
73x=42
74x=42
75## END
76
77#### redirects allowed in words, typed args, and after block
78shopt -s ysh:upgrade
79
80rm -f out
81touch out
82
83cd /tmp >>out {
84 echo 1 $PWD
85}
86
87cd /tmp >>out (; ; ^(echo 2 $PWD))
88
89cd /tmp (; ; ^(echo 3 $PWD)) >>out
90
91cd /tmp {
92 echo 4 $PWD
93} >> out
94
95cat out
96
97## STDOUT:
981 /tmp
992 /tmp
1003 /tmp
1014 /tmp
102## END
103
104#### block literal in expression mode: ^(echo $PWD)
105shopt -s ysh:all
106
107const myblock = ^(echo $PWD | wc -l)
108call io->eval(myblock)
109
110const b2 = ^(echo one; echo two)
111call io->eval(b2)
112
113## STDOUT:
1141
115one
116two
117## END
118
119#### block arg as typed expression
120
121shopt -s oil:all
122
123# literal
124cd /tmp (; ; ^(echo $PWD))
125
126const myblock = ^(echo $PWD)
127cd /tmp (; ; myblock)
128
129## STDOUT:
130/tmp
131/tmp
132## END
133
134#### Pass invalid typed args
135
136cd /tmp (42) # should be a block
137## status: 3
138
139#### Pass too many typed args
140
141cd /tmp (1, 2)
142## status: 3
143
144#### 'builtin' and 'command' with block
145shopt --set oil:upgrade
146builtin cd / {
147 echo "builtin $PWD"
148}
149command cd / {
150 echo "command $PWD"
151}
152## STDOUT:
153builtin /
154command /
155## END
156
157#### Consistency: Exit Status and Blocks
158shopt --set parse_brace
159
160cd / {
161 false
162}
163echo cd=$?
164
165shopt --unset errexit {
166 false
167}
168echo shopt=$?
169
170shvar FOO=foo {
171 echo " FOO=$FOO"
172 false
173}
174echo shvar=$?
175
176try {
177 false
178}
179echo try=$?
180
181## STDOUT:
182cd=0
183shopt=0
184 FOO=foo
185shvar=0
186try=0
187## END
188
189#### Consistency: Unwanted Blocks Are Errors
190shopt --set parse_brace
191
192true { echo BAD }
193echo true $?
194
195false ( 42, 43 )
196echo false $?
197
198echo { echo BAD }
199echo echo block $?
200
201echo ( 42, 43 )
202echo echo args $?
203
204command echo 'command block' { echo BAD }
205echo command echo $?
206
207builtin echo 'builtin block' { echo BAD }
208echo builtin echo $?
209
210pushd $TMP { echo BAD }
211echo pushd $?
212
213## STDOUT:
214true 2
215false 2
216echo block 2
217echo args 2
218command echo 2
219builtin echo 2
220pushd 2
221## END
222
223#### Block with Bare Assignments
224
225# oil:all has parse_equals
226# is there any way to turn on parse_equals only in config blocks?
227# but we don't know what's a block ahead of time
228# I think we would have to check at runtime. Look at VarChecker
229
230shopt --set oil:all
231
232proc Rule(s ; ; ; b) {
233 echo "rule $s"
234}
235
236proc myrules(name) {
237 Rule $name-python {
238 kind = 'python'
239 }
240
241 Rule $name-cc {
242 kind = 'cc' # should NOT conflict
243 }
244}
245
246myrules foo
247myrules bar
248
249## STDOUT:
250rule foo-python
251rule foo-cc
252rule bar-python
253rule bar-cc
254## END
255
256#### Proc that doesn't take a block
257shopt --set parse_brace parse_proc parse_paren
258
259proc task(name ; ; ; b = null) {
260 echo "task name=$name"
261 if (b) {
262 call io->eval(b)
263 return 33
264 } else {
265 echo 'no block'
266 return 44
267 }
268}
269
270task spam
271echo status=$?
272
273echo
274
275task foo {
276 echo 'running'
277 echo 'block'
278}
279echo status=$?
280
281## STDOUT:
282task name=spam
283no block
284status=44
285
286task name=foo
287running
288block
289status=33
290## END
291