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

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