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

397 lines, 207 significant
1## compare_shells: bash
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]} # bash 4.4 fixed in bash 5.2.21
160## STDOUT:
161ABC DEF
162ABC DEF
163## END
164
165#### ${x@u} U 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'
170
171echo "${x@u}"
172
173echo "${x@U}"
174
175echo "${x@L}"
176
177## STDOUT:
178Abc DEF
179ABC DEF
180abc def
181## END
182
183
184#### ${x@Q}
185x="FOO'BAR spam\"eggs"
186eval "new=${x@Q}"
187test "$x" = "$new" && echo OK
188## STDOUT:
189OK
190## END
191
192#### ${array@Q} and ${array[@]@Q}
193array=(x 'y\nz')
194echo ${array[@]@Q}
195echo ${array@Q}
196echo ${array@Q}
197## STDOUT:
198'x' 'y\nz'
199'x'
200'x'
201## END
202## OK osh STDOUT:
203x $'y\\nz'
204x
205x
206## END
207
208#### ${!prefix@} ${!prefix*} yields sorted array of var names
209ZOO=zoo
210ZIP=zip
211ZOOM='one two'
212Z='three four'
213
214z=lower
215
216argv.py ${!Z*}
217argv.py ${!Z@}
218argv.py "${!Z*}"
219argv.py "${!Z@}"
220for i in 1 2; do argv.py ${!Z*} ; done
221for i in 1 2; do argv.py ${!Z@} ; done
222for i in 1 2; do argv.py "${!Z*}"; done
223for i in 1 2; do argv.py "${!Z@}"; done
224## STDOUT:
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['Z ZIP ZOO ZOOM']
234['Z ZIP ZOO ZOOM']
235['Z', 'ZIP', 'ZOO', 'ZOOM']
236['Z', 'ZIP', 'ZOO', 'ZOOM']
237## END
238
239#### ${!prefix@} matches var name (regression)
240hello1=1 hello2=2 hello3=3
241echo ${!hello@}
242hello=()
243echo ${!hello@}
244## STDOUT:
245hello1 hello2 hello3
246hello hello1 hello2 hello3
247## END
248
249#### ${var@a} for attributes
250array=(one two)
251echo ${array@a}
252declare -r array=(one two)
253echo ${array@a}
254declare -rx PYTHONPATH=hi
255echo ${PYTHONPATH@a}
256
257# bash and osh differ here
258#declare -rxn x=z
259#echo ${x@a}
260## STDOUT:
261a
262ar
263rx
264## END
265
266#### ${var@a} error conditions
267echo [${?@a}]
268## STDOUT:
269[]
270## END
271
272#### undef and @P @Q @a
273$SH -c 'echo ${undef@P}'
274echo status=$?
275$SH -c 'echo ${undef@Q}'
276echo status=$?
277$SH -c 'echo ${undef@a}'
278echo status=$?
279## STDOUT:
280
281status=0
282
283status=0
284
285status=0
286## END
287## OK osh STDOUT:
288
289status=0
290''
291status=0
292
293status=0
294## END
295
296
297#### argv array and @P @Q @a
298$SH -c 'echo ${@@P}' dummy a b c
299echo status=$?
300$SH -c 'echo ${@@Q}' dummy a 'b\nc'
301echo status=$?
302$SH -c 'echo ${@@a}' dummy a b c
303echo status=$?
304## STDOUT:
305a b c
306status=0
307'a' 'b\nc'
308status=0
309
310status=0
311## END
312## OK osh STDOUT:
313status=1
314a $'b\\nc'
315status=0
316a
317status=0
318## END
319
320#### assoc array and @P @Q @a
321
322# note: "y z" causes a bug!
323$SH -c 'declare -A A=(["x"]="y"); echo ${A@P} - ${A[@]@P}'
324echo status=$?
325
326# note: "y z" causes a bug!
327$SH -c 'declare -A A=(["x"]="y"); echo ${A@Q} - ${A[@]@Q}'
328echo status=$?
329
330$SH -c 'declare -A A=(["x"]=y); echo ${A@a} - ${A[@]@a}'
331echo status=$?
332## STDOUT:
333- y
334status=0
335- 'y'
336status=0
337A - A
338status=0
339## END
340## OK osh STDOUT:
341status=1
342status=1
343A - A
344status=0
345## END
346
347#### ${!var[@]@X}
348# note: "y z" causes a bug!
349$SH -c 'declare -A A=(["x"]="y"); echo ${!A[@]@P}'
350if test $? -ne 0; then echo fail; fi
351
352# note: "y z" causes a bug!
353$SH -c 'declare -A A=(["x y"]="y"); echo ${!A[@]@Q}'
354if test $? -ne 0; then echo fail; fi
355
356$SH -c 'declare -A A=(["x"]=y); echo ${!A[@]@a}'
357if test $? -ne 0; then echo fail; fi
358# STDOUT:
359
360
361
362# END
363## OK osh STDOUT:
364fail
365'x y'
366a
367## END
368
369#### ${#var@X} is a parse error
370# note: "y z" causes a bug!
371$SH -c 'declare -A A=(["x"]="y"); echo ${#A[@]@P}'
372if test $? -ne 0; then echo fail; fi
373
374# note: "y z" causes a bug!
375$SH -c 'declare -A A=(["x"]="y"); echo ${#A[@]@Q}'
376if test $? -ne 0; then echo fail; fi
377
378$SH -c 'declare -A A=(["x"]=y); echo ${#A[@]@a}'
379if test $? -ne 0; then echo fail; fi
380## STDOUT:
381fail
382fail
383fail
384## END
385
386#### ${!A@a} and ${!A[@]@a}
387declare -A A=(["x"]=y)
388echo x=${!A[@]@a}
389echo x=${!A@a}
390
391# OSH prints 'a' for indexed array because the AssocArray with ! turns into
392# it. Disallowing it would be the other reasonable behavior.
393
394## STDOUT:
395x=
396x=
397## END