Remove unneeded fwd declaration
[libside.git] / tests / utils / tap.sh
CommitLineData
82abd52d
MJ
1#!/bin/bash
2#
3# SPDX-License-Identifier: GPL-3.0-or-later
4# SPDX-FileCopyrightText: 2010 Patrick LeBoutillier <patrick.leboutillier@gmail.com>
5
6_version='1.01'
7
8_plan_set=0
9_no_plan=0
10_skip_all=0
11_test_died=0
12_expected_tests=0
13_executed_tests=0
14_failed_tests=0
15TODO=
16
17
18usage(){
19 cat <<'USAGE'
20tap-functions: A TAP-producing BASH library
21
22PLAN:
23 plan_no_plan
24 plan_skip_all [REASON]
25 plan_tests NB_TESTS
26
27TEST:
28 ok RESULT [NAME]
29 okx COMMAND
30 is RESULT EXPECTED [NAME]
31 isnt RESULT EXPECTED [NAME]
32 like RESULT PATTERN [NAME]
33 unlike RESULT PATTERN [NAME]
34 pass [NAME]
35 fail [NAME]
36
37SKIP:
38 skip [CONDITION] [REASON] [NB_TESTS=1]
39
40 skip $feature_not_present "feature not present" 2 || {
41 is $a "a"
42 is $b "b"
43 }
44
45TODO:
46 Specify TODO mode by setting $TODO:
47 TODO="not implemented yet"
48 ok $result "some not implemented test"
49 unset TODO
50
51OTHER:
52 diag MSG
53
54EXAMPLE:
55 #!/bin/bash
56
57 . tap-functions
58
59 plan_tests 7
60
61 me=$USER
62 is $USER $me "I am myself"
63 like $HOME $me "My home is mine"
64 like "`id`" $me "My id matches myself"
65
66 /bin/ls $HOME 1>&2
67 ok $? "/bin/ls $HOME"
68 # Same thing using okx shortcut
69 okx /bin/ls $HOME
70
71 [[ "`id -u`" != "0" ]]
72 i_am_not_root=$?
73 skip $i_am_not_root "Must be root" || {
74 okx ls /root
75 }
76
77 TODO="figure out how to become root..."
78 okx [ "$HOME" == "/root" ]
79 unset TODO
80USAGE
81 exit
82}
83
84opt=
85set_u=
86while getopts ":sx" opt ; do
87 case $_opt in
88 u) set_u=1 ;;
89 *) usage ;;
90 esac
91done
92shift $(( OPTIND - 1 ))
93# Don't allow uninitialized variables if requested
94[[ -n "$set_u" ]] && set -u
95unset opt set_u
96
97# Used to call _cleanup on shell exit
98trap _exit EXIT
99
100
101plan_no_plan(){
102 (( _plan_set != 0 )) && "You tried to plan twice!"
103
104 _plan_set=1
105 _no_plan=1
106
107 return 0
108}
109
110
111plan_skip_all(){
112 local reason=${1:-''}
113
114 (( _plan_set != 0 )) && _die "You tried to plan twice!"
115
116 _print_plan 0 "Skip $reason"
117
118 _skip_all=1
119 _plan_set=1
120 _exit 0
121
122 return 0
123}
124
125plan_tests(){
126 local tests=${1:?}
127
128 (( _plan_set != 0 )) && _die "You tried to plan twice!"
129 (( tests == 0 )) && _die "You said to run 0 tests! You've got to run something."
130
131 _print_plan $tests
132 _expected_tests=$tests
133 _plan_set=1
134
135 return $tests
136}
137
138
139_print_plan(){
140 local tests=${1:?}
141 local directive=${2:-''}
142
143 echo -n "1..$tests"
144 [[ -n "$directive" ]] && echo -n " # $directive"
145 echo
146}
147
148
149pass(){
150 local name=$1
151 ok 0 "$name"
152}
153
154
155fail(){
156 local name=$1
157 ok 1 "$name"
158}
159
160# This is the workhorse method that actually
161# prints the tests result.
162ok(){
163 local result=${1:?}
164 local name=${2:-''}
165
166 (( _plan_set == 0 )) && _die "You tried to run a test without a plan! Gotta have a plan."
167
168 _executed_tests=$(( $_executed_tests + 1 ))
169
170 if [[ -n "$name" ]] ; then
171 if _matches "$name" "^[0-9]+$" ; then
172 diag " You named your test '$name'. You shouldn't use numbers for your test names."
173 diag " Very confusing."
174 fi
175 fi
176
177 if (( result != 0 )) ; then
178 echo -n "not "
179 _failed_tests=$(( _failed_tests + 1 ))
180 fi
181 echo -n "ok $_executed_tests"
182
183 if [[ -n "$name" ]] ; then
184 local ename=${name//\#/\\#}
185 echo -n " - $ename"
186 fi
187
188 if [[ -n "$TODO" ]] ; then
189 echo -n " # TODO $TODO" ;
190 if (( result != 0 )) ; then
191 _failed_tests=$(( _failed_tests - 1 ))
192 fi
193 fi
194
195 echo
196 if (( result != 0 )) ; then
197 local file='tap-functions'
198 local func=
199 local line=
200
201 local i=0
202 local bt=$(caller $i)
203 while _matches "$bt" "tap-functions$" ; do
204 i=$(( $i + 1 ))
205 bt=$(caller $i)
206 done
207 local backtrace=
208 eval $(caller $i | (read line func file ; echo "backtrace=\"$file:$func() at line $line.\""))
209
210 local t=
211 [[ -n "$TODO" ]] && t="(TODO) "
212
213 if [[ -n "$name" ]] ; then
214 diag " Failed ${t}test '$name'"
215 diag " in $backtrace"
216 else
217 diag " Failed ${t}test in $backtrace"
218 fi
219 fi
220
221 return $result
222}
223
224
225okx(){
226 local command="$@"
227
228 local line=
229 diag "Output of '$command':"
230 "$@" | while read line ; do
231 diag "$line"
232 done
233 ok ${PIPESTATUS[0]} "$command"
234}
235
236
237_equals(){
238 local result=${1:?}
239 local expected=${2:?}
240
241 if [[ "$result" == "$expected" ]] ; then
242 return 0
243 else
244 return 1
245 fi
246}
247
248
249# Thanks to Aaron Kangas for the patch to allow regexp matching
250# under bash < 3.
251 _bash_major_version=${BASH_VERSION%%.*}
252_matches(){
253 local result=${1:?}
254 local pattern=${2:?}
255
256 if [[ -z "$result" || -z "$pattern" ]] ; then
257 return 1
258 else
259 if (( _bash_major_version >= 3 )) ; then
260 [[ "$result" =~ "$pattern" ]]
261 else
262 echo "$result" | egrep -q "$pattern"
263 fi
264 fi
265}
266
267
268_is_diag(){
269 local result=${1:?}
270 local expected=${2:?}
271
272 diag " got: '$result'"
273 diag " expected: '$expected'"
274}
275
276
277is(){
278 local result=${1:?}
279 local expected=${2:?}
280 local name=${3:-''}
281
282 _equals "$result" "$expected"
283 (( $? == 0 ))
284 ok $? "$name"
285 local r=$?
286 (( r != 0 )) && _is_diag "$result" "$expected"
287 return $r
288}
289
290
291isnt(){
292 local result=${1:?}
293 local expected=${2:?}
294 local name=${3:-''}
295
296 _equals "$result" "$expected"
297 (( $? != 0 ))
298 ok $? "$name"
299 local r=$?
300 (( r != 0 )) && _is_diag "$result" "$expected"
301 return $r
302}
303
304
305like(){
306 local result=${1:?}
307 local pattern=${2:?}
308 local name=${3:-''}
309
310 _matches "$result" "$pattern"
311 (( $? == 0 ))
312 ok $? "$name"
313 local r=$?
314 (( r != 0 )) && diag " '$result' doesn't match '$pattern'"
315 return $r
316}
317
318
319unlike(){
320 local result=${1:?}
321 local pattern=${2:?}
322 local name=${3:-''}
323
324 _matches "$result" "$pattern"
325 (( $? != 0 ))
326 ok $? "$name"
327 local r=$?
328 (( r != 0 )) && diag " '$result' matches '$pattern'"
329 return $r
330}
331
332
333skip(){
334 local condition=${1:?}
335 local reason=${2:-''}
336 local n=${3:-1}
337
338 if (( condition == 0 )) ; then
339 local i=
340 for (( i=0 ; i<$n ; i++ )) ; do
341 _executed_tests=$(( _executed_tests + 1 ))
342 echo "ok $_executed_tests # skip: $reason"
343 done
344 return 0
345 else
346 return
347 fi
348}
349
350
351diag(){
352 local msg=${1:?}
353
354 if [[ -n "$msg" ]] ; then
355 echo "# $msg"
356 fi
357
358 return 1
359}
360
361
362_die(){
363 local reason=${1:-'<unspecified error>'}
364
365 echo "$reason" >&2
366 _test_died=1
367 _exit 255
368}
369
370
371BAIL_OUT(){
372 local reason=${1:-''}
373
374 echo "Bail out! $reason" >&2
375 _exit 255
376}
377
378
379_cleanup(){
380 local rc=0
381
382 if (( _plan_set == 0 )) ; then
383 diag "Looks like your test died before it could output anything."
384 return $rc
385 fi
386
387 if (( _test_died != 0 )) ; then
388 diag "Looks like your test died just after $_executed_tests."
389 return $rc
390 fi
391
392 if (( _skip_all == 0 && _no_plan != 0 )) ; then
393 _print_plan $_executed_tests
394 fi
395
396 local s=
397 if (( _no_plan == 0 && _expected_tests < _executed_tests )) ; then
398 s= ; (( _expected_tests > 1 )) && s=s
399 local extra=$(( _executed_tests - _expected_tests ))
400 diag "Looks like you planned $_expected_tests test$s but ran $extra extra."
401 rc=1 ;
402 fi
403
404 if (( _no_plan == 0 && _expected_tests > _executed_tests )) ; then
405 s= ; (( _expected_tests > 1 )) && s=s
406 diag "Looks like you planned $_expected_tests test$s but only ran $_executed_tests."
407 fi
408
409 if (( _failed_tests > 0 )) ; then
410 s= ; (( _failed_tests > 1 )) && s=s
411 diag "Looks like you failed $_failed_tests test$s of $_executed_tests."
412 fi
413
414 return $rc
415}
416
417
418_exit_status(){
419 if (( _no_plan != 0 || _plan_set == 0 )) ; then
420 return $_failed_tests
421 fi
422
423 if (( _expected_tests < _executed_tests )) ; then
424 return $(( _executed_tests - _expected_tests ))
425 fi
426
427 return $(( _failed_tests + ( _expected_tests - _executed_tests )))
428}
429
430
431_exit(){
432 local rc=${1:-''}
433 if [[ -z "$rc" ]] ; then
434 _exit_status
435 rc=$?
436 fi
437
438 _cleanup
439 local alt_rc=$?
440 (( alt_rc != 0 )) && rc=$alt_rc
441 trap - EXIT
442 exit $rc
443}
This page took 0.054104 seconds and 4 git commands to generate.