OILS / spec / ble-features.test.sh View on Github | oils.pub

387 lines, 218 significant
1## compare_shells: bash zsh mksh ash dash yash
2
3#### [bash_unset] local-unset / dynamic-unset for localvar
4unlocal() { unset -v "$1"; }
5
6f1() {
7 local v=local
8 unset v
9 echo "[$1,local,(unset)] v: ${v-(unset)}"
10}
11v=global
12f1 global
13
14f1() {
15 local v=local
16 unlocal v
17 echo "[$1,local,(unlocal)] v: ${v-(unset)}"
18}
19v=global
20f1 'global'
21
22## STDOUT:
23# bash-unset
24# local-unset = value-unset
25# dynamic-unset = cell-unset
26[global,local,(unset)] v: (unset)
27[global,local,(unlocal)] v: global
28## END
29
30## OK osh/mksh/yash STDOUT:
31# always-cell-unset
32# local-unset = cell-unset
33# dynamic-unset = cell-unset
34[global,local,(unset)] v: global
35[global,local,(unlocal)] v: global
36## END
37
38## OK-2 zsh/ash/dash STDOUT:
39# always-value-unset
40# local-unset = value-unset
41# dynamic-unset = value-unset
42[global,local,(unset)] v: (unset)
43[global,local,(unlocal)] v: (unset)
44## END
45
46
47#### [bash_unset] local-unset / dynamic-unset for localvar (mutated from tempenv)
48unlocal() { unset -v "$1"; }
49
50f1() {
51 local v=local
52 unset v
53 echo "[$1,local,(unset)] v: ${v-(unset)}"
54}
55v=global
56v=tempenv f1 'global,tempenv'
57
58f1() {
59 local v=local
60 unlocal v
61 echo "[$1,local,(unlocal)] v: ${v-(unset)}"
62}
63v=global
64v=tempenv f1 'global,tempenv'
65
66## STDOUT:
67# bash-unset (bash-5.1)
68# local-unset = local-unset
69# dynamic-unset = cell-unset
70[global,tempenv,local,(unset)] v: (unset)
71[global,tempenv,local,(unlocal)] v: global
72## END
73
74# Note on bug in bash 4.3 to bash 5.0
75# [global,tempenv,local,(unset)] v: global
76# [global,tempenv,local,(unlocal)] v: global
77
78## OK osh/mksh/yash STDOUT:
79# always-cell-unset
80# local-unset = cell-unset
81# dynamic-unset = cell-unset
82[global,tempenv,local,(unset)] v: tempenv
83[global,tempenv,local,(unlocal)] v: tempenv
84## END
85
86## OK-2 zsh/ash/dash STDOUT:
87# always-value-unset
88# local-unset = value-unset
89# dynamic-unset = value-unset
90[global,tempenv,local,(unset)] v: (unset)
91[global,tempenv,local,(unlocal)] v: (unset)
92## END
93
94
95#### [bash_unset] local-unset / dynamic-unset for tempenv
96unlocal() { unset -v "$1"; }
97
98f1() {
99 unset v
100 echo "[$1,(unset)] v: ${v-(unset)}"
101}
102v=global
103v=tempenv f1 'global,tempenv'
104
105f1() {
106 unlocal v
107 echo "[$1,(unlocal)] v: ${v-(unset)}"
108}
109v=global
110v=tempenv f1 'global,tempenv'
111
112## STDOUT:
113# always-cell-unset, bash-unset
114# local-unset = cell-unset
115# dynamic-unset = cell-unset
116[global,tempenv,(unset)] v: global
117[global,tempenv,(unlocal)] v: global
118## END
119
120## OK zsh/ash/dash/mksh STDOUT:
121# always-value-unset, mksh-unset
122# local-unset = value-unset
123# dynamic-unset = value-unset
124[global,tempenv,(unset)] v: (unset)
125[global,tempenv,(unlocal)] v: (unset)
126## END
127
128#### [bash_unset] function call with tempenv vs tempenv-eval
129unlocal() { unset -v "$1"; }
130
131f5() {
132 echo "[$1] v: ${v-(unset)}"
133 local v
134 echo "[$1,local] v: ${v-(unset)}"
135 ( unset v
136 echo "[$1,local+unset] v: ${v-(unset)}" )
137 ( unlocal v
138 echo "[$1,local+unlocal] v: ${v-(unset)}" )
139}
140v=global
141f5 'global'
142v=tempenv f5 'global,tempenv'
143v=tempenv eval 'f5 "global,tempenv,(eval)"'
144
145## STDOUT:
146# bash-unset (bash-5.1)
147[global] v: global
148[global,local] v: (unset)
149[global,local+unset] v: (unset)
150[global,local+unlocal] v: global
151[global,tempenv] v: tempenv
152[global,tempenv,local] v: tempenv
153[global,tempenv,local+unset] v: (unset)
154[global,tempenv,local+unlocal] v: global
155[global,tempenv,(eval)] v: tempenv
156[global,tempenv,(eval),local] v: tempenv
157[global,tempenv,(eval),local+unset] v: (unset)
158[global,tempenv,(eval),local+unlocal] v: tempenv
159## END
160
161# Note on bug in bash 4.3 to bash 5.0
162# [global] v: global
163# [global,local] v: (unset)
164# [global,local+unset] v: (unset)
165# [global,local+unlocal] v: global
166# [global,tempenv] v: tempenv
167# [global,tempenv,local] v: tempenv
168# [global,tempenv,local+unset] v: global
169# [global,tempenv,local+unlocal] v: global
170# [global,tempenv,(eval)] v: tempenv
171# [global,tempenv,(eval),local] v: tempenv
172# [global,tempenv,(eval),local+unset] v: (unset)
173# [global,tempenv,(eval),local+unlocal] v: tempenv
174
175## OK-2 ash STDOUT:
176# always-value-unset x init.unset
177[global] v: global
178[global,local] v: (unset)
179[global,local+unset] v: (unset)
180[global,local+unlocal] v: (unset)
181[global,tempenv] v: tempenv
182[global,tempenv,local] v: tempenv
183[global,tempenv,local+unset] v: (unset)
184[global,tempenv,local+unlocal] v: (unset)
185[global,tempenv,(eval)] v: tempenv
186[global,tempenv,(eval),local] v: (unset)
187[global,tempenv,(eval),local+unset] v: (unset)
188[global,tempenv,(eval),local+unlocal] v: (unset)
189## END
190
191## OK-3 zsh STDOUT:
192# always-value-unset x init.empty
193[global] v: global
194[global,local] v:
195[global,local+unset] v: (unset)
196[global,local+unlocal] v: (unset)
197[global,tempenv] v: tempenv
198[global,tempenv,local] v:
199[global,tempenv,local+unset] v: (unset)
200[global,tempenv,local+unlocal] v: (unset)
201[global,tempenv,(eval)] v: tempenv
202[global,tempenv,(eval),local] v:
203[global,tempenv,(eval),local+unset] v: (unset)
204[global,tempenv,(eval),local+unlocal] v: (unset)
205## END
206
207## OK-4 dash STDOUT:
208# always-value-unset x init.inherit
209[global] v: global
210[global,local] v: global
211[global,local+unset] v: (unset)
212[global,local+unlocal] v: (unset)
213[global,tempenv] v: tempenv
214[global,tempenv,local] v: tempenv
215[global,tempenv,local+unset] v: (unset)
216[global,tempenv,local+unlocal] v: (unset)
217[global,tempenv,(eval)] v: tempenv
218[global,tempenv,(eval),local] v: tempenv
219[global,tempenv,(eval),local+unset] v: (unset)
220[global,tempenv,(eval),local+unlocal] v: (unset)
221## END
222
223## OK osh/yash/mksh STDOUT:
224# always-cell-unset x init.unset
225[global] v: global
226[global,local] v: (unset)
227[global,local+unset] v: global
228[global,local+unlocal] v: global
229[global,tempenv] v: tempenv
230[global,tempenv,local] v: (unset)
231[global,tempenv,local+unset] v: tempenv
232[global,tempenv,local+unlocal] v: tempenv
233[global,tempenv,(eval)] v: tempenv
234[global,tempenv,(eval),local] v: (unset)
235[global,tempenv,(eval),local+unset] v: tempenv
236[global,tempenv,(eval),local+unlocal] v: tempenv
237## END
238
239
240#### [bash_unset] localvar-inherit from tempenv
241f1() {
242 local v
243 echo "[$1,(local)] v: ${v-(unset)}"
244}
245f2() {
246 f1 "$1,(func)"
247}
248f3() {
249 local v=local
250 f1 "$1,local,(func)"
251}
252v=global
253
254f1 'global'
255v=tempenv f1 'global,tempenv'
256(export v=global; f1 'xglobal')
257
258f2 'global'
259v=tempenv f2 'global,tempenv'
260(export v=global; f2 'xglobal')
261
262f3 'global'
263
264## STDOUT:
265# init.bash
266# init.unset for local
267# init.inherit for tempenv
268[global,(local)] v: (unset)
269[global,tempenv,(local)] v: tempenv
270[xglobal,(local)] v: (unset)
271[global,(func),(local)] v: (unset)
272[global,tempenv,(func),(local)] v: tempenv
273[xglobal,(func),(local)] v: (unset)
274[global,local,(func),(local)] v: (unset)
275## END
276
277## OK osh/mksh/yash STDOUT:
278# init.unset
279[global,(local)] v: (unset)
280[global,tempenv,(local)] v: (unset)
281[xglobal,(local)] v: (unset)
282[global,(func),(local)] v: (unset)
283[global,tempenv,(func),(local)] v: (unset)
284[xglobal,(func),(local)] v: (unset)
285[global,local,(func),(local)] v: (unset)
286## END
287
288## OK-2 ash STDOUT:
289# init.unset x tempenv-in-localctx
290[global,(local)] v: (unset)
291[global,tempenv,(local)] v: tempenv
292[xglobal,(local)] v: (unset)
293[global,(func),(local)] v: (unset)
294[global,tempenv,(func),(local)] v: (unset)
295[xglobal,(func),(local)] v: (unset)
296[global,local,(func),(local)] v: (unset)
297## END
298
299## OK-3 zsh STDOUT:
300# init.empty
301[global,(local)] v:
302[global,tempenv,(local)] v:
303[xglobal,(local)] v:
304[global,(func),(local)] v:
305[global,tempenv,(func),(local)] v:
306[xglobal,(func),(local)] v:
307[global,local,(func),(local)] v:
308## END
309
310## OK-4 dash STDOUT:
311# init.inherit
312[global,(local)] v: global
313[global,tempenv,(local)] v: tempenv
314[xglobal,(local)] v: global
315[global,(func),(local)] v: global
316[global,tempenv,(func),(local)] v: tempenv
317[xglobal,(func),(local)] v: global
318[global,local,(func),(local)] v: local
319## END
320
321
322#### [compat_array] ${arr} is ${arr[0]}
323case ${SH##*/} in (dash|ash) exit 1;; esac # dash/ash does not have arrays
324case ${SH##*/} in (osh) shopt -s compat_array;; esac
325case ${SH##*/} in (zsh) setopt KSH_ARRAYS;; esac
326arr=(foo bar baz)
327argv.py "$arr" "${arr}"
328## stdout: ['foo', 'foo']
329
330## N-I dash/ash status: 1
331## N-I dash/ash stdout-json: ""
332
333## OK yash stdout: ['foo', 'bar', 'baz', 'foo', 'bar', 'baz']
334
335#### [compat_array] scalar write to arrays
336case ${SH##*/} in
337(dash|ash) exit 1;; # dash/ash does not have arrays
338(osh) shopt -s compat_array;;
339(zsh) setopt KSH_ARRAYS;;
340esac
341
342a=(1 0 0)
343: $(( a++ ))
344argv.py "${a[@]}"
345## stdout: ['2', '0', '0']
346
347## N-I dash/ash status: 1
348## N-I dash/ash stdout-json: ""
349
350## OK yash STDOUT:
351# yash does not support scalar access. Instead, it replaces the array
352# with a scalar.
353['1']
354## END
355
356#### [compat_array] scalar write to associative arrays
357case ${SH##*/} in
358(dash|ash|yash|mksh) exit 1;; # dash/ash/yash/mksh does not have associative arrays
359(osh) shopt -s compat_array;;
360(zsh) setopt KSH_ARRAYS;;
361esac
362
363declare -A d=()
364d['0']=1
365d['foo']=hello
366d['bar']=world
367((d++))
368argv.py ${d['0']} ${d['foo']} ${d['bar']}
369## stdout: ['2', 'hello', 'world']
370
371## N-I dash/ash/yash/mksh status: 1
372## N-I dash/ash/yash/mksh stdout-json: ""
373
374## N-I zsh stdout: ['1', 'hello', 'world']
375
376#### [compat_array] ${alpha@a}
377declare -A alpha=(['1']=2)
378echo type=${alpha@a}
379shopt -s compat_array
380echo type=${alpha@a}
381## STDOUT:
382type=A
383type=A
384## END
385## N-I mksh/zsh status: 1
386## N-I dash/ash/yash status: 2
387## N-I dash/ash/yash/mksh/zsh stdout-json: ""