1#! /bin/sh 2# vim:et:ft=sh:sts=2:sw=2 3# 4# shFlags unit test for the flag definition methods 5# 6# Copyright 2008-2020 Kate Ward. All Rights Reserved. 7# Released under the Apache 2.0 license. 8# 9# Author: [email protected] (Kate Ward) 10# https://github.com/kward/shflags 11# 12### ShellCheck (http://www.shellcheck.net/) 13# Disable source following. 14# shellcheck disable=SC1090,SC1091 15 16# TODO(kward): assert on FLAGS errors 17# TODO(kward): testNonStandardIFS() 18 19# These variables will be overridden by the test helpers. 20stdoutF="${TMPDIR:-/tmp}/STDOUT" 21stderrF="${TMPDIR:-/tmp}/STDERR" 22 23# Load test helpers. 24. ./shflags_test_helpers 25 26testGetoptStandard() { 27 if ! _flags_getoptStandard '-b' >"${stdoutF}" 2>"${stderrF}"; then 28 fail "error parsing -b flag" 29 _showTestOutput 30 fi 31 32 if _flags_getoptStandard '-x' >"${stdoutF}" 2>"${stderrF}"; then 33 fail "expected error parsing invalid -x flag" 34 _showTestOutput 35 fi 36} 37 38testGetoptEnhanced() { 39 if ! flags_getoptIsEnh; then 40 return 41 fi 42 43 if ! _flags_getoptEnhanced '-b' >"${stdoutF}" 2>"${stderrF}"; then 44 fail "error parsing -b flag" 45 _showTestOutput 46 fi 47 if ! _flags_getoptEnhanced '--bool' >"${stdoutF}" 2>"${stderrF}"; then 48 fail "error parsing --bool flag" 49 _showTestOutput 50 fi 51 52 if _flags_getoptEnhanced '-x' >"${stdoutF}" 2>"${stderrF}"; then 53 fail "expected error parsing invalid -x flag" 54 _showTestOutput 55 fi 56 if _flags_getoptEnhanced '--xyz' >"${stdoutF}" 2>"${stderrF}"; then 57 fail "expected error parsing invalid --xyz flag" 58 _showTestOutput 59 fi 60} 61 62testValidBoolsShort() { 63 desc='bool_true_arg' 64 if FLAGS -b >"${stdoutF}" 2>"${stderrF}"; then 65 assertTrue "${desc}: expected true value" "${FLAGS_bool:-}" 66 else 67 fail "${desc}: FLAGS returned a non-zero result ($?)" 68 fi 69 th_showOutput 70 71 desc='bool2_defined' 72 DEFINE_boolean bool2 true '2nd boolean' B 73 if FLAGS >"${stdoutF}" 2>"${stderrF}"; then 74 assertTrue "${desc}: expected true value" "${FLAGS_bool2:-}" 75 else 76 fail "${desc}: FLAGS returned a non-zero result ($?)" 77 fi 78 th_showOutput 79 80 desc='bool_false_arg' 81 if FLAGS -B >"${stdoutF}" 2>"${stderrF}"; then 82 assertFalse "${desc}: expected false value" "${FLAGS_bool2:-}" 83 else 84 fail "${desc}: FLAGS returned a non-zero result ($?)" 85 fi 86 th_showOutput 87} 88 89# TODO(kate): separate into multiple functions to reflect correct usage 90testValidBoolsLong() { 91 flags_getoptIsEnh 92 [ $? -eq "${FLAGS_FALSE}" ] && return 93 94 # Note: the default value of bool is 'false'. 95 96 # Leave flag false. 97 FLAGS --nobool >"${stdoutF}" 2>"${stderrF}" 98 r3turn=$? 99 assertTrue "FLAGS returned a non-zero result (${r3turn})" ${r3turn} 100 assertFalse '--noXX flag resulted in true value.' "${FLAGS_bool:-}" 101 assertFalse 'expected no output to STDERR' "[ -s '${stderrF}' ]" 102 th_showOutput ${r3turn} "${stdoutF}" "${stderrF}" 103 104 # Flip flag true. 105 FLAGS --bool >"${stdoutF}" 2>"${stderrF}" 106 r3turn=$? 107 assertTrue "FLAGS returned a non-zero result (${r3turn})" ${r3turn} 108 assertTrue '--XX flag resulted in false value.' "${FLAGS_bool:-}" 109 assertFalse 'expected no output to STDERR' "[ -s '${stderrF}' ]" 110 th_showOutput ${r3turn} "${stdoutF}" "${stderrF}" 111 112 # Flip flag back false. 113 FLAGS --nobool >"${stdoutF}" 2>"${stderrF}" 114 r3turn=$? 115 assertTrue "FLAGS returned a non-zero result (${r3turn})" ${r3turn} 116 assertFalse '--noXX flag resulted in true value.' "${FLAGS_bool:-}" 117 assertFalse 'expected no output to STDERR' "[ -s '${stderrF}' ]" 118 th_showOutput ${r3turn} "${stdoutF}" "${stderrF}" 119} 120 121testFloats() { 122 _testFloats '-f' 123 if flags_getoptIsEnh; then 124 _testFloats '--float' 125 fi 126} 127 128_testFloats() { 129 flag=$1 130 131 for value in ${TH_FLOAT_VALID}; do 132 if FLAGS "${flag}" "${value}" >"${stdoutF}" 2>"${stderrF}"; then 133 # shellcheck disable=SC2154 134 assertEquals "${flag}: incorrect value" "${value}" "${FLAGS_float}" 135 else 136 fail "${flag}: unexpected non-zero result ($?)" 137 th_showOutput 138 fi 139 done 140 141 for value in ${TH_FLOAT_INVALID}; do 142 # Wrap FLAGS in () to catch errors. 143 if (FLAGS "${flag}" "${value}" >"${stdoutF}" 2>"${stderrF}"); then 144 fail "${flag}: expected a non-zero result" 145 th_showOutput 146 else 147 assertEquals "${flag}: expected an error" $? "${FLAGS_ERROR}" 148 fi 149 done 150} 151 152testIntegers() { 153 _testIntegers '-i' 154 if flags_getoptIsEnh; then 155 _testIntegers '--int' 156 fi 157} 158 159_testIntegers() { 160 flag=$1 161 162 for value in ${TH_INT_VALID}; do 163 if FLAGS "${flag}" "${value}" >"${stdoutF}" 2>"${stderrF}"; then 164 # shellcheck disable=SC2154 165 assertEquals "${flag}: incorrect value" "${value}" "${FLAGS_int}" 166 else 167 fail "${flag}: unexpected non-zero result ($?)" 168 th_showOutput 169 fi 170 done 171 172 for value in ${TH_INT_INVALID}; do 173 # Wrap FLAGS in () to catch errors. 174 if (FLAGS "${flag}" "${value}" >"${stdoutF}" 2>"${stderrF}"); then 175 fail "${flag}: expected a non-zero result" 176 th_showOutput 177 else 178 assertEquals "${flag}: expected an error" $? "${FLAGS_ERROR}" 179 fi 180 done 181} 182 183testStrings() { 184 _testStrings 'std_single_word' -s single_word 185 if flags_getoptIsEnh; then 186 _testStrings 'enh_single_word' --str single_word 187 _testStrings 'enh_multi_word' --str 'string with spaces' 188 fi 189} 190 191_testStrings() { 192 desc=$1 193 flag=$2 194 value=$3 195 196 if FLAGS "${flag}" "${value}" >"${stdoutF}" 2>"${stderrF}"; then 197 # shellcheck disable=SC2154 198 assertEquals "${desc}: incorrect value" "${value}" "${FLAGS_str}" 199 else 200 fail "${desc}: unexpected non-zero result ($?)" 201 # Validate that an error is thrown for unsupported getopt uses. 202 assertFatalMsg '.* spaces in options' 203 th_showOutput 204 fi 205} 206 207testMultipleFlags() { 208 _testMultipleFlags '-b' '-i' '-f' '-s' 209 flags_getoptIsEnh 210 [ $? -eq "${FLAGS_FALSE}" ] && return 211 _testMultipleFlags '--bool' '--int' '--float' '--str' 212} 213 214_testMultipleFlags() { 215 boolFlag=$1 216 intFlag=$2 217 floatFlag=$3 218 strFlag=$4 219 220 FLAGS \ 221 "${boolFlag}" \ 222 "${intFlag}" 567 \ 223 "${floatFlag}" 123.45678 \ 224 "${strFlag}" 'some_string' \ 225 >"${stdoutF}" 2>"${stderrF}" 226 r3turn=$? 227 assertTrue "use of multiple flags returned a non-zero result" ${r3turn} 228 assertTrue 'boolean test failed.' "${FLAGS_bool}" 229 assertNotSame 'float test failed.' 0 "${FLAGS_float}" 230 assertNotSame 'integer test failed.' 0 "${FLAGS_int}" 231 assertNotSame 'string test failed.' '' "${FLAGS_str}" 232 assertFalse 'expected no output to STDERR' "[ -s '${stderrF}' ]" 233 th_showOutput ${r3turn} "${stdoutF}" "${stderrF}" 234} 235 236_testNonFlagArgs() { 237 argc=$1 238 shift 239 240 FLAGS "$@" >"${stdoutF}" 2>"${stderrF}" 241 r3turn=$? 242 assertTrue 'parse returned non-zero value.' ${r3turn} 243 th_showOutput ${r3turn} "${stdoutF}" "${stderrF}" 244 245 eval set -- "${FLAGS_ARGV}" 246 assertEquals 'wrong count of argv arguments returned.' "${argc}" $# 247} 248 249testSingleNonFlagArg() { _testNonFlagArgs 1 argOne; } 250testMultipleNonFlagArgs() { _testNonFlagArgs 3 argOne argTwo arg3; } 251 252testMultipleNonFlagStringArgsWithSpaces() { 253 if flags_getoptIsEnh; then 254 _testNonFlagArgs 3 argOne 'arg two' arg3 255 fi 256} 257 258testFlagsWithEquals() { 259 if ! flags_getoptIsEnh; then 260 return 261 fi 262 263 FLAGS --str='str_flag' 'non_flag' >"${stdoutF}" 2>"${stderrF}" 264 assertTrue 'FLAGS returned a non-zero result' $? 265 assertEquals 'string flag not set properly' 'str_flag' "${FLAGS_str}" 266 th_showOutput ${r3turn} "${stdoutF}" "${stderrF}" 267 268 eval set -- "${FLAGS_ARGV}" 269 assertEquals 'wrong count of argv arguments returned.' 1 $# 270} 271 272testComplicatedCommandLineStandard() { 273 flags_getoptIsEnh 274 [ $? -eq "${FLAGS_TRUE}" ] && return 275 276 # Note: standard getopt stops parsing after first non-flag argument, which 277 # results in the remaining flags being treated as arguments instead. 278 FLAGS -i 1 non_flag_1 -s 'two' non_flag_2 -f 3 non_flag_3 \ 279 >"${stdoutF}" 2>"${stderrF}" 280 r3turn=$? 281 assertTrue 'FLAGS returned a non-zero result' ${r3turn} 282 assertEquals 'failed int test' 1 "${FLAGS_int}" 283 th_showOutput ${r3turn} "${stdoutF}" "${stderrF}" 284 285 eval set -- "${FLAGS_ARGV}" 286 assertEquals 'incorrect number of argv values' 7 $# 287} 288 289testComplicatedCommandLineEnhanced() { 290 flags_getoptIsEnh 291 [ $? -eq "${FLAGS_FALSE}" ] && return 292 293 FLAGS -i 1 non_flag_1 --str='two' non_flag_2 --float 3 'non flag 3' \ 294 >"${stdoutF}" 2>"${stderrF}" 295 r3turn=$? 296 assertTrue 'FLAGS returned a non-zero result' ${r3turn} 297 assertEquals 'failed int test' 1 "${FLAGS_int}" 298 assertEquals 'failed str test' 'two' "${FLAGS_str}" 299 assertEquals 'failed float test' 3 "${FLAGS_float}" 300 th_showOutput ${r3turn} "${stdoutF}" "${stderrF}" 301 302 eval set -- "${FLAGS_ARGV}" 303 assertEquals 'incorrect number of argv values' 3 $# 304} 305 306oneTimeSetUp() { 307 th_oneTimeSetUp 308 309 if flags_getoptIsStd; then 310 th_warn 'Standard version of getopt found. Enhanced tests will be skipped.' 311 else 312 th_warn 'Enhanced version of getopt found. Standard tests will be skipped.' 313 fi 314} 315 316setUp() { 317 DEFINE_boolean bool false 'boolean test' 'b' 318 DEFINE_float float 0.0 'float test' 'f' 319 DEFINE_integer int 0 'integer test' 'i' 320 DEFINE_string str '' 'string test' 's' 321} 322 323tearDown() { 324 flags_reset 325} 326 327# showTestOutput for the most recently run test. 328_showTestOutput() { th_showOutput "${SHUNIT_FALSE}" "${stdoutF}" "${stderrF}"; } 329 330# Load and run shUnit2. 331# shellcheck disable=SC2034 332[ -n "${ZSH_VERSION:-}" ] && SHUNIT_PARENT=$0 333. "${TH_SHUNIT}" 334