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

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