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