2 # Copyright (c) 2009 Eric Wong <normalperson@yhbt.net>
4 # TAP-producing shell library for POSIX-compliant Bourne shells We do
5 # not _rely_ on Bourne Again features, though we will use "set -o
6 # pipefail" from ksh93 or bash 3 if available
8 # Only generic, non-project/non-language-specific stuff goes here. We
9 # only have POSIX dependencies for the core tests (without --verbose),
10 # though we'll enable useful non-POSIX things if they're available.
12 # This test library is intentionally unforgiving, it does not support
13 # skipping tests nor continuing after any failure. Any failures
14 # immediately halt execution as do any references to undefined
17 # When --verbose is specified, we always prefix stdout/stderr
18 # output with "#" to avoid confusing TAP consumers. Otherwise
19 # the normal stdout/stderr streams are redirected to /dev/null
21 # dup normal stdout(fd=1) and stderr (fd=2) to fd=3 and fd=4 respectively
22 # normal TAP output goes to fd=3, nothing should go to fd=4
25 # ensure a sane environment
26 TZ
=UTC LC_ALL
=C LANG
=C
30 # pipefail is non-POSIX, but very useful in ksh93/bash
31 ( set -o pipefail
2>/dev
/null
) && set -o pipefail
35 # Unlike other test frameworks, we are unforgiving and bail immediately
36 # on any failures. We do this because we're lazy about error handling
37 # and also because we believe anything broken should not be allowed to
38 # propagate throughout the rest of the test
50 # list of files to remove unconditionally on exit
53 # list of files to remove only on successful exit
56 # emit output to stdout, it'll be parsed by the TAP consumer
57 # so it must be TAP-compliant output
62 # emits non-parsed information to stdout, it will be prefixed with a '#'
63 # to not throw off TAP consumers
68 # exit with an error and print a diagnostic
74 # our at_exit handler, it'll fire for all exits except SIGKILL (unavoidable)
81 t_info
"t_done not called"
84 elif test -n "$t_current"
86 t_echo
"not ok $t_nr - $t_current"
88 if test $t_expect_nr -ne -1
90 test $t_expect_nr -eq $t_nr ||
{
91 t_info
"planned $t_expect_nr tests but ran $t_nr"
92 test $code -ne 0 || code
=1
96 t_info
"unexpected test failure"
97 test $code -ne 0 || code
=1
100 test $code -eq 0 && rm -f $T_OK_RM_LIST
107 # close test-specific extra file descriptors
112 # call this at the start of your test to specify the number of tests
115 test "$1" -ge 1 || die
"must plan at least one test"
116 test $t_expect_nr -eq -1 || die
"tried to plan twice in one test"
119 t_echo
1..
$t_expect_nr "#" "$@"
124 test $t_expect_nr -le 0 && die
"no tests planned"
125 test -n "$t_current" && t_echo
"ok $t_nr - $t_current"
129 # finalizes any previously test and starts a new one
132 t_nr
=$
(( $t_nr + 1 ))
135 # just in case somebody wanted to cheat us:
139 # finalizes the current test without starting a new one
145 # run this to signify the end of your test
150 test $t_expect_nr -eq $t_nr ||
exit 1
154 # create and assign named-pipes to variable _names_ passed to this function
159 _tmp
=$
(mktemp
-t $T.$$.
$_id.XXXXXXXX
)
163 T_RM_LIST
="$T_RM_LIST $_tmp"
167 t_verbose
=false t_trace
=false
169 while test "$#" -ne 0
174 -v|
--verbose) t_verbose
=true
;;
175 --trace) t_trace
=true t_verbose
=true
;;
176 *) die
"Unknown option: $arg" ;;
180 # we always only setup stdout, nothing should end up in the "real" stderr
183 if test x
"$(which mktemp 2>/dev/null)" = x
185 die
"mktemp(1) not available for --verbose"
187 t_fifos t_stdout t_stderr
190 # use a subshell so seds are not waitable
191 $SED -e 's/^/#: /' < $t_stdout &
192 $SED -e 's/^/#! /' < $t_stderr &
195 exec > $t_stdout 2> $t_stderr
197 exec > /dev
/null
2> /dev
/null