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