OILS / spec / var-op-bash.test.sh View on Github | oilshell.org

393 lines, 202 significant
1## compare_shells: bash-4.4
2## oils_failures_allowed: 6
3
4# TODO: bash 5.2.21 with lower case
5
6#### Lower Case with , and ,,
7x='ABC DEF'
8echo ${x,}
9echo ${x,,}
10echo empty=${empty,}
11echo empty=${empty,,}
12## STDOUT:
13aBC DEF
14abc def
15empty=
16empty=
17## END
18
19#### Upper Case with ^ and ^^
20x='abc def'
21echo ${x^}
22echo ${x^^}
23echo empty=${empty^}
24echo empty=${empty^^}
25## STDOUT:
26Abc def
27ABC DEF
28empty=
29empty=
30## END
31
32#### Case folding - Unicode characters
33
34# https://www.utf8-chartable.de/unicode-utf8-table.pl
35
36x=$'\u00C0\u00C8' # upper grave
37y=$'\u00E1\u00E9' # lower acute
38
39echo u ${x^}
40echo U ${x^^}
41
42echo l ${x,}
43echo L ${x,,}
44
45echo u ${y^}
46echo U ${y^^}
47
48echo l ${y,}
49echo L ${y,,}
50
51## STDOUT:
52u ÀÈ
53U ÀÈ
54l àÈ
55L àè
56u Áé
57U ÁÉ
58l áé
59L áé
60## END
61
62#### Case folding - multi code point
63
64echo shell
65small=$'\u00DF'
66echo u ${small^}
67echo U ${small^^}
68
69echo l ${small,}
70echo L ${small,,}
71echo
72
73echo python2
74python2 -c '
75small = u"\u00DF"
76print(small.upper().encode("utf-8"))
77print(small.lower().encode("utf-8"))
78'
79echo
80
81# Not in the container images, but python 3 DOES support it!
82# This is moved to demo/survey-case-fold.sh
83
84if false; then
85echo python3
86python3 -c '
87import sys
88small = u"\u00DF"
89sys.stdout.buffer.write(small.upper().encode("utf-8") + b"\n")
90sys.stdout.buffer.write(small.lower().encode("utf-8") + b"\n")
91'
92fi
93
94if false; then
95 # Yes, supported
96 echo node.js
97
98 nodejs -e '
99 var small = "\u00DF"
100 console.log(small.toUpperCase())
101 console.log(small.toLowerCase())
102 '
103fi
104
105## STDOUT:
106## END
107## BUG bash STDOUT:
108shell
109u ß
110U ß
111l ß
112L ß
113
114python2
115ß
116ß
117
118## END
119
120#### Case folding that depends on locale (not enabled, requires Turkish locale)
121
122# Hm this works in demo/survey-case-fold.sh
123# Is this a bash 4.4 thing?
124
125#export LANG='tr_TR.UTF-8'
126#echo $LANG
127
128x='i'
129
130echo u ${x^}
131echo U ${x^^}
132
133echo l ${x,}
134echo L ${x,,}
135
136## OK bash/osh STDOUT:
137u I
138U I
139l i
140L i
141## END
142
143#### Lower Case with constant string (VERY WEIRD)
144x='AAA ABC DEF'
145echo ${x,A}
146echo ${x,,A} # replaces every A only?
147## STDOUT:
148aAA ABC DEF
149aaa aBC DEF
150## END
151
152#### Lower Case glob
153
154# Hm with C.UTF-8, this does no case folding?
155export LC_ALL=en_US.UTF-8
156
157x='ABC DEF'
158echo ${x,[d-f]}
159echo ${x,,[d-f]} # This seems buggy, it doesn't include F?
160## STDOUT:
161ABC DEF
162ABC deF
163## END
164
165#### ${x@u} U l L upper / lower case (bash 5.1 feature)
166
167# https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
168
169x='abc def'
170echo "${x@u}"
171
172# TODO: we need to upgrade the spec tests to bash 5.1 (or bash 5.2 is coming
173# out soon)
174
175## N-I bash status: 1
176## N-I bash STDOUT:
177## END
178
179
180#### ${x@Q}
181x="FOO'BAR spam\"eggs"
182eval "new=${x@Q}"
183test "$x" = "$new" && echo OK
184## STDOUT:
185OK
186## END
187
188#### ${array@Q} and ${array[@]@Q}
189array=(x 'y\nz')
190echo ${array[@]@Q}
191echo ${array@Q}
192echo ${array@Q}
193## STDOUT:
194'x' 'y\nz'
195'x'
196'x'
197## END
198## OK osh STDOUT:
199x $'y\\nz'
200x
201x
202## END
203
204#### ${!prefix@} ${!prefix*} yields sorted array of var names
205ZOO=zoo
206ZIP=zip
207ZOOM='one two'
208Z='three four'
209
210z=lower
211
212argv.py ${!Z*}
213argv.py ${!Z@}
214argv.py "${!Z*}"
215argv.py "${!Z@}"
216for i in 1 2; do argv.py ${!Z*} ; done
217for i in 1 2; do argv.py ${!Z@} ; done
218for i in 1 2; do argv.py "${!Z*}"; done
219for i in 1 2; do argv.py "${!Z@}"; done
220## STDOUT:
221['Z', 'ZIP', 'ZOO', 'ZOOM']
222['Z', 'ZIP', 'ZOO', 'ZOOM']
223['Z ZIP ZOO ZOOM']
224['Z', 'ZIP', 'ZOO', 'ZOOM']
225['Z', 'ZIP', 'ZOO', 'ZOOM']
226['Z', 'ZIP', 'ZOO', 'ZOOM']
227['Z', 'ZIP', 'ZOO', 'ZOOM']
228['Z', 'ZIP', 'ZOO', 'ZOOM']
229['Z ZIP ZOO ZOOM']
230['Z ZIP ZOO ZOOM']
231['Z', 'ZIP', 'ZOO', 'ZOOM']
232['Z', 'ZIP', 'ZOO', 'ZOOM']
233## END
234
235#### ${!prefix@} matches var name (regression)
236hello1=1 hello2=2 hello3=3
237echo ${!hello@}
238hello=()
239echo ${!hello@}
240## STDOUT:
241hello1 hello2 hello3
242hello hello1 hello2 hello3
243## END
244
245#### ${var@a} for attributes
246array=(one two)
247echo ${array@a}
248declare -r array=(one two)
249echo ${array@a}
250declare -rx PYTHONPATH=hi
251echo ${PYTHONPATH@a}
252
253# bash and osh differ here
254#declare -rxn x=z
255#echo ${x@a}
256## STDOUT:
257a
258ar
259rx
260## END
261
262#### ${var@a} error conditions
263echo [${?@a}]
264## STDOUT:
265[]
266## END
267
268#### undef and @P @Q @a
269$SH -c 'echo ${undef@P}'
270echo status=$?
271$SH -c 'echo ${undef@Q}'
272echo status=$?
273$SH -c 'echo ${undef@a}'
274echo status=$?
275## STDOUT:
276
277status=0
278
279status=0
280
281status=0
282## END
283## OK osh STDOUT:
284
285status=0
286''
287status=0
288
289status=0
290## END
291
292
293#### argv array and @P @Q @a
294$SH -c 'echo ${@@P}' dummy a b c
295echo status=$?
296$SH -c 'echo ${@@Q}' dummy a 'b\nc'
297echo status=$?
298$SH -c 'echo ${@@a}' dummy a b c
299echo status=$?
300## STDOUT:
301a b c
302status=0
303'a' 'b\nc'
304status=0
305
306status=0
307## END
308## OK osh STDOUT:
309status=1
310a $'b\\nc'
311status=0
312a
313status=0
314## END
315
316#### assoc array and @P @Q @a
317
318# note: "y z" causes a bug!
319$SH -c 'declare -A A=(["x"]="y"); echo ${A@P} - ${A[@]@P}'
320echo status=$?
321
322# note: "y z" causes a bug!
323$SH -c 'declare -A A=(["x"]="y"); echo ${A@Q} - ${A[@]@Q}'
324echo status=$?
325
326$SH -c 'declare -A A=(["x"]=y); echo ${A@a} - ${A[@]@a}'
327echo status=$?
328## STDOUT:
329- y
330status=0
331- 'y'
332status=0
333A - A
334status=0
335## END
336## OK osh STDOUT:
337status=1
338status=1
339A - A
340status=0
341## END
342
343#### ${!var[@]@X}
344# note: "y z" causes a bug!
345$SH -c 'declare -A A=(["x"]="y"); echo ${!A[@]@P}'
346if test $? -ne 0; then echo fail; fi
347
348# note: "y z" causes a bug!
349$SH -c 'declare -A A=(["x y"]="y"); echo ${!A[@]@Q}'
350if test $? -ne 0; then echo fail; fi
351
352$SH -c 'declare -A A=(["x"]=y); echo ${!A[@]@a}'
353if test $? -ne 0; then echo fail; fi
354# STDOUT:
355
356
357
358# END
359## OK osh STDOUT:
360fail
361'x y'
362a
363## END
364
365#### ${#var@X} is a parse error
366# note: "y z" causes a bug!
367$SH -c 'declare -A A=(["x"]="y"); echo ${#A[@]@P}'
368if test $? -ne 0; then echo fail; fi
369
370# note: "y z" causes a bug!
371$SH -c 'declare -A A=(["x"]="y"); echo ${#A[@]@Q}'
372if test $? -ne 0; then echo fail; fi
373
374$SH -c 'declare -A A=(["x"]=y); echo ${#A[@]@a}'
375if test $? -ne 0; then echo fail; fi
376## STDOUT:
377fail
378fail
379fail
380## END
381
382#### ${!A@a} and ${!A[@]@a}
383declare -A A=(["x"]=y)
384echo x=${!A[@]@a}
385echo x=${!A@a}
386
387# OSH prints 'a' for indexed array because the AssocArray with ! turns into
388# it. Disallowing it would be the other reasonable behavior.
389
390## STDOUT:
391x=
392x=
393## END