Browse code

added testing suit to easier access

Blackbeard authored on 2018-09-14 22:49:17
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,1169 @@
1
+#! /bin/sh
2
+# vim:et:ft=sh:sts=2:sw=2
3
+#
4
+# Copyright 2008-2018 Kate Ward. All Rights Reserved.
5
+# Released under the Apache 2.0 license.
6
+#
7
+# shUnit2 -- Unit testing framework for Unix shell scripts.
8
+# https://github.com/kward/shunit2
9
+#
10
+# Author: kate.ward@forestent.com (Kate Ward)
11
+#
12
+# shUnit2 is a xUnit based unit test framework for Bourne shell scripts. It is
13
+# based on the popular JUnit unit testing framework for Java.
14
+#
15
+# $() are not fully portable (POSIX != portable).
16
+#   shellcheck disable=SC2006
17
+# expr may be antiquated, but it is the only solution in some cases.
18
+#   shellcheck disable=SC2003
19
+
20
+# Return if shunit2 already loaded.
21
+command [ -n "${SHUNIT_VERSION:-}" ] && exit 0
22
+SHUNIT_VERSION='2.1.8pre'
23
+
24
+# Return values that scripts can use.
25
+SHUNIT_TRUE=0
26
+SHUNIT_FALSE=1
27
+SHUNIT_ERROR=2
28
+
29
+# Logging functions.
30
+_shunit_warn() {
31
+  ${__SHUNIT_CMD_ECHO_ESC} \
32
+      "${__shunit_ansi_yellow}shunit2:WARN${__shunit_ansi_none} $*" >&2
33
+}
34
+_shunit_error() {
35
+  ${__SHUNIT_CMD_ECHO_ESC} \
36
+      "${__shunit_ansi_red}shunit2:ERROR${__shunit_ansi_none} $*" >&2
37
+}
38
+_shunit_fatal() {
39
+  ${__SHUNIT_CMD_ECHO_ESC} \
40
+      "${__shunit_ansi_red}shunit2:FATAL${__shunit_ansi_none} $*" >&2
41
+  exit ${SHUNIT_ERROR}
42
+}
43
+
44
+# Determine some reasonable command defaults.
45
+__SHUNIT_UNAME_S=`uname -s`
46
+case "${__SHUNIT_UNAME_S}" in
47
+  BSD) __SHUNIT_CMD_EXPR='gexpr' ;;
48
+  *) __SHUNIT_CMD_EXPR='expr' ;;
49
+esac
50
+
51
+__SHUNIT_CMD_ECHO_ESC='echo -e'
52
+# shellcheck disable=SC2039
53
+command [ "`echo -e test`" = '-e test' ] && __SHUNIT_CMD_ECHO_ESC='echo'
54
+
55
+# Commands a user can override if needed.
56
+SHUNIT_CMD_EXPR=${SHUNIT_CMD_EXPR:-${__SHUNIT_CMD_EXPR}}
57
+
58
+# Enable color output. Options are 'never', 'always', or 'auto'.
59
+SHUNIT_COLOR=${SHUNIT_COLOR:-auto}
60
+
61
+# Specific shell checks.
62
+if command [ -n "${ZSH_VERSION:-}" ]; then
63
+  setopt |grep "^shwordsplit$" >/dev/null
64
+  if command [ $? -ne ${SHUNIT_TRUE} ]; then
65
+    _shunit_fatal 'zsh shwordsplit option is required for proper operation'
66
+  fi
67
+  if command [ -z "${SHUNIT_PARENT:-}" ]; then
68
+    _shunit_fatal "zsh does not pass \$0 through properly. please declare \
69
+\"SHUNIT_PARENT=\$0\" before calling shUnit2"
70
+  fi
71
+fi
72
+
73
+#
74
+# Constants
75
+#
76
+
77
+__SHUNIT_MODE_SOURCED='sourced'
78
+__SHUNIT_MODE_STANDALONE='standalone'
79
+__SHUNIT_PARENT=${SHUNIT_PARENT:-$0}
80
+
81
+# User provided test prefix -- define SHUNIT_TEST_PREFIX variable.
82
+__SHUNIT_TEST_PREFIX=${SHUNIT_TEST_PREFIX:-}
83
+
84
+# ANSI colors.
85
+__SHUNIT_ANSI_NONE='\033[0m'
86
+__SHUNIT_ANSI_RED='\033[1;31m'
87
+__SHUNIT_ANSI_GREEN='\033[1;32m'
88
+__SHUNIT_ANSI_YELLOW='\033[1;33m'
89
+__SHUNIT_ANSI_CYAN='\033[1;36m'
90
+
91
+# Set the constants readonly.
92
+__shunit_constants=`set |grep '^__SHUNIT_' |cut -d= -f1`
93
+echo "${__shunit_constants}" |grep '^Binary file' >/dev/null && \
94
+    __shunit_constants=`set |grep -a '^__SHUNIT_' |cut -d= -f1`
95
+for __shunit_const in ${__shunit_constants}; do
96
+  if command [ -z "${ZSH_VERSION:-}" ]; then
97
+    readonly "${__shunit_const}"
98
+  else
99
+    case ${ZSH_VERSION} in
100
+      [123].*) readonly "${__shunit_const}" ;;
101
+      *) readonly -g "${__shunit_const}"  # Declare readonly constants globally.
102
+    esac
103
+  fi
104
+done
105
+unset __shunit_const __shunit_constants
106
+
107
+#
108
+# Internal variables.
109
+#
110
+
111
+# Variables.
112
+__shunit_lineno=''  # Line number of executed test.
113
+__shunit_mode=${__SHUNIT_MODE_SOURCED}  # Operating mode.
114
+__shunit_reportGenerated=${SHUNIT_FALSE}  # Is report generated.
115
+__shunit_script=''  # Filename of unittest script (standalone mode).
116
+__shunit_skip=${SHUNIT_FALSE}  # Is skipping enabled.
117
+__shunit_suite=''  # Suite of tests to execute.
118
+
119
+# ANSI colors (populated by _shunit_configureColor()).
120
+__shunit_ansi_none=''
121
+__shunit_ansi_red=''
122
+__shunit_ansi_green=''
123
+__shunit_ansi_yellow=''
124
+__shunit_ansi_cyan=''
125
+
126
+# Counts of tests.
127
+__shunit_testSuccess=${SHUNIT_TRUE}
128
+__shunit_testsTotal=0
129
+__shunit_testsPassed=0
130
+__shunit_testsFailed=0
131
+
132
+# Counts of asserts.
133
+__shunit_assertsTotal=0
134
+__shunit_assertsPassed=0
135
+__shunit_assertsFailed=0
136
+__shunit_assertsSkipped=0
137
+
138
+#
139
+# Macros.
140
+#
141
+
142
+# shellcheck disable=SC2016,SC2089
143
+_SHUNIT_LINENO_='eval __shunit_lineno=""; if command [ "${1:-}" = "--lineno" ]; then command [ -n "$2" ] && __shunit_lineno="[$2] "; shift 2; fi'
144
+
145
+#-----------------------------------------------------------------------------
146
+# Assertion functions.
147
+#
148
+
149
+# Assert that two values are equal to one another.
150
+#
151
+# Args:
152
+#   message: string: failure message [optional]
153
+#   expected: string: expected value
154
+#   actual: string: actual value
155
+# Returns:
156
+#   integer: success (TRUE/FALSE/ERROR constant)
157
+assertEquals() {
158
+  # shellcheck disable=SC2090
159
+  ${_SHUNIT_LINENO_}
160
+  if command [ $# -lt 2 -o $# -gt 3 ]; then
161
+    _shunit_error "assertEquals() requires two or three arguments; $# given"
162
+    _shunit_assertFail
163
+    return ${SHUNIT_ERROR}
164
+  fi
165
+  _shunit_shouldSkip && return ${SHUNIT_TRUE}
166
+
167
+  shunit_message_=${__shunit_lineno}
168
+  if command [ $# -eq 3 ]; then
169
+    shunit_message_="${shunit_message_}$1"
170
+    shift
171
+  fi
172
+  shunit_expected_=$1
173
+  shunit_actual_=$2
174
+
175
+  shunit_return=${SHUNIT_TRUE}
176
+  if command [ "${shunit_expected_}" = "${shunit_actual_}" ]; then
177
+    _shunit_assertPass
178
+  else
179
+    failNotEquals "${shunit_message_}" "${shunit_expected_}" "${shunit_actual_}"
180
+    shunit_return=${SHUNIT_FALSE}
181
+  fi
182
+
183
+  unset shunit_message_ shunit_expected_ shunit_actual_
184
+  return ${shunit_return}
185
+}
186
+# shellcheck disable=SC2016,SC2034
187
+_ASSERT_EQUALS_='eval assertEquals --lineno "${LINENO:-}"'
188
+
189
+# Assert that two values are not equal to one another.
190
+#
191
+# Args:
192
+#   message: string: failure message [optional]
193
+#   expected: string: expected value
194
+#   actual: string: actual value
195
+# Returns:
196
+#   integer: success (TRUE/FALSE/ERROR constant)
197
+assertNotEquals() {
198
+  # shellcheck disable=SC2090
199
+  ${_SHUNIT_LINENO_}
200
+  if command [ $# -lt 2 -o $# -gt 3 ]; then
201
+    _shunit_error "assertNotEquals() requires two or three arguments; $# given"
202
+    _shunit_assertFail
203
+    return ${SHUNIT_ERROR}
204
+  fi
205
+  _shunit_shouldSkip && return ${SHUNIT_TRUE}
206
+
207
+  shunit_message_=${__shunit_lineno}
208
+  if command [ $# -eq 3 ]; then
209
+    shunit_message_="${shunit_message_}$1"
210
+    shift
211
+  fi
212
+  shunit_expected_=$1
213
+  shunit_actual_=$2
214
+
215
+  shunit_return=${SHUNIT_TRUE}
216
+  if command [ "${shunit_expected_}" != "${shunit_actual_}" ]; then
217
+    _shunit_assertPass
218
+  else
219
+    failSame "${shunit_message_}" "$@"
220
+    shunit_return=${SHUNIT_FALSE}
221
+  fi
222
+
223
+  unset shunit_message_ shunit_expected_ shunit_actual_
224
+  return ${shunit_return}
225
+}
226
+# shellcheck disable=SC2016,SC2034
227
+_ASSERT_NOT_EQUALS_='eval assertNotEquals --lineno "${LINENO:-}"'
228
+
229
+# Assert that a value is null (i.e. an empty string)
230
+#
231
+# Args:
232
+#   message: string: failure message [optional]
233
+#   actual: string: actual value
234
+# Returns:
235
+#   integer: success (TRUE/FALSE/ERROR constant)
236
+assertNull() {
237
+  # shellcheck disable=SC2090
238
+  ${_SHUNIT_LINENO_}
239
+  if command [ $# -lt 1 -o $# -gt 2 ]; then
240
+    _shunit_error "assertNull() requires one or two arguments; $# given"
241
+    _shunit_assertFail
242
+    return ${SHUNIT_ERROR}
243
+  fi
244
+  _shunit_shouldSkip && return ${SHUNIT_TRUE}
245
+
246
+  shunit_message_=${__shunit_lineno}
247
+  if command [ $# -eq 2 ]; then
248
+    shunit_message_="${shunit_message_}$1"
249
+    shift
250
+  fi
251
+  assertTrue "${shunit_message_}" "[ -z '$1' ]"
252
+  shunit_return=$?
253
+
254
+  unset shunit_message_
255
+  return ${shunit_return}
256
+}
257
+# shellcheck disable=SC2016,SC2034
258
+_ASSERT_NULL_='eval assertNull --lineno "${LINENO:-}"'
259
+
260
+# Assert that a value is not null (i.e. a non-empty string)
261
+#
262
+# Args:
263
+#   message: string: failure message [optional]
264
+#   actual: string: actual value
265
+# Returns:
266
+#   integer: success (TRUE/FALSE/ERROR constant)
267
+assertNotNull() {
268
+  # shellcheck disable=SC2090
269
+  ${_SHUNIT_LINENO_}
270
+  if command [ $# -gt 2 ]; then  # allowing 0 arguments as $1 might actually be null
271
+    _shunit_error "assertNotNull() requires one or two arguments; $# given"
272
+    _shunit_assertFail
273
+    return ${SHUNIT_ERROR}
274
+  fi
275
+  _shunit_shouldSkip && return ${SHUNIT_TRUE}
276
+
277
+  shunit_message_=${__shunit_lineno}
278
+  if command [ $# -eq 2 ]; then
279
+    shunit_message_="${shunit_message_}$1"
280
+    shift
281
+  fi
282
+  shunit_actual_=`_shunit_escapeCharactersInString "${1:-}"`
283
+  test -n "${shunit_actual_}"
284
+  assertTrue "${shunit_message_}" $?
285
+  shunit_return=$?
286
+
287
+  unset shunit_actual_ shunit_message_
288
+  return ${shunit_return}
289
+}
290
+# shellcheck disable=SC2016,SC2034
291
+_ASSERT_NOT_NULL_='eval assertNotNull --lineno "${LINENO:-}"'
292
+
293
+# Assert that two values are the same (i.e. equal to one another).
294
+#
295
+# Args:
296
+#   message: string: failure message [optional]
297
+#   expected: string: expected value
298
+#   actual: string: actual value
299
+# Returns:
300
+#   integer: success (TRUE/FALSE/ERROR constant)
301
+assertSame() {
302
+  # shellcheck disable=SC2090
303
+  ${_SHUNIT_LINENO_}
304
+  if command [ $# -lt 2 -o $# -gt 3 ]; then
305
+    _shunit_error "assertSame() requires two or three arguments; $# given"
306
+    _shunit_assertFail
307
+    return ${SHUNIT_ERROR}
308
+  fi
309
+  _shunit_shouldSkip && return ${SHUNIT_TRUE}
310
+
311
+  shunit_message_=${__shunit_lineno}
312
+  if command [ $# -eq 3 ]; then
313
+    shunit_message_="${shunit_message_}$1"
314
+    shift
315
+  fi
316
+  assertEquals "${shunit_message_}" "$1" "$2"
317
+  shunit_return=$?
318
+
319
+  unset shunit_message_
320
+  return ${shunit_return}
321
+}
322
+# shellcheck disable=SC2016,SC2034
323
+_ASSERT_SAME_='eval assertSame --lineno "${LINENO:-}"'
324
+
325
+# Assert that two values are not the same (i.e. not equal to one another).
326
+#
327
+# Args:
328
+#   message: string: failure message [optional]
329
+#   expected: string: expected value
330
+#   actual: string: actual value
331
+# Returns:
332
+#   integer: success (TRUE/FALSE/ERROR constant)
333
+assertNotSame() {
334
+  # shellcheck disable=SC2090
335
+  ${_SHUNIT_LINENO_}
336
+  if command [ $# -lt 2 -o $# -gt 3 ]; then
337
+    _shunit_error "assertNotSame() requires two or three arguments; $# given"
338
+    _shunit_assertFail
339
+    return ${SHUNIT_ERROR}
340
+  fi
341
+  _shunit_shouldSkip && return ${SHUNIT_TRUE}
342
+
343
+  shunit_message_=${__shunit_lineno}
344
+  if command [ $# -eq 3 ]; then
345
+    shunit_message_="${shunit_message_:-}$1"
346
+    shift
347
+  fi
348
+  assertNotEquals "${shunit_message_}" "$1" "$2"
349
+  shunit_return=$?
350
+
351
+  unset shunit_message_
352
+  return ${shunit_return}
353
+}
354
+# shellcheck disable=SC2016,SC2034
355
+_ASSERT_NOT_SAME_='eval assertNotSame --lineno "${LINENO:-}"'
356
+
357
+# Assert that a value or shell test condition is true.
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
+#   assertTrue 0
368
+#   assertTrue "[ 34 -gt 23 ]"
369
+# The following test will fail with a message:
370
+#   assertTrue 123
371
+#   assertTrue "test failed" "[ -r '/non/existent/file' ]"
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)
378
+assertTrue() {
379
+  # shellcheck disable=SC2090
380
+  ${_SHUNIT_LINENO_}
381
+  if command [ $# -lt 1 -o $# -gt 2 ]; then
382
+    _shunit_error "assertTrue() takes one or two arguments; $# given"
383
+    _shunit_assertFail
384
+    return ${SHUNIT_ERROR}
385
+  fi
386
+  _shunit_shouldSkip && return ${SHUNIT_TRUE}
387
+
388
+  shunit_message_=${__shunit_lineno}
389
+  if command [ $# -eq 2 ]; then
390
+    shunit_message_="${shunit_message_}$1"
391
+    shift
392
+  fi
393
+  shunit_condition_=$1
394
+
395
+  # See if condition is an integer, i.e. a return value.
396
+  shunit_match_=`expr "${shunit_condition_}" : '\([0-9]*\)'`
397
+  shunit_return=${SHUNIT_TRUE}
398
+  if command [ -z "${shunit_condition_}" ]; then
399
+    # Null condition.
400
+    shunit_return=${SHUNIT_FALSE}
401
+  elif command [ -n "${shunit_match_}" -a "${shunit_condition_}" = "${shunit_match_}" ]
402
+  then
403
+    # Possible return value. Treating 0 as true, and non-zero as false.
404
+    command [ "${shunit_condition_}" -ne 0 ] && shunit_return=${SHUNIT_FALSE}
405
+  else
406
+    # Hopefully... a condition.
407
+    ( eval "${shunit_condition_}" ) >/dev/null 2>&1
408
+    command [ $? -ne 0 ] && shunit_return=${SHUNIT_FALSE}
409
+  fi
410
+
411
+  # Record the test.
412
+  if command [ ${shunit_return} -eq ${SHUNIT_TRUE} ]; then
413
+    _shunit_assertPass
414
+  else
415
+    _shunit_assertFail "${shunit_message_}"
416
+  fi
417
+
418
+  unset shunit_message_ shunit_condition_ shunit_match_
419
+  return ${shunit_return}
420
+}
421
+# shellcheck disable=SC2016,SC2034
422
+_ASSERT_TRUE_='eval assertTrue --lineno "${LINENO:-}"'
423
+
424
+# Assert that a value or shell test condition is false.
425
+#
426
+# In shell, a value of 0 is true and a non-zero value is false. Any integer
427
+# value passed can thereby be tested.
428
+#
429
+# Shell supports much more complicated tests though, and a means to support
430
+# them was needed. As such, this function tests that conditions are true or
431
+# false through evaluation rather than just looking for a true or false.
432
+#
433
+# The following test will succeed:
434
+#   assertFalse 1
435
+#   assertFalse "[ 'apples' = 'oranges' ]"
436
+# The following test will fail with a message:
437
+#   assertFalse 0
438
+#   assertFalse "test failed" "[ 1 -eq 1 -a 2 -eq 2 ]"
439
+#
440
+# Args:
441
+#   message: string: failure message [optional]
442
+#   condition: string: integer value or shell conditional statement
443
+# Returns:
444
+#   integer: success (TRUE/FALSE/ERROR constant)
445
+assertFalse() {
446
+  # shellcheck disable=SC2090
447
+  ${_SHUNIT_LINENO_}
448
+  if command [ $# -lt 1 -o $# -gt 2 ]; then
449
+    _shunit_error "assertFalse() quires one or two arguments; $# given"
450
+    _shunit_assertFail
451
+    return ${SHUNIT_ERROR}
452
+  fi
453
+  _shunit_shouldSkip && return ${SHUNIT_TRUE}
454
+
455
+  shunit_message_=${__shunit_lineno}
456
+  if command [ $# -eq 2 ]; then
457
+    shunit_message_="${shunit_message_}$1"
458
+    shift
459
+  fi
460
+  shunit_condition_=$1
461
+
462
+  # See if condition is an integer, i.e. a return value.
463
+  shunit_match_=`expr "${shunit_condition_}" : '\([0-9]*\)'`
464
+  shunit_return=${SHUNIT_TRUE}
465
+  if command [ -z "${shunit_condition_}" ]; then
466
+    # Null condition.
467
+    shunit_return=${SHUNIT_FALSE}
468
+  elif command [ -n "${shunit_match_}" -a "${shunit_condition_}" = "${shunit_match_}" ]
469
+  then
470
+    # Possible return value. Treating 0 as true, and non-zero as false.
471
+    command [ "${shunit_condition_}" -eq 0 ] && shunit_return=${SHUNIT_FALSE}
472
+  else
473
+    # Hopefully... a condition.
474
+    ( eval "${shunit_condition_}" ) >/dev/null 2>&1
475
+    command [ $? -eq 0 ] && shunit_return=${SHUNIT_FALSE}
476
+  fi
477
+
478
+  # Record the test.
479
+  if command [ "${shunit_return}" -eq "${SHUNIT_TRUE}" ]; then
480
+    _shunit_assertPass
481
+  else
482
+    _shunit_assertFail "${shunit_message_}"
483
+  fi
484
+
485
+  unset shunit_message_ shunit_condition_ shunit_match_
486
+  return "${shunit_return}"
487
+}
488
+# shellcheck disable=SC2016,SC2034
489
+_ASSERT_FALSE_='eval assertFalse --lineno "${LINENO:-}"'
490
+
491
+#-----------------------------------------------------------------------------
492
+# Failure functions.
493
+#
494
+
495
+# Records a test failure.
496
+#
497
+# Args:
498
+#   message: string: failure message [optional]
499
+# Returns:
500
+#   integer: success (TRUE/FALSE/ERROR constant)
501
+fail() {
502
+  # shellcheck disable=SC2090
503
+  ${_SHUNIT_LINENO_}
504
+  if command [ $# -gt 1 ]; then
505
+    _shunit_error "fail() requires zero or one arguments; $# given"
506
+    return ${SHUNIT_ERROR}
507
+  fi
508
+  _shunit_shouldSkip && return ${SHUNIT_TRUE}
509
+
510
+  shunit_message_=${__shunit_lineno}
511
+  if command [ $# -eq 1 ]; then
512
+    shunit_message_="${shunit_message_}$1"
513
+    shift
514
+  fi
515
+
516
+  _shunit_assertFail "${shunit_message_}"
517
+
518
+  unset shunit_message_
519
+  return ${SHUNIT_FALSE}
520
+}
521
+# shellcheck disable=SC2016,SC2034
522
+_FAIL_='eval fail --lineno "${LINENO:-}"'
523
+
524
+# Records a test failure, stating two values were not equal.
525
+#
526
+# Args:
527
+#   message: string: failure message [optional]
528
+#   expected: string: expected value
529
+#   actual: string: actual value
530
+# Returns:
531
+#   integer: success (TRUE/FALSE/ERROR constant)
532
+failNotEquals() {
533
+  # shellcheck disable=SC2090
534
+  ${_SHUNIT_LINENO_}
535
+  if command [ $# -lt 2 -o $# -gt 3 ]; then
536
+    _shunit_error "failNotEquals() requires one or two arguments; $# given"
537
+    return ${SHUNIT_ERROR}
538
+  fi
539
+  _shunit_shouldSkip && return ${SHUNIT_TRUE}
540
+
541
+  shunit_message_=${__shunit_lineno}
542
+  if command [ $# -eq 3 ]; then
543
+    shunit_message_="${shunit_message_}$1"
544
+    shift
545
+  fi
546
+  shunit_expected_=$1
547
+  shunit_actual_=$2
548
+
549
+  shunit_message_=${shunit_message_%% }
550
+  _shunit_assertFail "${shunit_message_:+${shunit_message_} }expected:<${shunit_expected_}> but was:<${shunit_actual_}>"
551
+
552
+  unset shunit_message_ shunit_expected_ shunit_actual_
553
+  return ${SHUNIT_FALSE}
554
+}
555
+# shellcheck disable=SC2016,SC2034
556
+_FAIL_NOT_EQUALS_='eval failNotEquals --lineno "${LINENO:-}"'
557
+
558
+# Records a test failure, stating two values should have been the same.
559
+#
560
+# Args:
561
+#   message: string: failure message [optional]
562
+#   expected: string: expected value
563
+#   actual: string: actual value
564
+# Returns:
565
+#   integer: success (TRUE/FALSE/ERROR constant)
566
+failSame()
567
+{
568
+  # shellcheck disable=SC2090
569
+  ${_SHUNIT_LINENO_}
570
+  if command [ $# -lt 2 -o $# -gt 3 ]; then
571
+    _shunit_error "failSame() requires two or three arguments; $# given"
572
+    return ${SHUNIT_ERROR}
573
+  fi
574
+  _shunit_shouldSkip && return ${SHUNIT_TRUE}
575
+
576
+  shunit_message_=${__shunit_lineno}
577
+  if command [ $# -eq 3 ]; then
578
+    shunit_message_="${shunit_message_}$1"
579
+    shift
580
+  fi
581
+
582
+  shunit_message_=${shunit_message_%% }
583
+  _shunit_assertFail "${shunit_message_:+${shunit_message_} }expected not same"
584
+
585
+  unset shunit_message_
586
+  return ${SHUNIT_FALSE}
587
+}
588
+# shellcheck disable=SC2016,SC2034
589
+_FAIL_SAME_='eval failSame --lineno "${LINENO:-}"'
590
+
591
+# Records a test failure, stating two values were not equal.
592
+#
593
+# This is functionally equivalent to calling failNotEquals().
594
+#
595
+# Args:
596
+#   message: string: failure message [optional]
597
+#   expected: string: expected value
598
+#   actual: string: actual value
599
+# Returns:
600
+#   integer: success (TRUE/FALSE/ERROR constant)
601
+failNotSame() {
602
+  # shellcheck disable=SC2090
603
+  ${_SHUNIT_LINENO_}
604
+  if command [ $# -lt 2 -o $# -gt 3 ]; then
605
+    _shunit_error "failNotSame() requires one or two arguments; $# given"
606
+    return ${SHUNIT_ERROR}
607
+  fi
608
+  _shunit_shouldSkip && return ${SHUNIT_TRUE}
609
+
610
+  shunit_message_=${__shunit_lineno}
611
+  if command [ $# -eq 3 ]; then
612
+    shunit_message_="${shunit_message_}$1"
613
+    shift
614
+  fi
615
+  failNotEquals "${shunit_message_}" "$1" "$2"
616
+  shunit_return=$?
617
+
618
+  unset shunit_message_
619
+  return ${shunit_return}
620
+}
621
+# shellcheck disable=SC2016,SC2034
622
+_FAIL_NOT_SAME_='eval failNotSame --lineno "${LINENO:-}"'
623
+
624
+#-----------------------------------------------------------------------------
625
+# Skipping functions.
626
+#
627
+
628
+# Force remaining assert and fail functions to be "skipped".
629
+#
630
+# This function forces the remaining assert and fail functions to be "skipped",
631
+# i.e. they will have no effect. Each function skipped will be recorded so that
632
+# the total of asserts and fails will not be altered.
633
+#
634
+# Args:
635
+#   None
636
+startSkipping() { __shunit_skip=${SHUNIT_TRUE}; }
637
+
638
+# Resume the normal recording behavior of assert and fail calls.
639
+#
640
+# Args:
641
+#   None
642
+endSkipping() { __shunit_skip=${SHUNIT_FALSE}; }
643
+
644
+# Returns the state of assert and fail call skipping.
645
+#
646
+# Args:
647
+#   None
648
+# Returns:
649
+#   boolean: (TRUE/FALSE constant)
650
+isSkipping() { return ${__shunit_skip}; }
651
+
652
+#-----------------------------------------------------------------------------
653
+# Suite functions.
654
+#
655
+
656
+# Stub. This function should contains all unit test calls to be made.
657
+#
658
+# DEPRECATED (as of 2.1.0)
659
+#
660
+# This function can be optionally overridden by the user in their test suite.
661
+#
662
+# If this function exists, it will be called when shunit2 is sourced. If it
663
+# does not exist, shunit2 will search the parent script for all functions
664
+# beginning with the word 'test', and they will be added dynamically to the
665
+# test suite.
666
+#
667
+# This function should be overridden by the user in their unit test suite.
668
+# Note: see _shunit_mktempFunc() for actual implementation
669
+#
670
+# Args:
671
+#   None
672
+#suite() { :; }  # DO NOT UNCOMMENT THIS FUNCTION
673
+
674
+# Adds a function name to the list of tests schedule for execution.
675
+#
676
+# This function should only be called from within the suite() function.
677
+#
678
+# Args:
679
+#   function: string: name of a function to add to current unit test suite
680
+suite_addTest() {
681
+  shunit_func_=${1:-}
682
+
683
+  __shunit_suite="${__shunit_suite:+${__shunit_suite} }${shunit_func_}"
684
+  __shunit_testsTotal=`expr ${__shunit_testsTotal} + 1`
685
+
686
+  unset shunit_func_
687
+}
688
+
689
+# Stub. This function will be called once before any tests are run.
690
+#
691
+# Common one-time environment preparation tasks shared by all tests can be
692
+# defined here.
693
+#
694
+# This function should be overridden by the user in their unit test suite.
695
+# Note: see _shunit_mktempFunc() for actual implementation
696
+#
697
+# Args:
698
+#   None
699
+#oneTimeSetUp() { :; }  # DO NOT UNCOMMENT THIS FUNCTION
700
+
701
+# Stub. This function will be called once after all tests are finished.
702
+#
703
+# Common one-time environment cleanup tasks shared by all tests can be defined
704
+# here.
705
+#
706
+# This function should be overridden by the user in their unit test suite.
707
+# Note: see _shunit_mktempFunc() for actual implementation
708
+#
709
+# Args:
710
+#   None
711
+#oneTimeTearDown() { :; }  # DO NOT UNCOMMENT THIS FUNCTION
712
+
713
+# Stub. This function will be called before each test is run.
714
+#
715
+# Common environment preparation tasks shared by all tests can be defined here.
716
+#
717
+# This function should be overridden by the user in their unit test suite.
718
+# Note: see _shunit_mktempFunc() for actual implementation
719
+#
720
+# Args:
721
+#   None
722
+#setUp() { :; }  # DO NOT UNCOMMENT THIS FUNCTION
723
+
724
+# Note: see _shunit_mktempFunc() for actual implementation
725
+# Stub. This function will be called after each test is run.
726
+#
727
+# Common environment cleanup tasks shared by all tests can be defined here.
728
+#
729
+# This function should be overridden by the user in their unit test suite.
730
+# Note: see _shunit_mktempFunc() for actual implementation
731
+#
732
+# Args:
733
+#   None
734
+#tearDown() { :; }  # DO NOT UNCOMMENT THIS FUNCTION
735
+
736
+#------------------------------------------------------------------------------
737
+# Internal shUnit2 functions.
738
+#
739
+
740
+# Create a temporary directory to store various run-time files in.
741
+#
742
+# This function is a cross-platform temporary directory creation tool. Not all
743
+# OSes have the `mktemp` function, so one is included here.
744
+#
745
+# Args:
746
+#   None
747
+# Outputs:
748
+#   string: the temporary directory that was created
749
+_shunit_mktempDir() {
750
+  # Try the standard `mktemp` function.
751
+  ( exec mktemp -dqt shunit.XXXXXX 2>/dev/null ) && return
752
+
753
+  # The standard `mktemp` didn't work. Use our own.
754
+  # shellcheck disable=SC2039
755
+  if command [ -r '/dev/urandom' -a -x '/usr/bin/od' ]; then
756
+    _shunit_random_=`/usr/bin/od -vAn -N4 -tx4 </dev/urandom \
757
+        |sed 's/^[^0-9a-f]*//'`
758
+  elif command [ -n "${RANDOM:-}" ]; then
759
+    # $RANDOM works
760
+    _shunit_random_=${RANDOM}${RANDOM}${RANDOM}$$
761
+  else
762
+    # `$RANDOM` doesn't work.
763
+    _shunit_date_=`date '+%Y%m%d%H%M%S'`
764
+    _shunit_random_=`expr "${_shunit_date_}" / $$`
765
+  fi
766
+
767
+  _shunit_tmpDir_="${TMPDIR:-/tmp}/shunit.${_shunit_random_}"
768
+  ( umask 077 && command mkdir "${_shunit_tmpDir_}" ) || \
769
+      _shunit_fatal 'could not create temporary directory! exiting'
770
+
771
+  echo "${_shunit_tmpDir_}"
772
+  unset _shunit_date_ _shunit_random_ _shunit_tmpDir_
773
+}
774
+
775
+# This function is here to work around issues in Cygwin.
776
+#
777
+# Args:
778
+#   None
779
+_shunit_mktempFunc() {
780
+  for _shunit_func_ in oneTimeSetUp oneTimeTearDown setUp tearDown suite noexec
781
+  do
782
+    _shunit_file_="${__shunit_tmpDir}/${_shunit_func_}"
783
+    command cat <<EOF >"${_shunit_file_}"
784
+#! /bin/sh
785
+exit ${SHUNIT_TRUE}
786
+EOF
787
+    command chmod +x "${_shunit_file_}"
788
+  done
789
+
790
+  unset _shunit_file_
791
+}
792
+
793
+# Final cleanup function to leave things as we found them.
794
+#
795
+# Besides removing the temporary directory, this function is in charge of the
796
+# final exit code of the unit test. The exit code is based on how the script
797
+# was ended (e.g. normal exit, or via Ctrl-C).
798
+#
799
+# Args:
800
+#   name: string: name of the trap called (specified when trap defined)
801
+_shunit_cleanup() {
802
+  _shunit_name_=$1
803
+
804
+  case ${_shunit_name_} in
805
+    EXIT) _shunit_signal_=0 ;;
806
+    INT) _shunit_signal_=2 ;;
807
+    TERM) _shunit_signal_=15 ;;
808
+    *)
809
+      _shunit_error "unrecognized trap value (${_shunit_name_})"
810
+      _shunit_signal_=0
811
+      ;;
812
+  esac
813
+
814
+  # Do our work.
815
+  command rm -fr "${__shunit_tmpDir}"
816
+
817
+  # Exit for all non-EXIT signals.
818
+  if command [ "${_shunit_name_}" != 'EXIT' ]; then
819
+    _shunit_warn "trapped and now handling the (${_shunit_name_}) signal"
820
+    # Disable EXIT trap.
821
+    trap 0
822
+    # Add 128 to signal and exit.
823
+    exit "`expr "${_shunit_signal_}" + 128`"
824
+  elif command [ ${__shunit_reportGenerated} -eq ${SHUNIT_FALSE} ] ; then
825
+    _shunit_assertFail 'Unknown failure encountered running a test'
826
+    _shunit_generateReport
827
+    exit ${SHUNIT_ERROR}
828
+  fi
829
+
830
+  unset _shunit_name_ _shunit_signal_
831
+}
832
+
833
+# configureColor based on user color preference.
834
+#
835
+# Args:
836
+#   color: string: color mode (one of `always`, `auto`, or `none`).
837
+_shunit_configureColor() {
838
+  _shunit_color_=${SHUNIT_FALSE}  # By default, no color.
839
+  case $1 in
840
+    'always') _shunit_color_=${SHUNIT_TRUE} ;;
841
+    'auto')
842
+      ( exec tput >/dev/null 2>&1 )  # Check for existence of tput command.
843
+      if command [ $? -lt 127 ]; then
844
+        _shunit_tput_=`tput colors`
845
+        # shellcheck disable=SC2166,SC2181
846
+        command [ $? -eq 0 -a "${_shunit_tput_}" -ge 16 ] && _shunit_color_=${SHUNIT_TRUE}
847
+      fi
848
+      ;;
849
+    'none') ;;
850
+    *) _shunit_fatal "unrecognized color option '$1'" ;;
851
+  esac
852
+
853
+  case ${_shunit_color_} in
854
+    ${SHUNIT_TRUE})
855
+      __shunit_ansi_none=${__SHUNIT_ANSI_NONE}
856
+      __shunit_ansi_red=${__SHUNIT_ANSI_RED}
857
+      __shunit_ansi_green=${__SHUNIT_ANSI_GREEN}
858
+      __shunit_ansi_yellow=${__SHUNIT_ANSI_YELLOW}
859
+      __shunit_ansi_cyan=${__SHUNIT_ANSI_CYAN}
860
+      ;;
861
+    ${SHUNIT_FALSE})
862
+      __shunit_ansi_none=''
863
+      __shunit_ansi_red=''
864
+      __shunit_ansi_green=''
865
+      __shunit_ansi_yellow=''
866
+      __shunit_ansi_cyan=''
867
+      ;;
868
+  esac
869
+
870
+  unset _shunit_color_ _shunit_tput_
871
+}
872
+
873
+# The actual running of the tests happens here.
874
+#
875
+# Args:
876
+#   None
877
+_shunit_execSuite() {
878
+  for _shunit_test_ in ${__shunit_suite}; do
879
+    __shunit_testSuccess=${SHUNIT_TRUE}
880
+
881
+    # Disable skipping.
882
+    endSkipping
883
+
884
+    # Execute the per-test setup function.
885
+    setUp
886
+    command [ $? -eq ${SHUNIT_TRUE} ] \
887
+        || _shunit_fatal "setup() returned non-zero return code."
888
+
889
+    # Execute the test.
890
+    echo "${__SHUNIT_TEST_PREFIX}${_shunit_test_}"
891
+    eval "${_shunit_test_}"
892
+    if command [ $? -ne ${SHUNIT_TRUE} ]; then
893
+      _shunit_error "${_shunit_test_}() returned non-zero return code."
894
+      __shunit_testSuccess=${SHUNIT_ERROR}
895
+      _shunit_incFailedCount
896
+    fi
897
+
898
+    # Execute the per-test tear-down function.
899
+    tearDown
900
+    command [ $? -eq ${SHUNIT_TRUE} ] \
901
+        || _shunit_fatal "tearDown() returned non-zero return code."
902
+
903
+    # Update stats.
904
+    if command [ ${__shunit_testSuccess} -eq ${SHUNIT_TRUE} ]; then
905
+      __shunit_testsPassed=`expr ${__shunit_testsPassed} + 1`
906
+    else
907
+      __shunit_testsFailed=`expr ${__shunit_testsFailed} + 1`
908
+    fi
909
+  done
910
+
911
+  unset _shunit_test_
912
+}
913
+
914
+# Generates the user friendly report with appropriate OK/FAILED message.
915
+#
916
+# Args:
917
+#   None
918
+# Output:
919
+#   string: the report of successful and failed tests, as well as totals.
920
+_shunit_generateReport() {
921
+  _shunit_ok_=${SHUNIT_TRUE}
922
+
923
+  # If no exit code was provided one, determine an appropriate one.
924
+  command [ "${__shunit_testsFailed}" -gt 0 \
925
+      -o ${__shunit_testSuccess} -eq ${SHUNIT_FALSE} ] \
926
+          && _shunit_ok_=${SHUNIT_FALSE}
927
+
928
+  echo
929
+  _shunit_msg_="Ran ${__shunit_ansi_cyan}${__shunit_testsTotal}${__shunit_ansi_none}"
930
+  if command [ "${__shunit_testsTotal}" -eq 1 ]; then
931
+    ${__SHUNIT_CMD_ECHO_ESC} "${_shunit_msg_} test."
932
+  else
933
+    ${__SHUNIT_CMD_ECHO_ESC} "${_shunit_msg_} tests."
934
+  fi
935
+
936
+  _shunit_failures_=0
937
+  _shunit_skipped_=0
938
+  command [ "${__shunit_assertsFailed}" -gt 0 ] \
939
+      && _shunit_failures_="failures=${__shunit_assertsFailed}"
940
+  command [ "${__shunit_assertsSkipped}" -gt 0 ] \
941
+      && _shunit_skipped_="skipped=${__shunit_assertsSkipped}"
942
+
943
+  if command [ ${_shunit_ok_} -eq ${SHUNIT_TRUE} ]; then
944
+    _shunit_msg_="${__shunit_ansi_green}OK${__shunit_ansi_none}"
945
+    command [ "${_shunit_skipped_}" -gt 0 ] \
946
+        && _shunit_msg_="${_shunit_msg_} (${__shunit_ansi_yellow}${_shunit_skipped_}${__shunit_ansi_none})"
947
+  else
948
+    _shunit_msg_="${__shunit_ansi_red}FAILED${__shunit_ansi_none}"
949
+    _shunit_msg_="${_shunit_msg_} (${__shunit_ansi_red}${_shunit_failures_}${__shunit_ansi_none}"
950
+    command [ "${_shunit_skipped_}" -gt 0 ] \
951
+        && _shunit_msg_="${_shunit_msg_},${__shunit_ansi_yellow}${_shunit_skipped_}${__shunit_ansi_none}"
952
+    _shunit_msg_="${_shunit_msg_})"
953
+  fi
954
+
955
+  echo
956
+  ${__SHUNIT_CMD_ECHO_ESC} "${_shunit_msg_}"
957
+  __shunit_reportGenerated=${SHUNIT_TRUE}
958
+
959
+  unset _shunit_failures_ _shunit_msg_ _shunit_ok_ _shunit_skipped_
960
+}
961
+
962
+# Test for whether a function should be skipped.
963
+#
964
+# Args:
965
+#   None
966
+# Returns:
967
+#   boolean: whether the test should be skipped (TRUE/FALSE constant)
968
+_shunit_shouldSkip() {
969
+  command [ ${__shunit_skip} -eq ${SHUNIT_FALSE} ] && return ${SHUNIT_FALSE}
970
+  _shunit_assertSkip
971
+}
972
+
973
+# Records a successful test.
974
+#
975
+# Args:
976
+#   None
977
+_shunit_assertPass() {
978
+  __shunit_assertsPassed=`expr ${__shunit_assertsPassed} + 1`
979
+  __shunit_assertsTotal=`expr ${__shunit_assertsTotal} + 1`
980
+}
981
+
982
+# Records a test failure.
983
+#
984
+# Args:
985
+#   message: string: failure message to provide user
986
+_shunit_assertFail() {
987
+  __shunit_testSuccess=${SHUNIT_FALSE}
988
+  _shunit_incFailedCount
989
+
990
+  \[ $# -gt 0 ] && ${__SHUNIT_CMD_ECHO_ESC} \
991
+      "${__shunit_ansi_red}ASSERT:${__shunit_ansi_none}$*"
992
+}
993
+
994
+# Increment the count of failed asserts.
995
+#
996
+# Args:
997
+#   none
998
+_shunit_incFailedCount() {
999
+  __shunit_assertsFailed=`expr "${__shunit_assertsFailed}" + 1`
1000
+  __shunit_assertsTotal=`expr "${__shunit_assertsTotal}" + 1`
1001
+}
1002
+
1003
+
1004
+# Records a skipped test.
1005
+#
1006
+# Args:
1007
+#   None
1008
+_shunit_assertSkip() {
1009
+  __shunit_assertsSkipped=`expr "${__shunit_assertsSkipped}" + 1`
1010
+  __shunit_assertsTotal=`expr "${__shunit_assertsTotal}" + 1`
1011
+}
1012
+
1013
+# Prepare a script filename for sourcing.
1014
+#
1015
+# Args:
1016
+#   script: string: path to a script to source
1017
+# Returns:
1018
+#   string: filename prefixed with ./ (if necessary)
1019
+_shunit_prepForSourcing() {
1020
+  _shunit_script_=$1
1021
+  case "${_shunit_script_}" in
1022
+    /*|./*) echo "${_shunit_script_}" ;;
1023
+    *) echo "./${_shunit_script_}" ;;
1024
+  esac
1025
+  unset _shunit_script_
1026
+}
1027
+
1028
+# Escape a character in a string.
1029
+#
1030
+# Args:
1031
+#   c: string: unescaped character
1032
+#   s: string: to escape character in
1033
+# Returns:
1034
+#   string: with escaped character(s)
1035
+_shunit_escapeCharInStr() {
1036
+  command [ -n "$2" ] || return  # No point in doing work on an empty string.
1037
+
1038
+  # Note: using shorter variable names to prevent conflicts with
1039
+  # _shunit_escapeCharactersInString().
1040
+  _shunit_c_=$1
1041
+  _shunit_s_=$2
1042
+
1043
+  # Escape the character.
1044
+  # shellcheck disable=SC1003,SC2086
1045
+  echo ''${_shunit_s_}'' |sed 's/\'${_shunit_c_}'/\\\'${_shunit_c_}'/g'
1046
+
1047
+  unset _shunit_c_ _shunit_s_
1048
+}
1049
+
1050
+# Escape a character in a string.
1051
+#
1052
+# Args:
1053
+#   str: string: to escape characters in
1054
+# Returns:
1055
+#   string: with escaped character(s)
1056
+_shunit_escapeCharactersInString() {
1057
+  command [ -n "$1" ] || return  # No point in doing work on an empty string.
1058
+
1059
+  _shunit_str_=$1
1060
+
1061
+  # Note: using longer variable names to prevent conflicts with
1062
+  # _shunit_escapeCharInStr().
1063
+  for _shunit_char_ in '"' '$' "'" '`'; do
1064
+    _shunit_str_=`_shunit_escapeCharInStr "${_shunit_char_}" "${_shunit_str_}"`
1065
+  done
1066
+
1067
+  echo "${_shunit_str_}"
1068
+  unset _shunit_char_ _shunit_str_
1069
+}
1070
+
1071
+# Extract list of functions to run tests against.
1072
+#
1073
+# Args:
1074
+#   script: string: name of script to extract functions from
1075
+# Returns:
1076
+#   string: of function names
1077
+_shunit_extractTestFunctions() {
1078
+  _shunit_script_=$1
1079
+
1080
+  # Extract the lines with test function names, strip of anything besides the
1081
+  # function name, and output everything on a single line.
1082
+  _shunit_regex_='^[ 	]*(function )*test[A-Za-z0-9_]* *\(\)'
1083
+  # shellcheck disable=SC2196
1084
+  egrep "${_shunit_regex_}" "${_shunit_script_}" \
1085
+  |sed 's/^[^A-Za-z0-9_]*//;s/^function //;s/\([A-Za-z0-9_]*\).*/\1/g' \
1086
+  |xargs
1087
+
1088
+  unset _shunit_regex_ _shunit_script_
1089
+}
1090
+
1091
+#------------------------------------------------------------------------------
1092
+# Main.
1093
+#
1094
+
1095
+# Determine the operating mode.
1096
+if command [ $# -eq 0 ]; then
1097
+  __shunit_script=${__SHUNIT_PARENT}
1098
+  __shunit_mode=${__SHUNIT_MODE_SOURCED}
1099
+else
1100
+  __shunit_script=$1
1101
+  command [ -r "${__shunit_script}" ] || \
1102
+      _shunit_fatal "unable to read from ${__shunit_script}"
1103
+  __shunit_mode=${__SHUNIT_MODE_STANDALONE}
1104
+fi
1105
+
1106
+# Create a temporary storage location.
1107
+__shunit_tmpDir=`_shunit_mktempDir`
1108
+
1109
+# Provide a public temporary directory for unit test scripts.
1110
+# TODO(kward): document this.
1111
+SHUNIT_TMPDIR="${__shunit_tmpDir}/tmp"
1112
+command mkdir "${SHUNIT_TMPDIR}"
1113
+
1114
+# Setup traps to clean up after ourselves.
1115
+trap '_shunit_cleanup EXIT' 0
1116
+trap '_shunit_cleanup INT' 2
1117
+trap '_shunit_cleanup TERM' 15
1118
+
1119
+# Create phantom functions to work around issues with Cygwin.
1120
+_shunit_mktempFunc
1121
+PATH="${__shunit_tmpDir}:${PATH}"
1122
+
1123
+# Make sure phantom functions are executable. This will bite if `/tmp` (or the
1124
+# current `$TMPDIR`) points to a path on a partition that was mounted with the
1125
+# 'noexec' option. The noexec command was created with `_shunit_mktempFunc()`.
1126
+noexec 2>/dev/null || _shunit_fatal \
1127
+    'Please declare TMPDIR with path on partition with exec permission.'
1128
+
1129
+# We must manually source the tests in standalone mode.
1130
+if command [ "${__shunit_mode}" = "${__SHUNIT_MODE_STANDALONE}" ]; then
1131
+  # shellcheck disable=SC1090
1132
+  command . "`_shunit_prepForSourcing \"${__shunit_script}\"`"
1133
+fi
1134
+
1135
+# Configure default output coloring behavior.
1136
+_shunit_configureColor "${SHUNIT_COLOR}"
1137
+
1138
+# Execute the oneTimeSetUp function (if it exists).
1139
+oneTimeSetUp
1140
+command [ $? -eq ${SHUNIT_TRUE} ] \
1141
+    || _shunit_fatal "oneTimeSetUp() returned non-zero return code."
1142
+
1143
+# Execute the suite function defined in the parent test script.
1144
+# DEPRECATED as of 2.1.0.
1145
+suite
1146
+
1147
+# If no suite function was defined, dynamically build a list of functions.
1148
+if command [ -z "${__shunit_suite}" ]; then
1149
+  shunit_funcs_=`_shunit_extractTestFunctions "${__shunit_script}"`
1150
+  for shunit_func_ in ${shunit_funcs_}; do
1151
+    suite_addTest "${shunit_func_}"
1152
+  done
1153
+fi
1154
+unset shunit_func_ shunit_funcs_
1155
+
1156
+# Execute the suite of unit tests.
1157
+_shunit_execSuite
1158
+
1159
+# Execute the oneTimeTearDown function (if it exists).
1160
+oneTimeTearDown
1161
+command [ $? -eq ${SHUNIT_TRUE} ] \
1162
+    || _shunit_fatal "oneTimeTearDown() returned non-zero return code."
1163
+
1164
+# Generate a report summary.
1165
+_shunit_generateReport
1166
+
1167
+# That's it folks.
1168
+command [ "${__shunit_testsFailed}" -eq 0 ]
1169
+exit $?