t / t0040-parse-options.shon commit Merge branch 'maint' (d81c7d1)
   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    --default-string      set string to default
  34    --list <str>          add str to list
  35
  36Magic 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
  43Standard 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
  49EOF
  50
  51test_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
  57mv expect expect.err
  58
  59cat >expect.template <<EOF
  60boolean: 0
  61integer: 0
  62timestamp: 0
  63string: (not set)
  64abbrev: 7
  65verbose: 0
  66quiet: no
  67dry run: no
  68file: (not set)
  69EOF
  70
  71check() {
  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
  82check_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
  95test_expect_success 'OPT_BOOL() #1' 'check boolean: 1 --yes'
  96test_expect_success 'OPT_BOOL() #2' 'check boolean: 1 --no-doubt'
  97test_expect_success 'OPT_BOOL() #3' 'check boolean: 1 -D'
  98test_expect_success 'OPT_BOOL() #4' 'check boolean: 1 --no-fear'
  99test_expect_success 'OPT_BOOL() #5' 'check boolean: 1 -B'
 100
 101test_expect_success 'OPT_BOOL() is idempotent #1' 'check boolean: 1 --yes --yes'
 102test_expect_success 'OPT_BOOL() is idempotent #2' 'check boolean: 1 -DB'
 103
 104test_expect_success 'OPT_BOOL() negation #1' 'check boolean: 0 -D --no-yes'
 105test_expect_success 'OPT_BOOL() negation #2' 'check boolean: 0 -D --no-no-doubt'
 106
 107test_expect_success 'OPT_BOOL() no negation #1' 'check_unknown --fear'
 108test_expect_success 'OPT_BOOL() no negation #2' 'check_unknown --no-no-fear'
 109
 110test_expect_success 'OPT_BOOL() positivation' 'check boolean: 0 -D --doubt'
 111
 112cat > expect << EOF
 113boolean: 2
 114integer: 1729
 115timestamp: 0
 116string: 123
 117abbrev: 7
 118verbose: 2
 119quiet: no
 120dry run: yes
 121file: prefix/my.file
 122EOF
 123
 124test_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
 131cat > expect << EOF
 132boolean: 2
 133integer: 1729
 134timestamp: 0
 135string: 321
 136abbrev: 10
 137verbose: 2
 138quiet: no
 139dry run: no
 140file: prefix/fi.le
 141EOF
 142
 143test_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
 151test_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
 160cat > expect << EOF
 161boolean: 1
 162integer: 13
 163timestamp: 0
 164string: 123
 165abbrev: 7
 166verbose: 0
 167quiet: no
 168dry run: no
 169file: (not set)
 170arg 00: a1
 171arg 01: b1
 172arg 02: --boolean
 173EOF
 174
 175test_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
 182cat > expect << EOF
 183boolean: 0
 184integer: 2
 185timestamp: 0
 186string: (not set)
 187abbrev: 7
 188verbose: 0
 189quiet: no
 190dry run: no
 191file: (not set)
 192EOF
 193
 194test_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
 200test_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
 206test_expect_success 'ambiguously abbreviated option' '
 207        test-parse-options --strin 123;
 208        test $? = 129
 209'
 210
 211cat > expect << EOF
 212boolean: 0
 213integer: 0
 214timestamp: 0
 215string: 123
 216abbrev: 7
 217verbose: 0
 218quiet: no
 219dry run: no
 220file: (not set)
 221EOF
 222
 223test_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
 229cat > typo.err << EOF
 230error: did you mean \`--boolean\` (with two dashes ?)
 231EOF
 232
 233test_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
 239cat > typo.err << EOF
 240error: did you mean \`--ambiguous\` (with two dashes ?)
 241EOF
 242
 243test_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
 249cat > expect <<EOF
 250boolean: 0
 251integer: 0
 252timestamp: 0
 253string: (not set)
 254abbrev: 7
 255verbose: 0
 256quiet: no
 257dry run: no
 258file: (not set)
 259arg 00: --quux
 260EOF
 261
 262test_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
 268cat > expect <<EOF
 269boolean: 0
 270integer: 0
 271timestamp: 1
 272string: default
 273abbrev: 7
 274verbose: 0
 275quiet: yes
 276dry run: no
 277file: (not set)
 278arg 00: foo
 279EOF
 280
 281test_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
 288cat > expect <<EOF
 289Callback: "four", 0
 290boolean: 5
 291integer: 4
 292timestamp: 0
 293string: (not set)
 294abbrev: 7
 295verbose: 0
 296quiet: no
 297dry run: no
 298file: (not set)
 299EOF
 300
 301test_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
 307cat > expect <<EOF
 308Callback: "not set", 1
 309EOF
 310
 311test_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
 317cat > expect <<EOF
 318boolean: 1
 319integer: 23
 320timestamp: 0
 321string: (not set)
 322abbrev: 7
 323verbose: 0
 324quiet: no
 325dry run: no
 326file: (not set)
 327EOF
 328
 329test_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
 335test_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
 341cat > expect <<EOF
 342boolean: 6
 343integer: 0
 344timestamp: 0
 345string: (not set)
 346abbrev: 7
 347verbose: 0
 348quiet: no
 349dry run: no
 350file: (not set)
 351EOF
 352
 353test_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
 359test_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
 365test_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
 371cat > expect <<EOF
 372boolean: 0
 373integer: 12345
 374timestamp: 0
 375string: (not set)
 376abbrev: 7
 377verbose: 0
 378quiet: no
 379dry run: no
 380file: (not set)
 381EOF
 382
 383test_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
 389cat >expect <<EOF
 390boolean: 0
 391integer: 0
 392timestamp: 0
 393string: (not set)
 394abbrev: 7
 395verbose: 0
 396quiet: no
 397dry run: no
 398file: (not set)
 399EOF
 400
 401test_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
 407cat >>expect <<'EOF'
 408list: foo
 409list: bar
 410list: baz
 411EOF
 412test_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
 417test_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
 423test_done