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

266 lines, 141 significant
1## our_shell: ysh
2
3#### For loop over expression: List
4var mylist = [1, 2, 3]
5for item in (mylist) {
6 echo "item $item"
7}
8
9## STDOUT:
10item 1
11item 2
12item 3
13## END
14
15#### For loop over expression: Dict, not BashAssoc
16
17var mydict = {name: 'bob', age: 40}
18for key in (mydict) {
19 echo "key $key"
20}
21
22# We can declare this
23shopt --unset no_osh_builtins
24declare -A A=([name]=bob)
25
26# But there is no iteration
27for key in (A) {
28 echo "key $key"
29}
30
31## status: 3
32## STDOUT:
33key name
34key age
35## END
36
37
38#### For loop over range
39var myrange = 0 ..< 3
40for i in (myrange) {
41 echo "i $i"
42}
43
44## STDOUT:
45i 0
46i 1
47i 2
48## END
49
50#### Shell for loop with index (equivalent of enumerate())
51for i, item in a b c {
52 echo "$i $item"
53}
54## STDOUT:
550 a
561 b
572 c
58## END
59
60#### 3 indices with (mylist) is a runtime error
61for i, item bad in (['foo', 'bar']) {
62 echo "$i $item $bad"
63}
64## status: 2
65
66#### Shell for loop can't have 3 indices
67for i, bad, bad in a b c {
68 echo $i $item
69}
70## status: 2
71
72#### Any for loop can't have 4 indices
73for a, b, c, d in (['foo']) {
74 echo $i $item
75}
76## status: 2
77
78#### Expression for loop with index: List
79for i, item in (['spam', 'eggs']) {
80 echo "$i $item"
81}
82## STDOUT:
830 spam
841 eggs
85## END
86
87#### Expression for loop with index: Dict (TODO: define dict iter order)
88for key, value in ({name: 'bob', age: 40}) {
89 echo "pair $key $value"
90}
91## STDOUT:
92pair name bob
93pair age 40
94## END
95
96#### Dict: index key value loop (TODO: define dict iter order)
97for i, key, value in ({name: 'bob', age: 40}) {
98 echo "entry $i $key $value"
99}
100## STDOUT:
101entry 0 name bob
102entry 1 age 40
103## END
104
105
106#### Equivalent of zip()
107
108var array = :| d e f |
109
110for i, item in a b c {
111 echo "$i $item $[array[i]]"
112}
113
114## STDOUT:
1150 a d
1161 b e
1172 c f
118## END
119
120#### no_parse_bare_word eliminates confusion
121
122shopt --set no_parse_bare_word
123
124for x in mylist { # THIS FAILS
125 echo "BAD $x"
126}
127
128## status: 2
129## STDOUT:
130## END
131
132
133#### Object that's not iterable
134
135echo hi
136for x in (42) {
137 echo $x
138}
139
140## status: 3
141## STDOUT:
142hi
143## END
144
145#### YSH for with brace substitution and glob
146
147touch {foo,bar}.py
148for i, file in *.py {README,foo}.md {
149 echo "$i $file"
150}
151## STDOUT:
1520 bar.py
1531 foo.py
1542 README.md
1553 foo.md
156## END
157
158#### for x in (io.stdin) {
159
160# to avoid stdin conflict
161
162$[ENV.SH] $[ENV.REPO_ROOT]/spec/testdata/ysh-for-stdin.ysh
163
164## STDOUT:
165-1-
166-2-
167-3-
168
1690 1
1701 2
1712 3
172
173empty
174done
175
176empty2
177done2
178
179space
180hi
181## END
182
183#### I/O error in for x in (stdin) {
184
185set +o errexit
186
187# EISDIR - stdin descriptor is dir
188$[ENV.SH] -c 'for x in (io.stdin) { echo $x }' < /
189if test $? -ne 0; then
190 echo pass
191fi
192
193## STDOUT:
194pass
195## END
196
197#### Append to List in loop extends the loop (matches JS)
198
199# see demo/survey-loop
200
201var mylist = [1,2,3]
202for x in (mylist) {
203 if (x === 2) {
204 call mylist->append(99)
205 }
206 echo $x
207}
208## STDOUT:
2091
2102
2113
21299
213## END
214
215#### Remove from List in loop shortens it (matches JS)
216
217# see demo/survey-loop
218
219var mylist = [1,2,3,4]
220for x in (mylist) {
221 if (x === 2) {
222 call mylist->pop()
223 }
224 echo $x
225}
226## STDOUT:
2271
2282
2293
230## END
231
232#### Adding to Dict in loop does NOT extend the loop (matches JS)
233
234# see demo/survey-loop
235
236var mydict = {"1": null, "2": null, "3": null}
237for x in (mydict) {
238 if (x === "2") {
239 setvar mydict["99"] = null
240 }
241 echo $x
242}
243## STDOUT:
2441
2452
2463
247## END
248
249#### Removing from Dict in loop does NOT change the loop (does NOT match JS)
250
251# see demo/survey-loop
252
253var mydict = {"1": null, "2": null, "3": null, "4": null}
254for x in (mydict) {
255 if (x === "2") {
256 call mydict->erase("1")
257 call mydict->erase("3")
258 }
259 echo $x
260}
261## STDOUT:
2621
2632
2643
2654
266## END