blob: 590a5a8c1d95b95c30dee674dd57b3ebe55b600e [file] [log] [blame]
kate.ward43e7ca12011-06-10 11:13:10 +00001#! /bin/sh
2# $Id: shunit2 322 2011-04-24 00:09:45Z kate.ward@forestent.com $
kate.wardf51c6162008-06-17 16:38:35 +00003# vim:et:ft=sh:sts=2:sw=2
kate.wardf51c6162008-06-17 16:38:35 +00004#
kate.ward9a183b82010-03-18 00:25:34 +00005# Copyright 2008 Kate Ward. All Rights Reserved.
6# Released under the LGPL (GNU Lesser General Public License)
kate.wardf51c6162008-06-17 16:38:35 +00007#
kate.ward9a183b82010-03-18 00:25:34 +00008# shUnit2 -- Unit testing framework for Unix shell scripts.
9# http://code.google.com/p/shunit2/
kate.wardf51c6162008-06-17 16:38:35 +000010#
kate.ward9a183b82010-03-18 00:25:34 +000011# Author: kate.ward@forestent.com (Kate Ward)
kate.wardf51c6162008-06-17 16:38:35 +000012#
kate.ward9a183b82010-03-18 00:25:34 +000013# shUnit2 is a xUnit based unit test framework for Bourne shell scripts. It is
14# based on the popular JUnit unit testing framework for Java.
kate.wardf51c6162008-06-17 16:38:35 +000015
kate.ward43e7ca12011-06-10 11:13:10 +000016# return if shunit already loaded
17[ -n "${SHUNIT_VERSION:-}" ] && exit 0
18
19SHUNIT_VERSION='2.1.6'
kate.wardf51c6162008-06-17 16:38:35 +000020
21SHUNIT_TRUE=0
22SHUNIT_FALSE=1
23SHUNIT_ERROR=2
24
kate.ward43e7ca12011-06-10 11:13:10 +000025# enable strict mode by default
26SHUNIT_STRICT=${SHUNIT_STRICT:-${SHUNIT_TRUE}}
27
kate.ward38097672008-11-03 20:58:42 +000028_shunit_warn() { echo "shunit2:WARN $@" >&2; }
29_shunit_error() { echo "shunit2:ERROR $@" >&2; }
kate.ward43e7ca12011-06-10 11:13:10 +000030_shunit_fatal() { echo "shunit2:FATAL $@" >&2; exit ${SHUNIT_ERROR}; }
kate.ward38097672008-11-03 20:58:42 +000031
kate.wardf51c6162008-06-17 16:38:35 +000032# specific shell checks
33if [ -n "${ZSH_VERSION:-}" ]; then
kate.wardf32fb4f2008-07-11 15:20:38 +000034 setopt |grep "^shwordsplit$" >/dev/null
35 if [ $? -ne ${SHUNIT_TRUE} ]; then
36 _shunit_fatal 'zsh shwordsplit option is required for proper operation'
kate.wardf51c6162008-06-17 16:38:35 +000037 fi
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"
kate.wardf51c6162008-06-17 16:38:35 +000041 fi
42fi
43
kate.wardf51c6162008-06-17 16:38:35 +000044#
45# constants
46#
47
48__SHUNIT_ASSERT_MSG_PREFIX='ASSERT:'
kate.ward43e7ca12011-06-10 11:13:10 +000049__SHUNIT_MODE_SOURCED='sourced'
50__SHUNIT_MODE_STANDALONE='standalone'
kate.wardf51c6162008-06-17 16:38:35 +000051__SHUNIT_PARENT=${SHUNIT_PARENT:-$0}
52
53# set the constants readonly
kate.ward38097672008-11-03 20:58:42 +000054shunit_constants_=`set |grep '^__SHUNIT_' |cut -d= -f1`
kate.ward43e7ca12011-06-10 11:13:10 +000055echo "${shunit_constants_}" |grep '^Binary file' >/dev/null && \
56 shunit_constants_=`set |grep -a '^__SHUNIT_' |cut -d= -f1`
kate.ward38097672008-11-03 20:58:42 +000057for shunit_constant_ in ${shunit_constants_}; do
kate.wardf32fb4f2008-07-11 15:20:38 +000058 shunit_ro_opts_=''
kate.ward38097672008-11-03 20:58:42 +000059 case ${ZSH_VERSION:-} in
60 '') ;; # this isn't zsh
61 [123].*) ;; # early versions (1.x, 2.x, 3.x)
62 *) shunit_ro_opts_='-g' ;; # all later versions. declare readonly globally
63 esac
64 readonly ${shunit_ro_opts_} ${shunit_constant_}
kate.wardf51c6162008-06-17 16:38:35 +000065done
kate.ward38097672008-11-03 20:58:42 +000066unset shunit_constant_ shunit_constants_ shunit_ro_opts_
kate.wardf51c6162008-06-17 16:38:35 +000067
68# variables
kate.ward43e7ca12011-06-10 11:13:10 +000069__shunit_lineno='' # line number of executed test
70__shunit_mode=${__SHUNIT_MODE_SOURCED} # operating mode
71__shunit_reportGenerated=${SHUNIT_FALSE} # is report generated
72__shunit_script='' # filename of unittest script (standalone mode)
73__shunit_skip=${SHUNIT_FALSE} # is skipping enabled
74__shunit_suite='' # suite of tests to execute
kate.wardf51c6162008-06-17 16:38:35 +000075
kate.ward38097672008-11-03 20:58:42 +000076# counts of tests
77__shunit_testSuccess=${SHUNIT_TRUE}
78__shunit_testsTotal=0
kate.wardf51c6162008-06-17 16:38:35 +000079__shunit_testsPassed=0
80__shunit_testsFailed=0
kate.ward38097672008-11-03 20:58:42 +000081
82# counts of asserts
83__shunit_assertsTotal=0
84__shunit_assertsPassed=0
85__shunit_assertsFailed=0
86__shunit_assertsSkipped=0
87
kate.wardf32fb4f2008-07-11 15:20:38 +000088# macros
kate.ward38097672008-11-03 20:58:42 +000089_SHUNIT_LINENO_='eval __shunit_lineno=""; if [ "${1:-}" = "--lineno" ]; then [ -n "$2" ] && __shunit_lineno="[$2] "; shift 2; fi'
kate.wardf32fb4f2008-07-11 15:20:38 +000090
kate.wardf51c6162008-06-17 16:38:35 +000091#-----------------------------------------------------------------------------
92# assert functions
93#
94
kate.ward9a183b82010-03-18 00:25:34 +000095# Assert that two values are equal to one another.
96#
97# Args:
98# message: string: failure message [optional]
99# expected: string: expected value
100# actual: string: actual value
101# Returns:
102# integer: success (TRUE/FALSE/ERROR constant)
kate.wardf51c6162008-06-17 16:38:35 +0000103assertEquals()
104{
kate.wardf32fb4f2008-07-11 15:20:38 +0000105 ${_SHUNIT_LINENO_}
106 if [ $# -lt 2 -o $# -gt 3 ]; then
kate.ward38097672008-11-03 20:58:42 +0000107 _shunit_error "assertEquals() requires two or three arguments; $# given"
108 _shunit_error "1: ${1:+$1} 2: ${2:+$2} 3: ${3:+$3}"
kate.wardf32fb4f2008-07-11 15:20:38 +0000109 return ${SHUNIT_ERROR}
110 fi
kate.wardf51c6162008-06-17 16:38:35 +0000111 _shunit_shouldSkip && return ${SHUNIT_TRUE}
112
kate.ward38097672008-11-03 20:58:42 +0000113 shunit_message_=${__shunit_lineno}
kate.wardf32fb4f2008-07-11 15:20:38 +0000114 if [ $# -eq 3 ]; then
115 shunit_message_="${shunit_message_}$1"
kate.wardf51c6162008-06-17 16:38:35 +0000116 shift
117 fi
kate.wardf32fb4f2008-07-11 15:20:38 +0000118 shunit_expected_=$1
119 shunit_actual_=$2
kate.wardf51c6162008-06-17 16:38:35 +0000120
121 shunit_return=${SHUNIT_TRUE}
kate.wardf32fb4f2008-07-11 15:20:38 +0000122 if [ "${shunit_expected_}" = "${shunit_actual_}" ]; then
kate.ward38097672008-11-03 20:58:42 +0000123 _shunit_assertPass
kate.wardf51c6162008-06-17 16:38:35 +0000124 else
kate.wardf32fb4f2008-07-11 15:20:38 +0000125 failNotEquals "${shunit_message_}" "${shunit_expected_}" "${shunit_actual_}"
kate.wardf51c6162008-06-17 16:38:35 +0000126 shunit_return=${SHUNIT_FALSE}
127 fi
128
kate.ward38097672008-11-03 20:58:42 +0000129 unset shunit_message_ shunit_expected_ shunit_actual_
kate.wardf51c6162008-06-17 16:38:35 +0000130 return ${shunit_return}
131}
kate.wardf32fb4f2008-07-11 15:20:38 +0000132_ASSERT_EQUALS_='eval assertEquals --lineno "${LINENO:-}"'
kate.wardf51c6162008-06-17 16:38:35 +0000133
kate.ward9a183b82010-03-18 00:25:34 +0000134# Assert that two values are not equal to one another.
135#
136# Args:
137# message: string: failure message [optional]
138# expected: string: expected value
139# actual: string: actual value
140# Returns:
141# integer: success (TRUE/FALSE/ERROR constant)
kate.ward38097672008-11-03 20:58:42 +0000142assertNotEquals()
143{
144 ${_SHUNIT_LINENO_}
145 if [ $# -lt 2 -o $# -gt 3 ]; then
146 _shunit_error "assertNotEquals() requires two or three arguments; $# given"
147 return ${SHUNIT_ERROR}
148 fi
149 _shunit_shouldSkip && return ${SHUNIT_TRUE}
150
151 shunit_message_=${__shunit_lineno}
152 if [ $# -eq 3 ]; then
153 shunit_message_="${shunit_message_}$1"
154 shift
155 fi
kate.ward43e7ca12011-06-10 11:13:10 +0000156 shunit_expected_=$1
kate.ward38097672008-11-03 20:58:42 +0000157 shunit_actual_=$2
158
159 shunit_return=${SHUNIT_TRUE}
kate.ward43e7ca12011-06-10 11:13:10 +0000160 if [ "${shunit_expected_}" != "${shunit_actual_}" ]; then
kate.ward38097672008-11-03 20:58:42 +0000161 _shunit_assertPass
162 else
163 failSame "${shunit_message_}" "$@"
164 shunit_return=${SHUNIT_FALSE}
165 fi
166
kate.ward43e7ca12011-06-10 11:13:10 +0000167 unset shunit_message_ shunit_expected_ shunit_actual_
kate.ward38097672008-11-03 20:58:42 +0000168 return ${shunit_return}
169}
170_ASSERT_NOT_EQUALS_='eval assertNotEquals --lineno "${LINENO:-}"'
171
kate.ward9a183b82010-03-18 00:25:34 +0000172# Assert that a value is null (i.e. an empty string)
173#
174# Args:
175# message: string: failure message [optional]
176# actual: string: actual value
177# Returns:
178# integer: success (TRUE/FALSE/ERROR constant)
kate.wardf51c6162008-06-17 16:38:35 +0000179assertNull()
180{
kate.wardf32fb4f2008-07-11 15:20:38 +0000181 ${_SHUNIT_LINENO_}
182 if [ $# -lt 1 -o $# -gt 2 ]; then
kate.ward38097672008-11-03 20:58:42 +0000183 _shunit_error "assertNull() requires one or two arguments; $# given"
kate.wardf32fb4f2008-07-11 15:20:38 +0000184 return ${SHUNIT_ERROR}
185 fi
kate.wardf51c6162008-06-17 16:38:35 +0000186 _shunit_shouldSkip && return ${SHUNIT_TRUE}
187
kate.ward38097672008-11-03 20:58:42 +0000188 shunit_message_=${__shunit_lineno}
kate.wardf32fb4f2008-07-11 15:20:38 +0000189 if [ $# -eq 2 ]; then
190 shunit_message_="${shunit_message_}$1"
191 shift
192 fi
kate.ward38097672008-11-03 20:58:42 +0000193 assertTrue "${shunit_message_}" "[ -z '$1' ]"
194 shunit_return=$?
195
196 unset shunit_message_
197 return ${shunit_return}
kate.wardf51c6162008-06-17 16:38:35 +0000198}
kate.wardf32fb4f2008-07-11 15:20:38 +0000199_ASSERT_NULL_='eval assertNull --lineno "${LINENO:-}"'
kate.wardf51c6162008-06-17 16:38:35 +0000200
kate.ward9a183b82010-03-18 00:25:34 +0000201# Assert that a value is not null (i.e. a non-empty string)
202#
203# Args:
204# message: string: failure message [optional]
205# actual: string: actual value
206# Returns:
207# integer: success (TRUE/FALSE/ERROR constant)
kate.wardf51c6162008-06-17 16:38:35 +0000208assertNotNull()
209{
kate.wardf32fb4f2008-07-11 15:20:38 +0000210 ${_SHUNIT_LINENO_}
211 if [ $# -gt 2 ]; then # allowing 0 arguments as $1 might actually be null
kate.ward38097672008-11-03 20:58:42 +0000212 _shunit_error "assertNotNull() requires one or two arguments; $# given"
kate.wardf32fb4f2008-07-11 15:20:38 +0000213 return ${SHUNIT_ERROR}
214 fi
kate.wardf51c6162008-06-17 16:38:35 +0000215 _shunit_shouldSkip && return ${SHUNIT_TRUE}
216
kate.ward38097672008-11-03 20:58:42 +0000217 shunit_message_=${__shunit_lineno}
kate.wardf51c6162008-06-17 16:38:35 +0000218 if [ $# -eq 2 ]; then
kate.ward38097672008-11-03 20:58:42 +0000219 shunit_message_="${shunit_message_}$1"
220 shift
kate.wardf51c6162008-06-17 16:38:35 +0000221 fi
kate.ward43e7ca12011-06-10 11:13:10 +0000222 shunit_actual_=`_shunit_escapeCharactersInString "${1:-}"`
223 test -n "${shunit_actual_}"
224 assertTrue "${shunit_message_}" $?
kate.ward38097672008-11-03 20:58:42 +0000225 shunit_return=$?
226
kate.ward43e7ca12011-06-10 11:13:10 +0000227 unset shunit_actual_ shunit_message_
kate.ward38097672008-11-03 20:58:42 +0000228 return ${shunit_return}
kate.wardf51c6162008-06-17 16:38:35 +0000229}
kate.wardf32fb4f2008-07-11 15:20:38 +0000230_ASSERT_NOT_NULL_='eval assertNotNull --lineno "${LINENO:-}"'
kate.wardf51c6162008-06-17 16:38:35 +0000231
kate.ward9a183b82010-03-18 00:25:34 +0000232# Assert that two values are the same (i.e. equal to one another).
233#
234# Args:
235# message: string: failure message [optional]
236# expected: string: expected value
237# actual: string: actual value
238# Returns:
239# integer: success (TRUE/FALSE/ERROR constant)
kate.wardf51c6162008-06-17 16:38:35 +0000240assertSame()
241{
kate.wardf32fb4f2008-07-11 15:20:38 +0000242 ${_SHUNIT_LINENO_}
243 if [ $# -lt 2 -o $# -gt 3 ]; then
kate.ward43e7ca12011-06-10 11:13:10 +0000244 _shunit_error "assertSame() requires two or three arguments; $# given"
kate.wardf32fb4f2008-07-11 15:20:38 +0000245 return ${SHUNIT_ERROR}
246 fi
247 _shunit_shouldSkip && return ${SHUNIT_TRUE}
248
kate.ward38097672008-11-03 20:58:42 +0000249 shunit_message_=${__shunit_lineno}
250 if [ $# -eq 3 ]; then
251 shunit_message_="${shunit_message_}$1"
252 shift
kate.wardf32fb4f2008-07-11 15:20:38 +0000253 fi
kate.ward38097672008-11-03 20:58:42 +0000254 assertEquals "${shunit_message_}" "$1" "$2"
255 shunit_return=$?
256
257 unset shunit_message_
258 return ${shunit_return}
kate.wardf51c6162008-06-17 16:38:35 +0000259}
kate.wardf32fb4f2008-07-11 15:20:38 +0000260_ASSERT_SAME_='eval assertSame --lineno "${LINENO:-}"'
kate.wardf51c6162008-06-17 16:38:35 +0000261
kate.ward9a183b82010-03-18 00:25:34 +0000262# Assert that two values are not the same (i.e. not equal to one another).
263#
264# Args:
265# message: string: failure message [optional]
266# expected: string: expected value
267# actual: string: actual value
268# Returns:
269# integer: success (TRUE/FALSE/ERROR constant)
kate.wardf51c6162008-06-17 16:38:35 +0000270assertNotSame()
271{
kate.wardf32fb4f2008-07-11 15:20:38 +0000272 ${_SHUNIT_LINENO_}
273 if [ $# -lt 2 -o $# -gt 3 ]; then
kate.ward38097672008-11-03 20:58:42 +0000274 _shunit_error "assertNotSame() requires two or three arguments; $# given"
kate.wardf32fb4f2008-07-11 15:20:38 +0000275 return ${SHUNIT_ERROR}
276 fi
kate.wardf51c6162008-06-17 16:38:35 +0000277 _shunit_shouldSkip && return ${SHUNIT_TRUE}
278
kate.ward38097672008-11-03 20:58:42 +0000279 shunit_message_=${__shunit_lineno}
kate.wardf51c6162008-06-17 16:38:35 +0000280 if [ $# -eq 3 ]; then
kate.ward38097672008-11-03 20:58:42 +0000281 shunit_message_="${shunit_message_:-}$1"
kate.wardf51c6162008-06-17 16:38:35 +0000282 shift
283 fi
kate.ward38097672008-11-03 20:58:42 +0000284 assertNotEquals "${shunit_message_}" "$1" "$2"
285 shunit_return=$?
kate.wardf51c6162008-06-17 16:38:35 +0000286
kate.ward38097672008-11-03 20:58:42 +0000287 unset shunit_message_
kate.wardf51c6162008-06-17 16:38:35 +0000288 return ${shunit_return}
289}
kate.wardf32fb4f2008-07-11 15:20:38 +0000290_ASSERT_NOT_SAME_='eval assertNotSame --lineno "${LINENO:-}"'
kate.wardf51c6162008-06-17 16:38:35 +0000291
kate.ward9a183b82010-03-18 00:25:34 +0000292# Assert that a value or shell test condition is true.
293#
294# In shell, a value of 0 is true and a non-zero value is false. Any integer
295# value passed can thereby be tested.
296#
297# Shell supports much more complicated tests though, and a means to support
298# them was needed. As such, this function tests that conditions are true or
299# false through evaluation rather than just looking for a true or false.
300#
301# The following test will succeed:
302# assertTrue 0
303# assertTrue "[ 34 -gt 23 ]"
304# The folloing test will fail with a message:
305# assertTrue 123
306# assertTrue "test failed" "[ -r '/non/existant/file' ]"
307#
308# Args:
309# message: string: failure message [optional]
310# condition: string: integer value or shell conditional statement
311# Returns:
312# integer: success (TRUE/FALSE/ERROR constant)
kate.wardf51c6162008-06-17 16:38:35 +0000313assertTrue()
314{
kate.wardf32fb4f2008-07-11 15:20:38 +0000315 ${_SHUNIT_LINENO_}
316 if [ $# -gt 2 ]; then
kate.ward38097672008-11-03 20:58:42 +0000317 _shunit_error "assertTrue() takes one two arguments; $# given"
kate.wardf32fb4f2008-07-11 15:20:38 +0000318 return ${SHUNIT_ERROR}
319 fi
kate.wardf51c6162008-06-17 16:38:35 +0000320 _shunit_shouldSkip && return ${SHUNIT_TRUE}
321
kate.ward38097672008-11-03 20:58:42 +0000322 shunit_message_=${__shunit_lineno}
kate.wardf51c6162008-06-17 16:38:35 +0000323 if [ $# -eq 2 ]; then
kate.wardf32fb4f2008-07-11 15:20:38 +0000324 shunit_message_="${shunit_message_}$1"
kate.wardf51c6162008-06-17 16:38:35 +0000325 shift
326 fi
kate.wardf32fb4f2008-07-11 15:20:38 +0000327 shunit_condition_=$1
kate.wardf51c6162008-06-17 16:38:35 +0000328
329 # see if condition is an integer, i.e. a return value
kate.wardf32fb4f2008-07-11 15:20:38 +0000330 shunit_match_=`expr "${shunit_condition_}" : '\([0-9]*\)'`
331 shunit_return=${SHUNIT_TRUE}
332 if [ -z "${shunit_condition_}" ]; then
kate.wardf51c6162008-06-17 16:38:35 +0000333 # null condition
334 shunit_return=${SHUNIT_FALSE}
kate.ward43e7ca12011-06-10 11:13:10 +0000335 elif [ -n "${shunit_match_}" -a "${shunit_condition_}" = "${shunit_match_}" ]
336 then
kate.wardf51c6162008-06-17 16:38:35 +0000337 # possible return value. treating 0 as true, and non-zero as false.
kate.wardf32fb4f2008-07-11 15:20:38 +0000338 [ ${shunit_condition_} -ne 0 ] && shunit_return=${SHUNIT_FALSE}
kate.wardf51c6162008-06-17 16:38:35 +0000339 else
340 # (hopefully) a condition
kate.wardf32fb4f2008-07-11 15:20:38 +0000341 ( eval ${shunit_condition_} ) >/dev/null 2>&1
kate.wardf51c6162008-06-17 16:38:35 +0000342 [ $? -ne 0 ] && shunit_return=${SHUNIT_FALSE}
343 fi
344
345 # record the test
346 if [ ${shunit_return} -eq ${SHUNIT_TRUE} ]; then
kate.ward38097672008-11-03 20:58:42 +0000347 _shunit_assertPass
kate.wardf51c6162008-06-17 16:38:35 +0000348 else
kate.ward38097672008-11-03 20:58:42 +0000349 _shunit_assertFail "${shunit_message_}"
kate.wardf51c6162008-06-17 16:38:35 +0000350 fi
351
kate.wardf32fb4f2008-07-11 15:20:38 +0000352 unset shunit_message_ shunit_condition_ shunit_match_
kate.wardf51c6162008-06-17 16:38:35 +0000353 return ${shunit_return}
354}
kate.wardf32fb4f2008-07-11 15:20:38 +0000355_ASSERT_TRUE_='eval assertTrue --lineno "${LINENO:-}"'
kate.wardf51c6162008-06-17 16:38:35 +0000356
kate.ward9a183b82010-03-18 00:25:34 +0000357# Assert that a value or shell test condition is false.
358#
359# In shell, a value of 0 is true and a non-zero value is false. Any integer
360# value passed can thereby be tested.
361#
362# Shell supports much more complicated tests though, and a means to support
363# them was needed. As such, this function tests that conditions are true or
364# false through evaluation rather than just looking for a true or false.
365#
366# The following test will succeed:
367# assertFalse 1
368# assertFalse "[ 'apples' = 'oranges' ]"
369# The folloing test will fail with a message:
370# assertFalse 0
371# assertFalse "test failed" "[ 1 -eq 1 -a 2 -eq 2 ]"
372#
373# Args:
374# message: string: failure message [optional]
375# condition: string: integer value or shell conditional statement
376# Returns:
377# integer: success (TRUE/FALSE/ERROR constant)
kate.wardf51c6162008-06-17 16:38:35 +0000378assertFalse()
379{
kate.wardf32fb4f2008-07-11 15:20:38 +0000380 ${_SHUNIT_LINENO_}
381 if [ $# -lt 1 -o $# -gt 2 ]; then
kate.ward38097672008-11-03 20:58:42 +0000382 _shunit_error "assertFalse() quires one or two arguments; $# given"
kate.wardf32fb4f2008-07-11 15:20:38 +0000383 return ${SHUNIT_ERROR}
384 fi
kate.wardf51c6162008-06-17 16:38:35 +0000385 _shunit_shouldSkip && return ${SHUNIT_TRUE}
386
kate.ward38097672008-11-03 20:58:42 +0000387 shunit_message_=${__shunit_lineno}
kate.wardf51c6162008-06-17 16:38:35 +0000388 if [ $# -eq 2 ]; then
kate.wardf32fb4f2008-07-11 15:20:38 +0000389 shunit_message_="${shunit_message_}$1"
kate.wardf51c6162008-06-17 16:38:35 +0000390 shift
391 fi
kate.wardf32fb4f2008-07-11 15:20:38 +0000392 shunit_condition_=$1
kate.wardf51c6162008-06-17 16:38:35 +0000393
394 # see if condition is an integer, i.e. a return value
kate.wardf32fb4f2008-07-11 15:20:38 +0000395 shunit_match_=`expr "${shunit_condition_}" : '\([0-9]*\)'`
396 shunit_return=${SHUNIT_TRUE}
397 if [ -z "${shunit_condition_}" ]; then
kate.wardf51c6162008-06-17 16:38:35 +0000398 # null condition
399 shunit_return=${SHUNIT_FALSE}
kate.ward43e7ca12011-06-10 11:13:10 +0000400 elif [ -n "${shunit_match_}" -a "${shunit_condition_}" = "${shunit_match_}" ]
401 then
kate.wardf51c6162008-06-17 16:38:35 +0000402 # possible return value. treating 0 as true, and non-zero as false.
kate.wardf32fb4f2008-07-11 15:20:38 +0000403 [ ${shunit_condition_} -eq 0 ] && shunit_return=${SHUNIT_FALSE}
kate.wardf51c6162008-06-17 16:38:35 +0000404 else
405 # (hopefully) a condition
kate.wardf32fb4f2008-07-11 15:20:38 +0000406 ( eval ${shunit_condition_} ) >/dev/null 2>&1
kate.wardf51c6162008-06-17 16:38:35 +0000407 [ $? -eq 0 ] && shunit_return=${SHUNIT_FALSE}
408 fi
409
410 # record the test
411 if [ ${shunit_return} -eq ${SHUNIT_TRUE} ]; then
kate.ward38097672008-11-03 20:58:42 +0000412 _shunit_assertPass
kate.wardf51c6162008-06-17 16:38:35 +0000413 else
kate.ward38097672008-11-03 20:58:42 +0000414 _shunit_assertFail "${shunit_message_}"
kate.wardf51c6162008-06-17 16:38:35 +0000415 fi
416
kate.wardf32fb4f2008-07-11 15:20:38 +0000417 unset shunit_message_ shunit_condition_ shunit_match_
kate.wardf51c6162008-06-17 16:38:35 +0000418 return ${shunit_return}
419}
kate.wardf32fb4f2008-07-11 15:20:38 +0000420_ASSERT_FALSE_='eval assertFalse --lineno "${LINENO:-}"'
kate.wardf51c6162008-06-17 16:38:35 +0000421
422#-----------------------------------------------------------------------------
423# failure functions
424#
425
kate.ward9a183b82010-03-18 00:25:34 +0000426# Records a test failure.
427#
428# Args:
429# message: string: failure message [optional]
430# Returns:
431# integer: success (TRUE/FALSE/ERROR constant)
kate.wardf51c6162008-06-17 16:38:35 +0000432fail()
433{
kate.wardf32fb4f2008-07-11 15:20:38 +0000434 ${_SHUNIT_LINENO_}
435 if [ $# -gt 1 ]; then
kate.ward9a183b82010-03-18 00:25:34 +0000436 _shunit_error "fail() requires zero or one arguments; $# given"
kate.wardf32fb4f2008-07-11 15:20:38 +0000437 return ${SHUNIT_ERROR}
438 fi
kate.wardf51c6162008-06-17 16:38:35 +0000439 _shunit_shouldSkip && return ${SHUNIT_TRUE}
440
kate.ward38097672008-11-03 20:58:42 +0000441 shunit_message_=${__shunit_lineno}
kate.wardf32fb4f2008-07-11 15:20:38 +0000442 if [ $# -eq 1 ]; then
443 shunit_message_="${shunit_message_}$1"
444 shift
445 fi
kate.wardf51c6162008-06-17 16:38:35 +0000446
kate.ward38097672008-11-03 20:58:42 +0000447 _shunit_assertFail "${shunit_message_}"
kate.wardf51c6162008-06-17 16:38:35 +0000448
kate.wardf32fb4f2008-07-11 15:20:38 +0000449 unset shunit_message_
450 return ${SHUNIT_FALSE}
kate.wardf51c6162008-06-17 16:38:35 +0000451}
kate.wardf32fb4f2008-07-11 15:20:38 +0000452_FAIL_='eval fail --lineno "${LINENO:-}"'
kate.wardf51c6162008-06-17 16:38:35 +0000453
kate.ward9a183b82010-03-18 00:25:34 +0000454# Records a test failure, stating two values were not equal.
455#
456# Args:
457# message: string: failure message [optional]
kate.ward43e7ca12011-06-10 11:13:10 +0000458# expected: string: expected value
kate.ward9a183b82010-03-18 00:25:34 +0000459# actual: string: actual value
460# Returns:
461# integer: success (TRUE/FALSE/ERROR constant)
kate.wardf51c6162008-06-17 16:38:35 +0000462failNotEquals()
463{
kate.wardf32fb4f2008-07-11 15:20:38 +0000464 ${_SHUNIT_LINENO_}
465 if [ $# -lt 2 -o $# -gt 3 ]; then
kate.ward38097672008-11-03 20:58:42 +0000466 _shunit_error "failNotEquals() requires one or two arguments; $# given"
kate.wardf32fb4f2008-07-11 15:20:38 +0000467 return ${SHUNIT_ERROR}
468 fi
kate.wardf51c6162008-06-17 16:38:35 +0000469 _shunit_shouldSkip && return ${SHUNIT_TRUE}
470
kate.ward38097672008-11-03 20:58:42 +0000471 shunit_message_=${__shunit_lineno}
kate.wardf51c6162008-06-17 16:38:35 +0000472 if [ $# -eq 3 ]; then
kate.wardf32fb4f2008-07-11 15:20:38 +0000473 shunit_message_="${shunit_message_}$1"
kate.wardf51c6162008-06-17 16:38:35 +0000474 shift
475 fi
kate.ward43e7ca12011-06-10 11:13:10 +0000476 shunit_expected_=$1
kate.wardf32fb4f2008-07-11 15:20:38 +0000477 shunit_actual_=$2
kate.wardf51c6162008-06-17 16:38:35 +0000478
kate.ward43e7ca12011-06-10 11:13:10 +0000479 _shunit_assertFail "${shunit_message_:+${shunit_message_} }expected:<${shunit_expected_}> but was:<${shunit_actual_}>"
kate.wardf51c6162008-06-17 16:38:35 +0000480
kate.ward43e7ca12011-06-10 11:13:10 +0000481 unset shunit_message_ shunit_expected_ shunit_actual_
kate.wardf32fb4f2008-07-11 15:20:38 +0000482 return ${SHUNIT_FALSE}
kate.wardf51c6162008-06-17 16:38:35 +0000483}
kate.wardf32fb4f2008-07-11 15:20:38 +0000484_FAIL_NOT_EQUALS_='eval failNotEquals --lineno "${LINENO:-}"'
kate.wardf51c6162008-06-17 16:38:35 +0000485
kate.ward9a183b82010-03-18 00:25:34 +0000486# Records a test failure, stating two values should have been the same.
487#
488# Args:
489# message: string: failure message [optional]
490# expected: string: expected value
491# actual: string: actual value
492# Returns:
493# integer: success (TRUE/FALSE/ERROR constant)
kate.wardf51c6162008-06-17 16:38:35 +0000494failSame()
495{
kate.wardf32fb4f2008-07-11 15:20:38 +0000496 ${_SHUNIT_LINENO_}
497 if [ $# -lt 2 -o $# -gt 3 ]; then
kate.ward38097672008-11-03 20:58:42 +0000498 _shunit_error "failSame() requires two or three arguments; $# given"
kate.wardf32fb4f2008-07-11 15:20:38 +0000499 return ${SHUNIT_ERROR}
500 fi
kate.wardf51c6162008-06-17 16:38:35 +0000501 _shunit_shouldSkip && return ${SHUNIT_TRUE}
502
kate.ward38097672008-11-03 20:58:42 +0000503 shunit_message_=${__shunit_lineno}
kate.wardf32fb4f2008-07-11 15:20:38 +0000504 if [ $# -eq 3 ]; then
505 shunit_message_="${shunit_message_}$1"
506 shift
507 fi
kate.wardf51c6162008-06-17 16:38:35 +0000508
kate.ward38097672008-11-03 20:58:42 +0000509 _shunit_assertFail "${shunit_message_:+${shunit_message_} }expected not same"
kate.wardf51c6162008-06-17 16:38:35 +0000510
kate.wardf32fb4f2008-07-11 15:20:38 +0000511 unset shunit_message_
512 return ${SHUNIT_FALSE}
kate.wardf51c6162008-06-17 16:38:35 +0000513}
kate.wardf32fb4f2008-07-11 15:20:38 +0000514_FAIL_SAME_='eval failSame --lineno "${LINENO:-}"'
kate.wardf51c6162008-06-17 16:38:35 +0000515
kate.ward9a183b82010-03-18 00:25:34 +0000516# Records a test failure, stating two values were not equal.
517#
518# This is functionally equivalent to calling failNotEquals().
519#
520# Args:
521# message: string: failure message [optional]
kate.ward43e7ca12011-06-10 11:13:10 +0000522# expected: string: expected value
kate.ward9a183b82010-03-18 00:25:34 +0000523# actual: string: actual value
524# Returns:
525# integer: success (TRUE/FALSE/ERROR constant)
kate.wardf51c6162008-06-17 16:38:35 +0000526failNotSame()
527{
kate.wardf32fb4f2008-07-11 15:20:38 +0000528 ${_SHUNIT_LINENO_}
529 if [ $# -lt 2 -o $# -gt 3 ]; then
kate.ward38097672008-11-03 20:58:42 +0000530 _shunit_error "failNotEquals() requires one or two arguments; $# given"
kate.wardf32fb4f2008-07-11 15:20:38 +0000531 return ${SHUNIT_ERROR}
532 fi
533 _shunit_shouldSkip && return ${SHUNIT_TRUE}
534
kate.ward38097672008-11-03 20:58:42 +0000535 shunit_message_=${__shunit_lineno}
536 if [ $# -eq 3 ]; then
537 shunit_message_="${shunit_message_}$1"
538 shift
kate.wardf32fb4f2008-07-11 15:20:38 +0000539 fi
kate.ward38097672008-11-03 20:58:42 +0000540 failNotEquals "${shunit_message_}" "$1" "$2"
541 shunit_return=$?
542
543 unset shunit_message_
544 return ${shunit_return}
kate.wardf51c6162008-06-17 16:38:35 +0000545}
kate.wardf32fb4f2008-07-11 15:20:38 +0000546_FAIL_NOT_SAME_='eval failNotSame --lineno "${LINENO:-}"'
kate.wardf51c6162008-06-17 16:38:35 +0000547
548#-----------------------------------------------------------------------------
549# skipping functions
550#
551
kate.ward9a183b82010-03-18 00:25:34 +0000552# Force remaining assert and fail functions to be "skipped".
553#
554# This function forces the remaining assert and fail functions to be "skipped",
555# i.e. they will have no effect. Each function skipped will be recorded so that
556# the total of asserts and fails will not be altered.
557#
558# Args:
559# None
kate.wardf51c6162008-06-17 16:38:35 +0000560startSkipping()
561{
562 __shunit_skip=${SHUNIT_TRUE}
563}
564
kate.ward9a183b82010-03-18 00:25:34 +0000565# Resume the normal recording behavior of assert and fail calls.
566#
567# Args:
568# None
kate.wardf51c6162008-06-17 16:38:35 +0000569endSkipping()
570{
571 __shunit_skip=${SHUNIT_FALSE}
572}
573
kate.ward9a183b82010-03-18 00:25:34 +0000574# Returns the state of assert and fail call skipping.
575#
576# Args:
577# None
578# Returns:
579# boolean: (TRUE/FALSE constant)
kate.wardf51c6162008-06-17 16:38:35 +0000580isSkipping()
581{
582 return ${__shunit_skip}
583}
584
585#-----------------------------------------------------------------------------
586# suite functions
587#
588
kate.ward9a183b82010-03-18 00:25:34 +0000589# Stub. This function should contains all unit test calls to be made.
590#
591# DEPRECATED (as of 2.1.0)
592#
593# This function can be optionally overridden by the user in their test suite.
594#
595# If this function exists, it will be called when shunit2 is sourced. If it
596# does not exist, shunit2 will search the parent script for all functions
597# beginning with the word 'test', and they will be added dynamically to the
598# test suite.
599#
600# This function should be overridden by the user in their unit test suite.
kate.wardf51c6162008-06-17 16:38:35 +0000601# Note: see _shunit_mktempFunc() for actual implementation
kate.ward9a183b82010-03-18 00:25:34 +0000602#
603# Args:
604# None
605#suite() { :; } # DO NOT UNCOMMENT THIS FUNCTION
kate.wardf51c6162008-06-17 16:38:35 +0000606
kate.ward9a183b82010-03-18 00:25:34 +0000607# Adds a function name to the list of tests schedule for execution.
608#
609# This function should only be called from within the suite() function.
610#
611# Args:
612# function: string: name of a function to add to current unit test suite
kate.wardf51c6162008-06-17 16:38:35 +0000613suite_addTest()
614{
kate.ward38097672008-11-03 20:58:42 +0000615 shunit_func_=${1:-}
kate.wardf51c6162008-06-17 16:38:35 +0000616
kate.ward38097672008-11-03 20:58:42 +0000617 __shunit_suite="${__shunit_suite:+${__shunit_suite} }${shunit_func_}"
618 __shunit_testsTotal=`expr ${__shunit_testsTotal} + 1`
kate.wardf51c6162008-06-17 16:38:35 +0000619
kate.ward38097672008-11-03 20:58:42 +0000620 unset shunit_func_
kate.wardf51c6162008-06-17 16:38:35 +0000621}
622
kate.ward9a183b82010-03-18 00:25:34 +0000623# Stub. This function will be called once before any tests are run.
624#
625# Common one-time environment preparation tasks shared by all tests can be
626# defined here.
627#
628# This function should be overridden by the user in their unit test suite.
kate.wardf51c6162008-06-17 16:38:35 +0000629# Note: see _shunit_mktempFunc() for actual implementation
kate.ward9a183b82010-03-18 00:25:34 +0000630#
631# Args:
632# None
633#oneTimeSetUp() { :; } # DO NOT UNCOMMENT THIS FUNCTION
kate.wardf51c6162008-06-17 16:38:35 +0000634
kate.ward9a183b82010-03-18 00:25:34 +0000635# Stub. This function will be called once after all tests are finished.
636#
637# Common one-time environment cleanup tasks shared by all tests can be defined
638# here.
639#
640# This function should be overridden by the user in their unit test suite.
kate.wardf51c6162008-06-17 16:38:35 +0000641# Note: see _shunit_mktempFunc() for actual implementation
kate.ward9a183b82010-03-18 00:25:34 +0000642#
643# Args:
644# None
645#oneTimeTearDown() { :; } # DO NOT UNCOMMENT THIS FUNCTION
kate.wardf51c6162008-06-17 16:38:35 +0000646
kate.ward9a183b82010-03-18 00:25:34 +0000647# Stub. This function will be called before each test is run.
648#
649# Common environment preparation tasks shared by all tests can be defined here.
650#
651# This function should be overridden by the user in their unit test suite.
kate.wardf51c6162008-06-17 16:38:35 +0000652# Note: see _shunit_mktempFunc() for actual implementation
kate.ward9a183b82010-03-18 00:25:34 +0000653#
654# Args:
655# None
656#setUp() { :; }
kate.wardf51c6162008-06-17 16:38:35 +0000657
kate.wardf51c6162008-06-17 16:38:35 +0000658# Note: see _shunit_mktempFunc() for actual implementation
kate.ward9a183b82010-03-18 00:25:34 +0000659# Stub. This function will be called after each test is run.
660#
661# Common environment cleanup tasks shared by all tests can be defined here.
662#
663# This function should be overridden by the user in their unit test suite.
664# Note: see _shunit_mktempFunc() for actual implementation
665#
666# Args:
667# None
668#tearDown() { :; } # DO NOT UNCOMMENT THIS FUNCTION
kate.wardf51c6162008-06-17 16:38:35 +0000669
670#------------------------------------------------------------------------------
671# internal shUnit2 functions
672#
673
kate.ward9a183b82010-03-18 00:25:34 +0000674# Create a temporary directory to store various run-time files in.
675#
676# This function is a cross-platform temporary directory creation tool. Not all
kate.wardf51c6162008-06-17 16:38:35 +0000677# OSes have the mktemp function, so one is included here.
kate.ward9a183b82010-03-18 00:25:34 +0000678#
679# Args:
680# None
681# Outputs:
682# string: the temporary directory that was created
kate.wardf51c6162008-06-17 16:38:35 +0000683_shunit_mktempDir()
684{
685 # try the standard mktemp function
686 ( exec mktemp -dqt shunit.XXXXXX 2>/dev/null ) && return
687
688 # the standard mktemp didn't work. doing our own.
kate.ward9a183b82010-03-18 00:25:34 +0000689 if [ -r '/dev/urandom' -a -x '/usr/bin/od' ]; then
690 _shunit_random_=`/usr/bin/od -vAn -N4 -tx4 </dev/urandom \
691 |sed 's/^[^0-9a-f]*//'`
kate.wardf51c6162008-06-17 16:38:35 +0000692 elif [ -n "${RANDOM:-}" ]; then
693 # $RANDOM works
kate.ward38097672008-11-03 20:58:42 +0000694 _shunit_random_=${RANDOM}${RANDOM}${RANDOM}$$
kate.wardf51c6162008-06-17 16:38:35 +0000695 else
696 # $RANDOM doesn't work
kate.ward38097672008-11-03 20:58:42 +0000697 _shunit_date_=`date '+%Y%m%d%H%M%S'`
698 _shunit_random_=`expr ${_shunit_date_} / $$`
kate.wardf51c6162008-06-17 16:38:35 +0000699 fi
700
kate.ward38097672008-11-03 20:58:42 +0000701 _shunit_tmpDir_="${TMPDIR:-/tmp}/shunit.${_shunit_random_}"
kate.ward43e7ca12011-06-10 11:13:10 +0000702 ( umask 077 && mkdir "${_shunit_tmpDir_}" ) || \
703 _shunit_fatal 'could not create temporary directory! exiting'
kate.wardf51c6162008-06-17 16:38:35 +0000704
kate.ward38097672008-11-03 20:58:42 +0000705 echo ${_shunit_tmpDir_}
706 unset _shunit_date_ _shunit_random_ _shunit_tmpDir_
kate.wardf51c6162008-06-17 16:38:35 +0000707}
708
kate.ward43e7ca12011-06-10 11:13:10 +0000709# This function is here to work around issues in Cygwin.
kate.ward9a183b82010-03-18 00:25:34 +0000710#
711# Args:
712# None
kate.wardf51c6162008-06-17 16:38:35 +0000713_shunit_mktempFunc()
714{
kate.ward43e7ca12011-06-10 11:13:10 +0000715 for _shunit_func_ in oneTimeSetUp oneTimeTearDown setUp tearDown suite noexec
716 do
kate.ward38097672008-11-03 20:58:42 +0000717 _shunit_file_="${__shunit_tmpDir}/${_shunit_func_}"
718 cat <<EOF >"${_shunit_file_}"
kate.wardf51c6162008-06-17 16:38:35 +0000719#! /bin/sh
kate.ward38097672008-11-03 20:58:42 +0000720exit ${SHUNIT_TRUE}
kate.wardf51c6162008-06-17 16:38:35 +0000721EOF
kate.ward38097672008-11-03 20:58:42 +0000722 chmod +x "${_shunit_file_}"
kate.wardf51c6162008-06-17 16:38:35 +0000723 done
724
kate.ward38097672008-11-03 20:58:42 +0000725 unset _shunit_file_
726}
727
kate.ward9a183b82010-03-18 00:25:34 +0000728# Final cleanup function to leave things as we found them.
729#
730# Besides removing the temporary directory, this function is in charge of the
731# final exit code of the unit test. The exit code is based on how the script
732# was ended (e.g. normal exit, or via Ctrl-C).
733#
734# Args:
735# name: string: name of the trap called (specified when trap defined)
kate.ward38097672008-11-03 20:58:42 +0000736_shunit_cleanup()
737{
738 _shunit_name_=$1
739
740 case ${_shunit_name_} in
741 EXIT) _shunit_signal_=0 ;;
742 INT) _shunit_signal_=2 ;;
743 TERM) _shunit_signal_=15 ;;
744 *)
745 _shunit_warn "unrecognized trap value (${_shunit_name_})"
746 _shunit_signal_=0
747 ;;
748 esac
749
750 # do our work
751 rm -fr "${__shunit_tmpDir}"
752
753 # exit for all non-EXIT signals
754 if [ ${_shunit_name_} != 'EXIT' ]; then
755 _shunit_warn "trapped and now handling the (${_shunit_name_}) signal"
756 # disable EXIT trap
757 trap 0
758 # add 128 to signal and exit
759 exit `expr ${_shunit_signal_} + 128`
760 elif [ ${__shunit_reportGenerated} -eq ${SHUNIT_FALSE} ] ; then
761 _shunit_assertFail 'Unknown failure encountered running a test'
762 _shunit_generateReport
763 exit ${SHUNIT_ERROR}
764 fi
765
766 unset _shunit_name_ _shunit_signal_
767}
768
769# The actual running of the tests happens here.
kate.ward9a183b82010-03-18 00:25:34 +0000770#
771# Args:
772# None
kate.ward38097672008-11-03 20:58:42 +0000773_shunit_execSuite()
774{
775 for _shunit_test_ in ${__shunit_suite}; do
776 __shunit_testSuccess=${SHUNIT_TRUE}
777
778 # disable skipping
779 endSkipping
780
781 # execute the per-test setup function
782 setUp
783
784 # execute the test
785 echo "${_shunit_test_}"
786 eval ${_shunit_test_}
787
788 # execute the per-test tear-down function
789 tearDown
790
791 # update stats
792 if [ ${__shunit_testSuccess} -eq ${SHUNIT_TRUE} ]; then
793 __shunit_testsPassed=`expr ${__shunit_testsPassed} + 1`
794 else
795 __shunit_testsFailed=`expr ${__shunit_testsFailed} + 1`
796 fi
797 done
798
799 unset _shunit_test_
800}
801
kate.ward9a183b82010-03-18 00:25:34 +0000802# Generates the user friendly report with appropriate OK/FAILED message.
803#
804# Args:
805# None
806# Output:
807# string: the report of successful and failed tests, as well as totals.
kate.ward38097672008-11-03 20:58:42 +0000808_shunit_generateReport()
809{
810 _shunit_ok_=${SHUNIT_TRUE}
811
812 # if no exit code was provided one, determine an appropriate one
813 [ ${__shunit_testsFailed} -gt 0 \
814 -o ${__shunit_testSuccess} -eq ${SHUNIT_FALSE} ] \
815 && _shunit_ok_=${SHUNIT_FALSE}
816
817 echo
818 if [ ${__shunit_testsTotal} -eq 1 ]; then
819 echo "Ran ${__shunit_testsTotal} test."
820 else
821 echo "Ran ${__shunit_testsTotal} tests."
822 fi
823
824 _shunit_failures_=''
825 _shunit_skipped_=''
826 [ ${__shunit_assertsFailed} -gt 0 ] \
827 && _shunit_failures_="failures=${__shunit_assertsFailed}"
828 [ ${__shunit_assertsSkipped} -gt 0 ] \
829 && _shunit_skipped_="skipped=${__shunit_assertsSkipped}"
830
831 if [ ${_shunit_ok_} -eq ${SHUNIT_TRUE} ]; then
832 _shunit_msg_='OK'
833 [ -n "${_shunit_skipped_}" ] \
834 && _shunit_msg_="${_shunit_msg_} (${_shunit_skipped_})"
835 else
836 _shunit_msg_="FAILED (${_shunit_failures_}"
837 [ -n "${_shunit_skipped_}" ] \
838 && _shunit_msg_="${_shunit_msg_},${_shunit_skipped_}"
839 _shunit_msg_="${_shunit_msg_})"
840 fi
841
842 echo
843 echo ${_shunit_msg_}
844 __shunit_reportGenerated=${SHUNIT_TRUE}
845
846 unset _shunit_failures_ _shunit_msg_ _shunit_ok_ _shunit_skipped_
kate.wardf51c6162008-06-17 16:38:35 +0000847}
848
kate.ward9a183b82010-03-18 00:25:34 +0000849# Test for whether a function should be skipped.
850#
851# Args:
852# None
853# Returns:
854# boolean: whether the test should be skipped (TRUE/FALSE constant)
kate.wardf51c6162008-06-17 16:38:35 +0000855_shunit_shouldSkip()
856{
857 [ ${__shunit_skip} -eq ${SHUNIT_FALSE} ] && return ${SHUNIT_FALSE}
kate.ward38097672008-11-03 20:58:42 +0000858 _shunit_assertSkip
kate.wardf51c6162008-06-17 16:38:35 +0000859}
860
kate.ward9a183b82010-03-18 00:25:34 +0000861# Records a successful test.
862#
863# Args:
864# None
kate.ward38097672008-11-03 20:58:42 +0000865_shunit_assertPass()
kate.wardf51c6162008-06-17 16:38:35 +0000866{
kate.ward38097672008-11-03 20:58:42 +0000867 __shunit_assertsPassed=`expr ${__shunit_assertsPassed} + 1`
868 __shunit_assertsTotal=`expr ${__shunit_assertsTotal} + 1`
kate.wardf51c6162008-06-17 16:38:35 +0000869}
870
kate.ward9a183b82010-03-18 00:25:34 +0000871# Records a test failure.
872#
873# Args:
874# message: string: failure message to provide user
kate.ward38097672008-11-03 20:58:42 +0000875_shunit_assertFail()
kate.wardf51c6162008-06-17 16:38:35 +0000876{
kate.ward38097672008-11-03 20:58:42 +0000877 _shunit_msg_=$1
kate.wardf51c6162008-06-17 16:38:35 +0000878
kate.ward38097672008-11-03 20:58:42 +0000879 __shunit_testSuccess=${SHUNIT_FALSE}
880 __shunit_assertsFailed=`expr ${__shunit_assertsFailed} + 1`
881 __shunit_assertsTotal=`expr ${__shunit_assertsTotal} + 1`
882 echo "${__SHUNIT_ASSERT_MSG_PREFIX}${_shunit_msg_}"
kate.wardf51c6162008-06-17 16:38:35 +0000883
kate.ward38097672008-11-03 20:58:42 +0000884 unset _shunit_msg_
kate.wardf51c6162008-06-17 16:38:35 +0000885}
886
kate.ward9a183b82010-03-18 00:25:34 +0000887# Records a skipped test.
888#
889# Args:
890# None
kate.ward38097672008-11-03 20:58:42 +0000891_shunit_assertSkip()
kate.wardf51c6162008-06-17 16:38:35 +0000892{
kate.ward38097672008-11-03 20:58:42 +0000893 __shunit_assertsSkipped=`expr ${__shunit_assertsSkipped} + 1`
894 __shunit_assertsTotal=`expr ${__shunit_assertsTotal} + 1`
kate.wardf51c6162008-06-17 16:38:35 +0000895}
896
kate.ward43e7ca12011-06-10 11:13:10 +0000897# Prepare a script filename for sourcing.
898#
899# Args:
900# script: string: path to a script to source
901# Returns:
902# string: filename prefixed with ./ (if necessary)
903_shunit_prepForSourcing()
904{
905 _shunit_script_=$1
906 case "${_shunit_script_}" in
907 /*|./*) echo "${_shunit_script_}" ;;
908 *) echo "./${_shunit_script_}" ;;
909 esac
910 unset _shunit_script_
911}
912
913# Escape a character in a string.
914#
915# Args:
916# c: string: unescaped character
917# s: string: to escape character in
918# Returns:
919# string: with escaped character(s)
920_shunit_escapeCharInStr()
921{
922 [ -n "$2" ] || return # no point in doing work on an empty string
923
924 # Note: using shorter variable names to prevent conflicts with
925 # _shunit_escapeCharactersInString().
926 _shunit_c_=$1
927 _shunit_s_=$2
928
929
930 # escape the character
931 echo ''${_shunit_s_}'' |sed 's/\'${_shunit_c_}'/\\\'${_shunit_c_}'/g'
932
933 unset _shunit_c_ _shunit_s_
934}
935
936# Escape a character in a string.
937#
938# Args:
939# str: string: to escape characters in
940# Returns:
941# string: with escaped character(s)
942_shunit_escapeCharactersInString()
943{
944 [ -n "$1" ] || return # no point in doing work on an empty string
945
946 _shunit_str_=$1
947
948 # Note: using longer variable names to prevent conflicts with
949 # _shunit_escapeCharInStr().
950 for _shunit_char_ in '"' '$' "'" '`'; do
951 _shunit_str_=`_shunit_escapeCharInStr "${_shunit_char_}" "${_shunit_str_}"`
952 done
953
954 echo "${_shunit_str_}"
955 unset _shunit_char_ _shunit_str_
956}
957
958# Extract list of functions to run tests against.
959#
960# Args:
961# script: string: name of script to extract functions from
962# Returns:
963# string: of function names
964_shunit_extractTestFunctions()
965{
966 _shunit_script_=$1
967
968 # extract the lines with test function names, strip of anything besides the
969 # function name, and output everything on a single line.
970 _shunit_regex_='^[ ]*(function )*test[A-Za-z0-9_]* *\(\)'
971 egrep "${_shunit_regex_}" "${_shunit_script_}" \
972 |sed 's/^[^A-Za-z0-9_]*//;s/^function //;s/\([A-Za-z0-9_]*\).*/\1/g' \
973 |xargs
974
975 unset _shunit_regex_ _shunit_script_
976}
977
kate.wardf51c6162008-06-17 16:38:35 +0000978#------------------------------------------------------------------------------
979# main
980#
981
kate.ward43e7ca12011-06-10 11:13:10 +0000982# determine the operating mode
983if [ $# -eq 0 ]; then
984 __shunit_script=${__SHUNIT_PARENT}
985 __shunit_mode=${__SHUNIT_MODE_SOURCED}
986else
987 __shunit_script=$1
988 [ -r "${__shunit_script}" ] || \
989 _shunit_fatal "unable to read from ${__shunit_script}"
990 __shunit_mode=${__SHUNIT_MODE_STANDALONE}
991fi
992
kate.wardf51c6162008-06-17 16:38:35 +0000993# create a temporary storage location
kate.ward43e7ca12011-06-10 11:13:10 +0000994__shunit_tmpDir=`_shunit_mktempDir`
kate.wardf51c6162008-06-17 16:38:35 +0000995
kate.ward38097672008-11-03 20:58:42 +0000996# provide a public temporary directory for unit test scripts
997# TODO(kward): document this
kate.ward43e7ca12011-06-10 11:13:10 +0000998SHUNIT_TMPDIR="${__shunit_tmpDir}/tmp"
999mkdir "${SHUNIT_TMPDIR}"
kate.ward38097672008-11-03 20:58:42 +00001000
kate.wardf51c6162008-06-17 16:38:35 +00001001# setup traps to clean up after ourselves
1002trap '_shunit_cleanup EXIT' 0
1003trap '_shunit_cleanup INT' 2
1004trap '_shunit_cleanup TERM' 15
1005
1006# create phantom functions to work around issues with Cygwin
1007_shunit_mktempFunc
1008PATH="${__shunit_tmpDir}:${PATH}"
1009
kate.ward43e7ca12011-06-10 11:13:10 +00001010# make sure phantom functions are executable. this will bite if /tmp (or the
1011# current $TMPDIR) points to a path on a partition that was mounted with the
1012# 'noexec' option. the noexec command was created with _shunit_mktempFunc().
1013noexec 2>/dev/null || _shunit_fatal \
1014 'please declare TMPDIR with path on partition with exec permission'
1015
1016# we must manually source the tests in standalone mode
1017if [ "${__shunit_mode}" = "${__SHUNIT_MODE_STANDALONE}" ]; then
1018 . "`_shunit_prepForSourcing \"${__shunit_script}\"`"
1019fi
1020
kate.wardf51c6162008-06-17 16:38:35 +00001021# execute the oneTimeSetUp function (if it exists)
kate.wardf51c6162008-06-17 16:38:35 +00001022oneTimeSetUp
1023
1024# execute the suite function defined in the parent test script
1025# deprecated as of 2.1.0
1026suite
1027
1028# if no suite function was defined, dynamically build a list of functions
1029if [ -z "${__shunit_suite}" ]; then
kate.ward43e7ca12011-06-10 11:13:10 +00001030 shunit_funcs_=`_shunit_extractTestFunctions "${__shunit_script}"`
kate.wardf32fb4f2008-07-11 15:20:38 +00001031 for shunit_func_ in ${shunit_funcs_}; do
1032 suite_addTest ${shunit_func_}
kate.wardf51c6162008-06-17 16:38:35 +00001033 done
1034fi
kate.wardf32fb4f2008-07-11 15:20:38 +00001035unset shunit_func_ shunit_funcs_
kate.wardf51c6162008-06-17 16:38:35 +00001036
1037# execute the tests
1038_shunit_execSuite
1039
1040# execute the oneTimeTearDown function (if it exists)
1041oneTimeTearDown
1042
kate.ward38097672008-11-03 20:58:42 +00001043# generate the report
kate.wardf51c6162008-06-17 16:38:35 +00001044_shunit_generateReport
1045
kate.ward38097672008-11-03 20:58:42 +00001046# that's it folks
1047[ ${__shunit_testsFailed} -eq 0 ]
1048exit $?