diff --git a/src/expect-core b/src/expect-core index 50a18ff..a38c467 100644 --- a/src/expect-core +++ b/src/expect-core @@ -60,20 +60,57 @@ _expect--fail() { test "$1" -ne 0; } _expect--output() { - shift "$2" + local -ri nshift="$2" + local -r stderr="$3" + shift "$nshift" + + # output-specific clauses local -r cmp="$1" shift - local -r clause="$*" + local -ar clause=("$@") + + local nl + local intype + { + __expect--output-clause "${clause[@]}" | { + IFS=\| read nl intype + + if [ "$intype" == stderr ]; then + __chk-nshift 3 "$nshift" + exec 99<"$stderr" + fi + + # we will eventually be interested in this output + # TODO: fast check first, diff if non-match + diff <( echo $nl "$cmp" ) - <&99 &>/dev/null + } + } 99<&0 + + # long version in case pipefail isn't supported on the system + [ "${PIPESTATUS[0]}" -eq 0 -a "${PIPESTATUS[1]}" -eq 0 ] +} + +__expect--output-clause() +{ + [ $# -gt 0 ] || return 0 local nl= - if [ -n "$clause" ]; then - [ "$clause" == 'without newline' ] \ - && nl=-n \ - || _bail_clause output "$clause" + local input= + + if [ "$1 $2" == 'without newline' ]; then + nl=-n + shift 2 fi - # we will eventually be interested in this output - diff <( echo $nl "$cmp" ) - &>/dev/null + 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" } diff --git a/test/test-expect-core b/test/test-expect-core index 01e21dd..5856adf 100644 --- a/test/test-expect-core +++ b/test/test-expect-core @@ -52,16 +52,32 @@ describe output 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 \ + "test stderr" on stderr + to succeed + } 3< <( echo "test stderr" ) + end + + it fails on stdout mismatch + expect _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 + to fail + } 3< <( echo bar ) + end + it ignores exit code expect _expect--output 1 2 "foo" <<< "foo" to succeed end - it fails on output mismatch - expect _expect--output 0 2 "foo" <<< "bar" - to fail - end - # as is good practice for Unix utilities it expects trailing newline by default expect _expect--output 0 2 "foo" < <( echo -n foo )