tests: work around strangeness in MSYS
[automake.git] / tests / tap-functions.sh
blobe8ce8761127928b225a6cb933ea5b8cffbf875c6
1 # -*- shell-script -*-
3 # Copyright (C) 2011 Free Software Foundation, Inc.
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2, or (at your option)
8 # any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 # Helper functions used by TAP-producing tests of the Automake testsuite.
21 # IMPORTANT: All the functions defined in this file can *not* be used
22 # from within a subshell, unless explicitly noted otherwise.
25 # The counts of the TAP test results seen so far: total count and
26 # per-result counts.
27 tap_count_=0
28 tap_pass_count_=0
29 tap_skip_count_=0
30 tap_fail_count_=0
31 tap_xfail_count_=0
32 tap_xpass_count_=0
34 # The first "test -n" tries to avoid extra forks when possible.
35 if test -n "${ZSH_VERSION}${BASH_VERSION}" \
36 || (eval 'test $((1 + 1)) = 2') >/dev/null 2>&1
37 then
38 # Outer use of 'eval' needed to protect dumber shells from parsing
39 # errors.
40 eval 'incr_ () { eval "$1=\$((\${$1} + 1))"; }'
41 else
42 incr_ () { eval "$1=\`expr \${$1} + 1\`"; }
45 # not COMMAND [ARGS...]
46 # ---------------------
47 # Run the given command and invert its exit status.
48 not ()
50 if "$@"; then return 1; else return 0; fi
53 # plan_ [unknown|later|lazy|now|NUMBER-OF-PLANNED-TESTS]
54 # ------------------------------------------------------
55 # Print a TAP plan for the given number of tests. This must be called
56 # before reporting any test result. If called with the special argument
57 # "unknown" or "later", it will do nothing, expecting the calling script
58 # to declare the plan later. If called with the special argument "lazy"
59 # or "now", it will print a TAP plan that accounts for the number of tests
60 # seen so far.
61 plan_ ()
63 if test $# -eq 0; then
64 bailout_ "plan_: missing argument"
65 elif test $# -ge 2; then
66 bailout_ "plan_: too many arguments"
67 elif test x"$1" = x"unknown" || test x"$1" = x"later"; then
68 : No-op.
69 elif test x"$1" = x"lazy" || test x"$1" = x"now"; then
70 echo "1..$tap_count_" # Number of test results seen so far.
71 have_tap_plan_=yes
72 elif test $1 -ge 0; then
73 echo "1..$1"
74 have_tap_plan_=yes
75 else
76 bailout_ "plan_: invalid argument '$1'"
79 have_tap_plan_=no # Avoid interferences from the environment.
81 # diag_ [EXPLANATION]
82 # ------------------
83 # Report the given text as TAP diagnostic. Assumes the string denoting
84 # TAP diagnostic lines is stored in the `$diag_string_' variable; this is
85 # done to allow better interplay with TAP drivers that allow such a string
86 # to be configured.
87 diag_ ()
89 test $# -eq 0 || echo "$diag_string_ $*"
92 # Used by the `diag_' function above. User-overridable.
93 diag_string_="#"
95 # warn_ [EXPLANATION]
96 # ------------------
97 # Give a warning (using TAP diagnostic).
98 warn_ ()
100 case $# in
101 0) diag_ "WARNING: (unknown warning)";;
102 *) diag_ "WARNING: $*";;
103 esac
106 # result_ RESULT [-D DIRECTIVE] [-r REASON] [--] [DESCRIPTION...]
107 # ---------------------------------------------------------------
108 # Report a test case with the given RESULT (valid values are "ok" and
109 # "not ok") and the given DESCRIPTION (if any). If DIRECTIVE is given
110 # and non-empty (valid values being "TODO" and "SKIP"), it will be
111 # reported too, with the REASON (if given) appended.
112 result_ ()
114 set +x # Don't pollute the log files.
115 test $# -gt 0 || bailout_ "result_: missing argument"
116 tap_result_=$1; shift
117 case $tap_result_ in
118 "ok"|"not ok") ;;
119 *) bailout_ "result_: invalid result '$tap_result'" ;;
120 esac
121 tap_directive_= tap_reason_=
122 while test $# -gt 0; do
123 case $1 in
124 -D|--directive) tap_directive_=$2; shift;;
125 -r|--reason) tap_reason_=$2; shift;;
126 --) shift; break;;
127 -*) bailout_ "result_: invalid option '$1'";;
128 *) break;;
129 esac
130 shift
131 done
132 case $tap_directive_ in
133 ""|TODO|SKIP) ;;
134 *) bailout_ "result_: invalid directive '$directive_'" ;;
135 esac
136 incr_ tap_count_
137 case $tap_result_,$tap_directive_ in
138 ok,) incr_ tap_pass_count_;; # Passed.
139 not\ ok,TODO) incr_ tap_xfail_count_;; # Expected failure.
140 not\ ok,*) incr_ tap_fail_count_ ;; # Failed.
141 ok,TODO) incr_ tap_xpass_count_ ;; # Unexpected pass.
142 ok,SKIP) incr_ tap_skip_count_ ;; # Skipped.
143 *) bailout_ "internal error in 'result_'";; # Can't happen.
144 esac
145 tap_text_="$tap_result_ $tap_count_"
146 if test x"$*" != x; then
147 tap_text_="$tap_text_ - $*"
149 if test x"$tap_directive_" != x; then
150 tap_text_="$tap_text_ # $tap_directive_"${tap_reason_:+" $tap_reason_"}
152 printf '%s\n' "$tap_text_"
153 set -x # Restore shell xtraces.
156 # Shorthands for common usages of `result_'.
157 ok_ () { result_ 'ok' ${1+"$@"}; }
158 not_ok_ () { result_ 'not ok' ${1+"$@"}; }
159 skip_ () { result_ 'ok' -D SKIP ${1+"$@"}; }
161 # skip_row_ COUNT [-r REASON] [--] [DESCRIPTION...]
162 # -------------------------------------------------
163 # Report a COUNT of skipped test, with the given reason and descriptions
164 # (if any). Useful to avoid cascade failures in case a fair number of
165 # tests depend on an earlier one that failed.
166 skip_row_ ()
168 skip_count_=$1; shift
169 for i_ in `seq_ $skip_count_`; do skip_ ${1+"$@"}; done
172 # skip_all_ [REASON ...]
173 # ----------------------
174 # Skip all the tests in a test script. Must be used before calling `plan_'
175 # or reporting any test result. Can't be used from within a subshell.
176 skip_all_ ()
178 echo "1..0 # SKIP" ${1+"$@"}
179 have_tap_plan_=yes
180 Exit 0
183 # bailout_ [REASON ...]
184 # ---------------------
185 # Stop the execution of the current test suite right now, due to an
186 # unrecoverable error. Can be called at any point, but cannot be used
187 # from within a subshell.
188 bailout_ ()
190 echo 'Bail out!' ${1+"$@"}
191 Exit 99
194 # fatal_ [REASON ...]
195 # -------------------
196 # Same as `bailout_'; for compatibility with `plain-functions.sh'.
197 fatal_ ()
199 bailout_ ${1+"$@"}
202 # framework_failure_ [REASON ...]
203 # -------------------------------
204 # Stop the execution of the current test suite right now, due to an
205 # unrecoverable error in the set-up of the test case. Can be called
206 # at any point, but cannot be used from within a subshell.
207 framework_failure_ ()
209 bailout_ "set-up failure"${1+": $*"}
212 # command_ok_ TEST-DESCRIPTION [OPTIONS..] [--] CMD [ARGS...]
213 # -----------------------------------------------------------
214 # Helper subroutine for when a TAP result must be determined by the
215 # outcome of a command.
216 command_ok_ ()
218 tap_directive_= tap_reason_=
219 test $# -gt 0 || bailout_ "command_ok_: missing argument"
220 tap_description_=$1; shift
221 while test $# -gt 0; do
222 case $1 in
223 -D|--directive) tap_directive_=$2; shift;;
224 -r|--reason) tap_reason_=$2; shift;;
225 --) shift; break;;
226 -*) bailout_ "command_ok_: invalid option '$1'";;
227 *) break;;
228 esac
229 shift
230 done
231 tap_result_="ok"; "$@" || tap_result_="not ok"
232 result_ "$tap_result_" -D "$tap_directive_" -r "$tap_reason_" \
233 -- "$tap_description_"