OILS / spec / extglob-match.test.sh View on Github | oilshell.org

400 lines, 235 significant
1# Test extended glob matching with [[, case, etc.
2
3#### @ matches exactly one
4shopt -s extglob # needed for Oil, not bash
5[[ --verbose == --@(help|verbose) ]] && echo TRUE
6[[ --oops == --@(help|verbose) ]] || echo FALSE
7## STDOUT:
8TRUE
9FALSE
10## END
11
12#### @() with variable arms
13shopt -s extglob # needed for Oil, not bash
14choice1='help'
15choice2='verbose'
16[[ --verbose == --@($choice1|$choice2) ]] && echo TRUE
17[[ --oops == --@($choice1|$choice2) ]] || echo FALSE
18## STDOUT:
19TRUE
20FALSE
21## END
22
23#### extglob in variable
24shopt -s extglob
25
26# this syntax requires extglob in bash!!
27# OSH never allows it
28g=--@(help|verbose)
29
30quoted='--@(help|verbose)'
31
32[[ --help == $g ]] && echo TRUE
33[[ --verbose == $g ]] && echo TRUE
34[[ -- == $g ]] || echo FALSE
35[[ --help == $q ]] || echo FALSE
36[[ -- == $q ]] || echo FALSE
37## STDOUT:
38TRUE
39TRUE
40FALSE
41FALSE
42FALSE
43## END
44## N-I mksh STDOUT:
45FALSE
46FALSE
47FALSE
48## END
49## OK osh status: 1
50## OK osh STDOUT:
51## END
52
53#### Matching literal '@(cc)'
54
55# extglob is OFF. Doesn't affect bash or mksh!
56[[ cc == @(cc) ]]
57echo status=$?
58[[ cc == '@(cc)' ]]
59echo status=$?
60
61shopt -s extglob
62
63[[ cc == @(cc) ]]
64echo status=$?
65[[ cc == '@(cc)' ]]
66echo status=$?
67
68## STDOUT:
69status=0
70status=1
71status=0
72status=1
73## END
74
75#### nested @()
76shopt -s extglob
77pat='--@(help|verbose|no-@(long|short)-option)'
78[[ --no-long-option == $pat ]] && echo TRUE
79[[ --no-short-option == $pat ]] && echo TRUE
80[[ --help == $pat ]] && echo TRUE
81[[ --oops == $pat ]] || echo FALSE
82## STDOUT:
83TRUE
84TRUE
85TRUE
86FALSE
87## END
88## BUG mksh STDOUT:
89FALSE
90## END
91
92#### nested @() with quotes and vars
93shopt -s extglob
94prefix=no
95[[ --no-long-option == --@(help|verbose|$prefix-@(long|short)-'option') ]] &&
96 echo TRUE
97## STDOUT:
98TRUE
99## END
100
101#### ? matches 0 or 1
102shopt -s extglob # needed for Oil, not bash
103[[ -- == --?(help|verbose) ]] && echo TRUE
104[[ --oops == --?(help|verbose) ]] || echo FALSE
105## STDOUT:
106TRUE
107FALSE
108## END
109
110#### + matches 1 or more
111shopt -s extglob # needed for Oil, not bash
112[[ --helphelp == --+(help|verbose) ]] && echo TRUE
113[[ -- == --+(help|verbose) ]] || echo FALSE
114## STDOUT:
115TRUE
116FALSE
117## END
118
119#### * matches 0 or more
120shopt -s extglob # needed for Oil, not bash
121[[ -- == --*(help|verbose) ]] && echo TRUE
122[[ --oops == --*(help|verbose) ]] || echo FALSE
123## STDOUT:
124TRUE
125FALSE
126## END
127
128#### simple repetition with *(foo) and +(Foo)
129shopt -s extglob # needed for Oil, not bash
130[[ foofoo == *(foo) ]] && echo TRUE
131[[ foofoo == +(foo) ]] && echo TRUE
132## STDOUT:
133TRUE
134TRUE
135## END
136
137#### ! matches none
138shopt -s extglob # needed for Oil, not bash
139[[ --oops == --!(help|verbose) ]] && echo TRUE
140[[ --help == --!(help|verbose) ]] || echo FALSE
141## STDOUT:
142TRUE
143FALSE
144## END
145
146#### match is anchored
147shopt -s extglob # needed for Oil, not bash
148[[ foo_ == @(foo) ]] || echo FALSE
149[[ _foo == @(foo) ]] || echo FALSE
150[[ foo == @(foo) ]] && echo TRUE
151## STDOUT:
152FALSE
153FALSE
154TRUE
155## END
156
157#### repeated match is anchored
158shopt -s extglob # needed for Oil, not bash
159[[ foofoo_ == +(foo) ]] || echo FALSE
160[[ _foofoo == +(foo) ]] || echo FALSE
161[[ foofoo == +(foo) ]] && echo TRUE
162## STDOUT:
163FALSE
164FALSE
165TRUE
166## END
167
168#### repetition with glob
169shopt -s extglob # needed for Oil, not bash
170
171# NOTE that * means two different things here
172[[ foofoo_foo__foo___ == *(foo*) ]] && echo TRUE
173[[ Xoofoo_foo__foo___ == *(foo*) ]] || echo FALSE
174## STDOUT:
175TRUE
176FALSE
177## END
178
179#### No brace expansion in ==
180shopt -s extglob # needed for Oil, not bash
181
182[[ --X{a,b}X == --@(help|X{a,b}X) ]] && echo TRUE
183[[ --oops == --@(help|X{a,b}X) ]] || echo FALSE
184## STDOUT:
185TRUE
186FALSE
187## END
188
189#### adjacent extglob
190shopt -s extglob # needed for Oil, not bash
191
192[[ --help == @(--|++)@(help|verbose) ]] && echo TRUE
193[[ ++verbose == @(--|++)@(help|verbose) ]] && echo TRUE
194## STDOUT:
195TRUE
196TRUE
197## END
198
199#### nested extglob
200shopt -s extglob # needed for Oil, not bash
201
202[[ --help == --@(help|verbose=@(1|2)) ]] && echo TRUE
203[[ --verbose=1 == --@(help|verbose=@(1|2)) ]] && echo TRUE
204[[ --verbose=2 == --@(help|verbose=@(1|2)) ]] && echo TRUE
205[[ --verbose == --@(help|verbose=@(1|2)) ]] || echo FALSE
206## STDOUT:
207TRUE
208TRUE
209TRUE
210FALSE
211## END
212
213#### extglob empty string
214shopt -s extglob
215[[ '' == @(foo|bar) ]] || echo FALSE
216[[ '' == @(foo||bar) ]] && echo TRUE
217## STDOUT:
218FALSE
219TRUE
220## END
221
222#### extglob empty pattern
223shopt -s extglob
224[[ '' == @() ]] && echo TRUE
225[[ '' == @(||) ]] && echo TRUE
226[[ X == @() ]] || echo FALSE
227[[ '|' == @(||) ]] || echo FALSE
228## STDOUT:
229TRUE
230TRUE
231FALSE
232FALSE
233## END
234
235#### case with extglob
236shopt -s extglob
237for word in --help --verbose --unmatched -- -zxzx -; do
238 case $word in
239 --@(help|verbose) )
240 echo A
241 continue
242 ;;
243 ( --?(b|c) )
244 echo B
245 continue
246 ;;
247 ( -+(x|z) )
248 echo C
249 continue
250 ;;
251 ( -*(x|z) )
252 echo D
253 continue
254 ;;
255 *)
256 echo U
257 continue
258 ;;
259 esac
260done
261## STDOUT:
262A
263A
264U
265B
266C
267D
268## END
269
270#### [[ $x == !($str) ]]
271shopt -s extglob
272empty=''
273str='x'
274[[ $empty == !($str) ]] && echo TRUE # test glob match
275[[ $str == !($str) ]] || echo FALSE
276## STDOUT:
277TRUE
278FALSE
279## END
280
281#### Turning extglob on changes the meaning of [[ !(str) ]] in bash
282empty=''
283str='x'
284[[ !($empty) ]] && echo TRUE # test if $empty is empty
285[[ !($str) ]] || echo FALSE # test if $str is empty
286shopt -s extglob # mksh doesn't have this
287[[ !($empty) ]] && echo TRUE # negated glob
288[[ !($str) ]] && echo TRUE # negated glob
289## STDOUT:
290TRUE
291FALSE
292TRUE
293TRUE
294## END
295## OK mksh STDOUT:
296TRUE
297TRUE
298TRUE
299## END
300
301# osh fails with runtime error
302## OK osh status: 1
303## OK osh STDOUT:
304## END
305
306#### With extglob on, !($str) on the left or right of == has different meanings
307shopt -s extglob
308str='x'
309[[ 1 == !($str) ]] && echo TRUE # glob match
310
311## STDOUT:
312TRUE
313## END
314
315#### extglob inside arg word
316shopt -s extglob
317[[ foo == @(foo|bar) ]] && echo TRUE
318[[ foo == ${unset:-@(foo|bar)} ]] && echo TRUE
319[[ fo == ${unset:-@(foo|bar)} ]] || echo FALSE
320## STDOUT:
321TRUE
322TRUE
323FALSE
324## END
325## BUG mksh STDOUT:
326TRUE
327FALSE
328## END
329## OK osh status: 1
330## OK osh STDOUT:
331TRUE
332## END
333
334#### extglob is not detected in regex!
335shopt -s extglob
336[[ foo =~ ^@(foo|bar)$ ]] || echo FALSE
337## STDOUT:
338FALSE
339## END
340## N-I mksh stdout-json: ""
341## N-I mksh status: 1
342
343
344#### regular glob of single unicode char
345shopt -s extglob
346[[ __a__ == __?__ ]]
347echo $?
348[[ __μ__ == __?__ ]]
349echo $?
350## STDOUT:
3510
3520
353## END
354## BUG mksh STDOUT:
3550
3561
357## END
358
359#### extended glob of single unicode char
360shopt -s extglob
361[[ __a__ == @(__?__) ]]
362echo $?
363[[ __μ__ == @(__?__) ]]
364echo $?
365## STDOUT:
3660
3670
368## END
369## BUG mksh STDOUT:
3700
3711
372## END
373
374#### Extended glob in ${x//pat/replace}
375# not supported in OSH due to GlobToERE() strategy for positional info
376
377shopt -s extglob
378x=foo.py
379echo ${x//@(?.py)/Z}
380## STDOUT:
381foZ
382## END
383## N-I osh status: 1
384## N-I osh stdout-json: ""
385
386#### Extended glob in ${x%PATTERN}
387
388shopt -s extglob
389x=foo.py
390echo 'strip % ' ${x%.@(py|cc)}
391echo 'strip %%' ${x%%.@(py|cc)}
392echo 'strip # ' ${x#@(foo)}
393echo 'strip ##' ${x##@(foo)}
394
395## STDOUT:
396strip % foo
397strip %% foo
398strip # .py
399strip ## .py
400## END