OILS / spec / ysh-assign.test.sh View on Github | oils.pub

424 lines, 220 significant
1# Test var / setvar / etc.
2
3## our_shell: ysh
4## oils_failures_allowed: 2
5
6#### proc static check: const can't be mutated
7proc f {
8 const x = 'local'
9 echo x=$x
10 setvar x = 'mutated'
11 echo x=$x
12}
13## status: 2
14## STDOUT:
15## END
16
17#### top-level dynamic check: const can't be be mutated
18shopt -s ysh:all
19
20const x = 'foo'
21echo x=$x
22const x = 'bar'
23echo x=$x
24## status: 1
25## STDOUT:
26x=foo
27## END
28
29#### top level: var can be redefined by var/const
30var x = "global"
31echo x=$x
32f() {
33 var x = "local"
34 echo x=$x
35}
36f
37var x = "g2"
38echo x=$x
39const x = 'now-const'
40echo x=$x
41const x = 'oops'
42echo x=$x
43## status: 1
44## STDOUT:
45x=global
46x=local
47x=g2
48x=now-const
49## END
50
51#### setvar mutates local
52proc f {
53 var x = 'local'
54 echo x=$x
55 setvar x = 'mutated'
56 echo x=$x
57}
58
59var x = 'global'
60echo x=$x
61f
62echo x=$x
63## STDOUT:
64x=global
65x=local
66x=mutated
67x=global
68## END
69
70#### top level: setvar creates global
71setvar x = 'global'
72echo x=$x
73setvar x = 'g2'
74echo x=$x
75## STDOUT:
76x=global
77x=g2
78## END
79
80#### top level: setvar mutates var
81var x = 1
82setvar x = 42 # this is allowed
83echo $x
84setvar y = 50 # error because it's not declared
85echo $y
86## STDOUT:
8742
8850
89## END
90
91#### proc static check: variable changed by setvar must be declared
92shopt -s ysh:all
93
94var x = 1
95f() {
96 # setting global is OK
97 setglobal x = 'XX'
98 echo x=$x
99
100 # local NOT DECLARED
101 setvar x = 'YY'
102 echo y=$y
103}
104## status: 2
105## STDOUT:
106## END
107
108#### setglobal
109f() {
110 var x = 'local'
111 echo x=$x
112 setglobal x = 'mutated'
113}
114var x = 'global'
115echo x=$x
116f
117echo x=$x
118## STDOUT:
119x=global
120x=local
121x=mutated
122## END
123
124#### setglobal of undeclared var is allowed
125var x = 'XX'
126echo x=$x
127setglobal x = 'xx'
128echo x=$x
129
130# fatal error
131setglobal y = 'YY'
132
133## STDOUT:
134x=XX
135x=xx
136## END
137
138#### var a, b does implicit null init
139
140var x
141var a, b
142
143var c: Int, d: Int
144
145echo $x $a $b $c $d
146
147## STDOUT:
148null null null null null
149## END
150
151#### var x, y = f()
152
153# The syntax consistent with JavaScript would be
154# var x = 1, y = 2;
155
156var x, y = 1, 2
157echo "x=$x y=$y"
158
159func f() {
160 # this syntax would be nice, but is illegal
161 # return (3, 4)
162 return ([3, 4])
163}
164
165var a, b = f()
166echo "a=$a b=$b"
167
168
169## STDOUT:
170x=1 y=2
171a=3 b=4
172## END
173
174#### const x, y = f()
175
176func f() {
177 # this syntax would be nice, but is illegal
178 # return (3, 4)
179 return ([3, 4])
180}
181
182
183const a, b = f()
184echo "a=$a b=$b"
185
186setvar a = 9 # error
187
188## status: 1
189## STDOUT:
190a=3 b=4
191## END
192
193
194#### setvar x, y = 1, 2
195
196# Python doesn't allow you to have annotation on each variable!
197# https://www.python.org/dev/peps/pep-0526/#where-annotations-aren-t-allowed
198var x Int = 3
199var y Int = 4
200echo "x=$x y=$y"
201
202setvar x, y = 1, 9
203echo "x=$x y=$y"
204
205setvar y, x = x, y
206echo "x=$x y=$y"
207
208setvar x, y = x*2, x*3
209echo "x=$x y=$y"
210
211## STDOUT:
212x=3 y=4
213x=1 y=9
214x=9 y=1
215x=18 y=27
216## END
217
218#### setvar to swap List and Dict elements
219var x = [1, 2, 3]
220echo @x
221
222setvar x[0], x[1] = x[1], x[0]
223
224echo @x
225
226var d = {int: 42}
227
228setvar x[0], d.int = d.int, x[0]
229
230echo @x
231json write (d)
232
233## STDOUT:
2341 2 3
2352 1 3
23642 1 3
237{
238 "int": 2
239}
240## END
241
242#### setvar d.key = 42
243shopt -s ysh:all
244
245var d = {}
246setvar d['f2'] = 42
247setvar d.f3 = 43
248
249# Use the opposite thing to retrieve
250var f3 = d['f3']
251var f2 = d.f2
252echo f3=$f3
253echo f2=$f2
254## STDOUT:
255f3=43
256f2=42
257## END
258
259#### setvar mylist[1] = 42
260shopt -s ysh:all
261var mylist = [1,2,3]
262setvar mylist[1] = 42
263
264write --sep ' ' @mylist
265## STDOUT:
2661 42 3
267## END
268
269#### setvar mylist[99] out of range
270shopt -s ysh:all
271var mylist = [4,5,6]
272try {
273 setvar mylist[99] = 42
274}
275echo $[_error.code]
276
277try {
278 setvar mylist[-99] = 42
279}
280echo $[_error.code]
281
282write --sep ' ' @mylist
283
284## STDOUT:
2853
2863
2874 5 6
288## END
289
290#### mixing assignment builtins and YSH assignment
291shopt --set ysh:all parse_equals
292shopt --unset no_osh_builtins
293
294proc local-var {
295 local x=1
296 var x = 2
297 echo x=$x
298}
299
300proc readonly-var {
301 readonly x=1
302 var x = 2
303 echo x=$x
304}
305
306try { eval 'local-var' }
307echo status=$_status
308try { eval 'readonly-var' }
309echo status=$_status
310
311## STDOUT:
312x=2
313status=0
314status=1
315## END
316
317#### circular dict - TODO 2023-06 REGRESS
318var d = {name: 'foo'}
319pp test_ (d)
320
321setvar d['name'] = 123
322pp test_ (d)
323
324setvar d['name'] = 'mystr'
325pp test_ (d)
326
327setvar d['name'] = d
328pp test_ (d)
329
330# This used to print ...
331
332## STDOUT:
333(OrderedDict) <'name': 'foo'>
334(OrderedDict) <'name': 123>
335(OrderedDict) <'name': 'mystr'>
336(OrderedDict) <'name': ...>
337## END
338
339#### circular list - TODO 2023-06 REGRESS
340var L = [1,2,3]
341= L
342#setvar L[0] = L
343#= L
344## STDOUT:
345(List) [1, 2, 3]
346(List) [[...], 2, 3]
347## END
348
349
350#### exit code of var, const, setvar with command sub
351
352# NOTE: This feels PROBLEMATIC without command_sub_errexit feels like it should
353# be the last one ...
354
355run() {
356 $[ENV.REPO_ROOT]/bin/osh -O parse_proc -c "$@"
357
358 # Identical
359 # $[ENV.SH] +O ysh:all -O parse_proc -c "$@"
360}
361
362shopt --unset errexit
363
364run '
365var x = $(false)
366echo inside1=$?
367'
368echo outside1=$?
369
370run '
371setvar x = $(false)
372echo inside2=$?
373'
374echo outside2=$?
375
376# Argument list
377run '
378call split( $(false) )
379echo inside3=$?
380'
381echo outside3=$?
382
383# Place expression
384run '
385var d = {}
386setvar d[ $(false) ] = 42
387echo inside4=$?
388'
389echo outside4=$?
390
391## STDOUT:
392outside1=1
393outside2=1
394outside3=1
395outside4=1
396## END
397
398#### setvar obj[INVALID TYPE] =
399
400shopt --unset errexit
401
402$[ENV.SH] -c '
403var d = {}
404setvar d["key"] = 5
405echo "d.key = $[d.key]"
406setvar d[42] = 6
407echo "should not get here"
408'
409echo outside1=$?
410
411$[ENV.SH] -c '
412var L = [42]
413setvar L[0] = 43
414echo "L[0] = $[L[0]]"
415setvar L["key"] = 44
416'
417echo outside2=$?
418
419## STDOUT:
420d.key = 5
421outside1=3
422L[0] = 43
423outside2=3
424## END