Began move to shspec::* function naming

This is motivated by Google's shell coding standards and will reduce the
odds of a naming conflict with other functions (which, of course, would
cause terribly odd and difficult-to-find bugs, in both our system and
others').

If this seems like it creates long, overly-verbose function names with no
relief in sight---you're right. I'll have a solution for that in a bit, as a
separate project. ...as a part of my never-ending, growing heap of projects.
master
Mike Gerwitz 2014-06-13 17:10:02 -04:00
parent 4572d0f636
commit aa9044cc97
9 changed files with 95 additions and 90 deletions

View File

@ -28,12 +28,12 @@ source expect/env.sh
##
# Shorthand for bailing out on unrecognized clauses
_bail_clause()
shspec::bail-clause()
{
local -r type="$1"
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
# to evolve in the future without BC breaks in properly designed expection
# handlers.
__chk-shiftn()
shspec::_chk-shiftn()
{
local -ri expect="$1"
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"
}
@ -59,16 +59,16 @@ __chk-shiftn()
# spoken
#
# 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)
_expect--succeed() { test "$1" -eq 0; }
_expect--fail() { test "$1" -ne 0; }
shspec::expect::succeed() { test "$1" -eq 0; }
shspec::expect::fail() { test "$1" -ne 0; }
##
# Inverts the result of an expectation represented by the remainder clause
_expect--not() { ! _proxy-to "$@"; }
shspec::expect::not() { ! shspec::proxy-to "$@"; }

View File

@ -27,7 +27,7 @@ __INC_EXPECT_ENV=1
# Expect that an environment variable is set to a particular value, or
# assert on flags
#
__expect-env()
shspec::expect::__env()
{
local -r expflags="$1" var="$2" cmp="$3"
shift 3
@ -35,7 +35,7 @@ __expect-env()
# TODO: support escaped newlines
local flags val
__read-env-line "$var" flags val < "$envpath"
shspec::expect::__read-env-line "$var" flags val < "$envpath"
# perform flag assertion if requested
test -n "$expflags" && {
@ -74,7 +74,7 @@ __expect-env()
# Expected output is of the form:
# declare -flags? -- var="val"
#
__read-env-line()
shspec::expect::__read-env-line()
{
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--set()
shspec::expect::set()
{
local -ri shiftn="$2"
local -r envpath="$4"
shift "$shiftn"
# ensure envpath is available
__chk-shiftn 4 "$shiftn"
shspec::_chk-shiftn 4 "$shiftn"
# no flag expectation
__expect-env '' "$@"
shspec::expect::__env '' "$@"
}
##
# Alias for `set`
#
_expect--declare()
shspec::expect::declare()
{
_expect--set "$@"
shspec::expect::set "$@"
}
@ -118,16 +118,16 @@ _expect--declare()
#
# Same syntax as `set`
#
_expect--export()
shspec::expect::export()
{
local -ri shiftn="$2"
local -r envpath="$4"
shift "$shiftn"
# ensure envpath is available
__chk-shiftn 4 "$shiftn"
shspec::_chk-shiftn 4 "$shiftn"
# expect the -x flag, which denotes export
__expect-env x "$@"
shspec::expect::__env x "$@"
}

View File

@ -45,7 +45,7 @@ exec 99<>/dev/null
#
# This command is successful if and only if both the remainder clause and
# the provided command line complete successfully.
__expect-output-cmd()
shspec::expect::__output-cmd()
{
local -r cmd="$1"
shift
@ -62,11 +62,11 @@ __expect-output-cmd()
local nl
local intype
{
__expect-output-clause "${clause[@]}" | {
shspec::expect::__output-clause "${clause[@]}" | {
IFS=\| read nl intype
if [ "$intype" == stderr ]; then
__chk-shiftn 3 "$shiftn"
shspec::_chk-shiftn 3 "$shiftn"
exec 99<"$stderr"
fi
@ -78,7 +78,7 @@ __expect-output-cmd()
}
# parses output remainder clause according to the aforementioned rules
__expect-output-clause()
shspec::expect::__output-clause()
{
[ $# -gt 0 ] || return 0
@ -88,7 +88,7 @@ __expect-output-clause()
if [[ "$1 $2" =~ ^on\ std(err|out) ]]; then
[ "$2" == stderr ] && input="$2"
else
_bail_clause output "$*"
shspec::bail-clause output "$*"
fi
fi
@ -105,7 +105,7 @@ __expect-output-clause()
#
# This expectation assumes a trailing newline by default; this behavior can
# be suppressed with the `without newline' clause.
_expect--output()
shspec::expect::output()
{
local -a args=("$@")
local -i shiftn="$2"
@ -122,10 +122,11 @@ _expect--output()
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 cmp="$2"
@ -139,12 +140,12 @@ __expect--output-do()
##
# Expects that stdout matches the provided extended regular expression (as
# 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"
[[ "$(cat)" =~ $pat ]]
@ -153,13 +154,13 @@ __expect--match-do()
##
# Expects that both stdin and stderr (if available) are empty
_expect--silent()
shspec::expect::silent()
{
local -r stderr="${3:-/dev/null}"
shift "$2"
# 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
# it is non-empty

View File

@ -23,9 +23,9 @@ source spec.sh
declare -r tcase="${1?Missing test case path}"
_begin-spec
shspec::begin-spec
cd "$( dirname "$tcase" )" \
&& source "$tcase" \
|| exit $?
_end-spec
shspec::end-spec

View File

@ -38,7 +38,7 @@ declare -ir __SHIFTN=4
##
# Attempts to make tempoary path in /dev/shm, falling back to default
mktemp-shm()
shspec::__mktemp-shm()
{
local -r shm=/dev/shm
[ -d $shm -a -r $shm ] && mktemp -p$shm || mktemp
@ -46,10 +46,10 @@ mktemp-shm()
# stderr file
declare -r __spec_errpath="$(mktemp-shm)"
readonly __spec_errpath="$(shspec::__mktemp-shm)"
# env dump file
declare -r __spec_envpath="$(mktemp-shm)"
readonly __spec_envpath="$(shspec::__mktemp-shm)"
# most recent expect result and its exit code
declare __spec_result=
@ -64,7 +64,7 @@ declare __spec_caller=
#
# A specification is any shell script using the specification commands
# defined herein.
_begin-spec()
shspec::begin-spec()
{
: placeholder
}
@ -75,7 +75,7 @@ _begin-spec()
#
# If the specification was improperly nested, this will output a list of
# 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
_sstack-empty && return 0
@ -128,9 +128,10 @@ end()
# some statements are implicitly terminated; explicitly doing so is
# indicitive of a syntax issue
[ "${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'"
_sstack-pop >/dev/null || shspec::bail "unmatched \`end'"
}
@ -160,12 +161,13 @@ to()
{
__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)
_sstack-pop
__handle-to "$__spec_rexit" $__SHIFTN \
shspec::__handle-to "$__spec_rexit" $__SHIFTN \
"$__spec_errpath" "$__spec_envpath" "$@" \
|| fail "$*"
@ -181,7 +183,7 @@ to()
#
# <exit code> <shiftn> <...N> <expect type> <...remainder clause>
#
__handle-to()
shspec::__handle-to()
{
local -ri rexit="$1"
local -ri shiftn="$2"
@ -192,9 +194,9 @@ __handle-to()
local -r type="$1"
shift
local -r assert="_expect--$type"
local -r assert="shspec::expect::$type"
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
# to place $1 at the remainder clause, third is the path to the stderr
@ -210,7 +212,7 @@ __handle-to()
# Alias for _handle-to
#
# Shows intent to proxy a call and allows proxy implementation to vary.
_proxy-to() { __handle-to "$@"; }
shspec::proxy-to() { shspec::__handle-to "$@"; }
##
@ -249,7 +251,7 @@ fail()
echo " exit code: $__spec_rexit"
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
# spec caller, if any.
_bail()
shspec::bail()
{
local -r msg="$1"
local line="$2"

View File

@ -148,7 +148,8 @@ _sstack-assert-within()
local -r head="$(_sstack-head-type)"
[ "$head" == "$in" ] \
|| _bail "\`$chk' must $phrase \`$head'; found \`$head' at $file:$line"
|| shspec::bail \
"\`$chk' must $phrase \`$head'; found \`$head' at $file:$line"
}

View File

@ -21,16 +21,16 @@
describe be
it cannot stand alone
expect _expect--be 0 2
expect shspec::expect::be 0 2
to fail
end
it processes remainder clause as if it did not exist
(
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
)
end
@ -39,12 +39,12 @@ end
describe succeed
it will succeed when command exits with status code 0
expect _expect--succeed 0 2
expect shspec::expect::succeed 0 2
to succeed
end
it will fail when command exits with non-zero status code
expect _expect--succeed 1 2
expect shspec::expect::succeed 1 2
to fail
end
end
@ -52,12 +52,12 @@ end
describe fail
it will succeed when command exits with non-zero status code
expect _expect--fail 1 2
expect shspec::expect::fail 1 2
to succeed
end
it will fail when command exits with status code 0
expect _expect--fail 0 2
expect shspec::expect::fail 0 2
to fail
end
end
@ -66,11 +66,11 @@ end
describe not
it will invert the result of an expectation
# exit code of 1, so normally `succeed' would fail
expect _expect--not 1 2 succeed
expect shspec::expect::not 1 2 succeed
to 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
end
end
@ -78,49 +78,50 @@ end
describe output
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
end
# by convention, stderr file passed as third argument
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
to succeed
} 3< <( echo "test stderr" )
end
it fails on stdout mismatch
expect _expect--output 0 2 "foo" <<< "bar"
expect shspec::expect::output 0 2 "foo" <<< "bar"
to fail
end
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
} 3< <( echo bar )
end
it ignores exit code
expect _expect--output 1 2 "foo" <<< "foo"
expect shspec::expect::output 1 2 "foo" <<< "foo"
to succeed
end
# as is good practice for Unix utilities
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
end
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
end
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
end
end
@ -128,33 +129,33 @@ end
describe match
it will default to asserting against stdout
expect _expect--match 0 2 "foo" <<< "foo"
expect shspec::expect::match 0 2 "foo" <<< "foo"
to succeed
end
# by convention, stderr file passed as third argument
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
} 3< <( echo "test stderr" )
end
it ignores exit code
expect _expect--match 1 2 "foo" <<< "foo"
expect shspec::expect::match 1 2 "foo" <<< "foo"
to succeed
end
it will perform partial match
expect _expect--match 0 2 "foo" <<< "contains foo"
expect shspec::expect::match 0 2 "foo" <<< "contains foo"
to succeed
end
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
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
end
end
@ -163,32 +164,32 @@ end
describe silent
it succeeds when both stdout and stderr are empty
# omitting stderr arg
expect _expect--silent 0 2 < <(:)
expect shspec::expect::silent 0 2 < <(:)
to succeed
# empty stderr
expect _expect--silent 0 3 <(:) < <(:)
expect shspec::expect::silent 0 3 <(:) < <(:)
to succeed
end
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
end
it fails when stderr is empty but stdout is not
# omitting stderr arg
expect _expect--silent 0 2 <<< ""
expect shspec::expect::silent 0 2 <<< ""
to fail
# empty stderr
expect _expect--silent 0 3 <(:) <<< ""
expect shspec::expect::silent 0 3 <(:) <<< ""
to fail
end
# no arguments within context of the DSL, that is
it accepts no arguments
expect _expect--silent 0 2 foo < <(:)
expect shspec::expect::silent 0 2 foo < <(:)
to fail
end
end

View File

@ -31,7 +31,7 @@ declare -- nonexport_empty=""'
declare curchk
function setchk()
{
_expect--$curchk 0 4 <(:) <( echo "$stubenv" ) "$@"
shspec::expect::$curchk 0 4 <(:) <( echo "$stubenv" ) "$@"
}

View File

@ -38,9 +38,9 @@ test-run()
}
describe _begin-spec
describe shspec::begin-spec
it is a placeholder that exits successfully
expect _begin-spec
expect shspec::begin-spec
to succeed
end
end
@ -149,7 +149,7 @@ describe expect
it is provided premise exit code as first argument
expect test-run <<< '
declare excode=123
_expect--chk() { test "$1" -eq $excode; }
shspec::expect::chk() { test "$1" -eq $excode; }
describe foo
it exposes exit code
@ -165,7 +165,7 @@ describe expect
it is provided remainder clause after shift argument
expect test-run <<< '
declare remain="a b c"
_expect--chk()
shspec::expect::chk()
{
shift "$2"
test "$*" == "$remain"
@ -183,7 +183,7 @@ describe expect
it receives premise output via stdin
expect test-run <<< '
declare str=foo
_expect--chk() { test "$(cat)" == "$str"; }
shspec::expect::chk() { test "$(cat)" == "$str"; }
describe foo
it pipes command output
@ -198,7 +198,7 @@ describe expect
# newline will be added; we don't want that!
it does not have newline added to premise output if missing
expect test-run <<< '
_expect--chk() { test "$( wc -c )" -eq 0; }
shspec::expect::chk() { test "$( wc -c )" -eq 0; }
describe foo
it should not add newline
@ -308,18 +308,18 @@ describe expect
end
describe _proxy-to
describe shspec::proxy-to
it proxies remainder clause with variable shift length
expect test-run <<< '
expected="foo bar baz"
_expect--chk() { shift "$2"; test "$*" == "$expected"; }
shspec::expect::chk() { shift "$2"; test "$*" == "$expected"; }
describe foo
it should succeed
expect _proxy-to 0 2 chk $expected
expect shspec::proxy-to 0 2 chk $expected
to succeed
expect _proxy-to 0 3 /dev/null chk $expected
expect shspec::proxy-to 0 3 /dev/null chk $expected
to succeed
end
end