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

399 lines, 203 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 (setitem)
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 (setitem)
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#### mixing assignment builtins and YSH assignment
270shopt -s ysh:all parse_equals
271
272proc local-var {
273 local x=1
274 var x = 2
275 echo x=$x
276}
277
278proc readonly-var {
279 readonly x=1
280 var x = 2
281 echo x=$x
282}
283
284try { eval 'local-var' }
285echo status=$_status
286try { eval 'readonly-var' }
287echo status=$_status
288
289## STDOUT:
290x=2
291status=0
292status=1
293## END
294
295#### circular dict - TODO 2023-06 REGRESS
296var d = {name: 'foo'}
297= d
298setvar d['name'] = 123
299= d
300setvar d['name'] = 'mystr'
301= d
302#setvar d['name'] = d
303#= d
304
305# This used to print ...
306
307## STDOUT:
308(OrderedDict) <'name': 'foo'>
309(OrderedDict) <'name': 123>
310(OrderedDict) <'name': 'mystr'>
311(OrderedDict) <'name': ...>
312## END
313
314#### circular list - TODO 2023-06 REGRESS
315var L = [1,2,3]
316= L
317#setvar L[0] = L
318#= L
319## STDOUT:
320(List) [1, 2, 3]
321(List) [[...], 2, 3]
322## END
323
324
325#### exit code of var, const, setvar with command sub
326
327# NOTE: This feels PROBLEMATIC without command_sub_errexit feels like it should
328# be the last one ...
329
330run() {
331 $REPO_ROOT/bin/osh -O parse_proc -c "$@"
332
333 # Identical
334 # $SH +O ysh:all -O parse_proc -c "$@"
335}
336
337set +o errexit
338
339run '
340var x = $(false)
341echo inside1=$?
342'
343echo outside1=$?
344
345run '
346setvar x = $(false)
347echo inside2=$?
348'
349echo outside2=$?
350
351# Argument list
352run '
353call split( $(false) )
354echo inside3=$?
355'
356echo outside3=$?
357
358# Place expression
359run '
360var d = {}
361setvar d[ $(false) ] = 42
362echo inside4=$?
363'
364echo outside4=$?
365
366## STDOUT:
367outside1=1
368outside2=1
369outside3=1
370outside4=1
371## END
372
373#### setvar obj[INVALID TYPE] =
374
375set +o errexit
376
377$SH -c '
378var d = {}
379setvar d["key"] = 5
380echo "d.key = $[d.key]"
381setvar d[42] = 6
382echo "should not get here"
383'
384echo outside1=$?
385
386$SH -c '
387var L = [42]
388setvar L[0] = 43
389echo "L[0] = $[L[0]]"
390setvar L["key"] = 44
391'
392echo outside2=$?
393
394## STDOUT:
395d.key = 5
396outside1=3
397L[0] = 43
398outside2=3
399## END