1*63d4e48fSSadaf Ebrahimi#! /bin/sh 2*63d4e48fSSadaf Ebrahimi# vim:et:ft=sh:sts=2:sw=2 3*63d4e48fSSadaf Ebrahimi# 4*63d4e48fSSadaf Ebrahimi# shFlags unit tests for the internal functions. 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# expr may be antiquated, but it is the only solution in some cases. 16*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC2003 17*63d4e48fSSadaf Ebrahimi# $() are not fully portable (POSIX != portable). 18*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC2006 19*63d4e48fSSadaf Ebrahimi 20*63d4e48fSSadaf Ebrahimi# These variables will be overridden by the test helpers. 21*63d4e48fSSadaf EbrahimistdoutF="${TMPDIR:-/tmp}/STDOUT" 22*63d4e48fSSadaf EbrahimistderrF="${TMPDIR:-/tmp}/STDERR" 23*63d4e48fSSadaf Ebrahimi 24*63d4e48fSSadaf Ebrahimi# Load test helpers. 25*63d4e48fSSadaf Ebrahimi. ./shflags_test_helpers 26*63d4e48fSSadaf Ebrahimi 27*63d4e48fSSadaf EbrahimitestColumns() { 28*63d4e48fSSadaf Ebrahimi cols=`_flags_columns` 29*63d4e48fSSadaf Ebrahimi value=`expr "${cols}" : '\([0-9]*\)'` 30*63d4e48fSSadaf Ebrahimi assertNotNull "unexpected screen width (${cols})" "${value}" 31*63d4e48fSSadaf Ebrahimi} 32*63d4e48fSSadaf Ebrahimi 33*63d4e48fSSadaf EbrahimitestGetoptVers() { 34*63d4e48fSSadaf Ebrahimi # shellcheck disable=SC2162 35*63d4e48fSSadaf Ebrahimi while read desc mock want; do 36*63d4e48fSSadaf Ebrahimi assertEquals "${desc}" "$(_flags_getopt_vers "${mock}")" "${want}" 37*63d4e48fSSadaf Ebrahimi done <<EOF 38*63d4e48fSSadaf Ebrahimistandard mock_getopt_std ${__FLAGS_GETOPT_VERS_STD} 39*63d4e48fSSadaf Ebrahimienhanced mock_getopt_enh ${__FLAGS_GETOPT_VERS_ENH} 40*63d4e48fSSadaf EbrahimiEOF 41*63d4e48fSSadaf Ebrahimi} 42*63d4e48fSSadaf Ebrahimi 43*63d4e48fSSadaf Ebrahimi### The mock_getopt_* commands behave like "getopt -lfoo '' --foo" was called. 44*63d4e48fSSadaf Ebrahimi# macOS 10.13.0. 45*63d4e48fSSadaf Ebrahimimock_getopt_std() { echo ' -- --foo'; return 0; } 46*63d4e48fSSadaf Ebrahimi# Ubuntu 16.04.3 47*63d4e48fSSadaf Ebrahimimock_getopt_enh() { echo ' --foo --'; return 0; } 48*63d4e48fSSadaf Ebrahimi 49*63d4e48fSSadaf EbrahimitestGenOptStr() { 50*63d4e48fSSadaf Ebrahimi _testGenOptStr '' '' 51*63d4e48fSSadaf Ebrahimi 52*63d4e48fSSadaf Ebrahimi # shellcheck disable=SC2034 53*63d4e48fSSadaf Ebrahimi DEFINE_boolean bool false 'boolean value' b 54*63d4e48fSSadaf Ebrahimi _testGenOptStr 'b' 'bool' 55*63d4e48fSSadaf Ebrahimi 56*63d4e48fSSadaf Ebrahimi # shellcheck disable=SC2034 57*63d4e48fSSadaf Ebrahimi DEFINE_float float 0.0 'float value' f 58*63d4e48fSSadaf Ebrahimi _testGenOptStr 'bf:' 'bool,float:' 59*63d4e48fSSadaf Ebrahimi 60*63d4e48fSSadaf Ebrahimi # shellcheck disable=SC2034 61*63d4e48fSSadaf Ebrahimi DEFINE_integer int 0 'integer value' i 62*63d4e48fSSadaf Ebrahimi _testGenOptStr 'bf:i:' 'bool,float:,int:' 63*63d4e48fSSadaf Ebrahimi 64*63d4e48fSSadaf Ebrahimi # shellcheck disable=SC2034 65*63d4e48fSSadaf Ebrahimi DEFINE_string str 0 'string value' s 66*63d4e48fSSadaf Ebrahimi _testGenOptStr 'bf:i:s:' 'bool,float:,int:,str:' 67*63d4e48fSSadaf Ebrahimi 68*63d4e48fSSadaf Ebrahimi # shellcheck disable=SC2034 69*63d4e48fSSadaf Ebrahimi DEFINE_boolean help false 'show help' h 70*63d4e48fSSadaf Ebrahimi _testGenOptStr 'bf:i:s:h' 'bool,float:,int:,str:,help' 71*63d4e48fSSadaf Ebrahimi} 72*63d4e48fSSadaf Ebrahimi 73*63d4e48fSSadaf Ebrahimi_testGenOptStr() { 74*63d4e48fSSadaf Ebrahimi short=$1 75*63d4e48fSSadaf Ebrahimi long=$2 76*63d4e48fSSadaf Ebrahimi 77*63d4e48fSSadaf Ebrahimi result=`_flags_genOptStr "${__FLAGS_OPTSTR_SHORT}"` 78*63d4e48fSSadaf Ebrahimi assertTrue 'short option string generation failed' $? 79*63d4e48fSSadaf Ebrahimi assertEquals "${short}" "${result}" 80*63d4e48fSSadaf Ebrahimi 81*63d4e48fSSadaf Ebrahimi result=`_flags_genOptStr "${__FLAGS_OPTSTR_LONG}"` 82*63d4e48fSSadaf Ebrahimi assertTrue 'long option string generation failed' $? 83*63d4e48fSSadaf Ebrahimi assertEquals "${long}" "${result}" 84*63d4e48fSSadaf Ebrahimi} 85*63d4e48fSSadaf Ebrahimi 86*63d4e48fSSadaf EbrahimitestGetFlagInfo() { 87*63d4e48fSSadaf Ebrahimi __flags_blah_foobar='1234' 88*63d4e48fSSadaf Ebrahimi 89*63d4e48fSSadaf Ebrahimi desc='valid_flag' 90*63d4e48fSSadaf Ebrahimi if rslt="`_flags_getFlagInfo 'blah' 'foobar'`"; then 91*63d4e48fSSadaf Ebrahimi assertEquals "${desc}: invalid flag result" "${__flags_blah_foobar}" "${rslt}" 92*63d4e48fSSadaf Ebrahimi else 93*63d4e48fSSadaf Ebrahimi fail "${desc}: request for valid flag info failed" 94*63d4e48fSSadaf Ebrahimi fi 95*63d4e48fSSadaf Ebrahimi 96*63d4e48fSSadaf Ebrahimi desc='invalid_flag' 97*63d4e48fSSadaf Ebrahimi if rslt="`_flags_getFlagInfo 'blah' 'hubbabubba' >"${stdoutF}" 2>"${stderrF}"`"; then 98*63d4e48fSSadaf Ebrahimi fail "${desc}: expected invalid flag request to fail" 99*63d4e48fSSadaf Ebrahimi th_showOutput 100*63d4e48fSSadaf Ebrahimi else 101*63d4e48fSSadaf Ebrahimi assertEquals "${desc}: expected an error" "${FLAGS_ERROR}" $? 102*63d4e48fSSadaf Ebrahimi assertErrorMsg "missing flag info variable" 103*63d4e48fSSadaf Ebrahimi fi 104*63d4e48fSSadaf Ebrahimi} 105*63d4e48fSSadaf Ebrahimi 106*63d4e48fSSadaf EbrahimitestItemInList() { 107*63d4e48fSSadaf Ebrahimi list='this is a test' 108*63d4e48fSSadaf Ebrahimi # shellcheck disable=SC2162 109*63d4e48fSSadaf Ebrahimi while read desc item want; do 110*63d4e48fSSadaf Ebrahimi if [ "${want}" -eq "${FLAGS_TRUE}" ]; then 111*63d4e48fSSadaf Ebrahimi continue 112*63d4e48fSSadaf Ebrahimi fi 113*63d4e48fSSadaf Ebrahimi got=${FLAGS_TRUE} 114*63d4e48fSSadaf Ebrahimi if ! _flags_itemInList "${item}" "${list}"; then 115*63d4e48fSSadaf Ebrahimi got=${FLAGS_FALSE} 116*63d4e48fSSadaf Ebrahimi fi 117*63d4e48fSSadaf Ebrahimi assertEquals "${desc}: itemInList(${item})" "${want}" "${got}" 118*63d4e48fSSadaf Ebrahimi done <<EOF 119*63d4e48fSSadaf Ebrahimilead_item this ${FLAGS_TRUE} 120*63d4e48fSSadaf Ebrahimimiddle_item is ${FLAGS_TRUE} 121*63d4e48fSSadaf Ebrahimilast_item test ${FLAGS_TRUE} 122*63d4e48fSSadaf Ebrahimimissing_item asdf ${FLAGS_FALSE} 123*63d4e48fSSadaf Ebrahimitest_partial_te te ${FLAGS_FALSE} 124*63d4e48fSSadaf Ebrahimitest_partial_es es ${FLAGS_FALSE} 125*63d4e48fSSadaf Ebrahimitest_partial_st st ${FLAGS_FALSE} 126*63d4e48fSSadaf Ebrahimiempty_item '' ${FLAGS_FALSE} 127*63d4e48fSSadaf EbrahimiEOF 128*63d4e48fSSadaf Ebrahimi 129*63d4e48fSSadaf Ebrahimi if _flags_itemInList 'item' ''; then 130*63d4e48fSSadaf Ebrahimi fail 'empty lists should not match' 131*63d4e48fSSadaf Ebrahimi fi 132*63d4e48fSSadaf Ebrahimi} 133*63d4e48fSSadaf Ebrahimi 134*63d4e48fSSadaf EbrahimitestUnderscoreName() { 135*63d4e48fSSadaf Ebrahimi # shellcheck disable=SC2162 136*63d4e48fSSadaf Ebrahimi while read desc name want; do 137*63d4e48fSSadaf Ebrahimi got=`_flags_underscoreName "${name}"` 138*63d4e48fSSadaf Ebrahimi assertEquals "${desc}: underscoreName(${name})" "${got}" "${want}" 139*63d4e48fSSadaf Ebrahimi done <<EOF 140*63d4e48fSSadaf Ebrahimiwith_dashes name-with-dashes name_with_dashes 141*63d4e48fSSadaf Ebrahimiwith_underscores name_with_underscores name_with_underscores 142*63d4e48fSSadaf Ebrahimijust_alpha_numeric abc123 abc123 143*63d4e48fSSadaf Ebrahimiempty "" "" 144*63d4e48fSSadaf EbrahimiEOF 145*63d4e48fSSadaf Ebrahimi} 146*63d4e48fSSadaf Ebrahimi 147*63d4e48fSSadaf EbrahimitestBool() { 148*63d4e48fSSadaf Ebrahimi # Valid values. 149*63d4e48fSSadaf Ebrahimi for value in ${TH_BOOL_VALID}; do 150*63d4e48fSSadaf Ebrahimi got=${FLAGS_TRUE} 151*63d4e48fSSadaf Ebrahimi if ! _flags_validBool "${value}"; then 152*63d4e48fSSadaf Ebrahimi got=${FLAGS_FALSE} 153*63d4e48fSSadaf Ebrahimi fi 154*63d4e48fSSadaf Ebrahimi assertTrue "valid value (${value}) did not validate" "${got}" 155*63d4e48fSSadaf Ebrahimi done 156*63d4e48fSSadaf Ebrahimi 157*63d4e48fSSadaf Ebrahimi # Invalid values. 158*63d4e48fSSadaf Ebrahimi for value in ${TH_BOOL_INVALID}; do 159*63d4e48fSSadaf Ebrahimi got=${FLAGS_FALSE} 160*63d4e48fSSadaf Ebrahimi if _flags_validBool "${value}"; then 161*63d4e48fSSadaf Ebrahimi got=${FLAGS_TRUE} 162*63d4e48fSSadaf Ebrahimi fi 163*63d4e48fSSadaf Ebrahimi assertFalse "invalid value (${value}) validated" "${got}" 164*63d4e48fSSadaf Ebrahimi done 165*63d4e48fSSadaf Ebrahimi} 166*63d4e48fSSadaf Ebrahimi 167*63d4e48fSSadaf Ebrahimi_testValidFloat() { 168*63d4e48fSSadaf Ebrahimi # Valid values. 169*63d4e48fSSadaf Ebrahimi for value in ${TH_INT_VALID} ${TH_FLOAT_VALID}; do 170*63d4e48fSSadaf Ebrahimi got=${FLAGS_TRUE} 171*63d4e48fSSadaf Ebrahimi if ! _flags_validFloat "${value}"; then 172*63d4e48fSSadaf Ebrahimi got=${FLAGS_FALSE} 173*63d4e48fSSadaf Ebrahimi fi 174*63d4e48fSSadaf Ebrahimi assertTrue "valid value (${value}) did not validate" "${got}" 175*63d4e48fSSadaf Ebrahimi done 176*63d4e48fSSadaf Ebrahimi 177*63d4e48fSSadaf Ebrahimi # Invalid values. 178*63d4e48fSSadaf Ebrahimi for value in ${TH_FLOAT_INVALID}; do 179*63d4e48fSSadaf Ebrahimi got=${FLAGS_FALSE} 180*63d4e48fSSadaf Ebrahimi if _flags_validFloat "${value}"; then 181*63d4e48fSSadaf Ebrahimi got=${FLAGS_TRUE} 182*63d4e48fSSadaf Ebrahimi fi 183*63d4e48fSSadaf Ebrahimi assertFalse "invalid value (${value}) validated" "${got}" 184*63d4e48fSSadaf Ebrahimi done 185*63d4e48fSSadaf Ebrahimi} 186*63d4e48fSSadaf Ebrahimi 187*63d4e48fSSadaf EbrahimitestValidFloatBuiltin() { 188*63d4e48fSSadaf Ebrahimi if ! _flags_useBuiltin; then 189*63d4e48fSSadaf Ebrahimi startSkipping 190*63d4e48fSSadaf Ebrahimi fi 191*63d4e48fSSadaf Ebrahimi _testValidFloat 192*63d4e48fSSadaf Ebrahimi} 193*63d4e48fSSadaf Ebrahimi 194*63d4e48fSSadaf EbrahimitestValidFloatExpr() { 195*63d4e48fSSadaf Ebrahimi ( 196*63d4e48fSSadaf Ebrahimi _flags_useBuiltin() { return "${FLAGS_FALSE}"; } 197*63d4e48fSSadaf Ebrahimi _testValidFloat 198*63d4e48fSSadaf Ebrahimi ) 199*63d4e48fSSadaf Ebrahimi} 200*63d4e48fSSadaf Ebrahimi 201*63d4e48fSSadaf Ebrahimi_testValidInt() { 202*63d4e48fSSadaf Ebrahimi # Valid values. 203*63d4e48fSSadaf Ebrahimi for value in ${TH_INT_VALID}; do 204*63d4e48fSSadaf Ebrahimi got=${FLAGS_TRUE} 205*63d4e48fSSadaf Ebrahimi if ! _flags_validInt "${value}"; then 206*63d4e48fSSadaf Ebrahimi got=${FLAGS_FALSE} 207*63d4e48fSSadaf Ebrahimi fi 208*63d4e48fSSadaf Ebrahimi assertTrue "valid value (${value}) did not validate" "${got}" 209*63d4e48fSSadaf Ebrahimi done 210*63d4e48fSSadaf Ebrahimi 211*63d4e48fSSadaf Ebrahimi # Invalid values. 212*63d4e48fSSadaf Ebrahimi for value in ${TH_INT_INVALID}; do 213*63d4e48fSSadaf Ebrahimi got=${FLAGS_FALSE} 214*63d4e48fSSadaf Ebrahimi if _flags_validInt "${value}"; then 215*63d4e48fSSadaf Ebrahimi got=${FLAGS_TRUE} 216*63d4e48fSSadaf Ebrahimi fi 217*63d4e48fSSadaf Ebrahimi assertFalse "invalid value (${value}) should not validate" "${got}" 218*63d4e48fSSadaf Ebrahimi done 219*63d4e48fSSadaf Ebrahimi} 220*63d4e48fSSadaf Ebrahimi 221*63d4e48fSSadaf EbrahimitestValidIntBuiltin() { 222*63d4e48fSSadaf Ebrahimi if ! _flags_useBuiltin; then 223*63d4e48fSSadaf Ebrahimi startSkipping 224*63d4e48fSSadaf Ebrahimi fi 225*63d4e48fSSadaf Ebrahimi _testValidInt 226*63d4e48fSSadaf Ebrahimi} 227*63d4e48fSSadaf Ebrahimi 228*63d4e48fSSadaf EbrahimitestValidIntExpr() { 229*63d4e48fSSadaf Ebrahimi ( 230*63d4e48fSSadaf Ebrahimi _flags_useBuiltin() { return "${FLAGS_FALSE}"; } 231*63d4e48fSSadaf Ebrahimi _testValidInt 232*63d4e48fSSadaf Ebrahimi ) 233*63d4e48fSSadaf Ebrahimi} 234*63d4e48fSSadaf Ebrahimi 235*63d4e48fSSadaf Ebrahimi_testMath() { 236*63d4e48fSSadaf Ebrahimi if result=`_flags_math 1`; then 237*63d4e48fSSadaf Ebrahimi assertEquals '1' 1 "${result}" 238*63d4e48fSSadaf Ebrahimi else 239*63d4e48fSSadaf Ebrahimi fail '1 failed' 240*63d4e48fSSadaf Ebrahimi fi 241*63d4e48fSSadaf Ebrahimi 242*63d4e48fSSadaf Ebrahimi if result=`_flags_math '1 + 2'`; then 243*63d4e48fSSadaf Ebrahimi assertEquals '1+2' 3 "${result}" 244*63d4e48fSSadaf Ebrahimi else 245*63d4e48fSSadaf Ebrahimi fail '1+2 failed' 246*63d4e48fSSadaf Ebrahimi fi 247*63d4e48fSSadaf Ebrahimi 248*63d4e48fSSadaf Ebrahimi if result=`_flags_math '1 + 2 + 3'`; then 249*63d4e48fSSadaf Ebrahimi assertEquals '1+2+3' 6 "${result}" 250*63d4e48fSSadaf Ebrahimi else 251*63d4e48fSSadaf Ebrahimi fail '1+2+3 failed' 252*63d4e48fSSadaf Ebrahimi fi 253*63d4e48fSSadaf Ebrahimi 254*63d4e48fSSadaf Ebrahimi got=${FLAGS_TRUE} 255*63d4e48fSSadaf Ebrahimi if ! _flags_math >/dev/null 2>&1; then 256*63d4e48fSSadaf Ebrahimi got=${FLAGS_FALSE} 257*63d4e48fSSadaf Ebrahimi fi 258*63d4e48fSSadaf Ebrahimi assertFalse 'missing math succeeded' "${got}" 259*63d4e48fSSadaf Ebrahimi} 260*63d4e48fSSadaf Ebrahimi 261*63d4e48fSSadaf EbrahimitestMathBuiltin() { 262*63d4e48fSSadaf Ebrahimi _flags_useBuiltin || startSkipping 263*63d4e48fSSadaf Ebrahimi _testMath 264*63d4e48fSSadaf Ebrahimi} 265*63d4e48fSSadaf Ebrahimi 266*63d4e48fSSadaf EbrahimitestMathExpr() { 267*63d4e48fSSadaf Ebrahimi ( 268*63d4e48fSSadaf Ebrahimi _flags_useBuiltin() { return "${FLAGS_FALSE}"; } 269*63d4e48fSSadaf Ebrahimi _testMath 270*63d4e48fSSadaf Ebrahimi ) 271*63d4e48fSSadaf Ebrahimi} 272*63d4e48fSSadaf Ebrahimi 273*63d4e48fSSadaf Ebrahimi_testStrlen() { 274*63d4e48fSSadaf Ebrahimi len=`_flags_strlen` 275*63d4e48fSSadaf Ebrahimi assertTrue 'missing argument failed' $? 276*63d4e48fSSadaf Ebrahimi assertEquals 'missing argument' 0 "${len}" 277*63d4e48fSSadaf Ebrahimi 278*63d4e48fSSadaf Ebrahimi len=`_flags_strlen ''` 279*63d4e48fSSadaf Ebrahimi assertTrue 'empty argument failed' $? 280*63d4e48fSSadaf Ebrahimi assertEquals 'empty argument' 0 "${len}" 281*63d4e48fSSadaf Ebrahimi 282*63d4e48fSSadaf Ebrahimi len=`_flags_strlen abc123` 283*63d4e48fSSadaf Ebrahimi assertTrue 'single-word failed' $? 284*63d4e48fSSadaf Ebrahimi assertEquals 'single-word' 6 "${len}" 285*63d4e48fSSadaf Ebrahimi 286*63d4e48fSSadaf Ebrahimi len=`_flags_strlen 'This is a test'` 287*63d4e48fSSadaf Ebrahimi assertTrue 'multi-word failed' $? 288*63d4e48fSSadaf Ebrahimi assertEquals 'multi-word' 14 "${len}" 289*63d4e48fSSadaf Ebrahimi} 290*63d4e48fSSadaf Ebrahimi 291*63d4e48fSSadaf EbrahimitestStrlenBuiltin() { 292*63d4e48fSSadaf Ebrahimi _flags_useBuiltin || startSkipping 293*63d4e48fSSadaf Ebrahimi _testStrlen 294*63d4e48fSSadaf Ebrahimi} 295*63d4e48fSSadaf Ebrahimi 296*63d4e48fSSadaf EbrahimitestStrlenExpr() { 297*63d4e48fSSadaf Ebrahimi ( 298*63d4e48fSSadaf Ebrahimi _flags_useBuiltin() { return "${FLAGS_FALSE}"; } 299*63d4e48fSSadaf Ebrahimi _testStrlen 300*63d4e48fSSadaf Ebrahimi ) 301*63d4e48fSSadaf Ebrahimi} 302*63d4e48fSSadaf Ebrahimi 303*63d4e48fSSadaf EbrahimioneTimeSetUp() { 304*63d4e48fSSadaf Ebrahimi th_oneTimeSetUp 305*63d4e48fSSadaf Ebrahimi 306*63d4e48fSSadaf Ebrahimi _flags_useBuiltin || \ 307*63d4e48fSSadaf Ebrahimi th_warn 'Shell built-ins not supported. Some tests will be skipped.' 308*63d4e48fSSadaf Ebrahimi} 309*63d4e48fSSadaf Ebrahimi 310*63d4e48fSSadaf EbrahimitearDown() { 311*63d4e48fSSadaf Ebrahimi flags_reset 312*63d4e48fSSadaf Ebrahimi} 313*63d4e48fSSadaf Ebrahimi 314*63d4e48fSSadaf Ebrahimi# Load and run shUnit2. 315*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC2034 316*63d4e48fSSadaf Ebrahimi[ -n "${ZSH_VERSION:-}" ] && SHUNIT_PARENT=$0 317*63d4e48fSSadaf Ebrahimi. "${TH_SHUNIT}" 318