diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/shflags | 1155 | ||||
-rwxr-xr-x | src/shflags_test.sh | 116 | ||||
-rwxr-xr-x | src/shflags_test_defines.sh | 217 | ||||
-rw-r--r-- | src/shflags_test_helpers | 116 | ||||
-rwxr-xr-x | src/shflags_test_parsing.sh | 365 | ||||
-rwxr-xr-x | src/shflags_test_private.sh | 247 | ||||
-rwxr-xr-x | src/shflags_test_public.sh | 180 |
7 files changed, 0 insertions, 2396 deletions
diff --git a/src/shflags b/src/shflags deleted file mode 100644 index 11d3060..0000000 --- a/src/shflags +++ /dev/null @@ -1,1155 +0,0 @@ -# vim:et:ft=sh:sts=2:sw=2 -# -# Copyright 2008-2016 Kate Ward. All Rights Reserved. -# Released under the Apache License 2.0. -# -# shFlags -- Advanced command-line flag library for Unix shell scripts. -# http://code.google.com/p/shflags/ -# -# Author: kate.ward@forestent.com (Kate Ward) -# -# This module implements something like the google-gflags library available -# from http://code.google.com/p/google-gflags/. -# -# FLAG TYPES: This is a list of the DEFINE_*'s that you can do. All flags take -# a name, default value, help-string, and optional 'short' name (one-letter -# name). Some flags have other arguments, which are described with the flag. -# -# DEFINE_string: takes any input, and intreprets it as a string. -# -# DEFINE_boolean: does not take any arguments. Say --myflag to set -# FLAGS_myflag to true, or --nomyflag to set FLAGS_myflag to false. For short -# flags, passing the flag on the command-line negates the default value, i.e. -# if the default is true, passing the flag sets the value to false. -# -# DEFINE_float: takes an input and intreprets it as a floating point number. As -# shell does not support floats per-se, the input is merely validated as -# being a valid floating point value. -# -# DEFINE_integer: takes an input and intreprets it as an integer. -# -# SPECIAL FLAGS: There are a few flags that have special meaning: -# --help (or -?) prints a list of all the flags in a human-readable fashion -# --flagfile=foo read flags from foo. (not implemented yet) -# -- as in getopt(), terminates flag-processing -# -# EXAMPLE USAGE: -# -# -- begin hello.sh -- -# #! /bin/sh -# . ./shflags -# DEFINE_string name 'world' "somebody's name" n -# FLAGS "$@" || exit $? -# eval set -- "${FLAGS_ARGV}" -# echo "Hello, ${FLAGS_name}." -# -- end hello.sh -- -# -# $ ./hello.sh -n Kate -# Hello, Kate. -# -# CUSTOMIZABLE BEHAVIOR: -# -# A script can override the default 'getopt' command by providing the path to -# an alternate implementation by defining the FLAGS_GETOPT_CMD variable. -# -# NOTES: -# -# * Not all systems include a getopt version that supports long flags. On these -# systems, only short flags are recognized. - -#============================================================================== -# shFlags -# -# Shared attributes: -# flags_error: last error message -# flags_output: last function output (rarely valid) -# flags_return: last return value -# -# __flags_longNames: list of long names for all flags -# __flags_shortNames: list of short names for all flags -# __flags_boolNames: list of boolean flag names -# -# __flags_opts: options parsed by getopt -# -# Per-flag attributes: -# FLAGS_<flag_name>: contains value of flag named 'flag_name' -# __flags_<flag_name>_default: the default flag value -# __flags_<flag_name>_help: the flag help string -# __flags_<flag_name>_short: the flag short name -# __flags_<flag_name>_type: the flag type -# -# Notes: -# - lists of strings are space separated, and a null value is the '~' char. - -# return if FLAGS already loaded -[ -n "${FLAGS_VERSION:-}" ] && return 0 -FLAGS_VERSION='1.2.0' - -# return values that scripts can use -FLAGS_TRUE=0 -FLAGS_FALSE=1 -FLAGS_ERROR=2 - -# determine some reasonable command defaults -__FLAGS_UNAME_S=`uname -s` -case "${__FLAGS_UNAME_S}" in - BSD) __FLAGS_EXPR_CMD='gexpr' ;; - *) __FLAGS_EXPR_CMD='expr' ;; -esac - -# commands a user can override if needed -FLAGS_EXPR_CMD=${FLAGS_EXPR_CMD:-${__FLAGS_EXPR_CMD}} -FLAGS_GETOPT_CMD=${FLAGS_GETOPT_CMD:-getopt} - -# specific shell checks -if [ -n "${ZSH_VERSION:-}" ]; then - setopt |grep "^shwordsplit$" >/dev/null - if [ $? -ne ${FLAGS_TRUE} ]; then - _flags_fatal 'zsh shwordsplit option is required for proper zsh operation' - fi - if [ -z "${FLAGS_PARENT:-}" ]; then - _flags_fatal "zsh does not pass \$0 through properly. please declare' \ -\"FLAGS_PARENT=\$0\" before calling shFlags" - fi -fi - -# can we use built-ins? -( echo "${FLAGS_TRUE#0}"; ) >/dev/null 2>&1 -if [ $? -eq ${FLAGS_TRUE} ]; then - __FLAGS_USE_BUILTIN=${FLAGS_TRUE} -else - __FLAGS_USE_BUILTIN=${FLAGS_FALSE} -fi - -# -# constants -# - -# reserved flag names -__FLAGS_RESERVED_LIST=' ARGC ARGV ERROR FALSE GETOPT_CMD HELP PARENT TRUE ' -__FLAGS_RESERVED_LIST="${__FLAGS_RESERVED_LIST} VERSION " - -# getopt version -__FLAGS_GETOPT_VERS_STD=0 -__FLAGS_GETOPT_VERS_ENH=1 -__FLAGS_GETOPT_VERS_BSD=2 - -${FLAGS_GETOPT_CMD} >/dev/null 2>&1 -case $? in - 0) __FLAGS_GETOPT_VERS=${__FLAGS_GETOPT_VERS_STD} ;; # bsd getopt - 2) - # TODO(kward): look into '-T' option to test the internal getopt() version - if [ "`${FLAGS_GETOPT_CMD} --version`" = '-- ' ]; then - __FLAGS_GETOPT_VERS=${__FLAGS_GETOPT_VERS_STD} - else - __FLAGS_GETOPT_VERS=${__FLAGS_GETOPT_VERS_ENH} - fi - ;; - *) _flags_fatal 'unable to determine getopt version' ;; -esac - -# getopt optstring lengths -__FLAGS_OPTSTR_SHORT=0 -__FLAGS_OPTSTR_LONG=1 - -__FLAGS_NULL='~' - -# flag info strings -__FLAGS_INFO_DEFAULT='default' -__FLAGS_INFO_HELP='help' -__FLAGS_INFO_SHORT='short' -__FLAGS_INFO_TYPE='type' - -# flag lengths -__FLAGS_LEN_SHORT=0 -__FLAGS_LEN_LONG=1 - -# flag types -__FLAGS_TYPE_NONE=0 -__FLAGS_TYPE_BOOLEAN=1 -__FLAGS_TYPE_FLOAT=2 -__FLAGS_TYPE_INTEGER=3 -__FLAGS_TYPE_STRING=4 - -# set the constants readonly -__flags_constants=`set |awk -F= '/^FLAGS_/ || /^__FLAGS_/ {print $1}'` -for __flags_const in ${__flags_constants}; do - # skip certain flags - case ${__flags_const} in - FLAGS_HELP) continue ;; - FLAGS_PARENT) continue ;; - esac - # set flag readonly - if [ -z "${ZSH_VERSION:-}" ]; then - readonly ${__flags_const} - else # handle zsh - case ${ZSH_VERSION} in - [123].*) readonly ${__flags_const} ;; - *) readonly -g ${__flags_const} ;; # declare readonly constants globally - esac - fi -done -unset __flags_const __flags_constants - -# -# internal variables -# - -# space separated lists -__flags_boolNames=' ' # boolean flag names -__flags_longNames=' ' # long flag names -__flags_shortNames=' ' # short flag names -__flags_definedNames=' ' # defined flag names (used for validation) - -__flags_columns='' # screen width in columns -__flags_opts='' # temporary storage for parsed getopt flags - -#------------------------------------------------------------------------------ -# private functions -# - -# logging functions -_flags_debug() { echo "flags:DEBUG $@" >&2; } -_flags_warn() { echo "flags:WARN $@" >&2; } -_flags_error() { echo "flags:ERROR $@" >&2; } -_flags_fatal() { echo "flags:FATAL $@" >&2; exit ${FLAGS_ERROR}; } - -# Define a flag. -# -# Calling this function will define the following info variables for the -# specified flag: -# FLAGS_flagname - the name for this flag (based upon the long flag name) -# __flags_<flag_name>_default - the default value -# __flags_flagname_help - the help string -# __flags_flagname_short - the single letter alias -# __flags_flagname_type - the type of flag (one of __FLAGS_TYPE_*) -# -# Args: -# _flags__type: integer: internal type of flag (__FLAGS_TYPE_*) -# _flags__name: string: long flag name -# _flags__default: default flag value -# _flags__help: string: help string -# _flags__short: string: (optional) short flag name -# Returns: -# integer: success of operation, or error -_flags_define() -{ - if [ $# -lt 4 ]; then - flags_error='DEFINE error: too few arguments' - flags_return=${FLAGS_ERROR} - _flags_error "${flags_error}" - return ${flags_return} - fi - - _flags_type_=$1 - _flags_name_=$2 - _flags_default_=$3 - _flags_help_=$4 - _flags_short_=${5:-${__FLAGS_NULL}} - - _flags_return_=${FLAGS_TRUE} - _flags_usName_=`_flags_underscoreName ${_flags_name_}` - - # check whether the flag name is reserved - _flags_itemInList ${_flags_usName_} "${__FLAGS_RESERVED_LIST}" - if [ $? -eq ${FLAGS_TRUE} ]; then - flags_error="flag name (${_flags_name_}) is reserved" - _flags_return_=${FLAGS_ERROR} - fi - - # require short option for getopt that don't support long options - if [ ${_flags_return_} -eq ${FLAGS_TRUE} \ - -a ${__FLAGS_GETOPT_VERS} -ne ${__FLAGS_GETOPT_VERS_ENH} \ - -a "${_flags_short_}" = "${__FLAGS_NULL}" ] - then - flags_error="short flag required for (${_flags_name_}) on this platform" - _flags_return_=${FLAGS_ERROR} - fi - - # check for existing long name definition - if [ ${_flags_return_} -eq ${FLAGS_TRUE} ]; then - if _flags_itemInList ${_flags_usName_} ${__flags_definedNames}; then - flags_error="definition for ([no]${_flags_name_}) already exists" - _flags_warn "${flags_error}" - _flags_return_=${FLAGS_FALSE} - fi - fi - - # check for existing short name definition - if [ ${_flags_return_} -eq ${FLAGS_TRUE} \ - -a "${_flags_short_}" != "${__FLAGS_NULL}" ] - then - if _flags_itemInList "${_flags_short_}" ${__flags_shortNames}; then - flags_error="flag short name (${_flags_short_}) already defined" - _flags_warn "${flags_error}" - _flags_return_=${FLAGS_FALSE} - fi - fi - - # handle default value. note, on several occasions the 'if' portion of an - # if/then/else contains just a ':' which does nothing. a binary reversal via - # '!' is not done because it does not work on all shells. - if [ ${_flags_return_} -eq ${FLAGS_TRUE} ]; then - case ${_flags_type_} in - ${__FLAGS_TYPE_BOOLEAN}) - if _flags_validBool "${_flags_default_}"; then - case ${_flags_default_} in - true|t|0) _flags_default_=${FLAGS_TRUE} ;; - false|f|1) _flags_default_=${FLAGS_FALSE} ;; - esac - else - flags_error="invalid default flag value '${_flags_default_}'" - _flags_return_=${FLAGS_ERROR} - fi - ;; - - ${__FLAGS_TYPE_FLOAT}) - if _flags_validFloat "${_flags_default_}"; then - : - else - flags_error="invalid default flag value '${_flags_default_}'" - _flags_return_=${FLAGS_ERROR} - fi - ;; - - ${__FLAGS_TYPE_INTEGER}) - if _flags_validInt "${_flags_default_}"; then - : - else - flags_error="invalid default flag value '${_flags_default_}'" - _flags_return_=${FLAGS_ERROR} - fi - ;; - - ${__FLAGS_TYPE_STRING}) ;; # everything in shell is a valid string - - *) - flags_error="unrecognized flag type '${_flags_type_}'" - _flags_return_=${FLAGS_ERROR} - ;; - esac - fi - - if [ ${_flags_return_} -eq ${FLAGS_TRUE} ]; then - # store flag information - eval "FLAGS_${_flags_usName_}='${_flags_default_}'" - eval "__flags_${_flags_usName_}_${__FLAGS_INFO_TYPE}=${_flags_type_}" - eval "__flags_${_flags_usName_}_${__FLAGS_INFO_DEFAULT}=\ -\"${_flags_default_}\"" - eval "__flags_${_flags_usName_}_${__FLAGS_INFO_HELP}=\"${_flags_help_}\"" - eval "__flags_${_flags_usName_}_${__FLAGS_INFO_SHORT}='${_flags_short_}'" - - # append flag names to name lists - __flags_shortNames="${__flags_shortNames}${_flags_short_} " - __flags_longNames="${__flags_longNames}${_flags_name_} " - [ ${_flags_type_} -eq ${__FLAGS_TYPE_BOOLEAN} ] && \ - __flags_boolNames="${__flags_boolNames}no${_flags_name_} " - - # append flag names to defined names for later validation checks - __flags_definedNames="${__flags_definedNames}${_flags_usName_} " - [ ${_flags_type_} -eq ${__FLAGS_TYPE_BOOLEAN} ] && \ - __flags_definedNames="${__flags_definedNames}no${_flags_usName_} " - fi - - flags_return=${_flags_return_} - unset _flags_default_ _flags_help_ _flags_name_ _flags_return_ \ - _flags_short_ _flags_type_ _flags_usName_ - [ ${flags_return} -eq ${FLAGS_ERROR} ] && _flags_error "${flags_error}" - return ${flags_return} -} - -# Underscore a flag name by replacing dashes with underscores. -# -# Args: -# unnamed: string: log flag name -# Output: -# string: underscored name -_flags_underscoreName() -{ - echo $1 |tr '-' '_' -} - -# Return valid getopt options using currently defined list of long options. -# -# This function builds a proper getopt option string for short (and long) -# options, using the current list of long options for reference. -# -# Args: -# _flags_optStr: integer: option string type (__FLAGS_OPTSTR_*) -# Output: -# string: generated option string for getopt -# Returns: -# boolean: success of operation (always returns True) -_flags_genOptStr() -{ - _flags_optStrType_=$1 - - _flags_opts_='' - - for _flags_name_ in ${__flags_longNames}; do - _flags_usName_=`_flags_underscoreName ${_flags_name_}` - _flags_type_=`_flags_getFlagInfo ${_flags_usName_} ${__FLAGS_INFO_TYPE}` - [ $? -eq ${FLAGS_TRUE} ] || _flags_fatal 'call to _flags_type_ failed' - case ${_flags_optStrType_} in - ${__FLAGS_OPTSTR_SHORT}) - _flags_shortName_=`_flags_getFlagInfo \ - ${_flags_usName_} ${__FLAGS_INFO_SHORT}` - if [ "${_flags_shortName_}" != "${__FLAGS_NULL}" ]; then - _flags_opts_="${_flags_opts_}${_flags_shortName_}" - # getopt needs a trailing ':' to indicate a required argument - [ ${_flags_type_} -ne ${__FLAGS_TYPE_BOOLEAN} ] && \ - _flags_opts_="${_flags_opts_}:" - fi - ;; - - ${__FLAGS_OPTSTR_LONG}) - _flags_opts_="${_flags_opts_:+${_flags_opts_},}${_flags_name_}" - # getopt needs a trailing ':' to indicate a required argument - [ ${_flags_type_} -ne ${__FLAGS_TYPE_BOOLEAN} ] && \ - _flags_opts_="${_flags_opts_}:" - ;; - esac - done - - echo "${_flags_opts_}" - unset _flags_name_ _flags_opts_ _flags_optStrType_ _flags_shortName_ \ - _flags_type_ _flags_usName_ - return ${FLAGS_TRUE} -} - -# Returns flag details based on a flag name and flag info. -# -# Args: -# string: underscored flag name -# string: flag info (see the _flags_define function for valid info types) -# Output: -# string: value of dereferenced flag variable -# Returns: -# integer: one of FLAGS_{TRUE|FALSE|ERROR} -_flags_getFlagInfo() -{ - # note: adding gFI to variable names to prevent naming conflicts with calling - # functions - _flags_gFI_usName_=$1 - _flags_gFI_info_=$2 - - _flags_infoVar_="__flags_${_flags_gFI_usName_}_${_flags_gFI_info_}" - _flags_strToEval_="_flags_infoValue_=\"\${${_flags_infoVar_}:-}\"" - eval "${_flags_strToEval_}" - if [ -n "${_flags_infoValue_}" ]; then - flags_return=${FLAGS_TRUE} - else - # see if the _flags_gFI_usName_ variable is a string as strings can be - # empty... - # note: the DRY principle would say to have this function call itself for - # the next three lines, but doing so results in an infinite loop as an - # invalid _flags_name_ will also not have the associated _type variable. - # Because it doesn't (it will evaluate to an empty string) the logic will - # try to find the _type variable of the _type variable, and so on. Not so - # good ;-) - _flags_typeVar_="__flags_${_flags_gFI_usName_}_${__FLAGS_INFO_TYPE}" - _flags_strToEval_="_flags_typeValue_=\"\${${_flags_typeVar_}:-}\"" - eval "${_flags_strToEval_}" - if [ "${_flags_typeValue_}" = "${__FLAGS_TYPE_STRING}" ]; then - flags_return=${FLAGS_TRUE} - else - flags_return=${FLAGS_ERROR} - flags_error="missing flag info variable (${_flags_infoVar_})" - fi - fi - - echo "${_flags_infoValue_}" - unset _flags_gFI_usName_ _flags_gfI_info_ _flags_infoValue_ _flags_infoVar_ \ - _flags_strToEval_ _flags_typeValue_ _flags_typeVar_ - [ ${flags_return} -eq ${FLAGS_ERROR} ] && _flags_error "${flags_error}" - return ${flags_return} -} - -# Check for presense of item in a list. -# -# Passed a string (e.g. 'abc'), this function will determine if the string is -# present in the list of strings (e.g. ' foo bar abc '). -# -# Args: -# _flags_str_: string: string to search for in a list of strings -# unnamed: list: list of strings -# Returns: -# boolean: true if item is in the list -_flags_itemInList() { - _flags_str_=$1 - shift - - echo " ${*:-} " |grep " ${_flags_str_} " >/dev/null - if [ $? -eq 0 ]; then - flags_return=${FLAGS_TRUE} - else - flags_return=${FLAGS_FALSE} - fi - - unset _flags_str_ - return ${flags_return} -} - -# Returns the width of the current screen. -# -# Output: -# integer: width in columns of the current screen. -_flags_columns() -{ - if [ -z "${__flags_columns}" ]; then - # determine the value and store it - if eval stty size >/dev/null 2>&1; then - # stty size worked :-) - set -- `stty size` - __flags_columns=$2 - elif eval tput cols >/dev/null 2>&1; then - set -- `tput cols` - __flags_columns=$1 - else - __flags_columns=80 # default terminal width - fi - fi - echo ${__flags_columns} -} - -# Validate a boolean. -# -# Args: -# _flags__bool: boolean: value to validate -# Returns: -# bool: true if the value is a valid boolean -_flags_validBool() -{ - _flags_bool_=$1 - - flags_return=${FLAGS_TRUE} - case "${_flags_bool_}" in - true|t|0) ;; - false|f|1) ;; - *) flags_return=${FLAGS_FALSE} ;; - esac - - unset _flags_bool_ - return ${flags_return} -} - -# Validate a float. -# -# Args: -# _flags_float_: float: value to validate -# Returns: -# bool: true if the value is a valid integer -_flags_validFloat() -{ - flags_return=${FLAGS_FALSE} - [ -n "$1" ] || return ${flags_return} - _flags_float_=$1 - - if _flags_validInt ${_flags_float_}; then - flags_return=${FLAGS_TRUE} - elif _flags_useBuiltin; then - _flags_float_whole_=${_flags_float_%.*} - _flags_float_fraction_=${_flags_float_#*.} - if _flags_validInt ${_flags_float_whole_:-0} -a \ - _flags_validInt ${_flags_float_fraction_}; then - flags_return=${FLAGS_TRUE} - fi - unset _flags_float_whole_ _flags_float_fraction_ - else - flags_return=${FLAGS_TRUE} - case ${_flags_float_} in - -*) # negative floats - _flags_test_=`${FLAGS_EXPR_CMD} -- "${_flags_float_}" :\ - '\(-[0-9]*\.[0-9]*\)'` - ;; - *) # positive floats - _flags_test_=`${FLAGS_EXPR_CMD} -- "${_flags_float_}" :\ - '\([0-9]*\.[0-9]*\)'` - ;; - esac - [ "${_flags_test_}" != "${_flags_float_}" ] && flags_return=${FLAGS_FALSE} - unset _flags_test_ - fi - - unset _flags_float_ _flags_float_whole_ _flags_float_fraction_ - return ${flags_return} -} - -# Validate an integer. -# -# Args: -# _flags_int_: integer: value to validate -# Returns: -# bool: true if the value is a valid integer -_flags_validInt() -{ - flags_return=${FLAGS_FALSE} - [ -n "$1" ] || return ${flags_return} - _flags_int_=$1 - - case ${_flags_int_} in - -*.*) ;; # ignore negative floats (we'll invalidate them later) - -*) # strip possible leading negative sign - if _flags_useBuiltin; then - _flags_int_=${_flags_int_#-} - else - _flags_int_=`${FLAGS_EXPR_CMD} -- "${_flags_int_}" : '-\([0-9][0-9]*\)'` - fi - ;; - esac - - case ${_flags_int_} in - *[!0-9]*) flags_return=${FLAGS_FALSE} ;; - *) flags_return=${FLAGS_TRUE} ;; - esac - - unset _flags_int_ - return ${flags_return} -} - -# Parse command-line options using the standard getopt. -# -# Note: the flag options are passed around in the global __flags_opts so that -# the formatting is not lost due to shell parsing and such. -# -# Args: -# @: varies: command-line options to parse -# Returns: -# integer: a FLAGS success condition -_flags_getoptStandard() -{ - flags_return=${FLAGS_TRUE} - _flags_shortOpts_=`_flags_genOptStr ${__FLAGS_OPTSTR_SHORT}` - - # check for spaces in passed options - for _flags_opt_ in "$@"; do - # note: the silliness with the x's is purely for ksh93 on Ubuntu 6.06 - _flags_match_=`echo "x${_flags_opt_}x" |sed 's/ //g'` - if [ "${_flags_match_}" != "x${_flags_opt_}x" ]; then - flags_error='the available getopt does not support spaces in options' - flags_return=${FLAGS_ERROR} - break - fi - done - - if [ ${flags_return} -eq ${FLAGS_TRUE} ]; then - __flags_opts=`getopt ${_flags_shortOpts_} $@ 2>&1` - _flags_rtrn_=$? - if [ ${_flags_rtrn_} -ne ${FLAGS_TRUE} ]; then - _flags_warn "${__flags_opts}" - flags_error='unable to parse provided options with getopt.' - flags_return=${FLAGS_ERROR} - fi - fi - - unset _flags_match_ _flags_opt_ _flags_rtrn_ _flags_shortOpts_ - return ${flags_return} -} - -# Parse command-line options using the enhanced getopt. -# -# Note: the flag options are passed around in the global __flags_opts so that -# the formatting is not lost due to shell parsing and such. -# -# Args: -# @: varies: command-line options to parse -# Returns: -# integer: a FLAGS success condition -_flags_getoptEnhanced() -{ - flags_return=${FLAGS_TRUE} - _flags_shortOpts_=`_flags_genOptStr ${__FLAGS_OPTSTR_SHORT}` - _flags_boolOpts_=`echo "${__flags_boolNames}" \ - |sed 's/^ *//;s/ *$//;s/ /,/g'` - _flags_longOpts_=`_flags_genOptStr ${__FLAGS_OPTSTR_LONG}` - - __flags_opts=`${FLAGS_GETOPT_CMD} \ - -o ${_flags_shortOpts_} \ - -l "${_flags_longOpts_},${_flags_boolOpts_}" \ - -- "$@" 2>&1` - _flags_rtrn_=$? - if [ ${_flags_rtrn_} -ne ${FLAGS_TRUE} ]; then - _flags_warn "${__flags_opts}" - flags_error='unable to parse provided options with getopt.' - flags_return=${FLAGS_ERROR} - fi - - unset _flags_boolOpts_ _flags_longOpts_ _flags_rtrn_ _flags_shortOpts_ - return ${flags_return} -} - -# Dynamically parse a getopt result and set appropriate variables. -# -# This function does the actual conversion of getopt output and runs it through -# the standard case structure for parsing. The case structure is actually quite -# dynamic to support any number of flags. -# -# Args: -# argc: int: original command-line argument count -# @: varies: output from getopt parsing -# Returns: -# integer: a FLAGS success condition -_flags_parseGetopt() -{ - _flags_argc_=$1 - shift - - flags_return=${FLAGS_TRUE} - - if [ ${__FLAGS_GETOPT_VERS} -ne ${__FLAGS_GETOPT_VERS_ENH} ]; then - set -- $@ - else - # note the quotes around the `$@' -- they are essential! - eval set -- "$@" - fi - - # Provide user with the number of arguments to shift by later. - # NOTE: the FLAGS_ARGC variable is obsolete as of 1.0.3 because it does not - # properly give user access to non-flag arguments mixed in between flag - # arguments. Its usage was replaced by FLAGS_ARGV, and it is being kept only - # for backwards compatibility reasons. - FLAGS_ARGC=`_flags_math "$# - 1 - ${_flags_argc_}"` - - # handle options. note options with values must do an additional shift - while true; do - _flags_opt_=$1 - _flags_arg_=${2:-} - _flags_type_=${__FLAGS_TYPE_NONE} - _flags_name_='' - - # determine long flag name - case "${_flags_opt_}" in - --) shift; break ;; # discontinue option parsing - - --*) # long option - if _flags_useBuiltin; then - _flags_opt_=${_flags_opt_#*--} - else - _flags_opt_=`${FLAGS_EXPR_CMD} -- "${_flags_opt_}" : '--\(.*\)'` - fi - _flags_len_=${__FLAGS_LEN_LONG} - if _flags_itemInList "${_flags_opt_}" ${__flags_longNames}; then - _flags_name_=${_flags_opt_} - else - # check for negated long boolean version - if _flags_itemInList "${_flags_opt_}" ${__flags_boolNames}; then - if _flags_useBuiltin; then - _flags_name_=${_flags_opt_#*no} - else - _flags_name_=`${FLAGS_EXPR_CMD} -- "${_flags_opt_}" : 'no\(.*\)'` - fi - _flags_type_=${__FLAGS_TYPE_BOOLEAN} - _flags_arg_=${__FLAGS_NULL} - fi - fi - ;; - - -*) # short option - if _flags_useBuiltin; then - _flags_opt_=${_flags_opt_#*-} - else - _flags_opt_=`${FLAGS_EXPR_CMD} -- "${_flags_opt_}" : '-\(.*\)'` - fi - _flags_len_=${__FLAGS_LEN_SHORT} - if _flags_itemInList "${_flags_opt_}" ${__flags_shortNames}; then - # yes. match short name to long name. note purposeful off-by-one - # (too high) with awk calculations. - _flags_pos_=`echo "${__flags_shortNames}" \ - |awk 'BEGIN{RS=" ";rn=0}$0==e{rn=NR}END{print rn}' \ - e=${_flags_opt_}` - _flags_name_=`echo "${__flags_longNames}" \ - |awk 'BEGIN{RS=" "}rn==NR{print $0}' rn="${_flags_pos_}"` - fi - ;; - esac - - # die if the flag was unrecognized - if [ -z "${_flags_name_}" ]; then - flags_error="unrecognized option (${_flags_opt_})" - flags_return=${FLAGS_ERROR} - break - fi - - # set new flag value - _flags_usName_=`_flags_underscoreName ${_flags_name_}` - [ ${_flags_type_} -eq ${__FLAGS_TYPE_NONE} ] && \ - _flags_type_=`_flags_getFlagInfo \ - "${_flags_usName_}" ${__FLAGS_INFO_TYPE}` - case ${_flags_type_} in - ${__FLAGS_TYPE_BOOLEAN}) - if [ ${_flags_len_} -eq ${__FLAGS_LEN_LONG} ]; then - if [ "${_flags_arg_}" != "${__FLAGS_NULL}" ]; then - eval "FLAGS_${_flags_usName_}=${FLAGS_TRUE}" - else - eval "FLAGS_${_flags_usName_}=${FLAGS_FALSE}" - fi - else - _flags_strToEval_="_flags_val_=\ -\${__flags_${_flags_usName_}_${__FLAGS_INFO_DEFAULT}}" - eval "${_flags_strToEval_}" - if [ ${_flags_val_} -eq ${FLAGS_FALSE} ]; then - eval "FLAGS_${_flags_usName_}=${FLAGS_TRUE}" - else - eval "FLAGS_${_flags_usName_}=${FLAGS_FALSE}" - fi - fi - ;; - - ${__FLAGS_TYPE_FLOAT}) - if _flags_validFloat "${_flags_arg_}"; then - eval "FLAGS_${_flags_usName_}='${_flags_arg_}'" - else - flags_error="invalid float value (${_flags_arg_})" - flags_return=${FLAGS_ERROR} - break - fi - ;; - - ${__FLAGS_TYPE_INTEGER}) - if _flags_validInt "${_flags_arg_}"; then - eval "FLAGS_${_flags_usName_}='${_flags_arg_}'" - else - flags_error="invalid integer value (${_flags_arg_})" - flags_return=${FLAGS_ERROR} - break - fi - ;; - - ${__FLAGS_TYPE_STRING}) - eval "FLAGS_${_flags_usName_}='${_flags_arg_}'" - ;; - esac - - # handle special case help flag - if [ "${_flags_usName_}" = 'help' ]; then - if [ ${FLAGS_help} -eq ${FLAGS_TRUE} ]; then - flags_help - flags_error='help requested' - flags_return=${FLAGS_TRUE} - break - fi - fi - - # shift the option and non-boolean arguements out. - shift - [ ${_flags_type_} != ${__FLAGS_TYPE_BOOLEAN} ] && shift - done - - # give user back non-flag arguments - FLAGS_ARGV='' - while [ $# -gt 0 ]; do - FLAGS_ARGV="${FLAGS_ARGV:+${FLAGS_ARGV} }'$1'" - shift - done - - unset _flags_arg_ _flags_len_ _flags_name_ _flags_opt_ _flags_pos_ \ - _flags_strToEval_ _flags_type_ _flags_usName_ _flags_val_ - return ${flags_return} -} - -# Perform some path using built-ins. -# -# Args: -# $@: string: math expression to evaluate -# Output: -# integer: the result -# Returns: -# bool: success of math evaluation -_flags_math() -{ - if [ $# -eq 0 ]; then - flags_return=${FLAGS_FALSE} - elif _flags_useBuiltin; then - # Variable assignment is needed as workaround for Solaris Bourne shell, - # which cannot parse a bare $((expression)). - _flags_expr_='$(($@))' - eval echo ${_flags_expr_} - flags_return=$? - unset _flags_expr_ - else - eval expr $@ - flags_return=$? - fi - - return ${flags_return} -} - -# Cross-platform strlen() implementation. -# -# Args: -# _flags_str: string: to determine length of -# Output: -# integer: length of string -# Returns: -# bool: success of strlen evaluation -_flags_strlen() -{ - _flags_str_=${1:-} - - if [ -z "${_flags_str_}" ]; then - flags_output=0 - elif _flags_useBuiltin; then - flags_output=${#_flags_str_} - else - flags_output=`${FLAGS_EXPR_CMD} -- "${_flags_str_}" : '.*'` - fi - flags_return=$? - - unset _flags_str_ - echo ${flags_output} - return ${flags_return} -} - -# Use built-in helper function to enable unit testing. -# -# Args: -# None -# Returns: -# bool: true if built-ins should be used -_flags_useBuiltin() -{ - return ${__FLAGS_USE_BUILTIN} -} - -#------------------------------------------------------------------------------ -# public functions -# -# A basic boolean flag. Boolean flags do not take any arguments, and their -# value is either 1 (false) or 0 (true). For long flags, the false value is -# specified on the command line by prepending the word 'no'. With short flags, -# the presense of the flag toggles the current value between true and false. -# Specifying a short boolean flag twice on the command results in returning the -# value back to the default value. -# -# A default value is required for boolean flags. -# -# For example, lets say a Boolean flag was created whose long name was 'update' -# and whose short name was 'x', and the default value was 'false'. This flag -# could be explicitly set to 'true' with '--update' or by '-x', and it could be -# explicitly set to 'false' with '--noupdate'. -DEFINE_boolean() { _flags_define ${__FLAGS_TYPE_BOOLEAN} "$@"; } - -# Other basic flags. -DEFINE_float() { _flags_define ${__FLAGS_TYPE_FLOAT} "$@"; } -DEFINE_integer() { _flags_define ${__FLAGS_TYPE_INTEGER} "$@"; } -DEFINE_string() { _flags_define ${__FLAGS_TYPE_STRING} "$@"; } - -# Parse the flags. -# -# Args: -# unnamed: list: command-line flags to parse -# Returns: -# integer: success of operation, or error -FLAGS() -{ - # define a standard 'help' flag if one isn't already defined - [ -z "${__flags_help_type:-}" ] && \ - DEFINE_boolean 'help' false 'show this help' 'h' - - # parse options - if [ $# -gt 0 ]; then - if [ ${__FLAGS_GETOPT_VERS} -ne ${__FLAGS_GETOPT_VERS_ENH} ]; then - _flags_getoptStandard "$@" - else - _flags_getoptEnhanced "$@" - fi - flags_return=$? - else - # nothing passed; won't bother running getopt - __flags_opts='--' - flags_return=${FLAGS_TRUE} - fi - - if [ ${flags_return} -eq ${FLAGS_TRUE} ]; then - _flags_parseGetopt $# "${__flags_opts}" - flags_return=$? - fi - - [ ${flags_return} -eq ${FLAGS_ERROR} ] && _flags_fatal "${flags_error}" - return ${flags_return} -} - -# This is a helper function for determining the 'getopt' version for platforms -# where the detection isn't working. It simply outputs debug information that -# can be included in a bug report. -# -# Args: -# none -# Output: -# debug info that can be included in a bug report -# Returns: -# nothing -flags_getoptInfo() -{ - # platform info - _flags_debug "uname -a: `uname -a`" - _flags_debug "PATH: ${PATH}" - - # shell info - if [ -n "${BASH_VERSION:-}" ]; then - _flags_debug 'shell: bash' - _flags_debug "BASH_VERSION: ${BASH_VERSION}" - elif [ -n "${ZSH_VERSION:-}" ]; then - _flags_debug 'shell: zsh' - _flags_debug "ZSH_VERSION: ${ZSH_VERSION}" - fi - - # getopt info - ${FLAGS_GETOPT_CMD} >/dev/null - _flags_getoptReturn=$? - _flags_debug "getopt return: ${_flags_getoptReturn}" - _flags_debug "getopt --version: `${FLAGS_GETOPT_CMD} --version 2>&1`" - - unset _flags_getoptReturn -} - -# Returns whether the detected getopt version is the enhanced version. -# -# Args: -# none -# Output: -# none -# Returns: -# bool: true if getopt is the enhanced version -flags_getoptIsEnh() -{ - test ${__FLAGS_GETOPT_VERS} -eq ${__FLAGS_GETOPT_VERS_ENH} -} - -# Returns whether the detected getopt version is the standard version. -# -# Args: -# none -# Returns: -# bool: true if getopt is the standard version -flags_getoptIsStd() -{ - test ${__FLAGS_GETOPT_VERS} -eq ${__FLAGS_GETOPT_VERS_STD} -} - -# This is effectively a 'usage()' function. It prints usage information and -# exits the program with ${FLAGS_FALSE} if it is ever found in the command line -# arguments. Note this function can be overridden so other apps can define -# their own --help flag, replacing this one, if they want. -# -# Args: -# none -# Returns: -# integer: success of operation (always returns true) -flags_help() -{ - if [ -n "${FLAGS_HELP:-}" ]; then - echo "${FLAGS_HELP}" >&2 - else - echo "USAGE: ${FLAGS_PARENT:-$0} [flags] args" >&2 - fi - if [ -n "${__flags_longNames}" ]; then - echo 'flags:' >&2 - for flags_name_ in ${__flags_longNames}; do - flags_flagStr_='' - flags_boolStr_='' - flags_usName_=`_flags_underscoreName ${flags_name_}` - - flags_default_=`_flags_getFlagInfo \ - "${flags_usName_}" ${__FLAGS_INFO_DEFAULT}` - flags_help_=`_flags_getFlagInfo \ - "${flags_usName_}" ${__FLAGS_INFO_HELP}` - flags_short_=`_flags_getFlagInfo \ - "${flags_usName_}" ${__FLAGS_INFO_SHORT}` - flags_type_=`_flags_getFlagInfo \ - "${flags_usName_}" ${__FLAGS_INFO_TYPE}` - - [ "${flags_short_}" != "${__FLAGS_NULL}" ] && \ - flags_flagStr_="-${flags_short_}" - - if [ ${__FLAGS_GETOPT_VERS} -eq ${__FLAGS_GETOPT_VERS_ENH} ]; then - [ "${flags_short_}" != "${__FLAGS_NULL}" ] && \ - flags_flagStr_="${flags_flagStr_}," - # add [no] to long boolean flag names, except the 'help' flag - [ ${flags_type_} -eq ${__FLAGS_TYPE_BOOLEAN} \ - -a "${flags_usName_}" != 'help' ] && \ - flags_boolStr_='[no]' - flags_flagStr_="${flags_flagStr_}--${flags_boolStr_}${flags_name_}:" - fi - - case ${flags_type_} in - ${__FLAGS_TYPE_BOOLEAN}) - if [ ${flags_default_} -eq ${FLAGS_TRUE} ]; then - flags_defaultStr_='true' - else - flags_defaultStr_='false' - fi - ;; - ${__FLAGS_TYPE_FLOAT}|${__FLAGS_TYPE_INTEGER}) - flags_defaultStr_=${flags_default_} ;; - ${__FLAGS_TYPE_STRING}) flags_defaultStr_="'${flags_default_}'" ;; - esac - flags_defaultStr_="(default: ${flags_defaultStr_})" - - flags_helpStr_=" ${flags_flagStr_} ${flags_help_} ${flags_defaultStr_}" - _flags_strlen "${flags_helpStr_}" >/dev/null - flags_helpStrLen_=${flags_output} - flags_columns_=`_flags_columns` - - if [ ${flags_helpStrLen_} -lt ${flags_columns_} ]; then - echo "${flags_helpStr_}" >&2 - else - echo " ${flags_flagStr_} ${flags_help_}" >&2 - # note: the silliness with the x's is purely for ksh93 on Ubuntu 6.06 - # because it doesn't like empty strings when used in this manner. - flags_emptyStr_="`echo \"x${flags_flagStr_}x\" \ - |awk '{printf "%"length($0)-2"s", ""}'`" - flags_helpStr_=" ${flags_emptyStr_} ${flags_defaultStr_}" - _flags_strlen "${flags_helpStr_}" >/dev/null - flags_helpStrLen_=${flags_output} - - if [ ${__FLAGS_GETOPT_VERS} -eq ${__FLAGS_GETOPT_VERS_STD} \ - -o ${flags_helpStrLen_} -lt ${flags_columns_} ]; then - # indented to match help string - echo "${flags_helpStr_}" >&2 - else - # indented four from left to allow for longer defaults as long flag - # names might be used too, making things too long - echo " ${flags_defaultStr_}" >&2 - fi - fi - done - fi - - unset flags_boolStr_ flags_default_ flags_defaultStr_ flags_emptyStr_ \ - flags_flagStr_ flags_help_ flags_helpStr flags_helpStrLen flags_name_ \ - flags_columns_ flags_short_ flags_type_ flags_usName_ - return ${FLAGS_TRUE} -} - -# Reset shflags back to an uninitialized state. -# -# Args: -# none -# Returns: -# nothing -flags_reset() -{ - for flags_name_ in ${__flags_longNames}; do - flags_usName_=`_flags_underscoreName ${flags_name_}` - flags_strToEval_="unset FLAGS_${flags_usName_}" - for flags_type_ in \ - ${__FLAGS_INFO_DEFAULT} \ - ${__FLAGS_INFO_HELP} \ - ${__FLAGS_INFO_SHORT} \ - ${__FLAGS_INFO_TYPE} - do - flags_strToEval_=\ -"${flags_strToEval_} __flags_${flags_usName_}_${flags_type_}" - done - eval ${flags_strToEval_} - done - - # reset internal variables - __flags_boolNames=' ' - __flags_longNames=' ' - __flags_shortNames=' ' - __flags_definedNames=' ' - - unset flags_name_ flags_type_ flags_strToEval_ flags_usName_ -} diff --git a/src/shflags_test.sh b/src/shflags_test.sh deleted file mode 100755 index 18ca961..0000000 --- a/src/shflags_test.sh +++ /dev/null @@ -1,116 +0,0 @@ -#! /bin/sh -# vim:et:ft=sh:sts=2:sw=2 -# -# shFlags unit test suite runner. -# -# This script runs all the unit tests that can be found, and generates a nice -# report of the tests. - -MY_NAME=`basename $0` -MY_PATH=`dirname $0` - -PREFIX='shflags_test_' -SHELLS='/bin/sh /bin/bash /bin/dash /bin/ksh /bin/pdksh /bin/zsh' -TESTS='' -for test in ${PREFIX}[a-z]*.sh; do - TESTS="${TESTS} ${test}" -done - -# load libraries -. ../lib/versions -. ./shflags_test_helpers - -usage() -{ - echo "usage: ${MY_NAME} [-e key=val ...] [-s shell(s)] [-t test(s)]" -} - -env='' - -# process command line flags -while getopts 'e:hs:t:' opt; do - case ${opt} in - e) # set an environment variable - key=`expr "${OPTARG}" : '\([^=]*\)='` - val=`expr "${OPTARG}" : '[^=]*=\(.*\)'` - if [ -z "${key}" -o -z "${val}" ]; then - usage - exit 1 - fi - eval "${key}='${val}'" - export ${key} - env="${env:+${env} }${key}" - ;; - h) usage; exit 0 ;; # help output - s) shells=${OPTARG} ;; # list of shells to run - t) tests=${OPTARG} ;; # list of tests to run - *) usage; exit 1 ;; - esac -done -shift `expr ${OPTIND} - 1` - -# fill shells and/or tests -shells=${shells:-${SHELLS}} -tests=${tests:-${TESTS}} - -# error checking -if [ -z "${tests}" ]; then - th_error 'no tests found to run; exiting' - exit 1 -fi - -cat <<EOF -#------------------------------------------------------------------------------ -# System data -# - -# test run info -shells="${shells}" -tests="${tests}" -EOF -for key in ${env}; do - eval "echo \"${key}=\$${key}\"" -done -echo - -# output system data -echo "# system info" -echo "$ date" -date - -echo "$ uname -mprsv" -uname -mprsv - -# -# run tests -# - -for shell in ${shells}; do - echo - - cat <<EOF - -#------------------------------------------------------------------------------ -# Running the test suite with ${shell} -# -EOF - # check for existance of shell - if [ ! -x ${shell} ]; then - th_warn "unable to run tests with the ${shell} shell" - continue - fi - - shell_name=`basename ${shell}` - shell_version=`versions_shellVersion "${shell}"` - - echo "shell name: ${shell_name}" - echo "shell version: ${shell_version}" - - # execute the tests - for suite in ${tests}; do - suiteName=`expr "${suite}" : "${PREFIX}\(.*\).sh"` - echo - echo "--- Executing the '${suiteName}' test suite ---" - ( exec ${shell} ./${suite} 2>&1; ) - done -done diff --git a/src/shflags_test_defines.sh b/src/shflags_test_defines.sh deleted file mode 100755 index 1f76c3e..0000000 --- a/src/shflags_test_defines.sh +++ /dev/null @@ -1,217 +0,0 @@ -#! /bin/sh -# vim:et:ft=sh:sts=2:sw=2 -# -# shFlags unit test for the flag definition methods - -# load test helpers -. ./shflags_test_helpers - -#------------------------------------------------------------------------------ -# suite tests -# - -testFlagsDefine() -{ - # no arguments - _flags_define >"${stdoutF}" 2>"${stderrF}" - assertFalse '_flags_define() with no arguments should have failed.' $? - assertErrorMsg '' 'no arguments' - - # one argument - _flags_define arg1 >"${stdoutF}" 2>"${stderrF}" - assertFalse '_flags_define() call with one argument should fail' $? - assertErrorMsg '' 'one argument' - - # two arguments - _flags_define arg1 arg2 >"${stdoutF}" 2>"${stderrF}" - assertFalse '_flags_define() call with two arguments should fail' $? - assertErrorMsg '' 'two arguments' - - # three arguments - _flags_define arg1 arg2 arg3 >"${stdoutF}" 2>"${stderrF}" - assertFalse '_flags_define() call with three arguments should fail' $? - assertErrorMsg '' 'three arguments' - - # multiple definition -- assumes working boolean definition (tested elsewhere) - _flags_define ${__FLAGS_TYPE_BOOLEAN} multiDefBool true 'multi def #1' m - _flags_define ${__FLAGS_TYPE_BOOLEAN} multiDefBool false 'multi def #2' m \ - >"${stdoutF}" 2>"${stderrF}" - assertFalse '_flags_define() with existing flag name should fail' $? - assertTrue \ - '_flags_define() should not overwrite previously defined default.' \ - "${FLAGS_multiDefBool:-}" - assertWarnMsg '' 'existing flag' - - # duplicate dashed and underscored definition - _flags_define ${__FLAGS_TYPE_STRING} long-name 'foo' 'dashed name' l - _flags_define ${__FLAGS_TYPE_STRING} long_name 'bar' 'underscored name' l \ - >"${stdoutF}" 2>"${stderrF}" - assertFalse '_flags_define() with existing flag name should fail' $? - assertEquals \ - '_flags_define() should not overwrite previously defined default.' \ - "${FLAGS_long_name}" 'foo' - assertWarnMsg '' 'already exists' - - # TODO(kward): test requirement of enhanced getopt - - # invalid type - _flags_define invalid arg2 arg3 arg4 i >"${stdoutF}" 2>"${stderrF}" - assertFalse '_flags_define() with "invalid" type should have failed.' $? - assertErrorMsg 'unrecognized flag type' 'invalid type' -} - -testBoolean() -{ - # test true defaults - for default in 'true' 't' 0; do - flags_reset - DEFINE_boolean boolVal "${default}" 'my boolean' b - rtrn=$? - assertTrue \ - "DEFINE_boolean() call with default of '${default}' failed." \ - "${FLAGS_boolVal:-}" - assertTrue \ - "DEFINE_boolean() call with default of '${default}' returned faliure." \ - ${rtrn} - done - - # test false defaults - for default in 'false' 'f' 1; do - flags_reset - DEFINE_boolean boolVal "${default}" 'my boolean' b - rtrn=$? - assertFalse \ - "DEFINE_boolean() call with default of '${default}' failed." \ - "${FLAGS_boolVal:-}" - assertTrue \ - "DEFINE_boolean() call with default of '${default}' returned faliure." \ - ${rtrn} - done - - # test invalid default - flags_reset - DEFINE_boolean boolVal 'invalid' 'my boolean' b >"${stdoutF}" 2>"${stderrF}" - assertFalse 'DEFINE_boolean() call with invalid default did not fail.' $? - assertErrorMsg -} - -testFloat() -{ - # test valid defaults - for default in ${TH_FLOAT_VALID}; do - flags_reset - DEFINE_float floatVal ${default} "float: ${default}" f - rtrn=$? - assertSame "DEFINE_float() call with valid default failed." \ - ${default} "${FLAGS_floatVal:-}" - assertTrue \ - "DEFINE_float() call with valid default of '${default}' returned faliure." \ - ${rtrn} - done - - # test invalid defaults - flags_reset - DEFINE_float floatVal 'invalid' 'invalid float: string' f \ - >"${stdoutF}" 2>"${stderrF}" - assertFalse 'DEFINE_float() call with string value default did not fail.' $? - assertErrorMsg -} - -testInteger() -{ - # test valid defaults - for default in ${TH_INT_VALID}; do - flags_reset - DEFINE_integer intVal ${default} "integer: ${default}" i - rtrn=$? - assertSame \ - "DEFINE_integer() call with valid default failed." \ - ${default} "${FLAGS_intVal:-}" - assertTrue \ - "DEFINE_integer() call with valid default of '${default}' returned failure." \ - ${rtrn} - done - - # test invalid defaults - flags_reset - DEFINE_integer intVal 1.234 'invalid integer: float' i \ - >"${stdoutF}" 2>"${stderrF}" - assertFalse 'DEFINE_integer() call with float value default did not fail.' $? - assertErrorMsg 'invalid default' 'float default' - - DEFINE_integer intVal -1.234 'invalid integer: negative float' i \ - >"${stdoutF}" 2>"${stderrF}" - assertFalse \ - 'DEFINE_integer() call with negative float value default did not fail.' \ - $? - assertErrorMsg 'invalid default' 'negative float default' - - DEFINE_integer intVal 'invalid' 'invalid integer: string' i \ - >"${stdoutF}" 2>"${stderrF}" - assertFalse \ - 'DEFINE_integer() call with string value default did not fail.' \ - $? - assertErrorMsg 'invalid default' 'string default' -} - -testString() -{ - # test valid defaults - for default in \ - ${TH_BOOL_VALID} \ - ${TH_FLOAT_VALID} \ - ${TH_INT_VALID} \ - 'also valid' - do - flags_reset - DEFINE_string strVal "${default}" "string: ${default}" s - rtrn=$? - assertSame \ - "DEFINE_string() call with valid default failed." \ - "${default}" "${FLAGS_strVal:-}" - assertTrue \ - "DEFINE_string() call with valid default of '${default}' returned faliure." \ - ${rtrn} - done - - # test "empty" strings - flags_reset - DEFINE_string str '' "string: empty single quotes" s - rtrn=$? - assertSame \ - "DEFINE_string() call with valid default failed." \ - '' "${FLAGS_str:-}" -} - -testShortNameLength() -{ - # make sure short names are no longer than a single character - : -} - -testFlagNameIsReserved() -{ - ( DEFINE_string TRUE '' 'true is a reserved flag name' t \ - >"${stdoutF}" 2>"${stderrF}" ) - rtrn=$? - assertEquals ${FLAGS_ERROR} ${rtrn} - assertErrorMsg 'flag name (TRUE) is reserved' -} - -#------------------------------------------------------------------------------ -# suite functions -# - -oneTimeSetUp() -{ - th_oneTimeSetUp -} - -tearDown() -{ - flags_reset -} - -# load and run shUnit2 -[ -n "${ZSH_VERSION:-}" ] && SHUNIT_PARENT=$0 -. ${TH_SHUNIT} diff --git a/src/shflags_test_helpers b/src/shflags_test_helpers deleted file mode 100644 index d00f31e..0000000 --- a/src/shflags_test_helpers +++ /dev/null @@ -1,116 +0,0 @@ -# vim:et:ft=sh:sts=2:sw=2 -# -# shFlags unit test common functions - -__th_skipping=0 - -# treat unset variables as an error -set -u - -# set shwordsplit for zsh -[ -n "${ZSH_VERSION:-}" ] && setopt shwordsplit - -# my name -TH_MY_NAME=`basename "$0"` - -# path to shFlags library. can be overridden by setting SHFLAGS_INC -TH_SHFLAGS=${SHFLAGS_INC:-./shflags} - -# path to shUnit2 library. can be overridden by setting SHUNIT_INC -TH_SHUNIT=${SHUNIT_INC:-../lib/shunit2} - -TH_BOOL_VALID='true t 0 false f 1' -TH_BOOL_INVALID='123 123.0 invalid' -TH_FLOAT_VALID='-1234.0 -1.0 -.123 0.0 0. .123 1.0 1234.0' -TH_FLOAT_INVALID='true false 1.2.3 -1.2.3 ""' -TH_INT_VALID='-1234 -1 0 1 1234' -TH_INT_INVALID='true false -1.0 -.123 0.0 .123 1.0 ""' - -# -# test helper functions -# - -# message functions -th_trace() { echo "test:TRACE $@" >&2; } -th_debug() { echo "test:DEBUG $@" >&2; } -th_info() { echo "test:INFO $@" >&2; } -th_warn() { echo "test:WARN $@" >&2; } -th_error() { echo "test:ERROR $@" >&2; } -th_fatal() { echo "test:FATAL $@" >&2; } - -th_oneTimeSetUp() -{ - # load shFlags - [ -n "${ZSH_VERSION:-}" ] && FLAGS_PARENT=$0 - . ${TH_SHFLAGS} - - # these files will be cleaned up automatically by shUnit2 - tmpDir=${SHUNIT_TMPDIR} - stdoutF="${tmpDir}/stdout" - stderrF="${tmpDir}/stderr" - returnF="${tmpDir}/return" - expectedF="${tmpDir}/expected" -} - -th_showOutput() -{ - _th_rtrn=$1 - _th_stdout=$2 - _th_stderr=$3 - - isSkipping - if [ $? -eq ${SHUNIT_FALSE} -a ${_th_rtrn} != ${FLAGS_TRUE} ]; then - if [ -n "${_th_stdout}" -a -s "${_th_stdout}" ]; then - echo '>>> STDOUT' >&2 - cat "${_th_stdout}" >&2 - fi - if [ -n "${_th_stderr}" -a -s "${_th_stderr}" ]; then - echo '>>> STDERR' >&2 - cat "${_th_stderr}" >&2 - fi - if [ -n "${_th_stdout}" -o -n "${_th_stderr}" ]; then - echo '<<< end output' >&2 - fi - fi - - unset _th_rtrn _th_stdout _th_stderr -} - -# Some shells, zsh on Solaris in particular, return immediately from a sub-shell -# when a non-zero return value is encountered. To properly catch these values, -# they are either written to disk, or recognized as an error the file is empty. -th_clearReturn() { cp /dev/null "${returnF}"; } -th_queryReturn() -{ - if [ -s "${returnF}" ]; then - th_return=`cat "${returnF}"` - else - th_return=${SHUNIT_ERROR} - fi -} - -_th_assertMsg() -{ - _th_alert_type_=$1 - _th_alert_msg_=$2 - _th_msg_=$3 - - case ${_th_alert_type_} in - WARN) _th_alert_str_='a warning' ;; - ERROR) _th_alert_str_='an error' ;; - FATAL) _th_alert_str_='a fatal' ;; - esac - [ -z "${_th_alert_msg_}" ] && _th_alert_msg_='.*' - [ -n "${_th_msg_}" ] && _th_msg_="(${_th_msg_}) " - - grep -- "^flags:${_th_alert_type_} ${_th_alert_msg_}" "${stderrF}" \ - >/dev/null - assertTrue \ - "FLAGS ${_th_msg_}failure did not generate ${_th_alert_str_} message" $? - - unset _th_alert_type_ _th_alert_msg_ _th_alert_str_ _th_msg_ -} - -assertWarnMsg() { _th_assertMsg 'WARN' "${1:-}" "${2:-}"; } -assertErrorMsg() { _th_assertMsg 'ERROR' "${1:-}" "${2:-}"; } -assertFatalMsg() { _th_assertMsg 'FATAL' "${1:-}" "${2:-}"; } diff --git a/src/shflags_test_parsing.sh b/src/shflags_test_parsing.sh deleted file mode 100755 index d79a042..0000000 --- a/src/shflags_test_parsing.sh +++ /dev/null @@ -1,365 +0,0 @@ -#! /bin/sh -# vim:et:ft=sh:sts=2:sw=2 -# -# shFlags unit test for the flag definition methods -# -# TODO(kward): assert on FLAGS errors -# TODO(kward): testNonStandardIFS() - -# exit immediately if a pipeline or subshell exits with a non-zero status. -#set -e - -# treat unset variables as an error -set -u - -# load test helpers -. ./shflags_test_helpers - -#------------------------------------------------------------------------------ -# suite tests -# - -testGetoptStandard() -{ - _flags_getoptStandard '-b' >"${stdoutF}" 2>"${stderrF}" - rslt=$? - assertTrue "didn't parse valid flag 'b'" ${rslt} - th_showOutput ${rslt} "${stdoutF}" "${stderrF}" - - _flags_getoptStandard '-x' >"${stdoutF}" 2>"${stderrF}" - assertFalse "parsed invalid flag 'x'" $? -} - -testGetoptEnhanced() -{ - flags_getoptIsEnh || return - - _flags_getoptEnhanced '-b' >"${stdoutF}" 2>"${stderrF}" - assertTrue "didn't parse valid flag 'b'" $? - _flags_getoptEnhanced '--bool' >"${stdoutF}" 2>"${stderrF}" - assertTrue "didn't parse valid flag 'bool'" $? - - _flags_getoptEnhanced '-x' >"${stdoutF}" 2>"${stderrF}" - assertFalse "parsed invalid flag 'x'" $? - _flags_getoptEnhanced '--xyz' >"${stdoutF}" 2>"${stderrF}" - assertFalse "parsed invalid flag 'xyz'" $? -} - -testValidBoolsShort() -{ - FLAGS -b >"${stdoutF}" 2>"${stderrF}" - r3turn=$? - assertTrue "-b) FLAGS returned a non-zero result (${r3turn})" ${r3turn} - value=${FLAGS_bool:-} - assertTrue "-b) boolean was not true (${value})." "${value}" - assertFalse '-b) expected no output to STDERR' "[ -s '${stderrF}' ]" - test ${r3turn} -eq ${FLAGS_TRUE} -a ! -s "${stderrF}" - th_showOutput $? "${stdoutF}" "${stderrF}" - - DEFINE_boolean bool2 true '2nd boolean' B - FLAGS >"${stdoutF}" 2>"${stderrF}" - r3turn=$? - assertTrue "-B) FLAGS returned a non-zero result (${r3turn})" ${r3turn} - value=${FLAGS_bool2:-} - assertTrue "-B) boolean was not true (${value})" ${value} - assertFalse '-B) expected no output to STDERR' "[ -s '${stderrF}' ]" - test ${r3turn} -eq ${FLAGS_TRUE} -a ! -s "${stderrF}" - th_showOutput $? "${stdoutF}" "${stderrF}" - - FLAGS -B >"${stdoutF}" 2>"${stderrF}" - r3turn=$? - assertTrue "-B) FLAGS returned a non-zero result (${r3turn})" ${r3turn} - value=${FLAGS_bool2:-} - assertFalse "-B) boolean was not false (${value})" ${value} - assertFalse '-B) expected no output to STDERR' "[ -s '${stderrF}' ]" - test ${r3turn} -eq ${FLAGS_TRUE} -a ! -s "${stderrF}" - th_showOutput $? "${stdoutF}" "${stderrF}" -} - -# TODO(kate): separate into multiple functions to reflect correct usage -testValidBoolsLong() -{ - flags_getoptIsEnh || return - - # Note: the default value of bool is 'false'. - - # leave flag false - FLAGS --nobool >"${stdoutF}" 2>"${stderrF}" - r3turn=$? - assertTrue "FLAGS returned a non-zero result (${r3turn})" ${r3turn} - assertFalse '--noXX flag resulted in true value.' ${FLAGS_bool:-} - assertFalse 'expected no output to STDERR' "[ -s '${stderrF}' ]" - th_showOutput ${r3turn} "${stdoutF}" "${stderrF}" - - # flip flag true - FLAGS --bool >"${stdoutF}" 2>"${stderrF}" - r3turn=$? - assertTrue "FLAGS returned a non-zero result (${r3turn})" ${r3turn} - assertTrue '--XX flag resulted in false value.' ${FLAGS_bool:-} - assertFalse 'expected no output to STDERR' "[ -s '${stderrF}' ]" - th_showOutput ${r3turn} "${stdoutF}" "${stderrF}" - - # flip flag back false - FLAGS --nobool >"${stdoutF}" 2>"${stderrF}" - r3turn=$? - assertTrue "FLAGS returned a non-zero result (${r3turn})" ${r3turn} - assertFalse '--noXX flag resulted in true value.' ${FLAGS_bool:-} - assertFalse 'expected no output to STDERR' "[ -s '${stderrF}' ]" - th_showOutput ${r3turn} "${stdoutF}" "${stderrF}" -} - -testValidFloats() -{ - _testValidFloats '-f' - flags_getoptIsEnh || return - _testValidFloats '--float' -} - -_testValidFloats() -{ - flag=$1 - for value in ${TH_FLOAT_VALID}; do - FLAGS ${flag} ${value} >"${stdoutF}" 2>"${stderrF}" - r3turn=$? - assertTrue "FLAGS ${flag} ${value} returned non-zero result (${r3turn})" \ - ${r3turn} - assertEquals "float (${flag} ${value}) test failed." ${value} ${FLAGS_float} - assertFalse 'expected no output to STDERR' "[ -s '${stderrF}' ]" - th_showOutput ${r3turn} "${stdoutF}" "${stderrF}" - done -} - -testInvalidFloats() -{ - _testInvalidFloats '-f' - flags_getoptIsEnh || return - _testInvalidFloats '--float' -} - -_testInvalidFloats() -{ - flag=$1 - for value in ${TH_FLOAT_INVALID}; do - th_clearReturn - ( - FLAGS ${flag} ${value} >"${stdoutF}" 2>"${stderrF}" - echo $? >"${returnF}" - ) - th_queryReturn - assertFalse "FLAGS (${value}) returned a zero result" ${th_return} - assertFalse 'expected no output to STDOUT' "[ -s '${stdoutF}' ]" - assertTrue 'expected output to STDERR' "[ -s '${stderrF}' ]" - done -} - -testValidIntegers() -{ - _testValidIntegers '-i' - flags_getoptIsEnh || return - _testValidIntegers '--int' -} - -_testValidIntegers() -{ - flag=$1 - for value in ${TH_INT_VALID}; do - FLAGS ${flag} ${value} >"${stdoutF}" 2>"${stderrF}" - r3turn=$? - assertTrue "FLAGS (${value}) returned a non-zero result (${r3turn})" ${r3turn} - assertEquals "integer (${value}) test failed." ${value} ${FLAGS_int} - assertFalse 'expected no output to STDERR' "[ -s '${stderrF}' ]" - th_showOutput ${r3turn} "${stdoutF}" "${stderrF}" - done -} - -testInvalidIntegers() -{ - _testInvalidIntegers '-i' - flags_getoptIsEnh || return - _testInvalidIntegers '--int' -} - -_testInvalidIntegers() -{ - flag=$1 - for value in ${TH_INT_INVALID}; do - th_clearReturn - ( - FLAGS ${flag} ${value} >"${stdoutF}" 2>"${stderrF}" - echo $? >"${returnF}" - ) - th_queryReturn - assertFalse "invalid integer (${value}) test returned success." ${th_return} - assertFalse 'expected no output to STDOUT' "[ -s '${stdoutF}' ]" - assertTrue 'expected output to STDERR' "[ -s '${stderrF}' ]" - done -} - -testValidStrings() -{ - _testValidStrings -s single_word - if flags_getoptIsEnh; then - _testValidStrings --str single_word - _testValidStrings --str 'string with spaces' - fi -} - -_testValidStrings() -{ - flag=$1 - value=$2 - - FLAGS ${flag} "${value}" >"${stdoutF}" 2>"${stderrF}" - r3turn=$? - assertTrue "'FLAGS ${flag} ${value}' returned a non-zero result (${r3turn})" \ - ${r3turn} - assertEquals "string (${value}) test failed." "${value}" "${FLAGS_str}" - if [ ${r3turn} -eq ${FLAGS_TRUE} ]; then - assertFalse 'expected no output to STDERR' "[ -s '${stderrF}' ]" - else - # validate that an error is thrown for unsupported getopt uses - assertFatalMsg '.* spaces in options' - fi - th_showOutput ${r3turn} "${stdoutF}" "${stderrF}" -} - -testMultipleFlags() -{ - _testMultipleFlags '-b' '-i' '-f' '-s' - flags_getoptIsEnh || return - _testMultipleFlags '--bool' '--int' '--float' '--str' -} - -_testMultipleFlags() -{ - boolFlag=$1 - intFlag=$2 - floatFlag=$3 - strFlag=$4 - - FLAGS \ - ${boolFlag} \ - ${intFlag} 567 \ - ${floatFlag} 123.45678 \ - ${strFlag} 'some_string' \ - >"${stdoutF}" 2>"${stderrF}" - r3turn=$? - assertTrue "use of multple flags returned a non-zero result" ${r3turn} - assertTrue 'boolean test failed.' ${FLAGS_bool} - assertNotSame 'float test failed.' 0 ${FLAGS_float} - assertNotSame 'integer test failed.' 0 ${FLAGS_int} - assertNotSame 'string test failed.' '' ${FLAGS_str} - assertFalse 'expected no output to STDERR' "[ -s '${stderrF}' ]" - th_showOutput ${r3turn} "${stdoutF}" "${stderrF}" -} - -_testNonFlagArgs() -{ - argc=$1 - shift - - FLAGS "$@" >"${stdoutF}" 2>"${stderrF}" - r3turn=$? - assertTrue 'parse returned non-zero value.' ${r3turn} - th_showOutput ${r3turn} "${stdoutF}" "${stderrF}" - - eval set -- "${FLAGS_ARGV}" - assertEquals 'wrong count of argv arguments returned.' ${argc} $# - assertEquals 'wrong count of argc arguments returned.' 0 ${FLAGS_ARGC} -} - -testSingleNonFlagArg() -{ - _testNonFlagArgs 1 argOne -} - -testMultipleNonFlagArgs() -{ - _testNonFlagArgs 3 argOne argTwo arg3 -} - -testMultipleNonFlagStringArgsWithSpaces() -{ - flags_getoptIsEnh || return - _testNonFlagArgs 3 argOne 'arg two' arg3 -} - -testFlagsWithEquals() -{ - flags_getoptIsEnh || return - - FLAGS --str='str_flag' 'non_flag' >"${stdoutF}" 2>"${stderrF}" - assertTrue 'FLAGS returned a non-zero result' $? - assertEquals 'string flag not set properly' 'str_flag' "${FLAGS_str}" - th_showOutput ${r3turn} "${stdoutF}" "${stderrF}" - - eval set -- "${FLAGS_ARGV}" - assertEquals 'wrong count of argv arguments returned.' 1 $# - assertEquals 'wrong count of argc arguments returned.' 1 ${FLAGS_ARGC} -} - -testComplicatedCommandLineStandard() -{ - flags_getoptIsEnh && return - - # Note: standard getopt stops parsing after first non-flag argument, which - # results in the remaining flags being treated as arguments instead. - FLAGS -i 1 non_flag_1 -s 'two' non_flag_2 -f 3 non_flag_3 \ - >"${stdoutF}" 2>"${stderrF}" - r3turn=$? - assertTrue 'FLAGS returned a non-zero result' ${r3turn} - assertEquals 'failed int test' 1 ${FLAGS_int} - th_showOutput ${r3turn} "${stdoutF}" "${stderrF}" - - eval set -- "${FLAGS_ARGV}" - assertEquals 'incorrect number of argv values' 7 $# -} - -testComplicatedCommandLineEnhanced() -{ - flags_getoptIsEnh || return - - FLAGS -i 1 non_flag_1 --str='two' non_flag_2 --float 3 'non flag 3' \ - >"${stdoutF}" 2>"${stderrF}" - r3turn=$? - assertTrue 'FLAGS returned a non-zero result' ${r3turn} - assertEquals 'failed int test' 1 ${FLAGS_int} - assertEquals 'failed str test' 'two' "${FLAGS_str}" - assertEquals 'failed float test' 3 ${FLAGS_float} - th_showOutput ${r3turn} "${stdoutF}" "${stderrF}" - - eval set -- "${FLAGS_ARGV}" - assertEquals 'incorrect number of argv values' 3 $# -} - -#------------------------------------------------------------------------------ -# suite functions -# - -oneTimeSetUp() -{ - th_oneTimeSetUp - - if flags_getoptIsStd; then - th_warn 'Standard version of getopt found. Enhanced tests will be skipped.' - else - th_warn 'Enhanced version of getopt found. Standard tests will be skipped.' - fi -} - -setUp() -{ - DEFINE_boolean bool false 'boolean test' 'b' - DEFINE_float float 0.0 'float test' 'f' - DEFINE_integer int 0 'integer test' 'i' - DEFINE_string str '' 'string test' 's' -} - -tearDown() -{ - flags_reset -} - -# load and run shUnit2 -[ -n "${ZSH_VERSION:-}" ] && SHUNIT_PARENT=$0 -. ${TH_SHUNIT} diff --git a/src/shflags_test_private.sh b/src/shflags_test_private.sh deleted file mode 100755 index c252d42..0000000 --- a/src/shflags_test_private.sh +++ /dev/null @@ -1,247 +0,0 @@ -#! /bin/sh -# vim:et:ft=sh:sts=2:sw=2 -# -# shFlags unit test for the internal functions - -# load test helpers -. ./shflags_test_helpers - -#------------------------------------------------------------------------------ -# suite tests -# - -testColumns() -{ - cols=`_flags_columns` - value=`expr "${cols}" : '\([0-9]*\)'` - assertNotNull "unexpected screen width (${cols})" "${value}" -} - -testGenOptStr() -{ - _testGenOptStr '' '' - - DEFINE_boolean bool false 'boolean value' b - _testGenOptStr 'b' 'bool' - - DEFINE_float float 0.0 'float value' f - _testGenOptStr 'bf:' 'bool,float:' - - DEFINE_integer int 0 'integer value' i - _testGenOptStr 'bf:i:' 'bool,float:,int:' - - DEFINE_string str 0 'string value' s - _testGenOptStr 'bf:i:s:' 'bool,float:,int:,str:' - - DEFINE_boolean help false 'show help' h - _testGenOptStr 'bf:i:s:h' 'bool,float:,int:,str:,help' -} - -_testGenOptStr() -{ - short=$1 - long=$2 - - result=`_flags_genOptStr ${__FLAGS_OPTSTR_SHORT}` - assertTrue 'short option string generation failed' $? - assertEquals "${short}" "${result}" - - result=`_flags_genOptStr ${__FLAGS_OPTSTR_LONG}` - assertTrue 'long option string generation failed' $? - assertEquals "${long}" "${result}" -} - -testGetFlagInfo() -{ - __flags_blah_foobar='1234' - - rslt=`_flags_getFlagInfo 'blah' 'foobar'` - assertTrue 'request for valid flag info failed' $? - assertEquals 'invalid flag info returned' "${__flags_blah_foobar}" "${rslt}" - - rslt=`_flags_getFlagInfo 'blah' 'hubbabubba' >"${stdoutF}" 2>"${stderrF}"` - assertEquals 'invalid flag did not result in an error' ${FLAGS_ERROR} $? - assertErrorMsg 'missing flag info variable' -} - -testItemInList() -{ - list='this is a test' - - _flags_itemInList 'is' ${list} - assertTrue 'unable to find leading string (this)' $? - - _flags_itemInList 'is' ${list} - assertTrue 'unable to find string (is)' $? - - _flags_itemInList 'is' ${list} - assertTrue 'unable to find trailing string (test)' $? - - _flags_itemInList 'abc' ${list} - assertFalse 'found nonexistant string (abc)' $? - - _flags_itemInList '' ${list} - assertFalse 'empty strings should not match' $? - - _flags_itemInList 'blah' '' - assertFalse 'empty lists should not match' $? -} - -testValidBool() -{ - # valid values - for value in ${TH_BOOL_VALID}; do - _flags_validBool "${value}" - assertTrue "valid value (${value}) did not validate" $? - done - - # invalid values - for value in ${TH_BOOL_INVALID}; do - _flags_validBool "${value}" - assertFalse "invalid value (${value}) validated" $? - done -} - -_testValidFloat() -{ - # valid values - for value in ${TH_INT_VALID} ${TH_FLOAT_VALID}; do - _flags_validFloat "${value}" - assertTrue "valid value (${value}) did not validate" $? - done - - # invalid values - for value in ${TH_FLOAT_INVALID}; do - _flags_validFloat "${value}" - assertFalse "invalid value (${value}) validated" $? - done -} - -testValidFloatBuiltin() -{ - _flags_useBuiltin || startSkipping - _testValidFloat -} - -testValidFloatExpr() -{ - ( - _flags_useBuiltin() { return ${FLAGS_FALSE}; } - _testValidFloat - ) -} - -_testValidInt() -{ - # valid values - for value in ${TH_INT_VALID}; do - _flags_validInt "${value}" - assertTrue "valid value (${value}) did not validate" $? - done - - # invalid values - for value in ${TH_INT_INVALID}; do - _flags_validInt "${value}" - assertFalse "invalid value (${value}) should not validate" $? - done -} - -testValidIntBuiltin() -{ - _flags_useBuiltin || startSkipping - _testValidInt -} - -testValidIntExpr() -{ - ( - _flags_useBuiltin() { return ${FLAGS_FALSE}; } - _testValidInt - ) -} - -_testMath() -{ - result=`_flags_math 1` - assertTrue '1 failed' $? - assertEquals '1' 1 ${result} - - result=`_flags_math '1 + 2'` - assertTrue '1+2 failed' $? - assertEquals '1+2' 3 ${result} - - result=`_flags_math '1 + 2 + 3'` - assertTrue '1+2+3 failed' $? - assertEquals '1+2+3' 6 ${result} - - result=`_flags_math` - assertFalse 'missing math succeeded' $? -} - -testMathBuiltin() -{ - _flags_useBuiltin || startSkipping - _testMath -} - -testMathExpr() -{ - ( - _flags_useBuiltin() { return ${FLAGS_FALSE}; } - _testMath - ) -} - -_testStrlen() -{ - len=`_flags_strlen` - assertTrue 'missing argument failed' $? - assertEquals 'missing argument' 0 ${len} - - len=`_flags_strlen ''` - assertTrue 'empty argument failed' $? - assertEquals 'empty argument' 0 ${len} - - len=`_flags_strlen abc123` - assertTrue 'single-word failed' $? - assertEquals 'single-word' 6 ${len} - - len=`_flags_strlen 'This is a test'` - assertTrue 'multi-word failed' $? - assertEquals 'multi-word' 14 ${len} -} - -testStrlenBuiltin() -{ - _flags_useBuiltin || startSkipping - _testStrlen -} - -testStrlenExpr() -{ - ( - _flags_useBuiltin() { return ${FLAGS_FALSE}; } - _testStrlen - ) -} - -#------------------------------------------------------------------------------ -# suite functions -# - -oneTimeSetUp() -{ - th_oneTimeSetUp - - _flags_useBuiltin || \ - th_warn 'Shell built-ins not supported. Some tests will be skipped.' -} - -tearDown() -{ - flags_reset -} - -# load and run shUnit2 -[ -n "${ZSH_VERSION:-}" ] && SHUNIT_PARENT=$0 -. ${TH_SHUNIT} diff --git a/src/shflags_test_public.sh b/src/shflags_test_public.sh deleted file mode 100755 index 5efb43e..0000000 --- a/src/shflags_test_public.sh +++ /dev/null @@ -1,180 +0,0 @@ -#! /bin/sh -# vim:et:ft=sh:sts=2:sw=2 -# -# shFlags unit test for the public functions - -# load test helpers -. ./shflags_test_helpers - -#------------------------------------------------------------------------------ -# suite tests -# - -testHelp() -{ - _testHelp '-h' - flags_getoptIsEnh || return - _testHelp '--help' -} - -_testHelp() -{ - flag=$1 - - # test default help output - th_clearReturn - ( - FLAGS ${flag} >"${stdoutF}" 2>"${stderrF}" - echo $? >"${returnF}" - ) - th_queryReturn - assertTrue \ - 'short help request should have returned a true exit code.' \ - ${th_return} - grep 'show this help' "${stderrF}" >/dev/null - grepped=$? - assertTrue \ - 'short request for help should have produced some help output.' \ - ${grepped} - [ ${grepped} -ne ${FLAGS_TRUE} ] && th_showOutput - - # test proper output when FLAGS_HELP set - ( - FLAGS_HELP='this is a test' - FLAGS ${flag} >"${stdoutF}" 2>"${stderrF}" - ) - grep 'this is a test' "${stderrF}" >/dev/null - grepped=$? - assertTrue 'setting FLAGS_HELP did not produce expected result' ${grepped} - [ ${grepped} -ne ${FLAGS_TRUE} ] && th_showOutput - - # test that "'" chars work in help string - ( - DEFINE_boolean b false "help string containing a ' char" b - FLAGS ${flag} >"${stdoutF}" 2>"${stderrF}" - ) - grep "help string containing a ' char" "${stderrF}" >/dev/null - grepped=$? - assertTrue "help strings containing apostrophes don't work" ${grepped} - [ ${grepped} -ne ${FLAGS_TRUE} ] && th_showOutput -} - -mock_flags_columns() -{ - echo 80 -} - -testStandardHelpOutput() -{ - flags_getoptIsStd || startSkipping - - DEFINE_boolean test_bool false 'test boolean' b - DEFINE_integer test_int 0 'test integer' i - DEFINE_string test_str '' 'test string' s - DEFINE_string long_desc 'blah' \ - 'testing of a long description to force wrap of default value' D - DEFINE_string long_default \ - 'this_is_a_long_default_value_to_force_alternate_indentation' \ - 'testing of long default value' F - help='USAGE: standard [flags] args' - - cat >"${expectedF}" <<EOF -${help} -flags: - -b test boolean (default: false) - -i test integer (default: 0) - -s test string (default: '') - -D testing of a long description to force wrap of default value - (default: 'blah') - -F testing of long default value - (default: 'this_is_a_long_default_value_to_force_alternate_indentation') - -h show this help (default: false) -EOF - ( - _flags_columns() { mock_flags_columns; } - FLAGS_HELP=${help}; - FLAGS -h >"${stdoutF}" 2>"${stderrF}" - ) - r3turn=$? - assertTrue 'a call for help should not return an error' ${r3turn} - - diff "${expectedF}" "${stderrF}" >/dev/null - r3turn=$? - assertTrue 'unexpected help output' ${r3turn} - th_showOutput ${r3turn} "${stdoutF}" "${stderrF}" -} - -testEnhancedHelpOutput() -{ - flags_getoptIsEnh || startSkipping - - DEFINE_boolean test_bool false 'test boolean' b - DEFINE_integer test_int 0 'test integer' i - DEFINE_string test_str '' 'test string' s - DEFINE_string long_desc 'blah' \ - 'testing of a long description to force wrap of default value' D - DEFINE_string long_default \ - 'this_is_a_long_default_value_to_force_alternate_indentation' \ - 'testing of long default value' F - help='USAGE: enhanced [flags] args' - - cat >"${expectedF}" <<EOF -${help} -flags: - -b,--[no]test_bool: test boolean (default: false) - -i,--test_int: test integer (default: 0) - -s,--test_str: test string (default: '') - -D,--long_desc: testing of a long description to force wrap of default value - (default: 'blah') - -F,--long_default: testing of long default value - (default: 'this_is_a_long_default_value_to_force_alternate_indentation') - -h,--help: show this help (default: false) -EOF - ( - _flags_columns() { mock_flags_columns; } - FLAGS_HELP=${help}; - FLAGS -h >"${stdoutF}" 2>"${stderrF}" - ) - r3turn=$? - assertTrue 'a call for help should not return an error' ${r3turn} - - diff "${expectedF}" "${stderrF}" >/dev/null - differed=$? - assertTrue 'unexpected help output' ${differed} - th_showOutput ${differed} "${stdoutF}" "${stderrF}" -} - -testNoHelp() -{ - flags_getoptIsEnh || startSkipping - - ( FLAGS --nohelp >"${stdoutF}" 2>"${stderrF}" ) - r3turn=$? - assertTrue "FLAGS returned a non-zero result (${r3turn})" ${r3turn} - assertFalse 'expected no output to STDOUT' "[ -s '${stdoutF}' ]" - assertFalse 'expected no output to STDERR' "[ -s '${stderrF}' ]" -} - -#------------------------------------------------------------------------------ -# suite functions -# - -oneTimeSetUp() -{ - th_oneTimeSetUp - - if flags_getoptIsStd; then - th_warn 'Standard version of getopt found. Enhanced tests will be skipped.' - else - th_warn 'Enhanced version of getopt found. Standard tests will be skipped.' - fi -} - -setUp() -{ - flags_reset -} - -# load and run shUnit2 -[ -n "${ZSH_VERSION:-}" ] && SHUNIT_PARENT=$0 -. ${TH_SHUNIT} |