Merge branch 'bc/receive-pack-stdout-protection'
[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     --set23               set integer to 23
23     -t <time>             get timestamp of <time>
24     -L, --length <str>    get length of <str>
25     -F, --file <file>     set file to <file>
26
27 String options
28     -s, --string <string>
29                           get a string
30     --string2 <str>       get another string
31     --st <st>             get another string (pervert ordering)
32     -o <str>              get another string
33     --default-string      set string to default
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 ! -s output.err &&
54         test_cmp expect output
55 '
56
57 mv expect expect.err
58
59 cat >expect.template <<EOF
60 boolean: 0
61 integer: 0
62 timestamp: 0
63 string: (not set)
64 abbrev: 7
65 verbose: 0
66 quiet: no
67 dry run: no
68 file: (not set)
69 EOF
70
71 check() {
72         what="$1" &&
73         shift &&
74         expect="$1" &&
75         shift &&
76         sed "s/^$what .*/$what $expect/" <expect.template >expect &&
77         test-parse-options $* >output 2>output.err &&
78         test ! -s output.err &&
79         test_cmp expect output
80 }
81
82 check_unknown() {
83         case "$1" in
84         --*)
85                 echo error: unknown option \`${1#--}\' >expect ;;
86         -*)
87                 echo error: unknown switch \`${1#-}\' >expect ;;
88         esac &&
89         cat expect.err >>expect &&
90         test_must_fail test-parse-options $* >output 2>output.err &&
91         test ! -s output &&
92         test_cmp expect output.err
93 }
94
95 test_expect_success 'OPT_BOOL() #1' 'check boolean: 1 --yes'
96 test_expect_success 'OPT_BOOL() #2' 'check boolean: 1 --no-doubt'
97 test_expect_success 'OPT_BOOL() #3' 'check boolean: 1 -D'
98 test_expect_success 'OPT_BOOL() #4' 'check boolean: 1 --no-fear'
99 test_expect_success 'OPT_BOOL() #5' 'check boolean: 1 -B'
100
101 test_expect_success 'OPT_BOOL() is idempotent #1' 'check boolean: 1 --yes --yes'
102 test_expect_success 'OPT_BOOL() is idempotent #2' 'check boolean: 1 -DB'
103
104 test_expect_success 'OPT_BOOL() negation #1' 'check boolean: 0 -D --no-yes'
105 test_expect_success 'OPT_BOOL() negation #2' 'check boolean: 0 -D --no-no-doubt'
106
107 test_expect_success 'OPT_BOOL() no negation #1' 'check_unknown --fear'
108 test_expect_success 'OPT_BOOL() no negation #2' 'check_unknown --no-no-fear'
109
110 test_expect_success 'OPT_BOOL() positivation' 'check boolean: 0 -D --doubt'
111
112 cat > expect << EOF
113 boolean: 2
114 integer: 1729
115 timestamp: 0
116 string: 123
117 abbrev: 7
118 verbose: 2
119 quiet: no
120 dry run: yes
121 file: prefix/my.file
122 EOF
123
124 test_expect_success 'short options' '
125         test-parse-options -s123 -b -i 1729 -b -vv -n -F my.file \
126         > output 2> output.err &&
127         test_cmp expect output &&
128         test ! -s output.err
129 '
130
131 cat > expect << EOF
132 boolean: 2
133 integer: 1729
134 timestamp: 0
135 string: 321
136 abbrev: 10
137 verbose: 2
138 quiet: no
139 dry run: no
140 file: prefix/fi.le
141 EOF
142
143 test_expect_success 'long options' '
144         test-parse-options --boolean --integer 1729 --boolean --string2=321 \
145                 --verbose --verbose --no-dry-run --abbrev=10 --file fi.le\
146                 --obsolete > output 2> output.err &&
147         test ! -s output.err &&
148         test_cmp expect output
149 '
150
151 test_expect_success 'missing required value' '
152         test-parse-options -s;
153         test $? = 129 &&
154         test-parse-options --string;
155         test $? = 129 &&
156         test-parse-options --file;
157         test $? = 129
158 '
159
160 cat > expect << EOF
161 boolean: 1
162 integer: 13
163 timestamp: 0
164 string: 123
165 abbrev: 7
166 verbose: 0
167 quiet: no
168 dry run: no
169 file: (not set)
170 arg 00: a1
171 arg 01: b1
172 arg 02: --boolean
173 EOF
174
175 test_expect_success 'intermingled arguments' '
176         test-parse-options a1 --string 123 b1 --boolean -j 13 -- --boolean \
177                 > output 2> output.err &&
178         test ! -s output.err &&
179         test_cmp expect output
180 '
181
182 cat > expect << EOF
183 boolean: 0
184 integer: 2
185 timestamp: 0
186 string: (not set)
187 abbrev: 7
188 verbose: 0
189 quiet: no
190 dry run: no
191 file: (not set)
192 EOF
193
194 test_expect_success 'unambiguously abbreviated option' '
195         test-parse-options --int 2 --boolean --no-bo > output 2> output.err &&
196         test ! -s output.err &&
197         test_cmp expect output
198 '
199
200 test_expect_success 'unambiguously abbreviated option with "="' '
201         test-parse-options --int=2 > output 2> output.err &&
202         test ! -s output.err &&
203         test_cmp expect output
204 '
205
206 test_expect_success 'ambiguously abbreviated option' '
207         test-parse-options --strin 123;
208         test $? = 129
209 '
210
211 cat > expect << EOF
212 boolean: 0
213 integer: 0
214 timestamp: 0
215 string: 123
216 abbrev: 7
217 verbose: 0
218 quiet: no
219 dry run: no
220 file: (not set)
221 EOF
222
223 test_expect_success 'non ambiguous option (after two options it abbreviates)' '
224         test-parse-options --st 123 > output 2> output.err &&
225         test ! -s output.err &&
226         test_cmp expect output
227 '
228
229 cat > typo.err << EOF
230 error: did you mean \`--boolean\` (with two dashes ?)
231 EOF
232
233 test_expect_success 'detect possible typos' '
234         test_must_fail test-parse-options -boolean > output 2> output.err &&
235         test ! -s output &&
236         test_cmp typo.err output.err
237 '
238
239 cat > typo.err << EOF
240 error: did you mean \`--ambiguous\` (with two dashes ?)
241 EOF
242
243 test_expect_success 'detect possible typos' '
244         test_must_fail test-parse-options -ambiguous > output 2> output.err &&
245         test ! -s output &&
246         test_cmp typo.err output.err
247 '
248
249 cat > expect <<EOF
250 boolean: 0
251 integer: 0
252 timestamp: 0
253 string: (not set)
254 abbrev: 7
255 verbose: 0
256 quiet: no
257 dry run: no
258 file: (not set)
259 arg 00: --quux
260 EOF
261
262 test_expect_success 'keep some options as arguments' '
263         test-parse-options --quux > output 2> output.err &&
264         test ! -s output.err &&
265         test_cmp expect output
266 '
267
268 cat > expect <<EOF
269 boolean: 0
270 integer: 0
271 timestamp: 1
272 string: default
273 abbrev: 7
274 verbose: 0
275 quiet: yes
276 dry run: no
277 file: (not set)
278 arg 00: foo
279 EOF
280
281 test_expect_success 'OPT_DATE() and OPT_SET_PTR() work' '
282         test-parse-options -t "1970-01-01 00:00:01 +0000" --default-string \
283                 foo -q > output 2> output.err &&
284         test ! -s output.err &&
285         test_cmp expect output
286 '
287
288 cat > expect <<EOF
289 Callback: "four", 0
290 boolean: 5
291 integer: 4
292 timestamp: 0
293 string: (not set)
294 abbrev: 7
295 verbose: 0
296 quiet: no
297 dry run: no
298 file: (not set)
299 EOF
300
301 test_expect_success 'OPT_CALLBACK() and OPT_BIT() work' '
302         test-parse-options --length=four -b -4 > output 2> output.err &&
303         test ! -s output.err &&
304         test_cmp expect output
305 '
306
307 cat > expect <<EOF
308 Callback: "not set", 1
309 EOF
310
311 test_expect_success 'OPT_CALLBACK() and callback errors work' '
312         test_must_fail test-parse-options --no-length > output 2> output.err &&
313         test_cmp expect output &&
314         test_cmp expect.err output.err
315 '
316
317 cat > expect <<EOF
318 boolean: 1
319 integer: 23
320 timestamp: 0
321 string: (not set)
322 abbrev: 7
323 verbose: 0
324 quiet: no
325 dry run: no
326 file: (not set)
327 EOF
328
329 test_expect_success 'OPT_BIT() and OPT_SET_INT() work' '
330         test-parse-options --set23 -bbbbb --no-or4 > output 2> output.err &&
331         test ! -s output.err &&
332         test_cmp expect output
333 '
334
335 test_expect_success 'OPT_NEGBIT() and OPT_SET_INT() work' '
336         test-parse-options --set23 -bbbbb --neg-or4 > output 2> output.err &&
337         test ! -s output.err &&
338         test_cmp expect output
339 '
340
341 cat > expect <<EOF
342 boolean: 6
343 integer: 0
344 timestamp: 0
345 string: (not set)
346 abbrev: 7
347 verbose: 0
348 quiet: no
349 dry run: no
350 file: (not set)
351 EOF
352
353 test_expect_success 'OPT_BIT() works' '
354         test-parse-options -bb --or4 > output 2> output.err &&
355         test ! -s output.err &&
356         test_cmp expect output
357 '
358
359 test_expect_success 'OPT_NEGBIT() works' '
360         test-parse-options -bb --no-neg-or4 > output 2> output.err &&
361         test ! -s output.err &&
362         test_cmp expect output
363 '
364
365 test_expect_success 'OPT_COUNTUP() with PARSE_OPT_NODASH works' '
366         test-parse-options + + + + + + > output 2> output.err &&
367         test ! -s output.err &&
368         test_cmp expect output
369 '
370
371 cat > expect <<EOF
372 boolean: 0
373 integer: 12345
374 timestamp: 0
375 string: (not set)
376 abbrev: 7
377 verbose: 0
378 quiet: no
379 dry run: no
380 file: (not set)
381 EOF
382
383 test_expect_success 'OPT_NUMBER_CALLBACK() works' '
384         test-parse-options -12345 > output 2> output.err &&
385         test ! -s output.err &&
386         test_cmp expect output
387 '
388
389 cat >expect <<EOF
390 boolean: 0
391 integer: 0
392 timestamp: 0
393 string: (not set)
394 abbrev: 7
395 verbose: 0
396 quiet: no
397 dry run: no
398 file: (not set)
399 EOF
400
401 test_expect_success 'negation of OPT_NONEG flags is not ambiguous' '
402         test-parse-options --no-ambig >output 2>output.err &&
403         test ! -s output.err &&
404         test_cmp expect output
405 '
406
407 cat >>expect <<'EOF'
408 list: foo
409 list: bar
410 list: baz
411 EOF
412 test_expect_success '--list keeps list of strings' '
413         test-parse-options --list foo --list=bar --list=baz >output &&
414         test_cmp expect output
415 '
416
417 test_expect_success '--no-list resets list' '
418         test-parse-options --list=other --list=irrelevant --list=options \
419                 --no-list --list=foo --list=bar --list=baz >output &&
420         test_cmp expect output
421 '
422
423 test_done