1*63d4e48fSSadaf Ebrahimi#! /bin/sh 2*63d4e48fSSadaf Ebrahimi# vim:et:ft=sh:sts=2:sw=2 3*63d4e48fSSadaf Ebrahimi# 4*63d4e48fSSadaf Ebrahimi# shFlags unit test for the flag definition methods 5*63d4e48fSSadaf Ebrahimi# 6*63d4e48fSSadaf Ebrahimi# Copyright 2008-2020 Kate Ward. All Rights Reserved. 7*63d4e48fSSadaf Ebrahimi# Released under the Apache 2.0 license. 8*63d4e48fSSadaf Ebrahimi# 9*63d4e48fSSadaf Ebrahimi# Author: [email protected] (Kate Ward) 10*63d4e48fSSadaf Ebrahimi# https://github.com/kward/shflags 11*63d4e48fSSadaf Ebrahimi# 12*63d4e48fSSadaf Ebrahimi### ShellCheck (http://www.shellcheck.net/) 13*63d4e48fSSadaf Ebrahimi# Disable source following. 14*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC1090,SC1091 15*63d4e48fSSadaf Ebrahimi 16*63d4e48fSSadaf Ebrahimi# Exit immediately if a simple command exits with a non-zero status. 17*63d4e48fSSadaf Ebrahimiset -e 18*63d4e48fSSadaf Ebrahimi 19*63d4e48fSSadaf Ebrahimi# Treat unset variables as an error when performing parameter expansion. 20*63d4e48fSSadaf Ebrahimiset -u 21*63d4e48fSSadaf Ebrahimi 22*63d4e48fSSadaf Ebrahimi# These variables will be overridden by the test helpers. 23*63d4e48fSSadaf EbrahimistdoutF="${TMPDIR:-/tmp}/STDOUT" 24*63d4e48fSSadaf EbrahimistderrF="${TMPDIR:-/tmp}/STDERR" 25*63d4e48fSSadaf Ebrahimi 26*63d4e48fSSadaf Ebrahimi# Load test helpers. 27*63d4e48fSSadaf Ebrahimi. ./shflags_test_helpers 28*63d4e48fSSadaf Ebrahimi 29*63d4e48fSSadaf EbrahimitestFlagsDefine() { 30*63d4e48fSSadaf Ebrahimi # No arguments. 31*63d4e48fSSadaf Ebrahimi if _flags_define >"${stdoutF}" 2>"${stderrF}" 32*63d4e48fSSadaf Ebrahimi then :; else 33*63d4e48fSSadaf Ebrahimi assertEquals '_flags_define() with no arguments should error' "${FLAGS_ERROR}" $? 34*63d4e48fSSadaf Ebrahimi fi 35*63d4e48fSSadaf Ebrahimi assertErrorMsg '' 'no arguments' 36*63d4e48fSSadaf Ebrahimi 37*63d4e48fSSadaf Ebrahimi # One argument. 38*63d4e48fSSadaf Ebrahimi if _flags_define arg1 >"${stdoutF}" 2>"${stderrF}" 39*63d4e48fSSadaf Ebrahimi then :; else 40*63d4e48fSSadaf Ebrahimi assertEquals '_flags_define() call with one argument should error' "${FLAGS_ERROR}" $? 41*63d4e48fSSadaf Ebrahimi fi 42*63d4e48fSSadaf Ebrahimi assertErrorMsg '' 'one argument' 43*63d4e48fSSadaf Ebrahimi 44*63d4e48fSSadaf Ebrahimi # Two arguments. 45*63d4e48fSSadaf Ebrahimi if _flags_define arg1 arg2 >"${stdoutF}" 2>"${stderrF}" 46*63d4e48fSSadaf Ebrahimi then :; else 47*63d4e48fSSadaf Ebrahimi assertEquals '_flags_define() call with two arguments should error' "${FLAGS_ERROR}" $? 48*63d4e48fSSadaf Ebrahimi fi 49*63d4e48fSSadaf Ebrahimi assertErrorMsg '' 'two arguments' 50*63d4e48fSSadaf Ebrahimi 51*63d4e48fSSadaf Ebrahimi # Three arguments. 52*63d4e48fSSadaf Ebrahimi if _flags_define arg1 arg2 arg3 >"${stdoutF}" 2>"${stderrF}" 53*63d4e48fSSadaf Ebrahimi then :; else 54*63d4e48fSSadaf Ebrahimi assertEquals '_flags_define() call with three arguments should error' "${FLAGS_ERROR}" $? 55*63d4e48fSSadaf Ebrahimi fi 56*63d4e48fSSadaf Ebrahimi assertErrorMsg '' 'three arguments' 57*63d4e48fSSadaf Ebrahimi 58*63d4e48fSSadaf Ebrahimi # Multiple definition. Assumes working boolean definition (tested elsewhere). 59*63d4e48fSSadaf Ebrahimi if ! _flags_define "${__FLAGS_TYPE_BOOLEAN}" multiDefBool true 'multi def #1' m; then 60*63d4e48fSSadaf Ebrahimi fail "didn't expect _flags_define for 'multi def #1' to fail" 61*63d4e48fSSadaf Ebrahimi fi 62*63d4e48fSSadaf Ebrahimi if _flags_define "${__FLAGS_TYPE_BOOLEAN}" multiDefBool false 'multi def #2' m >"${stdoutF}" 2>"${stderrF}" 63*63d4e48fSSadaf Ebrahimi then :; else 64*63d4e48fSSadaf Ebrahimi assertEquals '_flags_define() with existing flag name should fail' "${FLAGS_FALSE}" $? 65*63d4e48fSSadaf Ebrahimi fi 66*63d4e48fSSadaf Ebrahimi assertTrue '_flags_define() should not overwrite previously defined default.' "${FLAGS_multiDefBool:-}" 67*63d4e48fSSadaf Ebrahimi assertWarnMsg '' 'existing flag' 68*63d4e48fSSadaf Ebrahimi 69*63d4e48fSSadaf Ebrahimi # Duplicate dashed and underscored definition. 70*63d4e48fSSadaf Ebrahimi if ! _flags_define "${__FLAGS_TYPE_STRING}" long-name 'foo' 'dashed name' l; then 71*63d4e48fSSadaf Ebrahimi fail "didn't expect _flags_define() for 'dashed name' to fail" 72*63d4e48fSSadaf Ebrahimi fi 73*63d4e48fSSadaf Ebrahimi if _flags_define "${__FLAGS_TYPE_STRING}" long_name 'bar' 'underscored name' l >"${stdoutF}" 2>"${stderrF}" 74*63d4e48fSSadaf Ebrahimi then :; else 75*63d4e48fSSadaf Ebrahimi assertEquals '_flags_define() with duplicate dashed and underscored definition should fail' "${FLAGS_FALSE}" $? 76*63d4e48fSSadaf Ebrahimi fi 77*63d4e48fSSadaf Ebrahimi # shellcheck disable=SC2154 78*63d4e48fSSadaf Ebrahimi assertEquals '_flags_define() should not overwrite previously defined default.' "${FLAGS_long_name}" 'foo' 79*63d4e48fSSadaf Ebrahimi assertWarnMsg '' 'already exists' 80*63d4e48fSSadaf Ebrahimi 81*63d4e48fSSadaf Ebrahimi # TODO(kward): test requirement of enhanced getopt. 82*63d4e48fSSadaf Ebrahimi 83*63d4e48fSSadaf Ebrahimi # Invalid type. 84*63d4e48fSSadaf Ebrahimi if _flags_define invalid arg2 arg3 arg4 i >"${stdoutF}" 2>"${stderrF}" 85*63d4e48fSSadaf Ebrahimi then :; else 86*63d4e48fSSadaf Ebrahimi assertEquals '_flags_define() with "invalid" type should have failed.' "${FLAGS_ERROR}" $? 87*63d4e48fSSadaf Ebrahimi fi 88*63d4e48fSSadaf Ebrahimi assertErrorMsg 'unrecognized flag type' 'invalid type' 89*63d4e48fSSadaf Ebrahimi} 90*63d4e48fSSadaf Ebrahimi 91*63d4e48fSSadaf EbrahimitestBoolean() { 92*63d4e48fSSadaf Ebrahimi while read -r desc ok default want; do 93*63d4e48fSSadaf Ebrahimi flags_reset 94*63d4e48fSSadaf Ebrahimi 95*63d4e48fSSadaf Ebrahimi if DEFINE_boolean boolVal "${default}" 'my boolean' b >"${stdoutF}" 2>"${stderrF}" 96*63d4e48fSSadaf Ebrahimi then 97*63d4e48fSSadaf Ebrahimi assertEquals "${desc}: incorrect FLAGS_boolVal value" "${FLAGS_boolVal:-}" "${want}" 98*63d4e48fSSadaf Ebrahimi else 99*63d4e48fSSadaf Ebrahimi got=$? 100*63d4e48fSSadaf Ebrahimi if [ "${ok}" -eq "${FLAGS_TRUE}" ]; then 101*63d4e48fSSadaf Ebrahimi assertEquals "${desc}: DEFINE_boolean() failed unexpectedly" "${want}" "${got}" 102*63d4e48fSSadaf Ebrahimi else 103*63d4e48fSSadaf Ebrahimi assertEquals "${desc}: DEFINE_boolean() expected different return value" "${want}" "${got}" 104*63d4e48fSSadaf Ebrahimi assertErrorMsg 105*63d4e48fSSadaf Ebrahimi fi 106*63d4e48fSSadaf Ebrahimi fi 107*63d4e48fSSadaf Ebrahimi done <<EOF 108*63d4e48fSSadaf Ebrahimitrue_long ${FLAGS_TRUE} true ${FLAGS_TRUE} 109*63d4e48fSSadaf Ebrahimitrue_short ${FLAGS_TRUE} t ${FLAGS_TRUE} 110*63d4e48fSSadaf Ebrahimitrue_int ${FLAGS_TRUE} 0 ${FLAGS_TRUE} 111*63d4e48fSSadaf Ebrahimifalse_long ${FLAGS_TRUE} false ${FLAGS_FALSE} 112*63d4e48fSSadaf Ebrahimifalse_short ${FLAGS_TRUE} f ${FLAGS_FALSE} 113*63d4e48fSSadaf Ebrahimifalse_int ${FLAGS_TRUE} 1 ${FLAGS_FALSE} 114*63d4e48fSSadaf Ebrahimiinvalid ${FLAGS_FALSE} invalid ${FLAGS_ERROR} 115*63d4e48fSSadaf EbrahimiEOF 116*63d4e48fSSadaf Ebrahimi} 117*63d4e48fSSadaf Ebrahimi 118*63d4e48fSSadaf EbrahimitestFloat() { 119*63d4e48fSSadaf Ebrahimi # Valid defaults. 120*63d4e48fSSadaf Ebrahimi for default in ${TH_FLOAT_VALID}; do 121*63d4e48fSSadaf Ebrahimi flags_reset 122*63d4e48fSSadaf Ebrahimi desc="valid_float_val='${default}'" 123*63d4e48fSSadaf Ebrahimi if DEFINE_float floatVal "${default}" 'valid float' f 124*63d4e48fSSadaf Ebrahimi then 125*63d4e48fSSadaf Ebrahimi got="${FLAGS_floatVal:-}" want="${default}" 126*63d4e48fSSadaf Ebrahimi assertEquals "${desc}: incorrect FLAGS_floatVal value" "${want}" "${got}" 127*63d4e48fSSadaf Ebrahimi else 128*63d4e48fSSadaf Ebrahimi assertEquals "${desc}: DEFINE_float() failed unexpectedly." "${FLAGS_TRUE}" $? 129*63d4e48fSSadaf Ebrahimi fi 130*63d4e48fSSadaf Ebrahimi done 131*63d4e48fSSadaf Ebrahimi 132*63d4e48fSSadaf Ebrahimi # Invalid defaults. 133*63d4e48fSSadaf Ebrahimi for default in ${TH_FLOAT_INVALID}; do 134*63d4e48fSSadaf Ebrahimi flags_reset 135*63d4e48fSSadaf Ebrahimi desc="invalid_float_val='${default}'" 136*63d4e48fSSadaf Ebrahimi if DEFINE_float floatVal "${default}" 'invalid float' f >"${stdoutF}" 2>"${stderrF}" 137*63d4e48fSSadaf Ebrahimi then 138*63d4e48fSSadaf Ebrahimi fail "${desc}: expected DEFINE_float() to fail" 139*63d4e48fSSadaf Ebrahimi else 140*63d4e48fSSadaf Ebrahimi assertEquals "${desc}: DEFINE_float() expected error" "${FLAGS_ERROR}" $? 141*63d4e48fSSadaf Ebrahimi assertErrorMsg 142*63d4e48fSSadaf Ebrahimi fi 143*63d4e48fSSadaf Ebrahimi done 144*63d4e48fSSadaf Ebrahimi} 145*63d4e48fSSadaf Ebrahimi 146*63d4e48fSSadaf EbrahimitestInteger() { 147*63d4e48fSSadaf Ebrahimi # Valid defaults. 148*63d4e48fSSadaf Ebrahimi for default in ${TH_INT_VALID}; do 149*63d4e48fSSadaf Ebrahimi flags_reset 150*63d4e48fSSadaf Ebrahimi desc="valid_int_val='${default}'" 151*63d4e48fSSadaf Ebrahimi if DEFINE_integer intVal "${default}" 'valid integer' i 152*63d4e48fSSadaf Ebrahimi then 153*63d4e48fSSadaf Ebrahimi got="${FLAGS_intVal:-}" want="${default}" 154*63d4e48fSSadaf Ebrahimi assertEquals "${desc}: incorrect FLAGS_intVal value" "${want}" "${got}" 155*63d4e48fSSadaf Ebrahimi else 156*63d4e48fSSadaf Ebrahimi assertEquals "${desc}: DEFINE_integer() failed unexpectedly." "${FLAGS_TRUE}" $? 157*63d4e48fSSadaf Ebrahimi fi 158*63d4e48fSSadaf Ebrahimi done 159*63d4e48fSSadaf Ebrahimi 160*63d4e48fSSadaf Ebrahimi # Invalid defaults. 161*63d4e48fSSadaf Ebrahimi for default in ${TH_INT_INVALID}; do 162*63d4e48fSSadaf Ebrahimi flags_reset 163*63d4e48fSSadaf Ebrahimi desc="invalid_int_val='${default}'" 164*63d4e48fSSadaf Ebrahimi if DEFINE_integer intVal "${default}" 'invalid integer' i >"${stdoutF}" 2>"${stderrF}" 165*63d4e48fSSadaf Ebrahimi then 166*63d4e48fSSadaf Ebrahimi fail "${desc}: expected DEFINE_integer() to fail" 167*63d4e48fSSadaf Ebrahimi else 168*63d4e48fSSadaf Ebrahimi assertEquals "${desc}: DEFINE_integer() expected error." "${FLAGS_ERROR}" $? 169*63d4e48fSSadaf Ebrahimi assertErrorMsg 170*63d4e48fSSadaf Ebrahimi fi 171*63d4e48fSSadaf Ebrahimi done 172*63d4e48fSSadaf Ebrahimi} 173*63d4e48fSSadaf Ebrahimi 174*63d4e48fSSadaf EbrahimitestString() { 175*63d4e48fSSadaf Ebrahimi # Valid defaults. 176*63d4e48fSSadaf Ebrahimi for default in ${TH_BOOL_VALID} ${TH_FLOAT_VALID} ${TH_INT_VALID} 'also valid' '' 177*63d4e48fSSadaf Ebrahimi do 178*63d4e48fSSadaf Ebrahimi flags_reset 179*63d4e48fSSadaf Ebrahimi desc="valid_string_val='${default}'" 180*63d4e48fSSadaf Ebrahimi if DEFINE_string strVal "${default}" "string: ${default}" s 181*63d4e48fSSadaf Ebrahimi then 182*63d4e48fSSadaf Ebrahimi got="${FLAGS_strVal:-}" want="${default}" 183*63d4e48fSSadaf Ebrahimi assertEquals "${desc}: incorrect FLAGS_strVal value" "${want}" "${got}" 184*63d4e48fSSadaf Ebrahimi else 185*63d4e48fSSadaf Ebrahimi assertEquals "${desc}: DEFINE_string() failed unexpectedly." "${FLAGS_TRUE}" $? 186*63d4e48fSSadaf Ebrahimi fi 187*63d4e48fSSadaf Ebrahimi done 188*63d4e48fSSadaf Ebrahimi 189*63d4e48fSSadaf Ebrahimi # There are no known invalid defaults. 190*63d4e48fSSadaf Ebrahimi} 191*63d4e48fSSadaf Ebrahimi 192*63d4e48fSSadaf EbrahimitestShortNameLength() { 193*63d4e48fSSadaf Ebrahimi # Make sure short names are no longer than a single character. 194*63d4e48fSSadaf Ebrahimi : 195*63d4e48fSSadaf Ebrahimi} 196*63d4e48fSSadaf Ebrahimi 197*63d4e48fSSadaf EbrahimitestFlagNameIsReserved() { 198*63d4e48fSSadaf Ebrahimi if DEFINE_string TRUE '' 'true is a reserved flag name' t >"${stdoutF}" 2>"${stderrF}" 199*63d4e48fSSadaf Ebrahimi then 200*63d4e48fSSadaf Ebrahimi fail "expected DEFINE with reserved flag name to fail" 201*63d4e48fSSadaf Ebrahimi else 202*63d4e48fSSadaf Ebrahimi assertEquals "expected error from DEFINE with reserved flag" "${FLAGS_ERROR}" $? 203*63d4e48fSSadaf Ebrahimi assertErrorMsg 'flag name (TRUE) is reserved' 204*63d4e48fSSadaf Ebrahimi fi 205*63d4e48fSSadaf Ebrahimi} 206*63d4e48fSSadaf Ebrahimi 207*63d4e48fSSadaf EbrahimioneTimeSetUp() { 208*63d4e48fSSadaf Ebrahimi th_oneTimeSetUp 209*63d4e48fSSadaf Ebrahimi} 210*63d4e48fSSadaf Ebrahimi 211*63d4e48fSSadaf EbrahimitearDown() { 212*63d4e48fSSadaf Ebrahimi flags_reset 213*63d4e48fSSadaf Ebrahimi} 214*63d4e48fSSadaf Ebrahimi 215*63d4e48fSSadaf Ebrahimi# Load and run shUnit2. 216*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC2034 217*63d4e48fSSadaf Ebrahimi[ -n "${ZSH_VERSION:-}" ] && SHUNIT_PARENT=$0 218*63d4e48fSSadaf Ebrahimi. "${TH_SHUNIT}" 219