]> git.ipfire.org Git - thirdparty/git.git/blob - t/t0040-parse-options.sh
test-parse-options: fix output when callback option fails
[thirdparty/git.git] / t / t0040-parse-options.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2007 Johannes Schindelin
4 #
5
6 test_description='our own option parser'
7
8 . ./test-lib.sh
9
10 cat >expect <<\EOF
11 usage: test-parse-options <options>
12
13 --yes get a boolean
14 -D, --no-doubt begins with 'no-'
15 -B, --no-fear be brave
16 -b, --boolean increment by one
17 -4, --or4 bitwise-or boolean with ...0100
18 --neg-or4 same as --no-or4
19
20 -i, --integer <n> get a integer
21 -j <n> get a integer, too
22 -m, --magnitude <n> get a magnitude
23 --set23 set integer to 23
24 -t <time> get timestamp of <time>
25 -L, --length <str> get length of <str>
26 -F, --file <file> set file to <file>
27
28 String options
29 -s, --string <string>
30 get a string
31 --string2 <str> get another string
32 --st <st> get another string (pervert ordering)
33 -o <str> get another string
34 --list <str> add str to list
35
36 Magic arguments
37 --quux means --quux
38 -NUM set integer to NUM
39 + same as -b
40 --ambiguous positive ambiguity
41 --no-ambiguous negative ambiguity
42
43 Standard options
44 --abbrev[=<n>] use <n> digits to display SHA-1s
45 -v, --verbose be verbose
46 -n, --dry-run dry run
47 -q, --quiet be quiet
48
49 EOF
50
51 test_expect_success 'test help' '
52 test_must_fail test-parse-options -h >output 2>output.err &&
53 test_must_be_empty output.err &&
54 test_i18ncmp expect output
55 '
56
57 mv expect expect.err
58
59 cat >expect.template <<\EOF
60 boolean: 0
61 integer: 0
62 magnitude: 0
63 timestamp: 0
64 string: (not set)
65 abbrev: 7
66 verbose: -1
67 quiet: 0
68 dry run: no
69 file: (not set)
70 EOF
71
72 check() {
73 what="$1" &&
74 shift &&
75 expect="$1" &&
76 shift &&
77 sed "s/^$what .*/$what $expect/" <expect.template >expect &&
78 test-parse-options $* >output 2>output.err &&
79 test_must_be_empty output.err &&
80 test_cmp expect output
81 }
82
83 check_i18n() {
84 what="$1" &&
85 shift &&
86 expect="$1" &&
87 shift &&
88 sed "s/^$what .*/$what $expect/" <expect.template >expect &&
89 test-parse-options $* >output 2>output.err &&
90 test_must_be_empty output.err &&
91 test_i18ncmp expect output
92 }
93
94 check_unknown() {
95 case "$1" in
96 --*)
97 echo error: unknown option \`${1#--}\' >expect ;;
98 -*)
99 echo error: unknown switch \`${1#-}\' >expect ;;
100 esac &&
101 cat expect.err >>expect &&
102 test_must_fail test-parse-options $* >output 2>output.err &&
103 test_must_be_empty output &&
104 test_cmp expect output.err
105 }
106
107 check_unknown_i18n() {
108 case "$1" in
109 --*)
110 echo error: unknown option \`${1#--}\' >expect ;;
111 -*)
112 echo error: unknown switch \`${1#-}\' >expect ;;
113 esac &&
114 cat expect.err >>expect &&
115 test_must_fail test-parse-options $* >output 2>output.err &&
116 test_must_be_empty output &&
117 test_i18ncmp expect output.err
118 }
119
120 test_expect_success 'OPT_BOOL() #1' 'check boolean: 1 --yes'
121 test_expect_success 'OPT_BOOL() #2' 'check boolean: 1 --no-doubt'
122 test_expect_success 'OPT_BOOL() #3' 'check boolean: 1 -D'
123 test_expect_success 'OPT_BOOL() #4' 'check boolean: 1 --no-fear'
124 test_expect_success 'OPT_BOOL() #5' 'check boolean: 1 -B'
125
126 test_expect_success 'OPT_BOOL() is idempotent #1' 'check boolean: 1 --yes --yes'
127 test_expect_success 'OPT_BOOL() is idempotent #2' 'check boolean: 1 -DB'
128
129 test_expect_success 'OPT_BOOL() negation #1' 'check boolean: 0 -D --no-yes'
130 test_expect_success 'OPT_BOOL() negation #2' 'check boolean: 0 -D --no-no-doubt'
131
132 test_expect_success 'OPT_BOOL() no negation #1' 'check_unknown_i18n --fear'
133 test_expect_success 'OPT_BOOL() no negation #2' 'check_unknown_i18n --no-no-fear'
134
135 test_expect_success 'OPT_BOOL() positivation' 'check boolean: 0 -D --doubt'
136
137 test_expect_success 'OPT_INT() negative' 'check integer: -2345 -i -2345'
138
139 test_expect_success 'OPT_MAGNITUDE() simple' '
140 check magnitude: 2345678 -m 2345678
141 '
142
143 test_expect_success 'OPT_MAGNITUDE() kilo' '
144 check magnitude: 239616 -m 234k
145 '
146
147 test_expect_success 'OPT_MAGNITUDE() mega' '
148 check magnitude: 104857600 -m 100m
149 '
150
151 test_expect_success 'OPT_MAGNITUDE() giga' '
152 check magnitude: 1073741824 -m 1g
153 '
154
155 test_expect_success 'OPT_MAGNITUDE() 3giga' '
156 check magnitude: 3221225472 -m 3g
157 '
158
159 cat >expect <<\EOF
160 boolean: 2
161 integer: 1729
162 magnitude: 16384
163 timestamp: 0
164 string: 123
165 abbrev: 7
166 verbose: 2
167 quiet: 0
168 dry run: yes
169 file: prefix/my.file
170 EOF
171
172 test_expect_success 'short options' '
173 test-parse-options -s123 -b -i 1729 -m 16k -b -vv -n -F my.file \
174 >output 2>output.err &&
175 test_cmp expect output &&
176 test_must_be_empty output.err
177 '
178
179 cat >expect <<\EOF
180 boolean: 2
181 integer: 1729
182 magnitude: 16384
183 timestamp: 0
184 string: 321
185 abbrev: 10
186 verbose: 2
187 quiet: 0
188 dry run: no
189 file: prefix/fi.le
190 EOF
191
192 test_expect_success 'long options' '
193 test-parse-options --boolean --integer 1729 --magnitude 16k \
194 --boolean --string2=321 --verbose --verbose --no-dry-run \
195 --abbrev=10 --file fi.le --obsolete \
196 >output 2>output.err &&
197 test_must_be_empty output.err &&
198 test_cmp expect output
199 '
200
201 test_expect_success 'missing required value' '
202 test_expect_code 129 test-parse-options -s &&
203 test_expect_code 129 test-parse-options --string &&
204 test_expect_code 129 test-parse-options --file
205 '
206
207 cat >expect <<\EOF
208 boolean: 1
209 integer: 13
210 magnitude: 0
211 timestamp: 0
212 string: 123
213 abbrev: 7
214 verbose: -1
215 quiet: 0
216 dry run: no
217 file: (not set)
218 arg 00: a1
219 arg 01: b1
220 arg 02: --boolean
221 EOF
222
223 test_expect_success 'intermingled arguments' '
224 test-parse-options a1 --string 123 b1 --boolean -j 13 -- --boolean \
225 >output 2>output.err &&
226 test_must_be_empty output.err &&
227 test_cmp expect output
228 '
229
230 cat >expect <<\EOF
231 boolean: 0
232 integer: 2
233 magnitude: 0
234 timestamp: 0
235 string: (not set)
236 abbrev: 7
237 verbose: -1
238 quiet: 0
239 dry run: no
240 file: (not set)
241 EOF
242
243 test_expect_success 'unambiguously abbreviated option' '
244 test-parse-options --int 2 --boolean --no-bo >output 2>output.err &&
245 test_must_be_empty output.err &&
246 test_cmp expect output
247 '
248
249 test_expect_success 'unambiguously abbreviated option with "="' '
250 test-parse-options --int=2 >output 2>output.err &&
251 test_must_be_empty output.err &&
252 test_cmp expect output
253 '
254
255 test_expect_success 'ambiguously abbreviated option' '
256 test_expect_code 129 test-parse-options --strin 123
257 '
258
259 cat >expect <<\EOF
260 boolean: 0
261 integer: 0
262 magnitude: 0
263 timestamp: 0
264 string: 123
265 abbrev: 7
266 verbose: -1
267 quiet: 0
268 dry run: no
269 file: (not set)
270 EOF
271
272 test_expect_success 'non ambiguous option (after two options it abbreviates)' '
273 test-parse-options --st 123 >output 2>output.err &&
274 test_must_be_empty output.err &&
275 test_cmp expect output
276 '
277
278 cat >typo.err <<\EOF
279 error: did you mean `--boolean` (with two dashes ?)
280 EOF
281
282 test_expect_success 'detect possible typos' '
283 test_must_fail test-parse-options -boolean >output 2>output.err &&
284 test_must_be_empty output &&
285 test_cmp typo.err output.err
286 '
287
288 cat >typo.err <<\EOF
289 error: did you mean `--ambiguous` (with two dashes ?)
290 EOF
291
292 test_expect_success 'detect possible typos' '
293 test_must_fail test-parse-options -ambiguous >output 2>output.err &&
294 test_must_be_empty output &&
295 test_cmp typo.err output.err
296 '
297
298 cat >expect <<\EOF
299 boolean: 0
300 integer: 0
301 magnitude: 0
302 timestamp: 0
303 string: (not set)
304 abbrev: 7
305 verbose: -1
306 quiet: 0
307 dry run: no
308 file: (not set)
309 arg 00: --quux
310 EOF
311
312 test_expect_success 'keep some options as arguments' '
313 test-parse-options --quux >output 2>output.err &&
314 test_must_be_empty output.err &&
315 test_cmp expect output
316 '
317
318 cat >expect <<\EOF
319 boolean: 0
320 integer: 0
321 magnitude: 0
322 timestamp: 1
323 string: (not set)
324 abbrev: 7
325 verbose: -1
326 quiet: 1
327 dry run: no
328 file: (not set)
329 arg 00: foo
330 EOF
331
332 test_expect_success 'OPT_DATE() works' '
333 test-parse-options -t "1970-01-01 00:00:01 +0000" \
334 foo -q >output 2>output.err &&
335 test_must_be_empty output.err &&
336 test_cmp expect output
337 '
338
339 cat >expect <<\EOF
340 Callback: "four", 0
341 boolean: 5
342 integer: 4
343 magnitude: 0
344 timestamp: 0
345 string: (not set)
346 abbrev: 7
347 verbose: -1
348 quiet: 0
349 dry run: no
350 file: (not set)
351 EOF
352
353 test_expect_success 'OPT_CALLBACK() and OPT_BIT() work' '
354 test-parse-options --length=four -b -4 >output 2>output.err &&
355 test_must_be_empty output.err &&
356 test_cmp expect output
357 '
358
359 >expect
360
361 test_expect_success 'OPT_CALLBACK() and callback errors work' '
362 test_must_fail test-parse-options --no-length >output 2>output.err &&
363 test_i18ncmp expect output &&
364 test_i18ncmp expect.err output.err
365 '
366
367 cat >expect <<\EOF
368 boolean: 1
369 integer: 23
370 magnitude: 0
371 timestamp: 0
372 string: (not set)
373 abbrev: 7
374 verbose: -1
375 quiet: 0
376 dry run: no
377 file: (not set)
378 EOF
379
380 test_expect_success 'OPT_BIT() and OPT_SET_INT() work' '
381 test-parse-options --set23 -bbbbb --no-or4 >output 2>output.err &&
382 test_must_be_empty output.err &&
383 test_cmp expect output
384 '
385
386 test_expect_success 'OPT_NEGBIT() and OPT_SET_INT() work' '
387 test-parse-options --set23 -bbbbb --neg-or4 >output 2>output.err &&
388 test_must_be_empty output.err &&
389 test_cmp expect output
390 '
391
392 cat >expect <<\EOF
393 boolean: 6
394 integer: 0
395 magnitude: 0
396 timestamp: 0
397 string: (not set)
398 abbrev: 7
399 verbose: -1
400 quiet: 0
401 dry run: no
402 file: (not set)
403 EOF
404
405 test_expect_success 'OPT_BIT() works' '
406 test-parse-options -bb --or4 >output 2>output.err &&
407 test_must_be_empty output.err &&
408 test_cmp expect output
409 '
410
411 test_expect_success 'OPT_NEGBIT() works' '
412 test-parse-options -bb --no-neg-or4 >output 2>output.err &&
413 test_must_be_empty output.err &&
414 test_cmp expect output
415 '
416
417 test_expect_success 'OPT_COUNTUP() with PARSE_OPT_NODASH works' '
418 test-parse-options + + + + + + >output 2>output.err &&
419 test_must_be_empty output.err &&
420 test_cmp expect output
421 '
422
423 cat >expect <<\EOF
424 boolean: 0
425 integer: 12345
426 magnitude: 0
427 timestamp: 0
428 string: (not set)
429 abbrev: 7
430 verbose: -1
431 quiet: 0
432 dry run: no
433 file: (not set)
434 EOF
435
436 test_expect_success 'OPT_NUMBER_CALLBACK() works' '
437 test-parse-options -12345 >output 2>output.err &&
438 test_must_be_empty output.err &&
439 test_cmp expect output
440 '
441
442 cat >expect <<\EOF
443 boolean: 0
444 integer: 0
445 magnitude: 0
446 timestamp: 0
447 string: (not set)
448 abbrev: 7
449 verbose: -1
450 quiet: 0
451 dry run: no
452 file: (not set)
453 EOF
454
455 test_expect_success 'negation of OPT_NONEG flags is not ambiguous' '
456 test-parse-options --no-ambig >output 2>output.err &&
457 test_must_be_empty output.err &&
458 test_cmp expect output
459 '
460
461 cat >>expect <<\EOF
462 list: foo
463 list: bar
464 list: baz
465 EOF
466 test_expect_success '--list keeps list of strings' '
467 test-parse-options --list foo --list=bar --list=baz >output &&
468 test_cmp expect output
469 '
470
471 test_expect_success '--no-list resets list' '
472 test-parse-options --list=other --list=irrelevant --list=options \
473 --no-list --list=foo --list=bar --list=baz >output &&
474 test_cmp expect output
475 '
476
477 cat >expect <<\EOF
478 boolean: 0
479 integer: 0
480 magnitude: 0
481 timestamp: 0
482 string: (not set)
483 abbrev: 7
484 verbose: -1
485 quiet: 3
486 dry run: no
487 file: (not set)
488 EOF
489
490 test_expect_success 'multiple quiet levels' '
491 test-parse-options -q -q -q >output 2>output.err &&
492 test_must_be_empty output.err &&
493 test_cmp expect output
494 '
495
496 cat >expect <<\EOF
497 boolean: 0
498 integer: 0
499 magnitude: 0
500 timestamp: 0
501 string: (not set)
502 abbrev: 7
503 verbose: 3
504 quiet: 0
505 dry run: no
506 file: (not set)
507 EOF
508
509 test_expect_success 'multiple verbose levels' '
510 test-parse-options -v -v -v >output 2>output.err &&
511 test_must_be_empty output.err &&
512 test_cmp expect output
513 '
514
515 cat >expect <<\EOF
516 boolean: 0
517 integer: 0
518 magnitude: 0
519 timestamp: 0
520 string: (not set)
521 abbrev: 7
522 verbose: -1
523 quiet: 0
524 dry run: no
525 file: (not set)
526 EOF
527
528 test_expect_success '--no-quiet sets --quiet to 0' '
529 test-parse-options --no-quiet >output 2>output.err &&
530 test_must_be_empty output.err &&
531 test_cmp expect output
532 '
533
534 cat >expect <<\EOF
535 boolean: 0
536 integer: 0
537 magnitude: 0
538 timestamp: 0
539 string: (not set)
540 abbrev: 7
541 verbose: -1
542 quiet: 0
543 dry run: no
544 file: (not set)
545 EOF
546
547 test_expect_success '--no-quiet resets multiple -q to 0' '
548 test-parse-options -q -q -q --no-quiet >output 2>output.err &&
549 test_must_be_empty output.err &&
550 test_cmp expect output
551 '
552
553 cat >expect <<\EOF
554 boolean: 0
555 integer: 0
556 magnitude: 0
557 timestamp: 0
558 string: (not set)
559 abbrev: 7
560 verbose: 0
561 quiet: 0
562 dry run: no
563 file: (not set)
564 EOF
565
566 test_expect_success '--no-verbose sets verbose to 0' '
567 test-parse-options --no-verbose >output 2>output.err &&
568 test_must_be_empty output.err &&
569 test_cmp expect output
570 '
571
572 cat >expect <<\EOF
573 boolean: 0
574 integer: 0
575 magnitude: 0
576 timestamp: 0
577 string: (not set)
578 abbrev: 7
579 verbose: 0
580 quiet: 0
581 dry run: no
582 file: (not set)
583 EOF
584
585 test_expect_success '--no-verbose resets multiple verbose to 0' '
586 test-parse-options -v -v -v --no-verbose >output 2>output.err &&
587 test_must_be_empty output.err &&
588 test_cmp expect output
589 '
590
591 test_done