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

394 lines, 223 significant
1#### cd with block
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: fatal error in block
31shopt -s oil:all
32cd / {
33 echo one
34 false
35 echo two
36}
37## status: 1
38## STDOUT:
39one
40## END
41
42
43#### cd with block: return in block
44shopt -s oil:all
45f() {
46 cd / {
47 echo one
48 return
49 echo two
50 }
51 echo 'end func'
52}
53f
54## STDOUT:
55one
56end func
57## END
58
59#### cd with block: break in block
60shopt -s oil:all
61f() {
62 cd / {
63 echo one
64 for i in 1 2; do
65 echo $i
66 break # break out of loop
67 done
68
69 break # break out of block isn't valid
70 echo two
71 }
72 echo end func
73}
74f
75## status: 1
76## STDOUT:
77one
781
79## END
80
81#### cd with block exits with status 0
82shopt -s ysh:all
83cd / {
84 echo block
85
86 # This return value is ignored.
87 # Or maybe this should be a runtime error?
88 return 1
89}
90echo status=$?
91## STDOUT:
92block
93status=0
94## END
95
96#### block doesn't have its own scope
97shopt -s ysh:all
98var x = 1
99echo "x=$x"
100cd / {
101 #set y = 5 # This would be an error because set doesn't do dynamic lookup
102 var x = 42
103 echo "x=$x"
104}
105echo "x=$x"
106## STDOUT:
107x=1
108x=42
109x=42
110## END
111
112#### redirects allowed in words, typed args, and after block
113shopt -s ysh:upgrade
114
115rm -f out
116touch out
117
118cd /tmp >>out {
119 echo 1 $PWD
120}
121
122cd /tmp >>out (; ; ^(echo 2 $PWD))
123
124cd /tmp (; ; ^(echo 3 $PWD)) >>out
125
126cd /tmp {
127 echo 4 $PWD
128} >> out
129
130cat out
131
132## STDOUT:
1331 /tmp
1342 /tmp
1353 /tmp
1364 /tmp
137## END
138
139#### block literal in expression mode: ^(echo $PWD)
140shopt -s oil:all
141
142const myblock = ^(echo $PWD | wc -l)
143eval (myblock)
144
145const b2 = ^(echo one; echo two)
146eval (b2)
147
148## STDOUT:
1491
150one
151two
152## END
153
154#### block arg as typed expression
155
156shopt -s oil:all
157
158# literal
159cd /tmp (; ; ^(echo $PWD))
160
161const myblock = ^(echo $PWD)
162cd /tmp (; ; myblock)
163
164## STDOUT:
165/tmp
166/tmp
167## END
168
169#### Pass invalid typed args
170
171cd /tmp (42) # should be a block
172## status: 3
173
174#### Pass too many typed args
175
176cd /tmp (1, 2)
177## status: 3
178
179#### 'builtin' and 'command' with block
180shopt --set oil:upgrade
181builtin cd / {
182 echo "builtin $PWD"
183}
184command cd / {
185 echo "command $PWD"
186}
187## STDOUT:
188builtin /
189command /
190## END
191
192
193#### Consistency: Control Flow and Blocks
194shopt --set parse_brace
195
196# "Invalid control flow at top level"
197eval '
198 cd / {
199 echo cd
200 break
201 }
202'
203echo cd no loop $?
204
205# warning: "Unexpected control flow in block" (strict_control_flow)
206eval '
207while true {
208 cd / {
209 echo cd
210 break
211 }
212}
213'
214echo cd loop $?
215
216eval '
217while true {
218 shopt --unset errexit {
219 echo shopt
220 continue
221 }
222}
223'
224echo shopt continue $?
225
226eval '
227while true {
228 shvar FOO=foo {
229 echo shvar
230 continue
231 }
232}
233'
234echo shvar continue $?
235
236
237eval '
238while true {
239 try {
240 echo try
241 break
242 }
243}
244'
245echo try break $?
246
247## STDOUT:
248cd
249cd no loop 0
250cd
251cd loop 1
252shopt
253shopt continue 1
254shvar
255shvar continue 1
256try
257try break 1
258## END
259
260#### Consistency: Exit Status and Blocks
261shopt --set parse_brace
262
263cd / {
264 false
265}
266echo cd=$?
267
268shopt --unset errexit {
269 false
270}
271echo shopt=$?
272
273shvar FOO=foo {
274 echo " FOO=$FOO"
275 false
276}
277echo shvar=$?
278
279try {
280 false
281}
282echo try=$?
283
284## STDOUT:
285cd=0
286shopt=0
287 FOO=foo
288shvar=0
289try=0
290## END
291
292#### Consistency: Unwanted Blocks Are Errors
293shopt --set parse_brace
294
295true { echo BAD }
296echo true $?
297
298false ( 42, 43 )
299echo false $?
300
301echo { echo BAD }
302echo echo block $?
303
304echo ( 42, 43 )
305echo echo args $?
306
307command echo 'command block' { echo BAD }
308echo command echo $?
309
310builtin echo 'builtin block' { echo BAD }
311echo builtin echo $?
312
313pushd $TMP { echo BAD }
314echo pushd $?
315
316## STDOUT:
317true 2
318false 2
319echo block 2
320echo args 2
321command echo 2
322builtin echo 2
323pushd 2
324## END
325
326#### Block with Bare Assignments
327
328# oil:all has parse_equals
329# is there any way to turn on parse_equals only in config blocks?
330# but we don't know what's a block ahead of time
331# I think we would have to check at runtime. Look at VarChecker
332
333shopt --set oil:all
334
335proc Rule(s ; ; ; b) {
336 echo "rule $s"
337}
338
339proc myrules(name) {
340 Rule $name-python {
341 kind = 'python'
342 }
343
344 Rule $name-cc {
345 kind = 'cc' # should NOT conflict
346 }
347}
348
349myrules foo
350myrules bar
351
352## STDOUT:
353rule foo-python
354rule foo-cc
355rule bar-python
356rule bar-cc
357## END
358
359#### Proc that doesn't take a block
360shopt --set parse_brace parse_proc parse_paren
361
362proc task(name ; ; ; b = null) {
363 echo "task name=$name"
364 if (b) {
365 eval (b)
366 return 33
367 } else {
368 echo 'no block'
369 return 44
370 }
371}
372
373task spam
374echo status=$?
375
376echo
377
378task foo {
379 echo 'running'
380 echo 'block'
381}
382echo status=$?
383
384## STDOUT:
385task name=spam
386no block
387status=44
388
389task name=foo
390running
391block
392status=33
393## END
394