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