1 # $Id: shunit2 277 2008-10-29 21:20:22Z kate.ward@forestent.com $
2 # vim:et:ft=sh:sts=2:sw=2
3 # vim:foldmethod=marker:foldmarker=/**,*/
6 # <?xml version="1.0" encoding="UTF-8"?>
7 # <s:shelldoc xmlns:s="http://www.forestent.com/projects/shelldoc/xsl/2005.0">
10 # Shell Unit Test Framework
12 # http://shunit2.googlecode.com/
14 # written by Kate Ward <kate.ward@forestent.com>
15 # released under the LGPL
17 # This module implements a xUnit based unit test framework similar to JUnit.
21 SHUNIT_VERSION='2.1.5'
27 _shunit_warn() { echo "shunit2:WARN $@" >&2; }
28 _shunit_error() { echo "shunit2:ERROR $@" >&2; }
29 _shunit_fatal() { echo "shunit2:FATAL $@" >&2; }
31 # specific shell checks
32 if [ -n "${ZSH_VERSION:-}" ]; then
33 setopt |grep "^shwordsplit$" >/dev/null
34 if [ $? -ne ${SHUNIT_TRUE} ]; then
35 _shunit_fatal 'zsh shwordsplit option is required for proper operation'
38 if [ -z "${SHUNIT_PARENT:-}" ]; then
39 _shunit_fatal "zsh does not pass \$0 through properly. please declare \
40 \"SHUNIT_PARENT=\$0\" before calling shUnit2"
49 __SHUNIT_ASSERT_MSG_PREFIX='ASSERT:'
50 __SHUNIT_PARENT=${SHUNIT_PARENT:-$0}
52 # set the constants readonly
53 shunit_constants_=`set |grep '^__SHUNIT_' |cut -d= -f1`
54 echo "${shunit_constants_}" |grep '^Binary file' >/dev/null \
55 && shunit_constants_=`set |grep -a '^__SHUNIT_' |cut -d= -f1`
56 for shunit_constant_ in ${shunit_constants_}; do
58 case ${ZSH_VERSION:-} in
59 '') ;; # this isn't zsh
60 [123].*) ;; # early versions (1.x, 2.x, 3.x)
61 *) shunit_ro_opts_='-g' ;; # all later versions. declare readonly globally
63 readonly ${shunit_ro_opts_} ${shunit_constant_}
65 unset shunit_constant_ shunit_constants_ shunit_ro_opts_
68 __shunit_skip=${SHUNIT_FALSE}
72 __shunit_testSuccess=${SHUNIT_TRUE}
74 __shunit_testsPassed=0
75 __shunit_testsFailed=0
78 __shunit_assertsTotal=0
79 __shunit_assertsPassed=0
80 __shunit_assertsFailed=0
81 __shunit_assertsSkipped=0
84 __shunit_reportGenerated=${SHUNIT_FALSE}
87 _SHUNIT_LINENO_='eval __shunit_lineno=""; if [ "${1:-}" = "--lineno" ]; then [ -n "$2" ] && __shunit_lineno="[$2] "; shift 2; fi'
89 #-----------------------------------------------------------------------------
94 # <s:function group="asserts">
95 # <entry align="right">
96 # <emphasis>void</emphasis>
101 # <funcdef><function>assertEquals</function></funcdef>
102 # <paramdef>string <parameter>[message]</parameter></paramdef>
103 # <paramdef>string <parameter>expected</parameter></paramdef>
104 # <paramdef>string <parameter>actual</parameter></paramdef>
107 # <para>Asserts that <emphasis>expected</emphasis> and
108 # <emphasis>actual</emphasis> are equal to one another. The message is
116 if [ $# -lt 2 -o $# -gt 3 ]; then
117 _shunit_error "assertEquals() requires two or three arguments; $# given"
118 _shunit_error "1: ${1:+$1} 2: ${2:+$2} 3: ${3:+$3}"
119 return ${SHUNIT_ERROR}
121 _shunit_shouldSkip && return ${SHUNIT_TRUE}
123 shunit_message_=${__shunit_lineno}
124 if [ $# -eq 3 ]; then
125 shunit_message_="${shunit_message_}$1"
131 shunit_return=${SHUNIT_TRUE}
132 if [ "${shunit_expected_}" = "${shunit_actual_}" ]; then
135 failNotEquals "${shunit_message_}" "${shunit_expected_}" "${shunit_actual_}"
136 shunit_return=${SHUNIT_FALSE}
139 unset shunit_message_ shunit_expected_ shunit_actual_
140 return ${shunit_return}
142 _ASSERT_EQUALS_='eval assertEquals --lineno "${LINENO:-}"'
145 # <s:function group="asserts">
146 # <entry align="right">
147 # <emphasis>void</emphasis>
152 # <funcdef><function>assertNotEquals</function></funcdef>
153 # <paramdef>string <parameter>[message]</parameter></paramdef>
154 # <paramdef>string <parameter>unexpected</parameter></paramdef>
155 # <paramdef>string <parameter>actual</parameter></paramdef>
158 # <para>Asserts that <emphasis>unexpected</emphasis> and
159 # <emphasis>actual</emphasis> are <emphasis role="strong">not</emphasis>
160 # equal to one another. The message is optional.</para>
167 if [ $# -lt 2 -o $# -gt 3 ]; then
168 _shunit_error "assertNotEquals() requires two or three arguments; $# given"
169 return ${SHUNIT_ERROR}
171 _shunit_shouldSkip && return ${SHUNIT_TRUE}
173 shunit_message_=${__shunit_lineno}
174 if [ $# -eq 3 ]; then
175 shunit_message_="${shunit_message_}$1"
178 shunit_unexpected_=$1
181 shunit_return=${SHUNIT_TRUE}
182 if [ "${shunit_unexpected_}" != "${shunit_actual_}" ]; then
185 failSame "${shunit_message_}" "$@"
186 shunit_return=${SHUNIT_FALSE}
189 unset shunit_message_ shunit_unexpected_ shunit_actual_
190 return ${shunit_return}
192 _ASSERT_NOT_EQUALS_='eval assertNotEquals --lineno "${LINENO:-}"'
195 # <s:function group="asserts">
196 # <entry align="right">
197 # <emphasis>void</emphasis>
202 # <funcdef><function>assertNull</function></funcdef>
203 # <paramdef>string <parameter>[message]</parameter></paramdef>
204 # <paramdef>string <parameter>value</parameter></paramdef>
207 # <para>Asserts that <emphasis>value</emphasis> is <literal>null</literal>,
208 # or in shell terms a zero-length string. The message is optional.</para>
215 if [ $# -lt 1 -o $# -gt 2 ]; then
216 _shunit_error "assertNull() requires one or two arguments; $# given"
217 return ${SHUNIT_ERROR}
219 _shunit_shouldSkip && return ${SHUNIT_TRUE}
221 shunit_message_=${__shunit_lineno}
222 if [ $# -eq 2 ]; then
223 shunit_message_="${shunit_message_}$1"
226 assertTrue "${shunit_message_}" "[ -z '$1' ]"
229 unset shunit_message_
230 return ${shunit_return}
232 _ASSERT_NULL_='eval assertNull --lineno "${LINENO:-}"'
235 # <s:function group="asserts">
236 # <entry align="right">
237 # <emphasis>void</emphasis>
242 # <funcdef><function>assertNotNull</function></funcdef>
243 # <paramdef>string <parameter>[message]</parameter></paramdef>
244 # <paramdef>string <parameter>value</parameter></paramdef>
247 # <para>Asserts that <emphasis>value</emphasis> is <emphasis
248 # role="strong">not</emphasis> <literal>null</literal>, or in shell terms not
249 # a zero-length string. The message is optional.</para>
256 if [ $# -gt 2 ]; then # allowing 0 arguments as $1 might actually be null
257 _shunit_error "assertNotNull() requires one or two arguments; $# given"
258 return ${SHUNIT_ERROR}
260 _shunit_shouldSkip && return ${SHUNIT_TRUE}
262 shunit_message_=${__shunit_lineno}
263 if [ $# -eq 2 ]; then
264 shunit_message_="${shunit_message_}$1"
267 assertTrue "${shunit_message_}" "[ -n '${1:-}' ]"
270 unset shunit_message_
271 return ${shunit_return}
273 _ASSERT_NOT_NULL_='eval assertNotNull --lineno "${LINENO:-}"'
276 # <s:function group="asserts">
277 # <entry align="right">
278 # <emphasis>void</emphasis>
283 # <funcdef><function>assertSame</function></funcdef>
284 # <paramdef>string <parameter>[message]</parameter></paramdef>
285 # <paramdef>string <parameter>expected</parameter></paramdef>
286 # <paramdef>string <parameter>actual</parameter></paramdef>
289 # <para>This function is functionally equivalent to
290 # <function>assertEquals</function>.</para>
297 if [ $# -lt 2 -o $# -gt 3 ]; then
298 _shunit_error "assertSame() requires two or three arguments; $# given"
299 return ${SHUNIT_ERROR}
301 _shunit_shouldSkip && return ${SHUNIT_TRUE}
303 shunit_message_=${__shunit_lineno}
304 if [ $# -eq 3 ]; then
305 shunit_message_="${shunit_message_}$1"
308 assertEquals "${shunit_message_}" "$1" "$2"
311 unset shunit_message_
312 return ${shunit_return}
314 _ASSERT_SAME_='eval assertSame --lineno "${LINENO:-}"'
317 # <s:function group="asserts">
318 # <entry align="right">
319 # <emphasis>void</emphasis>
324 # <funcdef><function>assertNotSame</function></funcdef>
325 # <paramdef>string <parameter>[message]</parameter></paramdef>
326 # <paramdef>string <parameter>unexpected</parameter></paramdef>
327 # <paramdef>string <parameter>actual</parameter></paramdef>
330 # <para>Asserts that <emphasis>unexpected</emphasis> and
331 # <emphasis>actual</emphasis> are <emphasis role="strong">not</emphasis>
332 # equal to one another. The message is optional.</para>
339 if [ $# -lt 2 -o $# -gt 3 ]; then
340 _shunit_error "assertNotSame() requires two or three arguments; $# given"
341 return ${SHUNIT_ERROR}
343 _shunit_shouldSkip && return ${SHUNIT_TRUE}
345 shunit_message_=${__shunit_lineno}
346 if [ $# -eq 3 ]; then
347 shunit_message_="${shunit_message_:-}$1"
350 assertNotEquals "${shunit_message_}" "$1" "$2"
353 unset shunit_message_
354 return ${shunit_return}
356 _ASSERT_NOT_SAME_='eval assertNotSame --lineno "${LINENO:-}"'
359 # <s:function group="asserts">
360 # <entry align="right">
361 # <emphasis>void</emphasis>
366 # <funcdef><function>assertTrue</function></funcdef>
367 # <paramdef>string <parameter>[message]</parameter></paramdef>
368 # <paramdef>string <parameter>condition</parameter></paramdef>
371 # <para>Asserts that a given shell test condition is true. The message is
373 # <para>Testing whether something is true or false is easy enough by using
374 # the assertEquals/assertNotSame functions. Shell supports much more
375 # complicated tests though, and a means to support them was needed. As such,
376 # this function tests that conditions are true or false through evaluation
377 # rather than just looking for a true or false.</para>
379 # The following test will succeed: <funcsynopsisinfo>assertTrue "[ 34 -gt 23 ]"</funcsynopsisinfo>
380 # The folloing test will fail with a message: <funcsynopsisinfo>assertTrue "test failed" "[ -r '/non/existant/file' ]"</funcsynopsisinfo>
388 if [ $# -gt 2 ]; then
389 _shunit_error "assertTrue() takes one two arguments; $# given"
390 return ${SHUNIT_ERROR}
392 _shunit_shouldSkip && return ${SHUNIT_TRUE}
394 shunit_message_=${__shunit_lineno}
395 if [ $# -eq 2 ]; then
396 shunit_message_="${shunit_message_}$1"
401 # see if condition is an integer, i.e. a return value
402 shunit_match_=`expr "${shunit_condition_}" : '\([0-9]*\)'`
403 shunit_return=${SHUNIT_TRUE}
404 if [ -z "${shunit_condition_}" ]; then
406 shunit_return=${SHUNIT_FALSE}
407 elif [ "${shunit_condition_}" = "${shunit_match_}" ]; then
408 # possible return value. treating 0 as true, and non-zero as false.
409 [ ${shunit_condition_} -ne 0 ] && shunit_return=${SHUNIT_FALSE}
411 # (hopefully) a condition
412 ( eval ${shunit_condition_} ) >/dev/null 2>&1
413 [ $? -ne 0 ] && shunit_return=${SHUNIT_FALSE}
417 if [ ${shunit_return} -eq ${SHUNIT_TRUE} ]; then
420 _shunit_assertFail "${shunit_message_}"
423 unset shunit_message_ shunit_condition_ shunit_match_
424 return ${shunit_return}
426 _ASSERT_TRUE_='eval assertTrue --lineno "${LINENO:-}"'
429 # <s:function group="asserts">
430 # <entry align="right">
431 # <emphasis>void</emphasis>
436 # <funcdef><function>assertFalse</function></funcdef>
437 # <paramdef>string <parameter>[message]</parameter></paramdef>
438 # <paramdef>string <parameter>condition</parameter></paramdef>
441 # <para>Asserts that a given shell test condition is false. The message is
443 # <para>Testing whether something is true or false is easy enough by using
444 # the assertEquals/assertNotSame functions. Shell supports much more
445 # complicated tests though, and a means to support them was needed. As such,
446 # this function tests that conditions are true or false through evaluation
447 # rather than just looking for a true or false.</para>
449 # The following test will succeed: <funcsynopsisinfo>assertFalse "[ 'apples' = 'oranges' ]"</funcsynopsisinfo>
450 # The folloing test will fail with a message: <funcsynopsisinfo>assertFalse "test failed" "[ 1 -eq 1 -a 2 -eq 2 ]"</funcsynopsisinfo>
458 if [ $# -lt 1 -o $# -gt 2 ]; then
459 _shunit_error "assertFalse() quires one or two arguments; $# given"
460 return ${SHUNIT_ERROR}
462 _shunit_shouldSkip && return ${SHUNIT_TRUE}
464 shunit_message_=${__shunit_lineno}
465 if [ $# -eq 2 ]; then
466 shunit_message_="${shunit_message_}$1"
471 # see if condition is an integer, i.e. a return value
472 shunit_match_=`expr "${shunit_condition_}" : '\([0-9]*\)'`
473 shunit_return=${SHUNIT_TRUE}
474 if [ -z "${shunit_condition_}" ]; then
476 shunit_return=${SHUNIT_FALSE}
477 elif [ "${shunit_condition_}" = "${shunit_match_}" ]; then
478 # possible return value. treating 0 as true, and non-zero as false.
479 [ ${shunit_condition_} -eq 0 ] && shunit_return=${SHUNIT_FALSE}
481 # (hopefully) a condition
482 ( eval ${shunit_condition_} ) >/dev/null 2>&1
483 [ $? -eq 0 ] && shunit_return=${SHUNIT_FALSE}
487 if [ ${shunit_return} -eq ${SHUNIT_TRUE} ]; then
490 _shunit_assertFail "${shunit_message_}"
493 unset shunit_message_ shunit_condition_ shunit_match_
494 return ${shunit_return}
496 _ASSERT_FALSE_='eval assertFalse --lineno "${LINENO:-}"'
498 #-----------------------------------------------------------------------------
503 # <s:function group="failures">
504 # <entry align="right">
505 # <emphasis>void</emphasis>
510 # <funcdef><function>fail</function></funcdef>
511 # <paramdef>string <parameter>[message]</parameter></paramdef>
514 # <para>Fails the test immediately, with the optional message.</para>
521 if [ $# -gt 1 ]; then
522 _shunit_error "fail() requires one or two arguments; $# given"
523 return ${SHUNIT_ERROR}
525 _shunit_shouldSkip && return ${SHUNIT_TRUE}
527 shunit_message_=${__shunit_lineno}
528 if [ $# -eq 1 ]; then
529 shunit_message_="${shunit_message_}$1"
533 _shunit_assertFail "${shunit_message_}"
535 unset shunit_message_
536 return ${SHUNIT_FALSE}
538 _FAIL_='eval fail --lineno "${LINENO:-}"'
541 # <s:function group="failures">
542 # <entry align="right">
543 # <emphasis>void</emphasis>
548 # <funcdef><function>failNotEquals</function></funcdef>
549 # <paramdef>string <parameter>[message]</parameter></paramdef>
550 # <paramdef>string <parameter>unexpected</parameter></paramdef>
551 # <paramdef>string <parameter>actual</parameter></paramdef>
554 # <para>Fails the test if <emphasis>unexpected</emphasis> and
555 # <emphasis>actual</emphasis> are <emphasis role="strong">not</emphasis>
556 # equal to one another. The message is optional.</para>
563 if [ $# -lt 2 -o $# -gt 3 ]; then
564 _shunit_error "failNotEquals() requires one or two arguments; $# given"
565 return ${SHUNIT_ERROR}
567 _shunit_shouldSkip && return ${SHUNIT_TRUE}
569 shunit_message_=${__shunit_lineno}
570 if [ $# -eq 3 ]; then
571 shunit_message_="${shunit_message_}$1"
574 shunit_unexpected_=$1
577 _shunit_assertFail "${shunit_message_:+${shunit_message_} }expected:<${shunit_unexpected_}> but was:<${shunit_actual_}>"
579 unset shunit_message_ shunit_unexpected_ shunit_actual_
580 return ${SHUNIT_FALSE}
582 _FAIL_NOT_EQUALS_='eval failNotEquals --lineno "${LINENO:-}"'
585 # <s:function group="failures">
586 # <entry align="right">
587 # <emphasis>void</emphasis>
592 # <funcdef><function>failSame</function></funcdef>
593 # <paramdef>string <parameter>[message]</parameter></paramdef>
596 # <para>Indicate test failure because arguments were the same. The message is
604 if [ $# -lt 2 -o $# -gt 3 ]; then
605 _shunit_error "failSame() requires two or three arguments; $# given"
606 return ${SHUNIT_ERROR}
608 _shunit_shouldSkip && return ${SHUNIT_TRUE}
610 shunit_message_=${__shunit_lineno}
611 if [ $# -eq 3 ]; then
612 shunit_message_="${shunit_message_}$1"
616 _shunit_assertFail "${shunit_message_:+${shunit_message_} }expected not same"
618 unset shunit_message_
619 return ${SHUNIT_FALSE}
621 _FAIL_SAME_='eval failSame --lineno "${LINENO:-}"'
624 # <s:function group="failures">
625 # <entry align="right">
626 # <emphasis>void</emphasis>
631 # <funcdef><function>failNotSame</function></funcdef>
632 # <paramdef>string <parameter>[message]</parameter></paramdef>
633 # <paramdef>string <parameter>expected</parameter></paramdef>
634 # <paramdef>string <parameter>actual</parameter></paramdef>
637 # <para>Indicate test failure because arguments were not the same. The
638 # message is optional.</para>
645 if [ $# -lt 2 -o $# -gt 3 ]; then
646 _shunit_error "failNotEquals() requires one or two arguments; $# given"
647 return ${SHUNIT_ERROR}
649 _shunit_shouldSkip && return ${SHUNIT_TRUE}
651 shunit_message_=${__shunit_lineno}
652 if [ $# -eq 3 ]; then
653 shunit_message_="${shunit_message_}$1"
656 failNotEquals "${shunit_message_}" "$1" "$2"
659 unset shunit_message_
660 return ${shunit_return}
662 _FAIL_NOT_SAME_='eval failNotSame --lineno "${LINENO:-}"'
664 #-----------------------------------------------------------------------------
669 # <s:function group="skipping">
670 # <entry align="right">
671 # <emphasis>void</emphasis>
676 # <funcdef><function>startSkipping</function></funcdef>
680 # <para>This function forces the remaining assert and fail functions to be
681 # "skipped", i.e. they will have no effect. Each function skipped will be
682 # recorded so that the total of asserts and fails will not be altered.</para>
688 __shunit_skip=${SHUNIT_TRUE}
692 # <s:function group="skipping">
693 # <entry align="right">
694 # <emphasis>void</emphasis>
699 # <funcdef><function>endSkipping</function></funcdef>
703 # <para>This function returns calls to the assert and fail functions to their
704 # default behavior, i.e. they will be called.</para>
710 __shunit_skip=${SHUNIT_FALSE}
714 # <s:function group="skipping">
715 # <entry align="right">
716 # <emphasis>boolean</emphasis>
721 # <funcdef><function>isSkipping</function></funcdef>
725 # <para>This function returns the state of skipping.</para>
731 return ${__shunit_skip}
734 #-----------------------------------------------------------------------------
739 # <s:function group="suites">
740 # <entry align="right">
741 # <emphasis>void</emphasis>
746 # <funcdef><function>suite</function></funcdef>
750 # <para>This function can be optionally overridden by the user in their test
752 # <para>If this function exists, it will be called when
753 # <command>shunit2</command> is sourced. If it does not exist, shUnit2 will
754 # search the parent script for all functions beginning with the word
755 # <literal>test</literal>, and they will be added dynamically to the test
760 # Note: see _shunit_mktempFunc() for actual implementation
764 # <s:function group="suites">
765 # <entry align="right">
766 # <emphasis>void</emphasis>
771 # <funcdef><function>suite_addTest</function></funcdef>
772 # <paramdef>string <parameter>function</parameter></paramdef>
775 # <para>This function adds a function name to the list of tests scheduled for
776 # execution as part of this test suite. This function should only be called
777 # from within the <function>suite()</function> function.</para>
785 __shunit_suite="${__shunit_suite:+${__shunit_suite} }${shunit_func_}"
786 __shunit_testsTotal=`expr ${__shunit_testsTotal} + 1`
792 # <s:function group="suites">
793 # <entry align="right">
794 # <emphasis>void</emphasis>
799 # <funcdef><function>oneTimeSetUp</function></funcdef>
803 # <para>This function can be be optionally overridden by the user in their
805 # <para>If this function exists, it will be called once before any tests are
806 # run. It is useful to prepare a common environment for all tests.</para>
810 # Note: see _shunit_mktempFunc() for actual implementation
811 # oneTimeSetUp() { :; }
814 # <s:function group="suites">
815 # <entry align="right">
816 # <emphasis>void</emphasis>
821 # <funcdef><function>oneTimeTearDown</function></funcdef>
825 # <para>This function can be be optionally overridden by the user in their
827 # <para>If this function exists, it will be called once after all tests are
828 # completed. It is useful to clean up the environment after all tests.</para>
832 # Note: see _shunit_mktempFunc() for actual implementation
833 # oneTimeTearDown() { :; }
836 # <s:function group="suites">
837 # <entry align="right">
838 # <emphasis>void</emphasis>
843 # <funcdef><function>setUp</function></funcdef>
847 # <para>This function can be be optionally overridden by the user in their
849 # <para>If this function exists, it will be called before each test is run.
850 # It is useful to reset the environment before each test.</para>
854 # Note: see _shunit_mktempFunc() for actual implementation
858 # <s:function group="suites">
859 # <entry align="right">
860 # <emphasis>void</emphasis>
865 # <funcdef><function>tearDown</function></funcdef>
869 # <para>This function can be be optionally overridden by the user in their
871 # <para>If this function exists, it will be called after each test completes.
872 # It is useful to clean up the environment after each test.</para>
876 # Note: see _shunit_mktempFunc() for actual implementation
879 #------------------------------------------------------------------------------
880 # internal shUnit2 functions
883 # this function is a cross-platform temporary directory creation tool. not all
884 # OSes have the mktemp function, so one is included here.
887 # try the standard mktemp function
888 ( exec mktemp -dqt shunit.XXXXXX 2>/dev/null ) && return
890 # the standard mktemp didn't work. doing our own.
891 if [ -r '/dev/urandom' ]; then
892 _shunit_random_=`od -vAn -N4 -tx4 </dev/urandom |sed 's/^[^0-9a-f]*//'`
893 elif [ -n "${RANDOM:-}" ]; then
895 _shunit_random_=${RANDOM}${RANDOM}${RANDOM}$$
897 # $RANDOM doesn't work
898 _shunit_date_=`date '+%Y%m%d%H%M%S'`
899 _shunit_random_=`expr ${_shunit_date_} / $$`
902 _shunit_tmpDir_="${TMPDIR:-/tmp}/shunit.${_shunit_random_}"
903 ( umask 077 && mkdir "${_shunit_tmpDir_}" ) || {
904 _shunit_fatal 'could not create temporary directory! exiting'
908 echo ${_shunit_tmpDir_}
909 unset _shunit_date_ _shunit_random_ _shunit_tmpDir_
912 # this function is here to work around issues in Cygwin
915 for _shunit_func_ in oneTimeSetUp oneTimeTearDown setUp tearDown suite; do
916 _shunit_file_="${__shunit_tmpDir}/${_shunit_func_}"
917 cat <<EOF >"${_shunit_file_}"
921 # If the path is changed, put it back for this command
922 PATH=/bin:/usr/bin chmod +x "${_shunit_file_}"
932 case ${_shunit_name_} in
933 EXIT) _shunit_signal_=0 ;;
934 INT) _shunit_signal_=2 ;;
935 TERM) _shunit_signal_=15 ;;
937 _shunit_warn "unrecognized trap value (${_shunit_name_})"
943 rm -fr "${__shunit_tmpDir}"
945 # exit for all non-EXIT signals
946 if [ ${_shunit_name_} != 'EXIT' ]; then
947 _shunit_warn "trapped and now handling the (${_shunit_name_}) signal"
950 # add 128 to signal and exit
951 exit `expr ${_shunit_signal_} + 128`
952 elif [ ${__shunit_reportGenerated} -eq ${SHUNIT_FALSE} ] ; then
953 _shunit_assertFail 'Unknown failure encountered running a test'
954 _shunit_generateReport
958 unset _shunit_name_ _shunit_signal_
961 # The actual running of the tests happens here.
964 for _shunit_test_ in ${__shunit_suite}; do
965 __shunit_testSuccess=${SHUNIT_TRUE}
970 # execute the per-test setup function
974 echo "${_shunit_test_}"
975 eval ${_shunit_test_}
977 # execute the per-test tear-down function
981 if [ ${__shunit_testSuccess} -eq ${SHUNIT_TRUE} ]; then
982 __shunit_testsPassed=`expr ${__shunit_testsPassed} + 1`
984 __shunit_testsFailed=`expr ${__shunit_testsFailed} + 1`
991 # This function exits shUnit2 with the appropriate error code and OK/FAILED
993 _shunit_generateReport()
995 _shunit_ok_=${SHUNIT_TRUE}
997 # if no exit code was provided one, determine an appropriate one
998 [ ${__shunit_testsFailed} -gt 0 \
999 -o ${__shunit_testSuccess} -eq ${SHUNIT_FALSE} ] \
1000 && _shunit_ok_=${SHUNIT_FALSE}
1003 if [ ${__shunit_testsTotal} -eq 1 ]; then
1004 echo "Ran ${__shunit_testsTotal} test."
1006 echo "Ran ${__shunit_testsTotal} tests."
1009 _shunit_failures_=''
1011 [ ${__shunit_assertsFailed} -gt 0 ] \
1012 && _shunit_failures_="failures=${__shunit_assertsFailed}"
1013 [ ${__shunit_assertsSkipped} -gt 0 ] \
1014 && _shunit_skipped_="skipped=${__shunit_assertsSkipped}"
1016 if [ ${_shunit_ok_} -eq ${SHUNIT_TRUE} ]; then
1018 [ -n "${_shunit_skipped_}" ] \
1019 && _shunit_msg_="${_shunit_msg_} (${_shunit_skipped_})"
1021 _shunit_msg_="FAILED (${_shunit_failures_}"
1022 [ -n "${_shunit_skipped_}" ] \
1023 && _shunit_msg_="${_shunit_msg_},${_shunit_skipped_}"
1024 _shunit_msg_="${_shunit_msg_})"
1028 echo ${_shunit_msg_}
1029 __shunit_reportGenerated=${SHUNIT_TRUE}
1031 unset _shunit_failures_ _shunit_msg_ _shunit_ok_ _shunit_skipped_
1034 _shunit_shouldSkip()
1036 [ ${__shunit_skip} -eq ${SHUNIT_FALSE} ] && return ${SHUNIT_FALSE}
1040 _shunit_assertPass()
1042 __shunit_assertsPassed=`expr ${__shunit_assertsPassed} + 1`
1043 __shunit_assertsTotal=`expr ${__shunit_assertsTotal} + 1`
1046 _shunit_assertFail()
1050 __shunit_testSuccess=${SHUNIT_FALSE}
1051 __shunit_assertsFailed=`expr ${__shunit_assertsFailed} + 1`
1052 __shunit_assertsTotal=`expr ${__shunit_assertsTotal} + 1`
1053 echo "${__SHUNIT_ASSERT_MSG_PREFIX}${_shunit_msg_}"
1058 _shunit_assertSkip()
1060 __shunit_assertsSkipped=`expr ${__shunit_assertsSkipped} + 1`
1061 __shunit_assertsTotal=`expr ${__shunit_assertsTotal} + 1`
1064 #------------------------------------------------------------------------------
1068 # create a temporary storage location
1069 __shunit_tmpDir=`_shunit_mktempDir`
1071 # provide a public temporary directory for unit test scripts
1072 # TODO(kward): document this
1073 shunit_tmpDir="${__shunit_tmpDir}/tmp"
1074 mkdir "${shunit_tmpDir}"
1076 # setup traps to clean up after ourselves
1077 trap '_shunit_cleanup EXIT' 0
1078 trap '_shunit_cleanup INT' 2
1079 trap '_shunit_cleanup TERM' 15
1081 # create phantom functions to work around issues with Cygwin
1083 PATH="${__shunit_tmpDir}:${PATH}"
1085 # execute the oneTimeSetUp function (if it exists)
1088 # execute the suite function defined in the parent test script
1089 # deprecated as of 2.1.0
1092 # if no suite function was defined, dynamically build a list of functions
1093 if [ -z "${__shunit_suite}" ]; then
1094 shunit_funcs_=`grep "^[ \t]*test[A-Za-z0-9_]* *()" ${__SHUNIT_PARENT} \
1095 |sed 's/[^A-Za-z0-9_]//g'`
1096 for shunit_func_ in ${shunit_funcs_}; do
1097 suite_addTest ${shunit_func_}
1100 unset shunit_func_ shunit_funcs_
1105 # execute the oneTimeTearDown function (if it exists)
1108 # generate the report
1109 _shunit_generateReport
1112 [ ${__shunit_testsFailed} -eq 0 ]