Function name reformatting
See commit messages for more information. I will be worrying about variables when I introduce another abstraction.master
commit
2ec3f8a01e
|
@ -28,12 +28,12 @@ source expect/env.sh
|
||||||
|
|
||||||
##
|
##
|
||||||
# Shorthand for bailing out on unrecognized clauses
|
# Shorthand for bailing out on unrecognized clauses
|
||||||
_bail_clause()
|
shspec::bail-clause()
|
||||||
{
|
{
|
||||||
local -r type="$1"
|
local -r type="$1"
|
||||||
local -r clause="$2"
|
local -r clause="$2"
|
||||||
|
|
||||||
_bail "unrecognized \`$type' clause: \`$2'"
|
shspec::bail "unrecognized \`$type' clause: \`$2'"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,12 +44,12 @@ _bail_clause()
|
||||||
# where the remainder clause begins; this ensures that shspec can continue
|
# where the remainder clause begins; this ensures that shspec can continue
|
||||||
# to evolve in the future without BC breaks in properly designed expection
|
# to evolve in the future without BC breaks in properly designed expection
|
||||||
# handlers.
|
# handlers.
|
||||||
__chk-shiftn()
|
shspec::_chk-shiftn()
|
||||||
{
|
{
|
||||||
local -ri expect="$1"
|
local -ri expect="$1"
|
||||||
local -ri given="$2"
|
local -ri given="$2"
|
||||||
|
|
||||||
test "$given" -ge "$expect" || _bail \
|
test "$given" -ge "$expect" || shspec::bail \
|
||||||
"internal: expected shift of at least $expect, but given $given"
|
"internal: expected shift of at least $expect, but given $given"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,16 +59,16 @@ __chk-shiftn()
|
||||||
# spoken
|
# spoken
|
||||||
#
|
#
|
||||||
# For example, "to be silent".
|
# For example, "to be silent".
|
||||||
_expect--be() { _proxy-to "$@"; }
|
shspec::expect::be() { shspec::proxy-to "$@"; }
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Basic success and failure (zero or non-zero exit code)
|
# Basic success and failure (zero or non-zero exit code)
|
||||||
_expect--succeed() { test "$1" -eq 0; }
|
shspec::expect::succeed() { test "$1" -eq 0; }
|
||||||
_expect--fail() { test "$1" -ne 0; }
|
shspec::expect::fail() { test "$1" -ne 0; }
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Inverts the result of an expectation represented by the remainder clause
|
# Inverts the result of an expectation represented by the remainder clause
|
||||||
_expect--not() { ! _proxy-to "$@"; }
|
shspec::expect::not() { ! shspec::proxy-to "$@"; }
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ __INC_EXPECT_ENV=1
|
||||||
# Expect that an environment variable is set to a particular value, or
|
# Expect that an environment variable is set to a particular value, or
|
||||||
# assert on flags
|
# assert on flags
|
||||||
#
|
#
|
||||||
__expect-env()
|
shspec::expect::__env()
|
||||||
{
|
{
|
||||||
local -r expflags="$1" var="$2" cmp="$3"
|
local -r expflags="$1" var="$2" cmp="$3"
|
||||||
shift 3
|
shift 3
|
||||||
|
@ -35,7 +35,7 @@ __expect-env()
|
||||||
|
|
||||||
# TODO: support escaped newlines
|
# TODO: support escaped newlines
|
||||||
local flags val
|
local flags val
|
||||||
__read-env-line "$var" flags val < "$envpath"
|
shspec::expect::__read-env-line "$var" flags val < "$envpath"
|
||||||
|
|
||||||
# perform flag assertion if requested
|
# perform flag assertion if requested
|
||||||
test -n "$expflags" && {
|
test -n "$expflags" && {
|
||||||
|
@ -74,7 +74,7 @@ __expect-env()
|
||||||
# Expected output is of the form:
|
# Expected output is of the form:
|
||||||
# declare -flags? -- var="val"
|
# declare -flags? -- var="val"
|
||||||
#
|
#
|
||||||
__read-env-line()
|
shspec::expect::__read-env-line()
|
||||||
{
|
{
|
||||||
local -r var="$1" destflag="$2" destval="$3"
|
local -r var="$1" destflag="$2" destval="$3"
|
||||||
|
|
||||||
|
@ -90,26 +90,26 @@ __read-env-line()
|
||||||
##
|
##
|
||||||
# Expect that an environment variable has been set to a certain value
|
# Expect that an environment variable has been set to a certain value
|
||||||
#
|
#
|
||||||
_expect--set()
|
shspec::expect::set()
|
||||||
{
|
{
|
||||||
local -ri shiftn="$2"
|
local -ri shiftn="$2"
|
||||||
local -r envpath="$4"
|
local -r envpath="$4"
|
||||||
shift "$shiftn"
|
shift "$shiftn"
|
||||||
|
|
||||||
# ensure envpath is available
|
# ensure envpath is available
|
||||||
__chk-shiftn 4 "$shiftn"
|
shspec::_chk-shiftn 4 "$shiftn"
|
||||||
|
|
||||||
# no flag expectation
|
# no flag expectation
|
||||||
__expect-env '' "$@"
|
shspec::expect::__env '' "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Alias for `set`
|
# Alias for `set`
|
||||||
#
|
#
|
||||||
_expect--declare()
|
shspec::expect::declare()
|
||||||
{
|
{
|
||||||
_expect--set "$@"
|
shspec::expect::set "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -118,16 +118,16 @@ _expect--declare()
|
||||||
#
|
#
|
||||||
# Same syntax as `set`
|
# Same syntax as `set`
|
||||||
#
|
#
|
||||||
_expect--export()
|
shspec::expect::export()
|
||||||
{
|
{
|
||||||
local -ri shiftn="$2"
|
local -ri shiftn="$2"
|
||||||
local -r envpath="$4"
|
local -r envpath="$4"
|
||||||
shift "$shiftn"
|
shift "$shiftn"
|
||||||
|
|
||||||
# ensure envpath is available
|
# ensure envpath is available
|
||||||
__chk-shiftn 4 "$shiftn"
|
shspec::_chk-shiftn 4 "$shiftn"
|
||||||
|
|
||||||
# expect the -x flag, which denotes export
|
# expect the -x flag, which denotes export
|
||||||
__expect-env x "$@"
|
shspec::expect::__env x "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ exec 99<>/dev/null
|
||||||
#
|
#
|
||||||
# This command is successful if and only if both the remainder clause and
|
# This command is successful if and only if both the remainder clause and
|
||||||
# the provided command line complete successfully.
|
# the provided command line complete successfully.
|
||||||
__expect-output-cmd()
|
shspec::expect::__output-cmd()
|
||||||
{
|
{
|
||||||
local -r cmd="$1"
|
local -r cmd="$1"
|
||||||
shift
|
shift
|
||||||
|
@ -62,11 +62,11 @@ __expect-output-cmd()
|
||||||
local nl
|
local nl
|
||||||
local intype
|
local intype
|
||||||
{
|
{
|
||||||
__expect-output-clause "${clause[@]}" | {
|
shspec::expect::__output-clause "${clause[@]}" | {
|
||||||
IFS=\| read nl intype
|
IFS=\| read nl intype
|
||||||
|
|
||||||
if [ "$intype" == stderr ]; then
|
if [ "$intype" == stderr ]; then
|
||||||
__chk-shiftn 3 "$shiftn"
|
shspec::_chk-shiftn 3 "$shiftn"
|
||||||
exec 99<"$stderr"
|
exec 99<"$stderr"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ __expect-output-cmd()
|
||||||
}
|
}
|
||||||
|
|
||||||
# parses output remainder clause according to the aforementioned rules
|
# parses output remainder clause according to the aforementioned rules
|
||||||
__expect-output-clause()
|
shspec::expect::__output-clause()
|
||||||
{
|
{
|
||||||
[ $# -gt 0 ] || return 0
|
[ $# -gt 0 ] || return 0
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ __expect-output-clause()
|
||||||
if [[ "$1 $2" =~ ^on\ std(err|out) ]]; then
|
if [[ "$1 $2" =~ ^on\ std(err|out) ]]; then
|
||||||
[ "$2" == stderr ] && input="$2"
|
[ "$2" == stderr ] && input="$2"
|
||||||
else
|
else
|
||||||
_bail_clause output "$*"
|
shspec::bail-clause output "$*"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ __expect-output-clause()
|
||||||
#
|
#
|
||||||
# This expectation assumes a trailing newline by default; this behavior can
|
# This expectation assumes a trailing newline by default; this behavior can
|
||||||
# be suppressed with the `without newline' clause.
|
# be suppressed with the `without newline' clause.
|
||||||
_expect--output()
|
shspec::expect::output()
|
||||||
{
|
{
|
||||||
local -a args=("$@")
|
local -a args=("$@")
|
||||||
local -i shiftn="$2"
|
local -i shiftn="$2"
|
||||||
|
@ -122,10 +122,11 @@ _expect--output()
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
__expect-output-cmd "__expect--output-do -$nl" "${args[@]}"
|
shspec::expect::__output-cmd "shspec::expect::__output-do -$nl" \
|
||||||
|
"${args[@]}"
|
||||||
}
|
}
|
||||||
|
|
||||||
__expect--output-do()
|
shspec::expect::__output-do()
|
||||||
{
|
{
|
||||||
local -r nl="${1:1}"
|
local -r nl="${1:1}"
|
||||||
local -r cmp="$2"
|
local -r cmp="$2"
|
||||||
|
@ -139,12 +140,12 @@ __expect--output-do()
|
||||||
##
|
##
|
||||||
# Expects that stdout matches the provided extended regular expression (as
|
# Expects that stdout matches the provided extended regular expression (as
|
||||||
# in regex(3))
|
# in regex(3))
|
||||||
_expect--match()
|
shspec::expect::match()
|
||||||
{
|
{
|
||||||
__expect-output-cmd '__expect--match-do' "$@"
|
shspec::expect::__output-cmd 'shspec::expect::__match-do' "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
__expect--match-do()
|
shspec::expect::__match-do()
|
||||||
{
|
{
|
||||||
local -r pat="$1"
|
local -r pat="$1"
|
||||||
[[ "$(cat)" =~ $pat ]]
|
[[ "$(cat)" =~ $pat ]]
|
||||||
|
@ -153,13 +154,13 @@ __expect--match-do()
|
||||||
|
|
||||||
##
|
##
|
||||||
# Expects that both stdin and stderr (if available) are empty
|
# Expects that both stdin and stderr (if available) are empty
|
||||||
_expect--silent()
|
shspec::expect::silent()
|
||||||
{
|
{
|
||||||
local -r stderr="${3:-/dev/null}"
|
local -r stderr="${3:-/dev/null}"
|
||||||
shift "$2"
|
shift "$2"
|
||||||
|
|
||||||
# we accept no arguments
|
# we accept no arguments
|
||||||
test $# -eq 0 || _bail_clause silent "$*"
|
test $# -eq 0 || shspec::bail-clause silent "$*"
|
||||||
|
|
||||||
# quick read using builtins; if we find any single byte, then we know that
|
# quick read using builtins; if we find any single byte, then we know that
|
||||||
# it is non-empty
|
# it is non-empty
|
||||||
|
|
|
@ -23,9 +23,9 @@ source spec.sh
|
||||||
|
|
||||||
declare -r tcase="${1?Missing test case path}"
|
declare -r tcase="${1?Missing test case path}"
|
||||||
|
|
||||||
_begin-spec
|
shspec::begin-spec
|
||||||
cd "$( dirname "$tcase" )" \
|
cd "$( dirname "$tcase" )" \
|
||||||
&& source "$tcase" \
|
&& source "$tcase" \
|
||||||
|| exit $?
|
|| exit $?
|
||||||
_end-spec
|
shspec::end-spec
|
||||||
|
|
||||||
|
|
58
src/spec.sh
58
src/spec.sh
|
@ -38,7 +38,7 @@ declare -ir __SHIFTN=4
|
||||||
|
|
||||||
##
|
##
|
||||||
# Attempts to make tempoary path in /dev/shm, falling back to default
|
# Attempts to make tempoary path in /dev/shm, falling back to default
|
||||||
mktemp-shm()
|
shspec::__mktemp-shm()
|
||||||
{
|
{
|
||||||
local -r shm=/dev/shm
|
local -r shm=/dev/shm
|
||||||
[ -d $shm -a -r $shm ] && mktemp -p$shm || mktemp
|
[ -d $shm -a -r $shm ] && mktemp -p$shm || mktemp
|
||||||
|
@ -46,10 +46,10 @@ mktemp-shm()
|
||||||
|
|
||||||
|
|
||||||
# stderr file
|
# stderr file
|
||||||
declare -r __spec_errpath="$(mktemp-shm)"
|
readonly __spec_errpath="$(shspec::__mktemp-shm)"
|
||||||
|
|
||||||
# env dump file
|
# env dump file
|
||||||
declare -r __spec_envpath="$(mktemp-shm)"
|
readonly __spec_envpath="$(shspec::__mktemp-shm)"
|
||||||
|
|
||||||
# most recent expect result and its exit code
|
# most recent expect result and its exit code
|
||||||
declare __spec_result=
|
declare __spec_result=
|
||||||
|
@ -64,7 +64,7 @@ declare __spec_caller=
|
||||||
#
|
#
|
||||||
# A specification is any shell script using the specification commands
|
# A specification is any shell script using the specification commands
|
||||||
# defined herein.
|
# defined herein.
|
||||||
_begin-spec()
|
shspec::begin-spec()
|
||||||
{
|
{
|
||||||
: placeholder
|
: placeholder
|
||||||
}
|
}
|
||||||
|
@ -75,15 +75,15 @@ _begin-spec()
|
||||||
#
|
#
|
||||||
# If the specification was improperly nested, this will output a list of
|
# If the specification was improperly nested, this will output a list of
|
||||||
# nesting errors and return a non-zero error. Otherwise, nothing is done.
|
# nesting errors and return a non-zero error. Otherwise, nothing is done.
|
||||||
_end-spec()
|
shspec::end-spec()
|
||||||
{
|
{
|
||||||
# if the stack is empty then everything is in order
|
# if the stack is empty then everything is in order
|
||||||
_sstack-empty && return 0
|
shspec::stack::_empty && return 0
|
||||||
|
|
||||||
# otherwise, output an error message for each item in the stack
|
# otherwise, output an error message for each item in the stack
|
||||||
until _sstack-empty; do
|
until shspec::stack::_empty; do
|
||||||
_sstack-read type line file _ < <(_sstack-head)
|
shspec::stack::_read type line file _ < <(shspec::stack::_head)
|
||||||
_sstack-pop
|
shspec::stack::_pop
|
||||||
echo "error: unterminated \`$type' at $file:$line"
|
echo "error: unterminated \`$type' at $file:$line"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ _end-spec()
|
||||||
describe()
|
describe()
|
||||||
{
|
{
|
||||||
local -r desc="$*"
|
local -r desc="$*"
|
||||||
_sstack-push "describe" $(caller) "$desc"
|
shspec::stack::_push "describe" $(caller) "$desc"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ describe()
|
||||||
it()
|
it()
|
||||||
{
|
{
|
||||||
local -r desc="$*"
|
local -r desc="$*"
|
||||||
_sstack-push "it" $(caller) "$desc"
|
shspec::stack::_push "it" $(caller) "$desc"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -122,15 +122,16 @@ it()
|
||||||
# should not use this command.
|
# should not use this command.
|
||||||
end()
|
end()
|
||||||
{
|
{
|
||||||
local -r head="$(_sstack-head-type)"
|
local -r head="$(shspec::stack::_head-type)"
|
||||||
local -r cleanhead="$head"
|
local -r cleanhead="$head"
|
||||||
|
|
||||||
# some statements are implicitly terminated; explicitly doing so is
|
# some statements are implicitly terminated; explicitly doing so is
|
||||||
# indicitive of a syntax issue
|
# indicitive of a syntax issue
|
||||||
[ "${head:0:1}" != : ] \
|
[ "${head:0:1}" != : ] \
|
||||||
|| _bail "unexpected \`end': still processing \`$cleanhead'" $(caller)
|
|| shspec::bail \
|
||||||
|
"unexpected \`end': still processing \`$cleanhead'" $(caller)
|
||||||
|
|
||||||
_sstack-pop >/dev/null || _bail "unmatched \`end'"
|
shspec::stack::_pop >/dev/null || shspec::bail "unmatched \`end'"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -144,10 +145,10 @@ end()
|
||||||
# That is, this declares "given this command, I can expect that..."
|
# That is, this declares "given this command, I can expect that..."
|
||||||
expect()
|
expect()
|
||||||
{
|
{
|
||||||
_sstack-assert-within it expect $(caller)
|
shspec::stack::_assert-within it expect $(caller)
|
||||||
__spec_result="$("$@" 2>"$__spec_errpath")"
|
__spec_result="$("$@" 2>"$__spec_errpath")"
|
||||||
__spec_rexit=$?
|
__spec_rexit=$?
|
||||||
_sstack-push :expect $(caller) "$@"
|
shspec::stack::_push :expect $(caller) "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -160,12 +161,13 @@ to()
|
||||||
{
|
{
|
||||||
__spec_caller=${__spec_caller:-$(caller)}
|
__spec_caller=${__spec_caller:-$(caller)}
|
||||||
|
|
||||||
[ $# -gt 0 ] || _bail "missing assertion string for \`to'" $__spec_caller
|
[ $# -gt 0 ] || \
|
||||||
|
shspec::bail "missing assertion string for \`to'" $__spec_caller
|
||||||
|
|
||||||
_sstack-assert-follow :expect to $(caller)
|
shspec::stack::_assert-follow :expect to $(caller)
|
||||||
_sstack-pop
|
shspec::stack::_pop
|
||||||
|
|
||||||
__handle-to "$__spec_rexit" $__SHIFTN \
|
shspec::__handle-to "$__spec_rexit" $__SHIFTN \
|
||||||
"$__spec_errpath" "$__spec_envpath" "$@" \
|
"$__spec_errpath" "$__spec_envpath" "$@" \
|
||||||
|| fail "$*"
|
|| fail "$*"
|
||||||
|
|
||||||
|
@ -181,7 +183,7 @@ to()
|
||||||
#
|
#
|
||||||
# <exit code> <shiftn> <...N> <expect type> <...remainder clause>
|
# <exit code> <shiftn> <...N> <expect type> <...remainder clause>
|
||||||
#
|
#
|
||||||
__handle-to()
|
shspec::__handle-to()
|
||||||
{
|
{
|
||||||
local -ri rexit="$1"
|
local -ri rexit="$1"
|
||||||
local -ri shiftn="$2"
|
local -ri shiftn="$2"
|
||||||
|
@ -192,9 +194,9 @@ __handle-to()
|
||||||
local -r type="$1"
|
local -r type="$1"
|
||||||
shift
|
shift
|
||||||
|
|
||||||
local -r assert="_expect--$type"
|
local -r assert="shspec::expect::$type"
|
||||||
type "$assert" &>/dev/null \
|
type "$assert" &>/dev/null \
|
||||||
|| _bail "unknown expectation: \`$type'" $__spec_caller
|
|| shspec::bail "unknown expectation: \`$type'" $__spec_caller
|
||||||
|
|
||||||
# first argument is exit code, second is the number of arguments to shift
|
# first argument is exit code, second is the number of arguments to shift
|
||||||
# to place $1 at the remainder clause, third is the path to the stderr
|
# to place $1 at the remainder clause, third is the path to the stderr
|
||||||
|
@ -210,7 +212,7 @@ __handle-to()
|
||||||
# Alias for _handle-to
|
# Alias for _handle-to
|
||||||
#
|
#
|
||||||
# Shows intent to proxy a call and allows proxy implementation to vary.
|
# Shows intent to proxy a call and allows proxy implementation to vary.
|
||||||
_proxy-to() { __handle-to "$@"; }
|
shspec::proxy-to() { shspec::__handle-to "$@"; }
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -221,8 +223,8 @@ and()
|
||||||
|
|
||||||
# the most recently popped value should be an expect premise, implying
|
# the most recently popped value should be an expect premise, implying
|
||||||
# that an expectation declaration implicitly popped it
|
# that an expectation declaration implicitly popped it
|
||||||
_sstack-unpop
|
shspec::stack::_unpop
|
||||||
_sstack-assert-within :expect and $(caller) \
|
shspec::stack::_assert-within :expect and $(caller) \
|
||||||
"follow an expectation as part of"
|
"follow an expectation as part of"
|
||||||
|
|
||||||
"$@"
|
"$@"
|
||||||
|
@ -249,7 +251,7 @@ fail()
|
||||||
echo " exit code: $__spec_rexit"
|
echo " exit code: $__spec_rexit"
|
||||||
|
|
||||||
echo
|
echo
|
||||||
_bail "expectation failure"
|
shspec::bail "expectation failure"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -261,7 +263,7 @@ fail()
|
||||||
#
|
#
|
||||||
# If no file and line number are provided, this will default to the current
|
# If no file and line number are provided, this will default to the current
|
||||||
# spec caller, if any.
|
# spec caller, if any.
|
||||||
_bail()
|
shspec::bail()
|
||||||
{
|
{
|
||||||
local -r msg="$1"
|
local -r msg="$1"
|
||||||
local line="$2"
|
local line="$2"
|
||||||
|
|
|
@ -28,7 +28,7 @@ declare -i __sstackp=0
|
||||||
|
|
||||||
##
|
##
|
||||||
# Push a frame onto the stack
|
# Push a frame onto the stack
|
||||||
_sstack-push()
|
shspec::stack::_push()
|
||||||
{
|
{
|
||||||
local -r type="$1"
|
local -r type="$1"
|
||||||
local -r srcline="$2"
|
local -r srcline="$2"
|
||||||
|
@ -44,7 +44,7 @@ _sstack-push()
|
||||||
# Pop a frame from the stack
|
# Pop a frame from the stack
|
||||||
#
|
#
|
||||||
# It is possible to recover the most recently popped frame.
|
# It is possible to recover the most recently popped frame.
|
||||||
_sstack-pop()
|
shspec::stack::_pop()
|
||||||
{
|
{
|
||||||
[ "$__sstackp" -gt 0 ] || return 1
|
[ "$__sstackp" -gt 0 ] || return 1
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ _sstack-pop()
|
||||||
# Note that this should never be called more than once in an attempt to
|
# Note that this should never be called more than once in an attempt to
|
||||||
# recover additional frames; it will not work, and you will make bad things
|
# recover additional frames; it will not work, and you will make bad things
|
||||||
# happen, and people will hate you.
|
# happen, and people will hate you.
|
||||||
_sstack-unpop()
|
shspec::stack::_unpop()
|
||||||
{
|
{
|
||||||
((__sstackp++))
|
((__sstackp++))
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ _sstack-unpop()
|
||||||
|
|
||||||
##
|
##
|
||||||
# Return with a non-zero status only if the stack is non-empty
|
# Return with a non-zero status only if the stack is non-empty
|
||||||
_sstack-empty()
|
shspec::stack::_empty()
|
||||||
{
|
{
|
||||||
test "$__sstackp" -eq 0
|
test "$__sstackp" -eq 0
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ _sstack-empty()
|
||||||
|
|
||||||
##
|
##
|
||||||
# Output the current size of the stack
|
# Output the current size of the stack
|
||||||
_sstack-size()
|
shspec::stack::_size()
|
||||||
{
|
{
|
||||||
echo "$__sstackp"
|
echo "$__sstackp"
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ _sstack-size()
|
||||||
|
|
||||||
##
|
##
|
||||||
# Output the current stack frame
|
# Output the current stack frame
|
||||||
_sstack-head()
|
shspec::stack::_head()
|
||||||
{
|
{
|
||||||
local -ri headi=$((__sstackp-1))
|
local -ri headi=$((__sstackp-1))
|
||||||
echo "${__sstack[$headi]}"
|
echo "${__sstack[$headi]}"
|
||||||
|
@ -94,27 +94,27 @@ _sstack-head()
|
||||||
|
|
||||||
##
|
##
|
||||||
# Output the type of the current stack frame
|
# Output the type of the current stack frame
|
||||||
_sstack-head-type()
|
shspec::stack::_head-type()
|
||||||
{
|
{
|
||||||
__sstack-headn 0
|
_shspec::stack::_headn 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Output the Nth datum of the current stack frame
|
# Output the Nth datum of the current stack frame
|
||||||
__sstack-headn()
|
_shspec::stack::_headn()
|
||||||
{
|
{
|
||||||
local -ri i="$1"
|
local -ri i="$1"
|
||||||
local parts
|
local parts
|
||||||
|
|
||||||
_sstack-read -a parts <<< "$(_sstack-head)"
|
shspec::stack::_read -a parts <<< "$(shspec::stack::_head)"
|
||||||
echo "${parts[$i]}"
|
echo "${parts[$i]}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Deconstruct stack frame from stdin in a `read`-like manner
|
# Deconstruct stack frame from stdin in a `read`-like manner
|
||||||
_sstack-read()
|
shspec::stack::_read()
|
||||||
{
|
{
|
||||||
IFS=\| read "$@"
|
IFS=\| read "$@"
|
||||||
}
|
}
|
||||||
|
@ -125,10 +125,10 @@ _sstack-read()
|
||||||
#
|
#
|
||||||
# Return immediately with a non-zero status if there are no frames on the
|
# Return immediately with a non-zero status if there are no frames on the
|
||||||
# stack.
|
# stack.
|
||||||
_sstack-read-pop()
|
shspec::stack::_read-pop()
|
||||||
{
|
{
|
||||||
local -r head="$(_sstack-pop)" || return 1
|
local -r head="$(shspec::stack::_pop)" || return 1
|
||||||
_sstack-read "$@" <<< "$head"
|
shspec::stack::_read "$@" <<< "$head"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ _sstack-read-pop()
|
||||||
#
|
#
|
||||||
# Conceptually, this allows determining if the parent node in a tree-like
|
# Conceptually, this allows determining if the parent node in a tree-like
|
||||||
# structure is of a certain type.
|
# structure is of a certain type.
|
||||||
_sstack-assert-within()
|
shspec::stack::_assert-within()
|
||||||
{
|
{
|
||||||
local -r in="$1"
|
local -r in="$1"
|
||||||
local -r chk="$2"
|
local -r chk="$2"
|
||||||
|
@ -145,20 +145,21 @@ _sstack-assert-within()
|
||||||
local -r file="$4"
|
local -r file="$4"
|
||||||
local -r phrase="${5:-be contained within}"
|
local -r phrase="${5:-be contained within}"
|
||||||
|
|
||||||
local -r head="$(_sstack-head-type)"
|
local -r head="$(shspec::stack::_head-type)"
|
||||||
|
|
||||||
[ "$head" == "$in" ] \
|
[ "$head" == "$in" ] \
|
||||||
|| _bail "\`$chk' must $phrase \`$head'; found \`$head' at $file:$line"
|
|| shspec::bail \
|
||||||
|
"\`$chk' must $phrase \`$head'; found \`$head' at $file:$line"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Alias for _sstack-assert-within with altered error message
|
# Alias for shspec::stack::_assert-within with altered error message
|
||||||
#
|
#
|
||||||
# This is intended to convey a different perspective: that a given node is a
|
# This is intended to convey a different perspective: that a given node is a
|
||||||
# sibling, not a child, in a tree-like structure.
|
# sibling, not a child, in a tree-like structure.
|
||||||
_sstack-assert-follow()
|
shspec::stack::_assert-follow()
|
||||||
{
|
{
|
||||||
_sstack-assert-within "$@" follow
|
shspec::stack::_assert-within "$@" follow
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,16 +21,16 @@
|
||||||
|
|
||||||
describe be
|
describe be
|
||||||
it cannot stand alone
|
it cannot stand alone
|
||||||
expect _expect--be 0 2
|
expect shspec::expect::be 0 2
|
||||||
to fail
|
to fail
|
||||||
end
|
end
|
||||||
|
|
||||||
it processes remainder clause as if it did not exist
|
it processes remainder clause as if it did not exist
|
||||||
(
|
(
|
||||||
expected="foo bar baz"
|
expected="foo bar baz"
|
||||||
_expect--awesome() { shift "$2"; test "$*" == "$expected"; }
|
shspec::expect::awesome() { shift "$2"; test "$*" == "$expected"; }
|
||||||
|
|
||||||
expect _expect--be 0 2 awesome $expected
|
expect shspec::expect::be 0 2 awesome $expected
|
||||||
to succeed
|
to succeed
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -39,12 +39,12 @@ end
|
||||||
|
|
||||||
describe succeed
|
describe succeed
|
||||||
it will succeed when command exits with status code 0
|
it will succeed when command exits with status code 0
|
||||||
expect _expect--succeed 0 2
|
expect shspec::expect::succeed 0 2
|
||||||
to succeed
|
to succeed
|
||||||
end
|
end
|
||||||
|
|
||||||
it will fail when command exits with non-zero status code
|
it will fail when command exits with non-zero status code
|
||||||
expect _expect--succeed 1 2
|
expect shspec::expect::succeed 1 2
|
||||||
to fail
|
to fail
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -52,12 +52,12 @@ end
|
||||||
|
|
||||||
describe fail
|
describe fail
|
||||||
it will succeed when command exits with non-zero status code
|
it will succeed when command exits with non-zero status code
|
||||||
expect _expect--fail 1 2
|
expect shspec::expect::fail 1 2
|
||||||
to succeed
|
to succeed
|
||||||
end
|
end
|
||||||
|
|
||||||
it will fail when command exits with status code 0
|
it will fail when command exits with status code 0
|
||||||
expect _expect--fail 0 2
|
expect shspec::expect::fail 0 2
|
||||||
to fail
|
to fail
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -66,11 +66,11 @@ end
|
||||||
describe not
|
describe not
|
||||||
it will invert the result of an expectation
|
it will invert the result of an expectation
|
||||||
# exit code of 1, so normally `succeed' would fail
|
# exit code of 1, so normally `succeed' would fail
|
||||||
expect _expect--not 1 2 succeed
|
expect shspec::expect::not 1 2 succeed
|
||||||
to succeed
|
to succeed
|
||||||
|
|
||||||
# exit code of 0, so normally `succeed' would succeed
|
# exit code of 0, so normally `succeed' would succeed
|
||||||
expect _expect--not 0 2 succeed
|
expect shspec::expect::not 0 2 succeed
|
||||||
to fail
|
to fail
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -78,49 +78,50 @@ end
|
||||||
|
|
||||||
describe output
|
describe output
|
||||||
it will default to asserting against stdout
|
it will default to asserting against stdout
|
||||||
expect _expect--output 0 2 "test string" <<< "test string"
|
expect shspec::expect::output 0 2 "test string" <<< "test string"
|
||||||
to succeed
|
to succeed
|
||||||
end
|
end
|
||||||
|
|
||||||
# by convention, stderr file passed as third argument
|
# by convention, stderr file passed as third argument
|
||||||
it can assert against stderr output
|
it can assert against stderr output
|
||||||
{
|
{
|
||||||
expect _expect--output 0 3 /dev/fd/3 \
|
expect shspec::expect::output 0 3 /dev/fd/3 \
|
||||||
"test stderr" on stderr
|
"test stderr" on stderr
|
||||||
to succeed
|
to succeed
|
||||||
} 3< <( echo "test stderr" )
|
} 3< <( echo "test stderr" )
|
||||||
end
|
end
|
||||||
|
|
||||||
it fails on stdout mismatch
|
it fails on stdout mismatch
|
||||||
expect _expect--output 0 2 "foo" <<< "bar"
|
expect shspec::expect::output 0 2 "foo" <<< "bar"
|
||||||
to fail
|
to fail
|
||||||
end
|
end
|
||||||
|
|
||||||
it fails on stderr mismatch
|
it fails on stderr mismatch
|
||||||
{
|
{
|
||||||
expect _expect--output 0 3 /dev/fd/3 "foo" on stderr
|
expect shspec::expect::output 0 3 /dev/fd/3 "foo" on stderr
|
||||||
to fail
|
to fail
|
||||||
} 3< <( echo bar )
|
} 3< <( echo bar )
|
||||||
end
|
end
|
||||||
|
|
||||||
it ignores exit code
|
it ignores exit code
|
||||||
expect _expect--output 1 2 "foo" <<< "foo"
|
expect shspec::expect::output 1 2 "foo" <<< "foo"
|
||||||
to succeed
|
to succeed
|
||||||
end
|
end
|
||||||
|
|
||||||
# as is good practice for Unix utilities
|
# as is good practice for Unix utilities
|
||||||
it expects trailing newline by default
|
it expects trailing newline by default
|
||||||
expect _expect--output 0 2 "foo" < <( echo -n foo )
|
expect shspec::expect::output 0 2 "foo" < <( echo -n foo )
|
||||||
to fail
|
to fail
|
||||||
end
|
end
|
||||||
|
|
||||||
it can disable trailing newline check with "'without newline'" clause
|
it can disable trailing newline check with "'without newline'" clause
|
||||||
expect _expect--output 0 2 "foo" without newline < <( echo -n foo )
|
expect shspec::expect::output 0 2 "foo" without newline \
|
||||||
|
< <( echo -n foo )
|
||||||
to succeed
|
to succeed
|
||||||
end
|
end
|
||||||
|
|
||||||
it errors on any unrecognized clause
|
it errors on any unrecognized clause
|
||||||
expect _expect--output 0 2 "foo" fluffy bunnies <<< "foo"
|
expect shspec::expect::output 0 2 "foo" fluffy bunnies <<< "foo"
|
||||||
to fail
|
to fail
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -128,33 +129,33 @@ end
|
||||||
|
|
||||||
describe match
|
describe match
|
||||||
it will default to asserting against stdout
|
it will default to asserting against stdout
|
||||||
expect _expect--match 0 2 "foo" <<< "foo"
|
expect shspec::expect::match 0 2 "foo" <<< "foo"
|
||||||
to succeed
|
to succeed
|
||||||
end
|
end
|
||||||
|
|
||||||
# by convention, stderr file passed as third argument
|
# by convention, stderr file passed as third argument
|
||||||
it can assert against stderr output
|
it can assert against stderr output
|
||||||
{
|
{
|
||||||
expect _expect--match 0 3 /dev/fd/3 "stderr" on stderr
|
expect shspec::expect::match 0 3 /dev/fd/3 "stderr" on stderr
|
||||||
to succeed
|
to succeed
|
||||||
} 3< <( echo "test stderr" )
|
} 3< <( echo "test stderr" )
|
||||||
end
|
end
|
||||||
|
|
||||||
it ignores exit code
|
it ignores exit code
|
||||||
expect _expect--match 1 2 "foo" <<< "foo"
|
expect shspec::expect::match 1 2 "foo" <<< "foo"
|
||||||
to succeed
|
to succeed
|
||||||
end
|
end
|
||||||
|
|
||||||
it will perform partial match
|
it will perform partial match
|
||||||
expect _expect--match 0 2 "foo" <<< "contains foo"
|
expect shspec::expect::match 0 2 "foo" <<< "contains foo"
|
||||||
to succeed
|
to succeed
|
||||||
end
|
end
|
||||||
|
|
||||||
it will match against a pattern
|
it will match against a pattern
|
||||||
expect _expect--match 0 2 "^foo.*baz" <<< "foo bar baz"
|
expect shspec::expect::match 0 2 "^foo.*baz" <<< "foo bar baz"
|
||||||
to succeed
|
to succeed
|
||||||
|
|
||||||
expect _expect--match 0 2 "^foo.*baz" <<< "bar foo bar baz"
|
expect shspec::expect::match 0 2 "^foo.*baz" <<< "bar foo bar baz"
|
||||||
to fail
|
to fail
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -163,32 +164,32 @@ end
|
||||||
describe silent
|
describe silent
|
||||||
it succeeds when both stdout and stderr are empty
|
it succeeds when both stdout and stderr are empty
|
||||||
# omitting stderr arg
|
# omitting stderr arg
|
||||||
expect _expect--silent 0 2 < <(:)
|
expect shspec::expect::silent 0 2 < <(:)
|
||||||
to succeed
|
to succeed
|
||||||
|
|
||||||
# empty stderr
|
# empty stderr
|
||||||
expect _expect--silent 0 3 <(:) < <(:)
|
expect shspec::expect::silent 0 3 <(:) < <(:)
|
||||||
to succeed
|
to succeed
|
||||||
end
|
end
|
||||||
|
|
||||||
it fails when stdout is empty but stderr is not
|
it fails when stdout is empty but stderr is not
|
||||||
expect _expect--silent 0 3 <( echo ) < <(:)
|
expect shspec::expect::silent 0 3 <( echo ) < <(:)
|
||||||
to fail
|
to fail
|
||||||
end
|
end
|
||||||
|
|
||||||
it fails when stderr is empty but stdout is not
|
it fails when stderr is empty but stdout is not
|
||||||
# omitting stderr arg
|
# omitting stderr arg
|
||||||
expect _expect--silent 0 2 <<< ""
|
expect shspec::expect::silent 0 2 <<< ""
|
||||||
to fail
|
to fail
|
||||||
|
|
||||||
# empty stderr
|
# empty stderr
|
||||||
expect _expect--silent 0 3 <(:) <<< ""
|
expect shspec::expect::silent 0 3 <(:) <<< ""
|
||||||
to fail
|
to fail
|
||||||
end
|
end
|
||||||
|
|
||||||
# no arguments within context of the DSL, that is
|
# no arguments within context of the DSL, that is
|
||||||
it accepts no arguments
|
it accepts no arguments
|
||||||
expect _expect--silent 0 2 foo < <(:)
|
expect shspec::expect::silent 0 2 foo < <(:)
|
||||||
to fail
|
to fail
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -31,7 +31,7 @@ declare -- nonexport_empty=""'
|
||||||
declare curchk
|
declare curchk
|
||||||
function setchk()
|
function setchk()
|
||||||
{
|
{
|
||||||
_expect--$curchk 0 4 <(:) <( echo "$stubenv" ) "$@"
|
shspec::expect::$curchk 0 4 <(:) <( echo "$stubenv" ) "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,9 +38,9 @@ test-run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
describe _begin-spec
|
describe shspec::begin-spec
|
||||||
it is a placeholder that exits successfully
|
it is a placeholder that exits successfully
|
||||||
expect _begin-spec
|
expect shspec::begin-spec
|
||||||
to succeed
|
to succeed
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -149,7 +149,7 @@ describe expect
|
||||||
it is provided premise exit code as first argument
|
it is provided premise exit code as first argument
|
||||||
expect test-run <<< '
|
expect test-run <<< '
|
||||||
declare excode=123
|
declare excode=123
|
||||||
_expect--chk() { test "$1" -eq $excode; }
|
shspec::expect::chk() { test "$1" -eq $excode; }
|
||||||
|
|
||||||
describe foo
|
describe foo
|
||||||
it exposes exit code
|
it exposes exit code
|
||||||
|
@ -165,7 +165,7 @@ describe expect
|
||||||
it is provided remainder clause after shift argument
|
it is provided remainder clause after shift argument
|
||||||
expect test-run <<< '
|
expect test-run <<< '
|
||||||
declare remain="a b c"
|
declare remain="a b c"
|
||||||
_expect--chk()
|
shspec::expect::chk()
|
||||||
{
|
{
|
||||||
shift "$2"
|
shift "$2"
|
||||||
test "$*" == "$remain"
|
test "$*" == "$remain"
|
||||||
|
@ -183,7 +183,7 @@ describe expect
|
||||||
it receives premise output via stdin
|
it receives premise output via stdin
|
||||||
expect test-run <<< '
|
expect test-run <<< '
|
||||||
declare str=foo
|
declare str=foo
|
||||||
_expect--chk() { test "$(cat)" == "$str"; }
|
shspec::expect::chk() { test "$(cat)" == "$str"; }
|
||||||
|
|
||||||
describe foo
|
describe foo
|
||||||
it pipes command output
|
it pipes command output
|
||||||
|
@ -198,7 +198,7 @@ describe expect
|
||||||
# newline will be added; we don't want that!
|
# newline will be added; we don't want that!
|
||||||
it does not have newline added to premise output if missing
|
it does not have newline added to premise output if missing
|
||||||
expect test-run <<< '
|
expect test-run <<< '
|
||||||
_expect--chk() { test "$( wc -c )" -eq 0; }
|
shspec::expect::chk() { test "$( wc -c )" -eq 0; }
|
||||||
|
|
||||||
describe foo
|
describe foo
|
||||||
it should not add newline
|
it should not add newline
|
||||||
|
@ -308,18 +308,18 @@ describe expect
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
describe _proxy-to
|
describe shspec::proxy-to
|
||||||
it proxies remainder clause with variable shift length
|
it proxies remainder clause with variable shift length
|
||||||
expect test-run <<< '
|
expect test-run <<< '
|
||||||
expected="foo bar baz"
|
expected="foo bar baz"
|
||||||
_expect--chk() { shift "$2"; test "$*" == "$expected"; }
|
shspec::expect::chk() { shift "$2"; test "$*" == "$expected"; }
|
||||||
|
|
||||||
describe foo
|
describe foo
|
||||||
it should succeed
|
it should succeed
|
||||||
expect _proxy-to 0 2 chk $expected
|
expect shspec::proxy-to 0 2 chk $expected
|
||||||
to succeed
|
to succeed
|
||||||
|
|
||||||
expect _proxy-to 0 3 /dev/null chk $expected
|
expect shspec::proxy-to 0 3 /dev/null chk $expected
|
||||||
to succeed
|
to succeed
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue