Home | History | Annotate | Download | only in src
      1 #! /bin/sh
      2 # vim:et:ft=sh:sts=2:sw=2
      3 #
      4 # shFlags unit test for the flag definition methods
      5 #
      6 # TODO(kward): assert on FLAGS errors
      7 # TODO(kward): testNonStandardIFS()
      8 
      9 # exit immediately if a pipeline or subshell exits with a non-zero status.
     10 #set -e
     11 
     12 # treat unset variables as an error
     13 set -u
     14 
     15 # load test helpers
     16 . ./shflags_test_helpers
     17 
     18 #------------------------------------------------------------------------------
     19 # suite tests
     20 #
     21 
     22 testGetoptStandard()
     23 {
     24   _flags_getoptStandard '-b' >"${stdoutF}" 2>"${stderrF}"
     25   rslt=$?
     26   assertTrue "didn't parse valid flag 'b'" ${rslt}
     27   th_showOutput ${rslt} "${stdoutF}" "${stderrF}"
     28 
     29   _flags_getoptStandard '-x' >"${stdoutF}" 2>"${stderrF}"
     30   assertFalse "parsed invalid flag 'x'" $?
     31 }
     32 
     33 testGetoptEnhanced()
     34 {
     35   flags_getoptIsEnh || return
     36 
     37   _flags_getoptEnhanced '-b' >"${stdoutF}" 2>"${stderrF}"
     38   assertTrue "didn't parse valid flag 'b'" $?
     39   _flags_getoptEnhanced '--bool' >"${stdoutF}" 2>"${stderrF}"
     40   assertTrue "didn't parse valid flag 'bool'" $?
     41 
     42   _flags_getoptEnhanced '-x' >"${stdoutF}" 2>"${stderrF}"
     43   assertFalse "parsed invalid flag 'x'" $?
     44   _flags_getoptEnhanced '--xyz' >"${stdoutF}" 2>"${stderrF}"
     45   assertFalse "parsed invalid flag 'xyz'" $?
     46 }
     47 
     48 testValidBoolsShort()
     49 {
     50   FLAGS -b >"${stdoutF}" 2>"${stderrF}"
     51   r3turn=$?
     52   assertTrue "-b) FLAGS returned a non-zero result (${r3turn})" ${r3turn}
     53   value=${FLAGS_bool:-}
     54   assertTrue "-b) boolean was not true (${value})." "${value}"
     55   assertFalse '-b) expected no output to STDERR' "[ -s '${stderrF}' ]"
     56   test ${r3turn} -eq ${FLAGS_TRUE} -a ! -s "${stderrF}"
     57   th_showOutput $? "${stdoutF}" "${stderrF}"
     58 
     59   DEFINE_boolean bool2 true '2nd boolean' B
     60   FLAGS >"${stdoutF}" 2>"${stderrF}"
     61   r3turn=$?
     62   assertTrue "-B) FLAGS returned a non-zero result (${r3turn})" ${r3turn}
     63   value=${FLAGS_bool2:-}
     64   assertTrue "-B) boolean was not true (${value})" ${value}
     65   assertFalse '-B) expected no output to STDERR' "[ -s '${stderrF}' ]"
     66   test ${r3turn} -eq ${FLAGS_TRUE} -a ! -s "${stderrF}"
     67   th_showOutput $? "${stdoutF}" "${stderrF}"
     68 
     69   FLAGS -B >"${stdoutF}" 2>"${stderrF}"
     70   r3turn=$?
     71   assertTrue "-B) FLAGS returned a non-zero result (${r3turn})" ${r3turn}
     72   value=${FLAGS_bool2:-}
     73   assertFalse "-B) boolean was not false (${value})" ${value}
     74   assertFalse '-B) expected no output to STDERR' "[ -s '${stderrF}' ]"
     75   test ${r3turn} -eq ${FLAGS_TRUE} -a ! -s "${stderrF}"
     76   th_showOutput $? "${stdoutF}" "${stderrF}"
     77 }
     78 
     79 # TODO(kate): separate into multiple functions to reflect correct usage
     80 testValidBoolsLong()
     81 {
     82   flags_getoptIsEnh || return
     83 
     84   # Note: the default value of bool is 'false'.
     85 
     86   # leave flag false
     87   FLAGS --nobool >"${stdoutF}" 2>"${stderrF}"
     88   r3turn=$?
     89   assertTrue "FLAGS returned a non-zero result (${r3turn})" ${r3turn}
     90   assertFalse '--noXX flag resulted in true value.' ${FLAGS_bool:-}
     91   assertFalse 'expected no output to STDERR' "[ -s '${stderrF}' ]"
     92   th_showOutput ${r3turn} "${stdoutF}" "${stderrF}"
     93 
     94   # flip flag true
     95   FLAGS --bool >"${stdoutF}" 2>"${stderrF}"
     96   r3turn=$?
     97   assertTrue "FLAGS returned a non-zero result (${r3turn})" ${r3turn}
     98   assertTrue '--XX flag resulted in false value.' ${FLAGS_bool:-}
     99   assertFalse 'expected no output to STDERR' "[ -s '${stderrF}' ]"
    100   th_showOutput ${r3turn} "${stdoutF}" "${stderrF}"
    101 
    102   # flip flag back false
    103   FLAGS --nobool >"${stdoutF}" 2>"${stderrF}"
    104   r3turn=$?
    105   assertTrue "FLAGS returned a non-zero result (${r3turn})" ${r3turn}
    106   assertFalse '--noXX flag resulted in true value.' ${FLAGS_bool:-}
    107   assertFalse 'expected no output to STDERR' "[ -s '${stderrF}' ]"
    108   th_showOutput ${r3turn} "${stdoutF}" "${stderrF}"
    109 }
    110 
    111 testValidFloats()
    112 {
    113   _testValidFloats '-f'
    114   flags_getoptIsEnh || return
    115   _testValidFloats '--float'
    116 }
    117 
    118 _testValidFloats()
    119 {
    120   flag=$1
    121   for value in ${TH_FLOAT_VALID}; do
    122     FLAGS ${flag} ${value} >"${stdoutF}" 2>"${stderrF}"
    123     r3turn=$?
    124     assertTrue "FLAGS ${flag} ${value} returned non-zero result (${r3turn})" \
    125         ${r3turn}
    126     assertEquals "float (${flag} ${value}) test failed." ${value} ${FLAGS_float}
    127     assertFalse 'expected no output to STDERR' "[ -s '${stderrF}' ]"
    128     th_showOutput ${r3turn} "${stdoutF}" "${stderrF}"
    129   done
    130 }
    131 
    132 testInvalidFloats()
    133 {
    134   _testInvalidFloats '-f'
    135   flags_getoptIsEnh || return
    136   _testInvalidFloats '--float'
    137 }
    138 
    139 _testInvalidFloats()
    140 {
    141   flag=$1
    142   for value in ${TH_FLOAT_INVALID}; do
    143     th_clearReturn
    144     (
    145       FLAGS ${flag} ${value} >"${stdoutF}" 2>"${stderrF}"
    146       echo $? >"${returnF}"
    147     )
    148     th_queryReturn
    149     assertFalse "FLAGS (${value}) returned a zero result" ${th_return}
    150     assertFalse 'expected no output to STDOUT' "[ -s '${stdoutF}' ]"
    151     assertTrue 'expected output to STDERR' "[ -s '${stderrF}' ]"
    152   done
    153 }
    154 
    155 testValidIntegers()
    156 {
    157   _testValidIntegers '-i'
    158   flags_getoptIsEnh || return
    159   _testValidIntegers '--int'
    160 }
    161 
    162 _testValidIntegers()
    163 {
    164   flag=$1
    165   for value in ${TH_INT_VALID}; do
    166     FLAGS ${flag} ${value} >"${stdoutF}" 2>"${stderrF}"
    167     r3turn=$?
    168     assertTrue "FLAGS (${value}) returned a non-zero result (${r3turn})" ${r3turn}
    169     assertEquals "integer (${value}) test failed." ${value} ${FLAGS_int}
    170     assertFalse 'expected no output to STDERR' "[ -s '${stderrF}' ]"
    171     th_showOutput ${r3turn} "${stdoutF}" "${stderrF}"
    172   done
    173 }
    174 
    175 testInvalidIntegers()
    176 {
    177   _testInvalidIntegers '-i'
    178   flags_getoptIsEnh || return
    179   _testInvalidIntegers '--int'
    180 }
    181 
    182 _testInvalidIntegers()
    183 {
    184   flag=$1
    185   for value in ${TH_INT_INVALID}; do
    186     th_clearReturn
    187     (
    188       FLAGS ${flag} ${value} >"${stdoutF}" 2>"${stderrF}"
    189       echo $? >"${returnF}"
    190     )
    191     th_queryReturn
    192     assertFalse "invalid integer (${value}) test returned success." ${th_return}
    193     assertFalse 'expected no output to STDOUT' "[ -s '${stdoutF}' ]"
    194     assertTrue 'expected output to STDERR' "[ -s '${stderrF}' ]"
    195   done
    196 }
    197 
    198 testValidStrings()
    199 {
    200   _testValidStrings -s single_word
    201   if flags_getoptIsEnh; then
    202     _testValidStrings --str single_word
    203     _testValidStrings --str 'string with spaces'
    204   fi
    205 }
    206 
    207 _testValidStrings()
    208 {
    209   flag=$1
    210   value=$2
    211 
    212   FLAGS ${flag} "${value}" >"${stdoutF}" 2>"${stderrF}"
    213   r3turn=$?
    214   assertTrue "'FLAGS ${flag} ${value}' returned a non-zero result (${r3turn})" \
    215       ${r3turn}
    216   assertEquals "string (${value}) test failed." "${value}" "${FLAGS_str}"
    217   if [ ${r3turn} -eq ${FLAGS_TRUE} ]; then
    218     assertFalse 'expected no output to STDERR' "[ -s '${stderrF}' ]"
    219   else
    220     # validate that an error is thrown for unsupported getopt uses
    221     assertFatalMsg '.* spaces in options'
    222   fi
    223   th_showOutput ${r3turn} "${stdoutF}" "${stderrF}"
    224 }
    225 
    226 testMultipleFlags()
    227 {
    228   _testMultipleFlags '-b' '-i' '-f' '-s'
    229   flags_getoptIsEnh || return
    230   _testMultipleFlags '--bool' '--int' '--float' '--str'
    231 }
    232 
    233 _testMultipleFlags()
    234 {
    235   boolFlag=$1
    236   intFlag=$2
    237   floatFlag=$3
    238   strFlag=$4
    239 
    240   FLAGS \
    241       ${boolFlag} \
    242       ${intFlag} 567 \
    243       ${floatFlag} 123.45678 \
    244       ${strFlag} 'some_string' \
    245       >"${stdoutF}" 2>"${stderrF}"
    246   r3turn=$?
    247   assertTrue "use of multple flags returned a non-zero result" ${r3turn}
    248   assertTrue 'boolean test failed.' ${FLAGS_bool}
    249   assertNotSame 'float test failed.' 0 ${FLAGS_float}
    250   assertNotSame 'integer test failed.' 0 ${FLAGS_int}
    251   assertNotSame 'string test failed.' '' ${FLAGS_str}
    252   assertFalse 'expected no output to STDERR' "[ -s '${stderrF}' ]"
    253   th_showOutput ${r3turn} "${stdoutF}" "${stderrF}"
    254 }
    255 
    256 _testNonFlagArgs()
    257 {
    258   argc=$1
    259   shift
    260 
    261   FLAGS "$@" >"${stdoutF}" 2>"${stderrF}"
    262   r3turn=$?
    263   assertTrue 'parse returned non-zero value.' ${r3turn}
    264   th_showOutput ${r3turn} "${stdoutF}" "${stderrF}"
    265 
    266   eval set -- "${FLAGS_ARGV}"
    267   assertEquals 'wrong count of argv arguments returned.' ${argc} $#
    268   assertEquals 'wrong count of argc arguments returned.' 0 ${FLAGS_ARGC}
    269 }
    270 
    271 testSingleNonFlagArg()
    272 {
    273   _testNonFlagArgs 1 argOne
    274 }
    275 
    276 testMultipleNonFlagArgs()
    277 {
    278   _testNonFlagArgs 3 argOne argTwo arg3
    279 }
    280 
    281 testMultipleNonFlagStringArgsWithSpaces()
    282 {
    283   flags_getoptIsEnh || return
    284   _testNonFlagArgs 3 argOne 'arg two' arg3
    285 }
    286 
    287 testFlagsWithEquals()
    288 {
    289   flags_getoptIsEnh || return
    290 
    291   FLAGS --str='str_flag' 'non_flag' >"${stdoutF}" 2>"${stderrF}"
    292   assertTrue 'FLAGS returned a non-zero result' $?
    293   assertEquals 'string flag not set properly' 'str_flag' "${FLAGS_str}"
    294   th_showOutput ${r3turn} "${stdoutF}" "${stderrF}"
    295 
    296   eval set -- "${FLAGS_ARGV}"
    297   assertEquals 'wrong count of argv arguments returned.' 1 $#
    298   assertEquals 'wrong count of argc arguments returned.' 1 ${FLAGS_ARGC}
    299 }
    300 
    301 testComplicatedCommandLineStandard()
    302 {
    303   flags_getoptIsEnh && return
    304 
    305   # Note: standard getopt stops parsing after first non-flag argument, which
    306   # results in the remaining flags being treated as arguments instead.
    307   FLAGS -i 1 non_flag_1 -s 'two' non_flag_2 -f 3 non_flag_3 \
    308       >"${stdoutF}" 2>"${stderrF}"
    309   r3turn=$?
    310   assertTrue 'FLAGS returned a non-zero result' ${r3turn}
    311   assertEquals 'failed int test' 1 ${FLAGS_int}
    312   th_showOutput ${r3turn} "${stdoutF}" "${stderrF}"
    313 
    314   eval set -- "${FLAGS_ARGV}"
    315   assertEquals 'incorrect number of argv values' 7 $#
    316 }
    317 
    318 testComplicatedCommandLineEnhanced()
    319 {
    320   flags_getoptIsEnh || return
    321 
    322   FLAGS -i 1 non_flag_1 --str='two' non_flag_2 --float 3 'non flag 3' \
    323       >"${stdoutF}" 2>"${stderrF}"
    324   r3turn=$?
    325   assertTrue 'FLAGS returned a non-zero result' ${r3turn}
    326   assertEquals 'failed int test' 1 ${FLAGS_int}
    327   assertEquals 'failed str test' 'two' "${FLAGS_str}"
    328   assertEquals 'failed float test' 3 ${FLAGS_float}
    329   th_showOutput ${r3turn} "${stdoutF}" "${stderrF}"
    330 
    331   eval set -- "${FLAGS_ARGV}"
    332   assertEquals 'incorrect number of argv values' 3 $#
    333 }
    334 
    335 #------------------------------------------------------------------------------
    336 # suite functions
    337 #
    338 
    339 oneTimeSetUp()
    340 {
    341   th_oneTimeSetUp
    342 
    343   if flags_getoptIsStd; then
    344     th_warn 'Standard version of getopt found. Enhanced tests will be skipped.'
    345   else
    346     th_warn 'Enhanced version of getopt found. Standard tests will be skipped.'
    347   fi
    348 }
    349 
    350 setUp()
    351 {
    352   DEFINE_boolean bool false 'boolean test' 'b'
    353   DEFINE_float float 0.0 'float test' 'f'
    354   DEFINE_integer int 0 'integer test' 'i'
    355   DEFINE_string str '' 'string test' 's'
    356 }
    357 
    358 tearDown()
    359 {
    360   flags_reset
    361 }
    362 
    363 # load and run shUnit2
    364 [ -n "${ZSH_VERSION:-}" ] && SHUNIT_PARENT=$0
    365 . ${TH_SHUNIT}
    366