Extracted output expectations into separate source file
parent
914dafc62a
commit
d0e508c2f5
127
src/expect-core
127
src/expect-core
|
@ -22,10 +22,7 @@
|
||||||
[ -z $__INC_EXPECT_CORE ] || return
|
[ -z $__INC_EXPECT_CORE ] || return
|
||||||
__INC_EXPECT_CORE=1
|
__INC_EXPECT_CORE=1
|
||||||
|
|
||||||
source util
|
source expect/output
|
||||||
|
|
||||||
# reserved for our uses
|
|
||||||
exec 99<>/dev/null
|
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
|
@ -69,125 +66,3 @@ _expect--be() { _proxy-to "$@"; }
|
||||||
_expect--succeed() { test "$1" -eq 0; }
|
_expect--succeed() { test "$1" -eq 0; }
|
||||||
_expect--fail() { test "$1" -ne 0; }
|
_expect--fail() { test "$1" -ne 0; }
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
# Expect that the given string is output on stdout or stderr
|
|
||||||
#
|
|
||||||
# Defaults to asserting against stdout; behavior may be overridden with the
|
|
||||||
# `on stderr' clause. Specifying `on stdout' may be used for clarity, but is
|
|
||||||
# redundant.
|
|
||||||
#
|
|
||||||
# This expectation assumes a trailing newline by default; this behavior can
|
|
||||||
# be suppressed with the `without newline' clause.
|
|
||||||
_expect--output()
|
|
||||||
{
|
|
||||||
local -a args=("$@")
|
|
||||||
local -i shiftn="$2"
|
|
||||||
shift "$shiftn"
|
|
||||||
local -r cmp="$1"
|
|
||||||
shift
|
|
||||||
local nl
|
|
||||||
|
|
||||||
if [ $# -gt 0 ]; then
|
|
||||||
# this is not a common clause; process before generic parsing
|
|
||||||
if [ "$1 $2" == 'without newline' ]; then
|
|
||||||
nl=-n
|
|
||||||
unset args[$shiftn+1], args[$shiftn+2]
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
__expect--output-cmd "__expect--output-do -$nl" "${args[@]}"
|
|
||||||
}
|
|
||||||
|
|
||||||
__expect--output-do()
|
|
||||||
{
|
|
||||||
local -r nl="${1:1}"
|
|
||||||
local -r cmp="$2"
|
|
||||||
|
|
||||||
# we will eventually be interested in this output
|
|
||||||
# TODO: fast check first, diff if non-match
|
|
||||||
diff <( echo $nl "$cmp" ) -
|
|
||||||
}
|
|
||||||
|
|
||||||
__expect--output-cmd()
|
|
||||||
{
|
|
||||||
local -r cmd="$1"
|
|
||||||
shift
|
|
||||||
|
|
||||||
local -ri shiftn="$2"
|
|
||||||
local -r stderr="$3"
|
|
||||||
shift "$shiftn"
|
|
||||||
|
|
||||||
# output-specific clauses
|
|
||||||
local -r cmp="$1"
|
|
||||||
shift
|
|
||||||
local -ar clause=("$@")
|
|
||||||
|
|
||||||
local nl
|
|
||||||
local intype
|
|
||||||
{
|
|
||||||
__expect--output-clause "${clause[@]}" | {
|
|
||||||
IFS=\| read nl intype
|
|
||||||
|
|
||||||
if [ "$intype" == stderr ]; then
|
|
||||||
__chk-shiftn 3 "$shiftn"
|
|
||||||
exec 99<"$stderr"
|
|
||||||
fi
|
|
||||||
|
|
||||||
$cmd "$cmp" <&99 &>/dev/null
|
|
||||||
}
|
|
||||||
} 99<&0
|
|
||||||
|
|
||||||
aok "${PIPESTATUS[@]}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# parses output remainder clause according to the aforementioned rules
|
|
||||||
__expect--output-clause()
|
|
||||||
{
|
|
||||||
[ $# -gt 0 ] || return 0
|
|
||||||
|
|
||||||
local input=
|
|
||||||
|
|
||||||
if [ $# -gt 0 ]; then
|
|
||||||
if [[ "$1 $2" =~ ^on\ std(err|out) ]]; then
|
|
||||||
[ "$2" == stderr ] && input="$2"
|
|
||||||
else
|
|
||||||
_bail_clause output "$*"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "$nl|$input"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
# Expects that stdout matches the provided extended regular expression (as
|
|
||||||
# in regex(3))
|
|
||||||
_expect--match()
|
|
||||||
{
|
|
||||||
__expect--output-cmd '__expect--match-do' "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
__expect--match-do()
|
|
||||||
{
|
|
||||||
local -r pat="$1"
|
|
||||||
[[ "$(cat)" =~ $pat ]]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
# Expects that both stdin and stderr (if available) are empty
|
|
||||||
_expect--silent()
|
|
||||||
{
|
|
||||||
local -r stderr="${3:-/dev/null}"
|
|
||||||
shift "$2"
|
|
||||||
|
|
||||||
# we accept no arguments
|
|
||||||
test $# -eq 0 || _bail_clause silent "$*"
|
|
||||||
|
|
||||||
# quick read using builtins; if we find any single byte, then we know that
|
|
||||||
# it is non-empty
|
|
||||||
read -N1 || read -N1 <"$stderr" || return 0
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,168 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Output expectations
|
||||||
|
#
|
||||||
|
# Copyright (C) 2014 Mike Gewitz
|
||||||
|
#
|
||||||
|
# This file is part of shspec.
|
||||||
|
#
|
||||||
|
# shspec is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
##
|
||||||
|
|
||||||
|
[ -z $__INC_EXPECT_OUTPUT ] || return
|
||||||
|
__INC_EXPECT_OUTPUT=1
|
||||||
|
|
||||||
|
source util
|
||||||
|
|
||||||
|
# reserved for our uses
|
||||||
|
exec 99<>/dev/null
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Generic output expectation processing
|
||||||
|
#
|
||||||
|
# This provides a generic facility for processing output on stdout or
|
||||||
|
# stderr, supporting `on std(err|out)' clauses.
|
||||||
|
#
|
||||||
|
# First processes remainder clause for common sub-clauses; any
|
||||||
|
# expectation-specific sub-clauses should therefore be processed and
|
||||||
|
# stripped beforehand to prevent errors.
|
||||||
|
#
|
||||||
|
# Assuming clause validity, determines (based on the clause) whether to
|
||||||
|
# assert against stdout or stderr, and then invokes the provided command
|
||||||
|
# line with an additional parameter representing the user-supplied
|
||||||
|
# comparison argument; stdout/stderr input is provided via stdin.
|
||||||
|
#
|
||||||
|
# This command is successful if and only if both the remainder clause and
|
||||||
|
# the provided command line complete successfully.
|
||||||
|
__expect-output-cmd()
|
||||||
|
{
|
||||||
|
local -r cmd="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
local -ri shiftn="$2"
|
||||||
|
local -r stderr="$3"
|
||||||
|
shift "$shiftn"
|
||||||
|
|
||||||
|
# output-specific clauses
|
||||||
|
local -r cmp="$1"
|
||||||
|
shift
|
||||||
|
local -ar clause=("$@")
|
||||||
|
|
||||||
|
local nl
|
||||||
|
local intype
|
||||||
|
{
|
||||||
|
__expect-output-clause "${clause[@]}" | {
|
||||||
|
IFS=\| read nl intype
|
||||||
|
|
||||||
|
if [ "$intype" == stderr ]; then
|
||||||
|
__chk-shiftn 3 "$shiftn"
|
||||||
|
exec 99<"$stderr"
|
||||||
|
fi
|
||||||
|
|
||||||
|
$cmd "$cmp" <&99 &>/dev/null
|
||||||
|
}
|
||||||
|
} 99<&0
|
||||||
|
|
||||||
|
aok "${PIPESTATUS[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# parses output remainder clause according to the aforementioned rules
|
||||||
|
__expect-output-clause()
|
||||||
|
{
|
||||||
|
[ $# -gt 0 ] || return 0
|
||||||
|
|
||||||
|
local input=
|
||||||
|
|
||||||
|
if [ $# -gt 0 ]; then
|
||||||
|
if [[ "$1 $2" =~ ^on\ std(err|out) ]]; then
|
||||||
|
[ "$2" == stderr ] && input="$2"
|
||||||
|
else
|
||||||
|
_bail_clause output "$*"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$nl|$input"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Expect that the given string is output on stdout or stderr
|
||||||
|
#
|
||||||
|
# Defaults to asserting against stdout; behavior may be overridden with the
|
||||||
|
# `on stderr' clause. Specifying `on stdout' may be used for clarity, but is
|
||||||
|
# redundant.
|
||||||
|
#
|
||||||
|
# This expectation assumes a trailing newline by default; this behavior can
|
||||||
|
# be suppressed with the `without newline' clause.
|
||||||
|
_expect--output()
|
||||||
|
{
|
||||||
|
local -a args=("$@")
|
||||||
|
local -i shiftn="$2"
|
||||||
|
shift "$shiftn"
|
||||||
|
local -r cmp="$1"
|
||||||
|
shift
|
||||||
|
local nl
|
||||||
|
|
||||||
|
if [ $# -gt 0 ]; then
|
||||||
|
# this is not a common clause; process before generic parsing
|
||||||
|
if [ "$1 $2" == 'without newline' ]; then
|
||||||
|
nl=-n
|
||||||
|
unset args[$shiftn+1], args[$shiftn+2]
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
__expect-output-cmd "__expect--output-do -$nl" "${args[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
__expect--output-do()
|
||||||
|
{
|
||||||
|
local -r nl="${1:1}"
|
||||||
|
local -r cmp="$2"
|
||||||
|
|
||||||
|
# we will eventually be interested in this output
|
||||||
|
# TODO: fast check first, diff if non-match
|
||||||
|
diff <( echo $nl "$cmp" ) -
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Expects that stdout matches the provided extended regular expression (as
|
||||||
|
# in regex(3))
|
||||||
|
_expect--match()
|
||||||
|
{
|
||||||
|
__expect-output-cmd '__expect--match-do' "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
__expect--match-do()
|
||||||
|
{
|
||||||
|
local -r pat="$1"
|
||||||
|
[[ "$(cat)" =~ $pat ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Expects that both stdin and stderr (if available) are empty
|
||||||
|
_expect--silent()
|
||||||
|
{
|
||||||
|
local -r stderr="${3:-/dev/null}"
|
||||||
|
shift "$2"
|
||||||
|
|
||||||
|
# we accept no arguments
|
||||||
|
test $# -eq 0 || _bail_clause silent "$*"
|
||||||
|
|
||||||
|
# quick read using builtins; if we find any single byte, then we know that
|
||||||
|
# it is non-empty
|
||||||
|
read -N1 || read -N1 <"$stderr" || return 0
|
||||||
|
return 1
|
||||||
|
}
|
Loading…
Reference in New Issue