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

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