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 13set -u 14 15# load test helpers 16. ./shflags_test_helpers 17 18#------------------------------------------------------------------------------ 19# suite tests 20# 21 22testGetoptStandard() 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 33testGetoptEnhanced() 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 48testValidBoolsShort() 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 80testValidBoolsLong() 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 111testValidFloats() 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 132testInvalidFloats() 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 155testValidIntegers() 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 175testInvalidIntegers() 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 198testValidStrings() 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 226testMultipleFlags() 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 271testSingleNonFlagArg() 272{ 273 _testNonFlagArgs 1 argOne 274} 275 276testMultipleNonFlagArgs() 277{ 278 _testNonFlagArgs 3 argOne argTwo arg3 279} 280 281testMultipleNonFlagStringArgsWithSpaces() 282{ 283 flags_getoptIsEnh || return 284 _testNonFlagArgs 3 argOne 'arg two' arg3 285} 286 287testFlagsWithEquals() 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 301testComplicatedCommandLineStandard() 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 318testComplicatedCommandLineEnhanced() 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 339oneTimeSetUp() 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 350setUp() 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 358tearDown() 359{ 360 flags_reset 361} 362 363# load and run shUnit2 364[ -n "${ZSH_VERSION:-}" ] && SHUNIT_PARENT=$0 365. ${TH_SHUNIT} 366