OILS / spec / case_.test.sh View on Github | oilshell.org

244 lines, 120 significant
1## compare_shells: bash dash mksh zsh
2## oils_failures_allowed: 0
3
4# Note: zsh passes most of these tests too
5
6#### Case statement
7case a in
8 a) echo A ;;
9 *) echo star ;;
10esac
11
12for x in a b; do
13 case $x in
14 # the pattern is DYNAMIC and evaluated on every iteration
15 $x) echo loop ;;
16 *) echo star ;;
17 esac
18done
19## STDOUT:
20A
21loop
22loop
23## END
24
25#### Case statement with ;;&
26# ;;& keeps testing conditions
27# NOTE: ;& and ;;& are bash 4 only, not on Mac
28case a in
29 a) echo A ;;&
30 *) echo star ;;&
31 *) echo star2 ;;
32esac
33## status: 0
34## STDOUT:
35A
36star
37star2
38## END
39## N-I dash stdout-json: ""
40## N-I dash status: 2
41## N-I zsh stdout-json: ""
42## N-I zsh status: 1
43
44#### Case statement with ;&
45# ;& ignores the next condition. Why would that be useful?
46
47for x in aa bb cc dd zz; do
48 case $x in
49 aa) echo aa ;&
50 bb) echo bb ;&
51 cc) echo cc ;;
52 dd) echo dd ;;
53 esac
54 echo --
55done
56
57## status: 0
58## STDOUT:
59aa
60bb
61cc
62--
63bb
64cc
65--
66cc
67--
68dd
69--
70--
71## END
72## N-I dash stdout-json: ""
73## N-I dash status: 2
74
75#### Case with empty condition
76case $empty in
77 ''|foo) echo match ;;
78 *) echo no ;;
79esac
80## stdout: match
81
82#### Match a literal with a glob character
83x='*.py'
84case "$x" in
85 '*.py') echo match ;;
86esac
87## stdout: match
88
89#### Match a literal with a glob character with a dynamic pattern
90x='b.py'
91pat='[ab].py'
92case "$x" in
93 $pat) echo match ;;
94esac
95## stdout: match
96## BUG zsh stdout-json: ""
97
98#### Quoted literal in glob pattern
99x='[ab].py'
100pat='[ab].py'
101case "$x" in
102 "$pat") echo match ;;
103esac
104## stdout: match
105
106#### Multiple Patterns Match
107x=foo
108result='-'
109case "$x" in
110 f*|*o) result="$result X"
111esac
112echo $result
113## stdout: - X
114
115#### Pattern ? matches 1 code point (many bytes), but not multiple code points
116
117# These two code points form a single character.
118two_code_points="__$(echo $'\u0061\u0300')__"
119
120# U+0061 is A, and U+0300 is an accent.
121#
122# (Example taken from # https://blog.golang.org/strings)
123#
124# However ? in bash/zsh only counts CODE POINTS. They do NOT take into account
125# this case.
126
127for s in '__a__' '__μ__' "$two_code_points"; do
128 case $s in
129 __?__)
130 echo yes
131 ;;
132 *)
133 echo no
134 esac
135done
136## STDOUT:
137yes
138yes
139no
140## END
141## BUG dash/mksh STDOUT:
142yes
143no
144no
145## END
146
147#### matching the byte 0xff against empty string - DISABLED - CI only bug?
148
149case $SH in *osh) echo soil-ci-buster-slim-bug; exit ;; esac
150
151# This doesn't make a difference on my local machine?
152# Is the underlying issue how libc fnmatch() respects Unicode?
153
154#LC_ALL=C
155#LC_ALL=C.UTF-8
156
157c=$(printf \\377)
158
159# OSH prints -1 here
160#echo "${#c}"
161
162case $c in
163 '') echo a ;;
164 "$c") echo b ;;
165esac
166
167case "$c" in
168 '') echo a ;;
169 "$c") echo b ;;
170esac
171
172## STDOUT:
173b
174b
175## END
176
177## OK osh STDOUT:
178soil-ci-buster-slim-bug
179## END
180
181#### matching every byte against itself
182
183# Why does OSH on the CI machine behave differently? Probably a libc bug fix
184# I'd guess?
185
186sum=0
187
188# note: NUL byte crashes OSH!
189for i in $(seq 1 255); do
190 hex=$(printf '%x' "$i")
191 c="$(printf "\\x$hex")" # command sub quirk: \n or \x0a turns into empty string
192
193 #echo -n $c | od -A n -t x1
194 #echo ${#c}
195
196 case "$c" in
197 # Newline matches empty string somehow. All shells agree. I guess
198 # fnmatch() ignores trailing newline?
199 #'') echo "[empty i=$i hex=$hex c=$c]" ;;
200 "$c") sum=$(( sum + 1 )) ;;
201 *) echo "[bug i=$i hex=$hex c=$c]" ;;
202 esac
203done
204
205echo sum=$sum
206
207## STDOUT:
208sum=255
209## END
210
211#### \(\) in pattern (regression)
212s='foo()'
213
214case $s in
215 *\(\)) echo 'match'
216esac
217
218case $SH in (dash) exit;; esac # not implemented
219
220shopt -s extglob
221
222case $s in
223 *(foo|bar)'()') echo 'extglob'
224esac
225## STDOUT:
226match
227extglob
228## END
229## N-I dash STDOUT:
230match
231## END
232
233
234#### case \n bug regression
235
236case
237in esac
238
239## STDOUT:
240## END
241## status: 2
242## OK mksh status: 1
243## OK zsh status: 127
244