xref: /aosp_15_r20/external/shflags/lib/shunit2 (revision 63d4e48fb639f6414be0db9d718e3be2667e4fed)
1*63d4e48fSSadaf Ebrahimi#! /bin/sh
2*63d4e48fSSadaf Ebrahimi# vim:et:ft=sh:sts=2:sw=2
3*63d4e48fSSadaf Ebrahimi#
4*63d4e48fSSadaf Ebrahimi# shUnit2 -- Unit testing framework for Unix shell scripts.
5*63d4e48fSSadaf Ebrahimi#
6*63d4e48fSSadaf Ebrahimi# Copyright 2008-2021 Kate Ward. All Rights Reserved.
7*63d4e48fSSadaf Ebrahimi# Released under the Apache 2.0 license.
8*63d4e48fSSadaf Ebrahimi# http://www.apache.org/licenses/LICENSE-2.0
9*63d4e48fSSadaf Ebrahimi#
10*63d4e48fSSadaf Ebrahimi# Author: [email protected] (Kate Ward)
11*63d4e48fSSadaf Ebrahimi# https://github.com/kward/shunit2
12*63d4e48fSSadaf Ebrahimi#
13*63d4e48fSSadaf Ebrahimi# shUnit2 is a xUnit based unit test framework for Bourne shell scripts. It is
14*63d4e48fSSadaf Ebrahimi# based on the popular JUnit unit testing framework for Java.
15*63d4e48fSSadaf Ebrahimi#
16*63d4e48fSSadaf Ebrahimi# `expr` may be antiquated, but it is the only solution in some cases.
17*63d4e48fSSadaf Ebrahimi#   shellcheck disable=SC2003
18*63d4e48fSSadaf Ebrahimi# Allow usage of legacy backticked `...` notation instead of $(...).
19*63d4e48fSSadaf Ebrahimi#   shellcheck disable=SC2006
20*63d4e48fSSadaf Ebrahimi
21*63d4e48fSSadaf Ebrahimi# Return if shunit2 already loaded.
22*63d4e48fSSadaf Ebrahimiif test -n "${SHUNIT_VERSION:-}"; then
23*63d4e48fSSadaf Ebrahimi  exit 0
24*63d4e48fSSadaf Ebrahimifi
25*63d4e48fSSadaf EbrahimiSHUNIT_VERSION='2.1.9pre'
26*63d4e48fSSadaf Ebrahimi
27*63d4e48fSSadaf Ebrahimi# Return values that scripts can use.
28*63d4e48fSSadaf EbrahimiSHUNIT_TRUE=0
29*63d4e48fSSadaf EbrahimiSHUNIT_FALSE=1
30*63d4e48fSSadaf EbrahimiSHUNIT_ERROR=2
31*63d4e48fSSadaf Ebrahimi
32*63d4e48fSSadaf Ebrahimi# Determine if `builtin` command exists.
33*63d4e48fSSadaf Ebrahimi__SHUNIT_BUILTIN='builtin'
34*63d4e48fSSadaf Ebrahimi# shellcheck disable=2039
35*63d4e48fSSadaf Ebrahimiif ! ("${__SHUNIT_BUILTIN}" echo 123 >/dev/null 2>&1); then
36*63d4e48fSSadaf Ebrahimi  __SHUNIT_BUILTIN=''
37*63d4e48fSSadaf Ebrahimifi
38*63d4e48fSSadaf Ebrahimi
39*63d4e48fSSadaf Ebrahimi# Determine some reasonable command defaults.
40*63d4e48fSSadaf Ebrahimi__SHUNIT_CMD_ECHO_ESC='echo -e'
41*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC2039,SC3037
42*63d4e48fSSadaf Ebrahimiif ${__SHUNIT_BUILTIN} [ "`echo -e test`" = '-e test' ]; then
43*63d4e48fSSadaf Ebrahimi  __SHUNIT_CMD_ECHO_ESC='echo'
44*63d4e48fSSadaf Ebrahimifi
45*63d4e48fSSadaf Ebrahimi
46*63d4e48fSSadaf Ebrahimi# Commands a user can override if needed.
47*63d4e48fSSadaf Ebrahimi__SHUNIT_CMD_TPUT='tput'
48*63d4e48fSSadaf EbrahimiSHUNIT_CMD_TPUT=${SHUNIT_CMD_TPUT:-${__SHUNIT_CMD_TPUT}}
49*63d4e48fSSadaf Ebrahimi
50*63d4e48fSSadaf Ebrahimi# Enable color output. Options are 'auto', 'always', or 'never'.
51*63d4e48fSSadaf EbrahimiSHUNIT_COLOR=${SHUNIT_COLOR:-auto}
52*63d4e48fSSadaf Ebrahimi
53*63d4e48fSSadaf Ebrahimi#
54*63d4e48fSSadaf Ebrahimi# Internal constants.
55*63d4e48fSSadaf Ebrahimi#
56*63d4e48fSSadaf Ebrahimi
57*63d4e48fSSadaf Ebrahimi__SHUNIT_MODE_SOURCED='sourced'
58*63d4e48fSSadaf Ebrahimi__SHUNIT_MODE_STANDALONE='standalone'
59*63d4e48fSSadaf Ebrahimi__SHUNIT_PARENT=${SHUNIT_PARENT:-$0}
60*63d4e48fSSadaf Ebrahimi
61*63d4e48fSSadaf Ebrahimi# User provided test prefix to display in front of the name of the test being
62*63d4e48fSSadaf Ebrahimi# executed. Define by setting the SHUNIT_TEST_PREFIX variable.
63*63d4e48fSSadaf Ebrahimi__SHUNIT_TEST_PREFIX=${SHUNIT_TEST_PREFIX:-}
64*63d4e48fSSadaf Ebrahimi
65*63d4e48fSSadaf Ebrahimi# ANSI colors.
66*63d4e48fSSadaf Ebrahimi__SHUNIT_ANSI_NONE='\033[0m'
67*63d4e48fSSadaf Ebrahimi__SHUNIT_ANSI_RED='\033[1;31m'
68*63d4e48fSSadaf Ebrahimi__SHUNIT_ANSI_GREEN='\033[1;32m'
69*63d4e48fSSadaf Ebrahimi__SHUNIT_ANSI_YELLOW='\033[1;33m'
70*63d4e48fSSadaf Ebrahimi__SHUNIT_ANSI_CYAN='\033[1;36m'
71*63d4e48fSSadaf Ebrahimi
72*63d4e48fSSadaf Ebrahimi#
73*63d4e48fSSadaf Ebrahimi# Internal variables.
74*63d4e48fSSadaf Ebrahimi#
75*63d4e48fSSadaf Ebrahimi
76*63d4e48fSSadaf Ebrahimi# Variables.
77*63d4e48fSSadaf Ebrahimi__shunit_lineno=''  # Line number of executed test.
78*63d4e48fSSadaf Ebrahimi__shunit_mode=${__SHUNIT_MODE_SOURCED}  # Operating mode.
79*63d4e48fSSadaf Ebrahimi__shunit_reportGenerated=${SHUNIT_FALSE}  # Is report generated.
80*63d4e48fSSadaf Ebrahimi__shunit_script=''  # Filename of unittest script (standalone mode).
81*63d4e48fSSadaf Ebrahimi__shunit_skip=${SHUNIT_FALSE}  # Is skipping enabled.
82*63d4e48fSSadaf Ebrahimi__shunit_suite=''  # Suite of tests to execute.
83*63d4e48fSSadaf Ebrahimi__shunit_clean=${SHUNIT_FALSE}  # _shunit_cleanup() was already called.
84*63d4e48fSSadaf Ebrahimi
85*63d4e48fSSadaf Ebrahimi# ANSI colors (populated by _shunit_configureColor()).
86*63d4e48fSSadaf Ebrahimi__shunit_ansi_none=''
87*63d4e48fSSadaf Ebrahimi__shunit_ansi_red=''
88*63d4e48fSSadaf Ebrahimi__shunit_ansi_green=''
89*63d4e48fSSadaf Ebrahimi__shunit_ansi_yellow=''
90*63d4e48fSSadaf Ebrahimi__shunit_ansi_cyan=''
91*63d4e48fSSadaf Ebrahimi
92*63d4e48fSSadaf Ebrahimi# Counts of tests.
93*63d4e48fSSadaf Ebrahimi__shunit_testSuccess=${SHUNIT_TRUE}
94*63d4e48fSSadaf Ebrahimi__shunit_testsTotal=0
95*63d4e48fSSadaf Ebrahimi__shunit_testsPassed=0
96*63d4e48fSSadaf Ebrahimi__shunit_testsFailed=0
97*63d4e48fSSadaf Ebrahimi
98*63d4e48fSSadaf Ebrahimi# Counts of asserts.
99*63d4e48fSSadaf Ebrahimi__shunit_assertsTotal=0
100*63d4e48fSSadaf Ebrahimi__shunit_assertsPassed=0
101*63d4e48fSSadaf Ebrahimi__shunit_assertsFailed=0
102*63d4e48fSSadaf Ebrahimi__shunit_assertsSkipped=0
103*63d4e48fSSadaf Ebrahimi
104*63d4e48fSSadaf Ebrahimi#
105*63d4e48fSSadaf Ebrahimi# Internal functions.
106*63d4e48fSSadaf Ebrahimi#
107*63d4e48fSSadaf Ebrahimi
108*63d4e48fSSadaf Ebrahimi# Logging.
109*63d4e48fSSadaf Ebrahimi_shunit_warn() {
110*63d4e48fSSadaf Ebrahimi  ${__SHUNIT_CMD_ECHO_ESC} "${__shunit_ansi_yellow}shunit2:WARN${__shunit_ansi_none} $*" >&2
111*63d4e48fSSadaf Ebrahimi}
112*63d4e48fSSadaf Ebrahimi_shunit_error() {
113*63d4e48fSSadaf Ebrahimi  ${__SHUNIT_CMD_ECHO_ESC} "${__shunit_ansi_red}shunit2:ERROR${__shunit_ansi_none} $*" >&2
114*63d4e48fSSadaf Ebrahimi}
115*63d4e48fSSadaf Ebrahimi_shunit_fatal() {
116*63d4e48fSSadaf Ebrahimi  ${__SHUNIT_CMD_ECHO_ESC} "${__shunit_ansi_red}shunit2:FATAL${__shunit_ansi_none} $*" >&2
117*63d4e48fSSadaf Ebrahimi  exit ${SHUNIT_ERROR}
118*63d4e48fSSadaf Ebrahimi}
119*63d4e48fSSadaf Ebrahimi
120*63d4e48fSSadaf Ebrahimi#
121*63d4e48fSSadaf Ebrahimi# Macros.
122*63d4e48fSSadaf Ebrahimi#
123*63d4e48fSSadaf Ebrahimi
124*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC2016,SC2089
125*63d4e48fSSadaf Ebrahimi_SHUNIT_LINENO_='eval __shunit_lineno=""; if ${__SHUNIT_BUILTIN} [ "${1:-}" = "--lineno" ] && ${__SHUNIT_BUILTIN} [ -n "${2:-}" ]; then __shunit_lineno="[${2}]"; shift 2; fi;'
126*63d4e48fSSadaf Ebrahimi
127*63d4e48fSSadaf Ebrahimi#
128*63d4e48fSSadaf Ebrahimi# Setup.
129*63d4e48fSSadaf Ebrahimi#
130*63d4e48fSSadaf Ebrahimi
131*63d4e48fSSadaf Ebrahimi# Specific shell checks.
132*63d4e48fSSadaf Ebrahimiif ${__SHUNIT_BUILTIN} [ -n "${ZSH_VERSION:-}" ]; then
133*63d4e48fSSadaf Ebrahimi  setopt |grep "^shwordsplit$" >/dev/null
134*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $? -ne ${SHUNIT_TRUE} ]; then
135*63d4e48fSSadaf Ebrahimi    _shunit_fatal 'zsh shwordsplit option is required for proper operation'
136*63d4e48fSSadaf Ebrahimi  fi
137*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ -z "${SHUNIT_PARENT:-}" ]; then
138*63d4e48fSSadaf Ebrahimi    _shunit_fatal "zsh does not pass \$0 through properly. please declare \
139*63d4e48fSSadaf Ebrahimi\"SHUNIT_PARENT=\$0\" before calling shUnit2"
140*63d4e48fSSadaf Ebrahimi  fi
141*63d4e48fSSadaf Ebrahimifi
142*63d4e48fSSadaf Ebrahimi
143*63d4e48fSSadaf Ebrahimi# Set the constants readonly.
144*63d4e48fSSadaf Ebrahimi__shunit_constants=`set |grep '^__SHUNIT_' |cut -d= -f1`
145*63d4e48fSSadaf Ebrahimiecho "${__shunit_constants}" |grep '^Binary file' >/dev/null && \
146*63d4e48fSSadaf Ebrahimi    __shunit_constants=`set |grep -a '^__SHUNIT_' |cut -d= -f1`
147*63d4e48fSSadaf Ebrahimifor __shunit_const in ${__shunit_constants}; do
148*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ -z "${ZSH_VERSION:-}" ]; then
149*63d4e48fSSadaf Ebrahimi    readonly "${__shunit_const}"
150*63d4e48fSSadaf Ebrahimi  else
151*63d4e48fSSadaf Ebrahimi    case ${ZSH_VERSION} in
152*63d4e48fSSadaf Ebrahimi      [123].*) readonly "${__shunit_const}" ;;
153*63d4e48fSSadaf Ebrahimi      *)
154*63d4e48fSSadaf Ebrahimi        # Declare readonly constants globally.
155*63d4e48fSSadaf Ebrahimi        # shellcheck disable=SC2039,SC3045
156*63d4e48fSSadaf Ebrahimi        readonly -g "${__shunit_const}"
157*63d4e48fSSadaf Ebrahimi    esac
158*63d4e48fSSadaf Ebrahimi  fi
159*63d4e48fSSadaf Ebrahimidone
160*63d4e48fSSadaf Ebrahimiunset __shunit_const __shunit_constants
161*63d4e48fSSadaf Ebrahimi
162*63d4e48fSSadaf Ebrahimi#-----------------------------------------------------------------------------
163*63d4e48fSSadaf Ebrahimi# Assertion functions.
164*63d4e48fSSadaf Ebrahimi#
165*63d4e48fSSadaf Ebrahimi
166*63d4e48fSSadaf Ebrahimi# Assert that two values are equal to one another.
167*63d4e48fSSadaf Ebrahimi#
168*63d4e48fSSadaf Ebrahimi# Args:
169*63d4e48fSSadaf Ebrahimi#   message: string: failure message [optional]
170*63d4e48fSSadaf Ebrahimi#   expected: string: expected value
171*63d4e48fSSadaf Ebrahimi#   actual: string: actual value
172*63d4e48fSSadaf Ebrahimi# Returns:
173*63d4e48fSSadaf Ebrahimi#   integer: success (TRUE/FALSE/ERROR constant)
174*63d4e48fSSadaf EbrahimiassertEquals() {
175*63d4e48fSSadaf Ebrahimi  # shellcheck disable=SC2090
176*63d4e48fSSadaf Ebrahimi  ${_SHUNIT_LINENO_}
177*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -lt 2 -o $# -gt 3 ]; then
178*63d4e48fSSadaf Ebrahimi    _shunit_error "assertEquals() requires two or three arguments; $# given"
179*63d4e48fSSadaf Ebrahimi    _shunit_assertFail
180*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_ERROR}
181*63d4e48fSSadaf Ebrahimi  fi
182*63d4e48fSSadaf Ebrahimi  if _shunit_shouldSkip; then
183*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_TRUE}
184*63d4e48fSSadaf Ebrahimi  fi
185*63d4e48fSSadaf Ebrahimi
186*63d4e48fSSadaf Ebrahimi  shunit_message_=${__shunit_lineno}
187*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -eq 3 ]; then
188*63d4e48fSSadaf Ebrahimi    shunit_message_="${shunit_message_}$1"
189*63d4e48fSSadaf Ebrahimi    shift
190*63d4e48fSSadaf Ebrahimi  fi
191*63d4e48fSSadaf Ebrahimi  shunit_expected_=$1
192*63d4e48fSSadaf Ebrahimi  shunit_actual_=$2
193*63d4e48fSSadaf Ebrahimi
194*63d4e48fSSadaf Ebrahimi  shunit_return=${SHUNIT_TRUE}
195*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ "${shunit_expected_}" = "${shunit_actual_}" ]; then
196*63d4e48fSSadaf Ebrahimi    _shunit_assertPass
197*63d4e48fSSadaf Ebrahimi  else
198*63d4e48fSSadaf Ebrahimi    failNotEquals "${shunit_message_}" "${shunit_expected_}" "${shunit_actual_}"
199*63d4e48fSSadaf Ebrahimi    shunit_return=${SHUNIT_FALSE}
200*63d4e48fSSadaf Ebrahimi  fi
201*63d4e48fSSadaf Ebrahimi
202*63d4e48fSSadaf Ebrahimi  unset shunit_message_ shunit_expected_ shunit_actual_
203*63d4e48fSSadaf Ebrahimi  return ${shunit_return}
204*63d4e48fSSadaf Ebrahimi}
205*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC2016,SC2034
206*63d4e48fSSadaf Ebrahimi_ASSERT_EQUALS_='eval assertEquals --lineno "${LINENO:-}"'
207*63d4e48fSSadaf Ebrahimi
208*63d4e48fSSadaf Ebrahimi# Assert that two values are not equal to one another.
209*63d4e48fSSadaf Ebrahimi#
210*63d4e48fSSadaf Ebrahimi# Args:
211*63d4e48fSSadaf Ebrahimi#   message: string: failure message [optional]
212*63d4e48fSSadaf Ebrahimi#   expected: string: expected value
213*63d4e48fSSadaf Ebrahimi#   actual: string: actual value
214*63d4e48fSSadaf Ebrahimi# Returns:
215*63d4e48fSSadaf Ebrahimi#   integer: success (TRUE/FALSE/ERROR constant)
216*63d4e48fSSadaf EbrahimiassertNotEquals() {
217*63d4e48fSSadaf Ebrahimi  # shellcheck disable=SC2090
218*63d4e48fSSadaf Ebrahimi  ${_SHUNIT_LINENO_}
219*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -lt 2 -o $# -gt 3 ]; then
220*63d4e48fSSadaf Ebrahimi    _shunit_error "assertNotEquals() requires two or three arguments; $# given"
221*63d4e48fSSadaf Ebrahimi    _shunit_assertFail
222*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_ERROR}
223*63d4e48fSSadaf Ebrahimi  fi
224*63d4e48fSSadaf Ebrahimi  if _shunit_shouldSkip; then
225*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_TRUE}
226*63d4e48fSSadaf Ebrahimi  fi
227*63d4e48fSSadaf Ebrahimi
228*63d4e48fSSadaf Ebrahimi  shunit_message_=${__shunit_lineno}
229*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -eq 3 ]; then
230*63d4e48fSSadaf Ebrahimi    shunit_message_="${shunit_message_}$1"
231*63d4e48fSSadaf Ebrahimi    shift
232*63d4e48fSSadaf Ebrahimi  fi
233*63d4e48fSSadaf Ebrahimi  shunit_expected_=$1
234*63d4e48fSSadaf Ebrahimi  shunit_actual_=$2
235*63d4e48fSSadaf Ebrahimi
236*63d4e48fSSadaf Ebrahimi  shunit_return=${SHUNIT_TRUE}
237*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ "${shunit_expected_}" != "${shunit_actual_}" ]; then
238*63d4e48fSSadaf Ebrahimi    _shunit_assertPass
239*63d4e48fSSadaf Ebrahimi  else
240*63d4e48fSSadaf Ebrahimi    failSame "${shunit_message_}" "${shunit_expected_}" "${shunit_actual_}"
241*63d4e48fSSadaf Ebrahimi    shunit_return=${SHUNIT_FALSE}
242*63d4e48fSSadaf Ebrahimi  fi
243*63d4e48fSSadaf Ebrahimi
244*63d4e48fSSadaf Ebrahimi  unset shunit_message_ shunit_expected_ shunit_actual_
245*63d4e48fSSadaf Ebrahimi  return ${shunit_return}
246*63d4e48fSSadaf Ebrahimi}
247*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC2016,SC2034
248*63d4e48fSSadaf Ebrahimi_ASSERT_NOT_EQUALS_='eval assertNotEquals --lineno "${LINENO:-}"'
249*63d4e48fSSadaf Ebrahimi
250*63d4e48fSSadaf Ebrahimi# Assert that a container contains a content.
251*63d4e48fSSadaf Ebrahimi#
252*63d4e48fSSadaf Ebrahimi# Args:
253*63d4e48fSSadaf Ebrahimi#   message: string: failure message [optional]
254*63d4e48fSSadaf Ebrahimi#   container: string: container to analyze
255*63d4e48fSSadaf Ebrahimi#   content: string: content to find
256*63d4e48fSSadaf Ebrahimi# Returns:
257*63d4e48fSSadaf Ebrahimi#   integer: success (TRUE/FALSE/ERROR constant)
258*63d4e48fSSadaf EbrahimiassertContains() {
259*63d4e48fSSadaf Ebrahimi  # shellcheck disable=SC2090
260*63d4e48fSSadaf Ebrahimi  ${_SHUNIT_LINENO_}
261*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -lt 2 -o $# -gt 3 ]; then
262*63d4e48fSSadaf Ebrahimi    _shunit_error "assertContains() requires two or three arguments; $# given"
263*63d4e48fSSadaf Ebrahimi    _shunit_assertFail
264*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_ERROR}
265*63d4e48fSSadaf Ebrahimi  fi
266*63d4e48fSSadaf Ebrahimi  if _shunit_shouldSkip; then
267*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_TRUE}
268*63d4e48fSSadaf Ebrahimi  fi
269*63d4e48fSSadaf Ebrahimi
270*63d4e48fSSadaf Ebrahimi  shunit_message_=${__shunit_lineno}
271*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -eq 3 ]; then
272*63d4e48fSSadaf Ebrahimi    shunit_message_="${shunit_message_}$1"
273*63d4e48fSSadaf Ebrahimi    shift
274*63d4e48fSSadaf Ebrahimi  fi
275*63d4e48fSSadaf Ebrahimi  shunit_container_=$1
276*63d4e48fSSadaf Ebrahimi  shunit_content_=$2
277*63d4e48fSSadaf Ebrahimi  shunit_return=${SHUNIT_TRUE}
278*63d4e48fSSadaf Ebrahimi  if echo "${shunit_container_}" |grep -F -- "${shunit_content_}" >/dev/null; then
279*63d4e48fSSadaf Ebrahimi    _shunit_assertPass
280*63d4e48fSSadaf Ebrahimi  else
281*63d4e48fSSadaf Ebrahimi    failNotFound "${shunit_message_}" "${shunit_content_}"
282*63d4e48fSSadaf Ebrahimi    shunit_return=${SHUNIT_FALSE}
283*63d4e48fSSadaf Ebrahimi  fi
284*63d4e48fSSadaf Ebrahimi
285*63d4e48fSSadaf Ebrahimi  unset shunit_message_ shunit_container_ shunit_content_
286*63d4e48fSSadaf Ebrahimi  return ${shunit_return}
287*63d4e48fSSadaf Ebrahimi}
288*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC2016,SC2034
289*63d4e48fSSadaf Ebrahimi_ASSERT_CONTAINS_='eval assertContains --lineno "${LINENO:-}"'
290*63d4e48fSSadaf Ebrahimi
291*63d4e48fSSadaf Ebrahimi# Assert that a container does not contain a content.
292*63d4e48fSSadaf Ebrahimi#
293*63d4e48fSSadaf Ebrahimi# Args:
294*63d4e48fSSadaf Ebrahimi#   message: string: failure message [optional]
295*63d4e48fSSadaf Ebrahimi#   container: string: container to analyze
296*63d4e48fSSadaf Ebrahimi#   content: string: content to look for
297*63d4e48fSSadaf Ebrahimi# Returns:
298*63d4e48fSSadaf Ebrahimi#   integer: success (TRUE/FALSE/ERROR constant)
299*63d4e48fSSadaf EbrahimiassertNotContains() {
300*63d4e48fSSadaf Ebrahimi  # shellcheck disable=SC2090
301*63d4e48fSSadaf Ebrahimi  ${_SHUNIT_LINENO_}
302*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -lt 2 -o $# -gt 3 ]; then
303*63d4e48fSSadaf Ebrahimi    _shunit_error "assertNotContains() requires two or three arguments; $# given"
304*63d4e48fSSadaf Ebrahimi    _shunit_assertFail
305*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_ERROR}
306*63d4e48fSSadaf Ebrahimi  fi
307*63d4e48fSSadaf Ebrahimi  if _shunit_shouldSkip; then
308*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_TRUE}
309*63d4e48fSSadaf Ebrahimi  fi
310*63d4e48fSSadaf Ebrahimi
311*63d4e48fSSadaf Ebrahimi  shunit_message_=${__shunit_lineno}
312*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -eq 3 ]; then
313*63d4e48fSSadaf Ebrahimi    shunit_message_="${shunit_message_}$1"
314*63d4e48fSSadaf Ebrahimi    shift
315*63d4e48fSSadaf Ebrahimi  fi
316*63d4e48fSSadaf Ebrahimi  shunit_container_=$1
317*63d4e48fSSadaf Ebrahimi  shunit_content_=$2
318*63d4e48fSSadaf Ebrahimi
319*63d4e48fSSadaf Ebrahimi  shunit_return=${SHUNIT_TRUE}
320*63d4e48fSSadaf Ebrahimi  if echo "$shunit_container_" | grep -F -- "$shunit_content_" > /dev/null; then
321*63d4e48fSSadaf Ebrahimi    failFound "${shunit_message_}" "${shunit_content_}"
322*63d4e48fSSadaf Ebrahimi    shunit_return=${SHUNIT_FALSE}
323*63d4e48fSSadaf Ebrahimi  else
324*63d4e48fSSadaf Ebrahimi    _shunit_assertPass
325*63d4e48fSSadaf Ebrahimi  fi
326*63d4e48fSSadaf Ebrahimi
327*63d4e48fSSadaf Ebrahimi  unset shunit_message_ shunit_container_ shunit_content_
328*63d4e48fSSadaf Ebrahimi  return ${shunit_return}
329*63d4e48fSSadaf Ebrahimi}
330*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC2016,SC2034
331*63d4e48fSSadaf Ebrahimi_ASSERT_NOT_CONTAINS_='eval assertNotContains --lineno "${LINENO:-}"'
332*63d4e48fSSadaf Ebrahimi
333*63d4e48fSSadaf Ebrahimi# Assert that a value is null (i.e. an empty string).
334*63d4e48fSSadaf Ebrahimi#
335*63d4e48fSSadaf Ebrahimi# Args:
336*63d4e48fSSadaf Ebrahimi#   message: string: failure message [optional]
337*63d4e48fSSadaf Ebrahimi#   actual: string: actual value
338*63d4e48fSSadaf Ebrahimi# Returns:
339*63d4e48fSSadaf Ebrahimi#   integer: success (TRUE/FALSE/ERROR constant)
340*63d4e48fSSadaf EbrahimiassertNull() {
341*63d4e48fSSadaf Ebrahimi  # shellcheck disable=SC2090
342*63d4e48fSSadaf Ebrahimi  ${_SHUNIT_LINENO_}
343*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -gt 2 ]; then
344*63d4e48fSSadaf Ebrahimi    # Allowing 0 arguments as $1 might actually be null.
345*63d4e48fSSadaf Ebrahimi    _shunit_error "assertNull() requires one or two arguments; $# given"
346*63d4e48fSSadaf Ebrahimi    _shunit_assertFail
347*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_ERROR}
348*63d4e48fSSadaf Ebrahimi  fi
349*63d4e48fSSadaf Ebrahimi  if _shunit_shouldSkip; then
350*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_TRUE}
351*63d4e48fSSadaf Ebrahimi  fi
352*63d4e48fSSadaf Ebrahimi
353*63d4e48fSSadaf Ebrahimi  shunit_message_=${__shunit_lineno}
354*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -eq 2 ]; then
355*63d4e48fSSadaf Ebrahimi    shunit_message_="${shunit_message_}$1"
356*63d4e48fSSadaf Ebrahimi    shift
357*63d4e48fSSadaf Ebrahimi  fi
358*63d4e48fSSadaf Ebrahimi
359*63d4e48fSSadaf Ebrahimi  ${__SHUNIT_BUILTIN} test -z "${1:-}"
360*63d4e48fSSadaf Ebrahimi  assertTrue "${shunit_message_}" $?
361*63d4e48fSSadaf Ebrahimi  shunit_return=$?
362*63d4e48fSSadaf Ebrahimi
363*63d4e48fSSadaf Ebrahimi  unset shunit_message_
364*63d4e48fSSadaf Ebrahimi  return ${shunit_return}
365*63d4e48fSSadaf Ebrahimi}
366*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC2016,SC2034
367*63d4e48fSSadaf Ebrahimi_ASSERT_NULL_='eval assertNull --lineno "${LINENO:-}"'
368*63d4e48fSSadaf Ebrahimi
369*63d4e48fSSadaf Ebrahimi# Assert that a value is not null (i.e. a non-empty string).
370*63d4e48fSSadaf Ebrahimi#
371*63d4e48fSSadaf Ebrahimi# Args:
372*63d4e48fSSadaf Ebrahimi#   message: string: failure message [optional]
373*63d4e48fSSadaf Ebrahimi#   actual: string: actual value
374*63d4e48fSSadaf Ebrahimi# Returns:
375*63d4e48fSSadaf Ebrahimi#   integer: success (TRUE/FALSE/ERROR constant)
376*63d4e48fSSadaf EbrahimiassertNotNull() {
377*63d4e48fSSadaf Ebrahimi  # shellcheck disable=SC2090
378*63d4e48fSSadaf Ebrahimi  ${_SHUNIT_LINENO_}
379*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -gt 2 ]; then
380*63d4e48fSSadaf Ebrahimi    # Allowing 0 arguments as $1 might actually be null.
381*63d4e48fSSadaf Ebrahimi    _shunit_error "assertNotNull() requires one or two arguments; $# given"
382*63d4e48fSSadaf Ebrahimi    _shunit_assertFail
383*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_ERROR}
384*63d4e48fSSadaf Ebrahimi  fi
385*63d4e48fSSadaf Ebrahimi  if _shunit_shouldSkip; then
386*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_TRUE}
387*63d4e48fSSadaf Ebrahimi  fi
388*63d4e48fSSadaf Ebrahimi
389*63d4e48fSSadaf Ebrahimi  shunit_message_=${__shunit_lineno}
390*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -eq 2 ]; then
391*63d4e48fSSadaf Ebrahimi    shunit_message_="${shunit_message_}$1"
392*63d4e48fSSadaf Ebrahimi    shift
393*63d4e48fSSadaf Ebrahimi  fi
394*63d4e48fSSadaf Ebrahimi
395*63d4e48fSSadaf Ebrahimi  ${__SHUNIT_BUILTIN} test -n "${1:-}"
396*63d4e48fSSadaf Ebrahimi  assertTrue "${shunit_message_}" $?
397*63d4e48fSSadaf Ebrahimi  shunit_return=$?
398*63d4e48fSSadaf Ebrahimi
399*63d4e48fSSadaf Ebrahimi  unset shunit_message_
400*63d4e48fSSadaf Ebrahimi  return ${shunit_return}
401*63d4e48fSSadaf Ebrahimi}
402*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC2016,SC2034
403*63d4e48fSSadaf Ebrahimi_ASSERT_NOT_NULL_='eval assertNotNull --lineno "${LINENO:-}"'
404*63d4e48fSSadaf Ebrahimi
405*63d4e48fSSadaf Ebrahimi# Assert that two values are the same (i.e. equal to one another).
406*63d4e48fSSadaf Ebrahimi#
407*63d4e48fSSadaf Ebrahimi# Args:
408*63d4e48fSSadaf Ebrahimi#   message: string: failure message [optional]
409*63d4e48fSSadaf Ebrahimi#   expected: string: expected value
410*63d4e48fSSadaf Ebrahimi#   actual: string: actual value
411*63d4e48fSSadaf Ebrahimi# Returns:
412*63d4e48fSSadaf Ebrahimi#   integer: success (TRUE/FALSE/ERROR constant)
413*63d4e48fSSadaf EbrahimiassertSame() {
414*63d4e48fSSadaf Ebrahimi  # shellcheck disable=SC2090
415*63d4e48fSSadaf Ebrahimi  ${_SHUNIT_LINENO_}
416*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -lt 2 -o $# -gt 3 ]; then
417*63d4e48fSSadaf Ebrahimi    _shunit_error "assertSame() requires two or three arguments; $# given"
418*63d4e48fSSadaf Ebrahimi    _shunit_assertFail
419*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_ERROR}
420*63d4e48fSSadaf Ebrahimi  fi
421*63d4e48fSSadaf Ebrahimi  if _shunit_shouldSkip; then
422*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_TRUE}
423*63d4e48fSSadaf Ebrahimi  fi
424*63d4e48fSSadaf Ebrahimi
425*63d4e48fSSadaf Ebrahimi  shunit_message_=${__shunit_lineno}
426*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -eq 3 ]; then
427*63d4e48fSSadaf Ebrahimi    shunit_message_="${shunit_message_}$1"
428*63d4e48fSSadaf Ebrahimi    shift
429*63d4e48fSSadaf Ebrahimi  fi
430*63d4e48fSSadaf Ebrahimi  assertEquals "${shunit_message_}" "$1" "$2"
431*63d4e48fSSadaf Ebrahimi  shunit_return=$?
432*63d4e48fSSadaf Ebrahimi
433*63d4e48fSSadaf Ebrahimi  unset shunit_message_
434*63d4e48fSSadaf Ebrahimi  return ${shunit_return}
435*63d4e48fSSadaf Ebrahimi}
436*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC2016,SC2034
437*63d4e48fSSadaf Ebrahimi_ASSERT_SAME_='eval assertSame --lineno "${LINENO:-}"'
438*63d4e48fSSadaf Ebrahimi
439*63d4e48fSSadaf Ebrahimi# Assert that two values are not the same (i.e. not equal to one another).
440*63d4e48fSSadaf Ebrahimi#
441*63d4e48fSSadaf Ebrahimi# Args:
442*63d4e48fSSadaf Ebrahimi#   message: string: failure message [optional]
443*63d4e48fSSadaf Ebrahimi#   expected: string: expected value
444*63d4e48fSSadaf Ebrahimi#   actual: string: actual value
445*63d4e48fSSadaf Ebrahimi# Returns:
446*63d4e48fSSadaf Ebrahimi#   integer: success (TRUE/FALSE/ERROR constant)
447*63d4e48fSSadaf EbrahimiassertNotSame() {
448*63d4e48fSSadaf Ebrahimi  # shellcheck disable=SC2090
449*63d4e48fSSadaf Ebrahimi  ${_SHUNIT_LINENO_}
450*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -lt 2 -o $# -gt 3 ]; then
451*63d4e48fSSadaf Ebrahimi    _shunit_error "assertNotSame() requires two or three arguments; $# given"
452*63d4e48fSSadaf Ebrahimi    _shunit_assertFail
453*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_ERROR}
454*63d4e48fSSadaf Ebrahimi  fi
455*63d4e48fSSadaf Ebrahimi  if _shunit_shouldSkip; then
456*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_TRUE}
457*63d4e48fSSadaf Ebrahimi  fi
458*63d4e48fSSadaf Ebrahimi
459*63d4e48fSSadaf Ebrahimi  shunit_message_=${__shunit_lineno}
460*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -eq 3 ]; then
461*63d4e48fSSadaf Ebrahimi    shunit_message_="${shunit_message_:-}$1"
462*63d4e48fSSadaf Ebrahimi    shift
463*63d4e48fSSadaf Ebrahimi  fi
464*63d4e48fSSadaf Ebrahimi  assertNotEquals "${shunit_message_}" "$1" "$2"
465*63d4e48fSSadaf Ebrahimi  shunit_return=$?
466*63d4e48fSSadaf Ebrahimi
467*63d4e48fSSadaf Ebrahimi  unset shunit_message_
468*63d4e48fSSadaf Ebrahimi  return ${shunit_return}
469*63d4e48fSSadaf Ebrahimi}
470*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC2016,SC2034
471*63d4e48fSSadaf Ebrahimi_ASSERT_NOT_SAME_='eval assertNotSame --lineno "${LINENO:-}"'
472*63d4e48fSSadaf Ebrahimi
473*63d4e48fSSadaf Ebrahimi# Assert that a value or shell test condition is true.
474*63d4e48fSSadaf Ebrahimi#
475*63d4e48fSSadaf Ebrahimi# In shell, a value of 0 is true and a non-zero value is false. Any integer
476*63d4e48fSSadaf Ebrahimi# value passed can thereby be tested.
477*63d4e48fSSadaf Ebrahimi#
478*63d4e48fSSadaf Ebrahimi# Shell supports much more complicated tests though, and a means to support
479*63d4e48fSSadaf Ebrahimi# them was needed. As such, this function tests that conditions are true or
480*63d4e48fSSadaf Ebrahimi# false through evaluation rather than just looking for a true or false.
481*63d4e48fSSadaf Ebrahimi#
482*63d4e48fSSadaf Ebrahimi# The following test will succeed:
483*63d4e48fSSadaf Ebrahimi#   assertTrue 0
484*63d4e48fSSadaf Ebrahimi#   assertTrue "[ 34 -gt 23 ]"
485*63d4e48fSSadaf Ebrahimi# The following test will fail with a message:
486*63d4e48fSSadaf Ebrahimi#   assertTrue 123
487*63d4e48fSSadaf Ebrahimi#   assertTrue "test failed" "[ -r '/non/existent/file' ]"
488*63d4e48fSSadaf Ebrahimi#
489*63d4e48fSSadaf Ebrahimi# Args:
490*63d4e48fSSadaf Ebrahimi#   message: string: failure message [optional]
491*63d4e48fSSadaf Ebrahimi#   condition: string: integer value or shell conditional statement
492*63d4e48fSSadaf Ebrahimi# Returns:
493*63d4e48fSSadaf Ebrahimi#   integer: success (TRUE/FALSE/ERROR constant)
494*63d4e48fSSadaf EbrahimiassertTrue() {
495*63d4e48fSSadaf Ebrahimi  # shellcheck disable=SC2090
496*63d4e48fSSadaf Ebrahimi  ${_SHUNIT_LINENO_}
497*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -lt 1 -o $# -gt 2 ]; then
498*63d4e48fSSadaf Ebrahimi    _shunit_error "assertTrue() takes one or two arguments; $# given"
499*63d4e48fSSadaf Ebrahimi    _shunit_assertFail
500*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_ERROR}
501*63d4e48fSSadaf Ebrahimi  fi
502*63d4e48fSSadaf Ebrahimi  if _shunit_shouldSkip; then
503*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_TRUE}
504*63d4e48fSSadaf Ebrahimi  fi
505*63d4e48fSSadaf Ebrahimi
506*63d4e48fSSadaf Ebrahimi  shunit_message_=${__shunit_lineno}
507*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -eq 2 ]; then
508*63d4e48fSSadaf Ebrahimi    shunit_message_="${shunit_message_}$1"
509*63d4e48fSSadaf Ebrahimi    shift
510*63d4e48fSSadaf Ebrahimi  fi
511*63d4e48fSSadaf Ebrahimi  shunit_condition_=$1
512*63d4e48fSSadaf Ebrahimi
513*63d4e48fSSadaf Ebrahimi  # See if condition is an integer, i.e. a return value.
514*63d4e48fSSadaf Ebrahimi  shunit_return=${SHUNIT_TRUE}
515*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ -z "${shunit_condition_}" ]; then
516*63d4e48fSSadaf Ebrahimi    # Null condition.
517*63d4e48fSSadaf Ebrahimi    shunit_return=${SHUNIT_FALSE}
518*63d4e48fSSadaf Ebrahimi  elif (expr \( "${shunit_condition_}" + '0' \) '=' "${shunit_condition_}" >/dev/null 2>&1)
519*63d4e48fSSadaf Ebrahimi  then
520*63d4e48fSSadaf Ebrahimi    # Possible return value. Treating 0 as true, and non-zero as false.
521*63d4e48fSSadaf Ebrahimi    if ${__SHUNIT_BUILTIN} [ "${shunit_condition_}" -ne 0 ]; then
522*63d4e48fSSadaf Ebrahimi      shunit_return=${SHUNIT_FALSE}
523*63d4e48fSSadaf Ebrahimi    fi
524*63d4e48fSSadaf Ebrahimi  else
525*63d4e48fSSadaf Ebrahimi    # Hopefully... a condition.
526*63d4e48fSSadaf Ebrahimi    if ! eval "${shunit_condition_}" >/dev/null 2>&1; then
527*63d4e48fSSadaf Ebrahimi      shunit_return=${SHUNIT_FALSE}
528*63d4e48fSSadaf Ebrahimi    fi
529*63d4e48fSSadaf Ebrahimi  fi
530*63d4e48fSSadaf Ebrahimi
531*63d4e48fSSadaf Ebrahimi  # Record the test.
532*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ ${shunit_return} -eq ${SHUNIT_TRUE} ]; then
533*63d4e48fSSadaf Ebrahimi    _shunit_assertPass
534*63d4e48fSSadaf Ebrahimi  else
535*63d4e48fSSadaf Ebrahimi    _shunit_assertFail "${shunit_message_}"
536*63d4e48fSSadaf Ebrahimi  fi
537*63d4e48fSSadaf Ebrahimi
538*63d4e48fSSadaf Ebrahimi  unset shunit_message_ shunit_condition_
539*63d4e48fSSadaf Ebrahimi  return ${shunit_return}
540*63d4e48fSSadaf Ebrahimi}
541*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC2016,SC2034
542*63d4e48fSSadaf Ebrahimi_ASSERT_TRUE_='eval assertTrue --lineno "${LINENO:-}"'
543*63d4e48fSSadaf Ebrahimi
544*63d4e48fSSadaf Ebrahimi# Assert that a value or shell test condition is false.
545*63d4e48fSSadaf Ebrahimi#
546*63d4e48fSSadaf Ebrahimi# In shell, a value of 0 is true and a non-zero value is false. Any integer
547*63d4e48fSSadaf Ebrahimi# value passed can thereby be tested.
548*63d4e48fSSadaf Ebrahimi#
549*63d4e48fSSadaf Ebrahimi# Shell supports much more complicated tests though, and a means to support
550*63d4e48fSSadaf Ebrahimi# them was needed. As such, this function tests that conditions are true or
551*63d4e48fSSadaf Ebrahimi# false through evaluation rather than just looking for a true or false.
552*63d4e48fSSadaf Ebrahimi#
553*63d4e48fSSadaf Ebrahimi# The following test will succeed:
554*63d4e48fSSadaf Ebrahimi#   assertFalse 1
555*63d4e48fSSadaf Ebrahimi#   assertFalse "[ 'apples' = 'oranges' ]"
556*63d4e48fSSadaf Ebrahimi# The following test will fail with a message:
557*63d4e48fSSadaf Ebrahimi#   assertFalse 0
558*63d4e48fSSadaf Ebrahimi#   assertFalse "test failed" "[ 1 -eq 1 -a 2 -eq 2 ]"
559*63d4e48fSSadaf Ebrahimi#
560*63d4e48fSSadaf Ebrahimi# Args:
561*63d4e48fSSadaf Ebrahimi#   message: string: failure message [optional]
562*63d4e48fSSadaf Ebrahimi#   condition: string: integer value or shell conditional statement
563*63d4e48fSSadaf Ebrahimi# Returns:
564*63d4e48fSSadaf Ebrahimi#   integer: success (TRUE/FALSE/ERROR constant)
565*63d4e48fSSadaf EbrahimiassertFalse() {
566*63d4e48fSSadaf Ebrahimi  # shellcheck disable=SC2090
567*63d4e48fSSadaf Ebrahimi  ${_SHUNIT_LINENO_}
568*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -lt 1 -o $# -gt 2 ]; then
569*63d4e48fSSadaf Ebrahimi    _shunit_error "assertFalse() requires one or two arguments; $# given"
570*63d4e48fSSadaf Ebrahimi    _shunit_assertFail
571*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_ERROR}
572*63d4e48fSSadaf Ebrahimi  fi
573*63d4e48fSSadaf Ebrahimi  if _shunit_shouldSkip; then
574*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_TRUE}
575*63d4e48fSSadaf Ebrahimi  fi
576*63d4e48fSSadaf Ebrahimi
577*63d4e48fSSadaf Ebrahimi  shunit_message_=${__shunit_lineno}
578*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -eq 2 ]; then
579*63d4e48fSSadaf Ebrahimi    shunit_message_="${shunit_message_}$1"
580*63d4e48fSSadaf Ebrahimi    shift
581*63d4e48fSSadaf Ebrahimi  fi
582*63d4e48fSSadaf Ebrahimi  shunit_condition_=$1
583*63d4e48fSSadaf Ebrahimi
584*63d4e48fSSadaf Ebrahimi  # See if condition is an integer, i.e. a return value.
585*63d4e48fSSadaf Ebrahimi  shunit_return=${SHUNIT_TRUE}
586*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ -z "${shunit_condition_}" ]; then
587*63d4e48fSSadaf Ebrahimi    # Null condition.
588*63d4e48fSSadaf Ebrahimi    shunit_return=${SHUNIT_TRUE}
589*63d4e48fSSadaf Ebrahimi  elif (expr \( "${shunit_condition_}" + '0' \) '=' "${shunit_condition_}" >/dev/null 2>&1); then
590*63d4e48fSSadaf Ebrahimi    # Possible return value. Treating 0 as true, and non-zero as false.
591*63d4e48fSSadaf Ebrahimi    if ${__SHUNIT_BUILTIN} [ "${shunit_condition_}" -eq 0 ]; then
592*63d4e48fSSadaf Ebrahimi      shunit_return=${SHUNIT_FALSE}
593*63d4e48fSSadaf Ebrahimi    fi
594*63d4e48fSSadaf Ebrahimi  else
595*63d4e48fSSadaf Ebrahimi    # Hopefully... a condition.
596*63d4e48fSSadaf Ebrahimi    # shellcheck disable=SC2086
597*63d4e48fSSadaf Ebrahimi    if eval ${shunit_condition_} >/dev/null 2>&1; then
598*63d4e48fSSadaf Ebrahimi      shunit_return=${SHUNIT_FALSE}
599*63d4e48fSSadaf Ebrahimi    fi
600*63d4e48fSSadaf Ebrahimi  fi
601*63d4e48fSSadaf Ebrahimi
602*63d4e48fSSadaf Ebrahimi  # Record the test.
603*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ "${shunit_return}" -eq "${SHUNIT_TRUE}" ]; then
604*63d4e48fSSadaf Ebrahimi    _shunit_assertPass
605*63d4e48fSSadaf Ebrahimi  else
606*63d4e48fSSadaf Ebrahimi    _shunit_assertFail "${shunit_message_}"
607*63d4e48fSSadaf Ebrahimi  fi
608*63d4e48fSSadaf Ebrahimi
609*63d4e48fSSadaf Ebrahimi  unset shunit_message_ shunit_condition_
610*63d4e48fSSadaf Ebrahimi  return "${shunit_return}"
611*63d4e48fSSadaf Ebrahimi}
612*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC2016,SC2034
613*63d4e48fSSadaf Ebrahimi_ASSERT_FALSE_='eval assertFalse --lineno "${LINENO:-}"'
614*63d4e48fSSadaf Ebrahimi
615*63d4e48fSSadaf Ebrahimi#-----------------------------------------------------------------------------
616*63d4e48fSSadaf Ebrahimi# Failure functions.
617*63d4e48fSSadaf Ebrahimi#
618*63d4e48fSSadaf Ebrahimi
619*63d4e48fSSadaf Ebrahimi# Records a test failure.
620*63d4e48fSSadaf Ebrahimi#
621*63d4e48fSSadaf Ebrahimi# Args:
622*63d4e48fSSadaf Ebrahimi#   message: string: failure message [optional]
623*63d4e48fSSadaf Ebrahimi# Returns:
624*63d4e48fSSadaf Ebrahimi#   integer: success (TRUE/FALSE/ERROR constant)
625*63d4e48fSSadaf Ebrahimifail() {
626*63d4e48fSSadaf Ebrahimi  # shellcheck disable=SC2090
627*63d4e48fSSadaf Ebrahimi  ${_SHUNIT_LINENO_}
628*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -gt 1 ]; then
629*63d4e48fSSadaf Ebrahimi    _shunit_error "fail() requires zero or one arguments; $# given"
630*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_ERROR}
631*63d4e48fSSadaf Ebrahimi  fi
632*63d4e48fSSadaf Ebrahimi  if _shunit_shouldSkip; then
633*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_TRUE}
634*63d4e48fSSadaf Ebrahimi  fi
635*63d4e48fSSadaf Ebrahimi
636*63d4e48fSSadaf Ebrahimi  shunit_message_=${__shunit_lineno}
637*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -eq 1 ]; then
638*63d4e48fSSadaf Ebrahimi    shunit_message_="${shunit_message_}$1"
639*63d4e48fSSadaf Ebrahimi    shift
640*63d4e48fSSadaf Ebrahimi  fi
641*63d4e48fSSadaf Ebrahimi
642*63d4e48fSSadaf Ebrahimi  _shunit_assertFail "${shunit_message_}"
643*63d4e48fSSadaf Ebrahimi
644*63d4e48fSSadaf Ebrahimi  unset shunit_message_
645*63d4e48fSSadaf Ebrahimi  return ${SHUNIT_FALSE}
646*63d4e48fSSadaf Ebrahimi}
647*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC2016,SC2034
648*63d4e48fSSadaf Ebrahimi_FAIL_='eval fail --lineno "${LINENO:-}"'
649*63d4e48fSSadaf Ebrahimi
650*63d4e48fSSadaf Ebrahimi# Records a test failure, stating two values were not equal.
651*63d4e48fSSadaf Ebrahimi#
652*63d4e48fSSadaf Ebrahimi# Args:
653*63d4e48fSSadaf Ebrahimi#   message: string: failure message [optional]
654*63d4e48fSSadaf Ebrahimi#   expected: string: expected value
655*63d4e48fSSadaf Ebrahimi#   actual: string: actual value
656*63d4e48fSSadaf Ebrahimi# Returns:
657*63d4e48fSSadaf Ebrahimi#   integer: success (TRUE/FALSE/ERROR constant)
658*63d4e48fSSadaf EbrahimifailNotEquals() {
659*63d4e48fSSadaf Ebrahimi  # shellcheck disable=SC2090
660*63d4e48fSSadaf Ebrahimi  ${_SHUNIT_LINENO_}
661*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -lt 2 -o $# -gt 3 ]; then
662*63d4e48fSSadaf Ebrahimi    _shunit_error "failNotEquals() requires one or two arguments; $# given"
663*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_ERROR}
664*63d4e48fSSadaf Ebrahimi  fi
665*63d4e48fSSadaf Ebrahimi  if _shunit_shouldSkip; then
666*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_TRUE}
667*63d4e48fSSadaf Ebrahimi  fi
668*63d4e48fSSadaf Ebrahimi
669*63d4e48fSSadaf Ebrahimi  shunit_message_=${__shunit_lineno}
670*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -eq 3 ]; then
671*63d4e48fSSadaf Ebrahimi    shunit_message_="${shunit_message_}$1"
672*63d4e48fSSadaf Ebrahimi    shift
673*63d4e48fSSadaf Ebrahimi  fi
674*63d4e48fSSadaf Ebrahimi  shunit_expected_=$1
675*63d4e48fSSadaf Ebrahimi  shunit_actual_=$2
676*63d4e48fSSadaf Ebrahimi
677*63d4e48fSSadaf Ebrahimi  shunit_message_=${shunit_message_%% }
678*63d4e48fSSadaf Ebrahimi  _shunit_assertFail "${shunit_message_:+${shunit_message_} }expected:<${shunit_expected_}> but was:<${shunit_actual_}>"
679*63d4e48fSSadaf Ebrahimi
680*63d4e48fSSadaf Ebrahimi  unset shunit_message_ shunit_expected_ shunit_actual_
681*63d4e48fSSadaf Ebrahimi  return ${SHUNIT_FALSE}
682*63d4e48fSSadaf Ebrahimi}
683*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC2016,SC2034
684*63d4e48fSSadaf Ebrahimi_FAIL_NOT_EQUALS_='eval failNotEquals --lineno "${LINENO:-}"'
685*63d4e48fSSadaf Ebrahimi
686*63d4e48fSSadaf Ebrahimi# Records a test failure, stating a value was found.
687*63d4e48fSSadaf Ebrahimi#
688*63d4e48fSSadaf Ebrahimi# Args:
689*63d4e48fSSadaf Ebrahimi#   message: string: failure message [optional]
690*63d4e48fSSadaf Ebrahimi#   content: string: found value
691*63d4e48fSSadaf Ebrahimi# Returns:
692*63d4e48fSSadaf Ebrahimi#   integer: success (TRUE/FALSE/ERROR constant)
693*63d4e48fSSadaf EbrahimifailFound() {
694*63d4e48fSSadaf Ebrahimi  # shellcheck disable=SC2090
695*63d4e48fSSadaf Ebrahimi  ${_SHUNIT_LINENO_}
696*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -lt 1 -o $# -gt 2 ]; then
697*63d4e48fSSadaf Ebrahimi    _shunit_error "failFound() requires one or two arguments; $# given"
698*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_ERROR}
699*63d4e48fSSadaf Ebrahimi  fi
700*63d4e48fSSadaf Ebrahimi  if _shunit_shouldSkip; then
701*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_TRUE}
702*63d4e48fSSadaf Ebrahimi  fi
703*63d4e48fSSadaf Ebrahimi
704*63d4e48fSSadaf Ebrahimi  shunit_message_=${__shunit_lineno}
705*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -eq 2 ]; then
706*63d4e48fSSadaf Ebrahimi    shunit_message_="${shunit_message_}$1"
707*63d4e48fSSadaf Ebrahimi    shift
708*63d4e48fSSadaf Ebrahimi  fi
709*63d4e48fSSadaf Ebrahimi  shunit_content_=$1
710*63d4e48fSSadaf Ebrahimi
711*63d4e48fSSadaf Ebrahimi  shunit_message_=${shunit_message_%% }
712*63d4e48fSSadaf Ebrahimi  _shunit_assertFail "${shunit_message_:+${shunit_message_} }found:<${shunit_content_}>"
713*63d4e48fSSadaf Ebrahimi
714*63d4e48fSSadaf Ebrahimi  unset shunit_message_ shunit_content_
715*63d4e48fSSadaf Ebrahimi  return ${SHUNIT_FALSE}
716*63d4e48fSSadaf Ebrahimi}
717*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC2016,SC2034
718*63d4e48fSSadaf Ebrahimi_FAIL_FOUND_='eval failFound --lineno "${LINENO:-}"'
719*63d4e48fSSadaf Ebrahimi
720*63d4e48fSSadaf Ebrahimi# Records a test failure, stating a content was not found.
721*63d4e48fSSadaf Ebrahimi#
722*63d4e48fSSadaf Ebrahimi# Args:
723*63d4e48fSSadaf Ebrahimi#   message: string: failure message [optional]
724*63d4e48fSSadaf Ebrahimi#   content: string: content not found
725*63d4e48fSSadaf Ebrahimi# Returns:
726*63d4e48fSSadaf Ebrahimi#   integer: success (TRUE/FALSE/ERROR constant)
727*63d4e48fSSadaf EbrahimifailNotFound() {
728*63d4e48fSSadaf Ebrahimi  # shellcheck disable=SC2090
729*63d4e48fSSadaf Ebrahimi  ${_SHUNIT_LINENO_}
730*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -lt 1 -o $# -gt 2 ]; then
731*63d4e48fSSadaf Ebrahimi    _shunit_error "failNotFound() requires one or two arguments; $# given"
732*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_ERROR}
733*63d4e48fSSadaf Ebrahimi  fi
734*63d4e48fSSadaf Ebrahimi  if _shunit_shouldSkip; then
735*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_TRUE}
736*63d4e48fSSadaf Ebrahimi  fi
737*63d4e48fSSadaf Ebrahimi
738*63d4e48fSSadaf Ebrahimi  shunit_message_=${__shunit_lineno}
739*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -eq 2 ]; then
740*63d4e48fSSadaf Ebrahimi    shunit_message_="${shunit_message_}$1"
741*63d4e48fSSadaf Ebrahimi    shift
742*63d4e48fSSadaf Ebrahimi  fi
743*63d4e48fSSadaf Ebrahimi  shunit_content_=$1
744*63d4e48fSSadaf Ebrahimi
745*63d4e48fSSadaf Ebrahimi  shunit_message_=${shunit_message_%% }
746*63d4e48fSSadaf Ebrahimi  _shunit_assertFail "${shunit_message_:+${shunit_message_} }not found:<${shunit_content_}>"
747*63d4e48fSSadaf Ebrahimi
748*63d4e48fSSadaf Ebrahimi  unset shunit_message_ shunit_content_
749*63d4e48fSSadaf Ebrahimi  return ${SHUNIT_FALSE}
750*63d4e48fSSadaf Ebrahimi}
751*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC2016,SC2034
752*63d4e48fSSadaf Ebrahimi_FAIL_NOT_FOUND_='eval failNotFound --lineno "${LINENO:-}"'
753*63d4e48fSSadaf Ebrahimi
754*63d4e48fSSadaf Ebrahimi# Records a test failure, stating two values should have been the same.
755*63d4e48fSSadaf Ebrahimi#
756*63d4e48fSSadaf Ebrahimi# Args:
757*63d4e48fSSadaf Ebrahimi#   message: string: failure message [optional]
758*63d4e48fSSadaf Ebrahimi#   expected: string: expected value
759*63d4e48fSSadaf Ebrahimi#   actual: string: actual value
760*63d4e48fSSadaf Ebrahimi# Returns:
761*63d4e48fSSadaf Ebrahimi#   integer: success (TRUE/FALSE/ERROR constant)
762*63d4e48fSSadaf EbrahimifailSame() {
763*63d4e48fSSadaf Ebrahimi  # shellcheck disable=SC2090
764*63d4e48fSSadaf Ebrahimi  ${_SHUNIT_LINENO_}
765*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -lt 2 -o $# -gt 3 ]; then
766*63d4e48fSSadaf Ebrahimi    _shunit_error "failSame() requires two or three arguments; $# given"
767*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_ERROR}
768*63d4e48fSSadaf Ebrahimi  fi
769*63d4e48fSSadaf Ebrahimi  if _shunit_shouldSkip; then
770*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_TRUE}
771*63d4e48fSSadaf Ebrahimi  fi
772*63d4e48fSSadaf Ebrahimi
773*63d4e48fSSadaf Ebrahimi  shunit_message_=${__shunit_lineno}
774*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -eq 3 ]; then
775*63d4e48fSSadaf Ebrahimi    shunit_message_="${shunit_message_}$1"
776*63d4e48fSSadaf Ebrahimi    shift
777*63d4e48fSSadaf Ebrahimi  fi
778*63d4e48fSSadaf Ebrahimi
779*63d4e48fSSadaf Ebrahimi  shunit_message_=${shunit_message_%% }
780*63d4e48fSSadaf Ebrahimi  _shunit_assertFail "${shunit_message_:+${shunit_message_} }expected not same"
781*63d4e48fSSadaf Ebrahimi
782*63d4e48fSSadaf Ebrahimi  unset shunit_message_
783*63d4e48fSSadaf Ebrahimi  return ${SHUNIT_FALSE}
784*63d4e48fSSadaf Ebrahimi}
785*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC2016,SC2034
786*63d4e48fSSadaf Ebrahimi_FAIL_SAME_='eval failSame --lineno "${LINENO:-}"'
787*63d4e48fSSadaf Ebrahimi
788*63d4e48fSSadaf Ebrahimi# Records a test failure, stating two values were not equal.
789*63d4e48fSSadaf Ebrahimi#
790*63d4e48fSSadaf Ebrahimi# This is functionally equivalent to calling failNotEquals().
791*63d4e48fSSadaf Ebrahimi#
792*63d4e48fSSadaf Ebrahimi# Args:
793*63d4e48fSSadaf Ebrahimi#   message: string: failure message [optional]
794*63d4e48fSSadaf Ebrahimi#   expected: string: expected value
795*63d4e48fSSadaf Ebrahimi#   actual: string: actual value
796*63d4e48fSSadaf Ebrahimi# Returns:
797*63d4e48fSSadaf Ebrahimi#   integer: success (TRUE/FALSE/ERROR constant)
798*63d4e48fSSadaf EbrahimifailNotSame() {
799*63d4e48fSSadaf Ebrahimi  # shellcheck disable=SC2090
800*63d4e48fSSadaf Ebrahimi  ${_SHUNIT_LINENO_}
801*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -lt 2 -o $# -gt 3 ]; then
802*63d4e48fSSadaf Ebrahimi    _shunit_error "failNotSame() requires one or two arguments; $# given"
803*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_ERROR}
804*63d4e48fSSadaf Ebrahimi  fi
805*63d4e48fSSadaf Ebrahimi  if _shunit_shouldSkip; then
806*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_TRUE}
807*63d4e48fSSadaf Ebrahimi  fi
808*63d4e48fSSadaf Ebrahimi
809*63d4e48fSSadaf Ebrahimi  shunit_message_=${__shunit_lineno}
810*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -eq 3 ]; then
811*63d4e48fSSadaf Ebrahimi    shunit_message_="${shunit_message_}$1"
812*63d4e48fSSadaf Ebrahimi    shift
813*63d4e48fSSadaf Ebrahimi  fi
814*63d4e48fSSadaf Ebrahimi  failNotEquals "${shunit_message_}" "$1" "$2"
815*63d4e48fSSadaf Ebrahimi  shunit_return=$?
816*63d4e48fSSadaf Ebrahimi
817*63d4e48fSSadaf Ebrahimi  unset shunit_message_
818*63d4e48fSSadaf Ebrahimi  return ${shunit_return}
819*63d4e48fSSadaf Ebrahimi}
820*63d4e48fSSadaf Ebrahimi# shellcheck disable=SC2016,SC2034
821*63d4e48fSSadaf Ebrahimi_FAIL_NOT_SAME_='eval failNotSame --lineno "${LINENO:-}"'
822*63d4e48fSSadaf Ebrahimi
823*63d4e48fSSadaf Ebrahimi#-----------------------------------------------------------------------------
824*63d4e48fSSadaf Ebrahimi# Skipping functions.
825*63d4e48fSSadaf Ebrahimi#
826*63d4e48fSSadaf Ebrahimi
827*63d4e48fSSadaf Ebrahimi# Force remaining assert and fail functions to be "skipped".
828*63d4e48fSSadaf Ebrahimi#
829*63d4e48fSSadaf Ebrahimi# This function forces the remaining assert and fail functions to be "skipped",
830*63d4e48fSSadaf Ebrahimi# i.e. they will have no effect. Each function skipped will be recorded so that
831*63d4e48fSSadaf Ebrahimi# the total of asserts and fails will not be altered.
832*63d4e48fSSadaf Ebrahimi#
833*63d4e48fSSadaf Ebrahimi# Args:
834*63d4e48fSSadaf Ebrahimi#   message: string: message to provide to user [optional]
835*63d4e48fSSadaf EbrahimistartSkipping() {
836*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -gt 0 ]; then _shunit_warn "[skipping] $*"; fi
837*63d4e48fSSadaf Ebrahimi  __shunit_skip=${SHUNIT_TRUE}
838*63d4e48fSSadaf Ebrahimi}
839*63d4e48fSSadaf Ebrahimi
840*63d4e48fSSadaf Ebrahimi# Resume the normal recording behavior of assert and fail calls.
841*63d4e48fSSadaf Ebrahimi#
842*63d4e48fSSadaf Ebrahimi# Args:
843*63d4e48fSSadaf Ebrahimi#   None
844*63d4e48fSSadaf EbrahimiendSkipping() { __shunit_skip=${SHUNIT_FALSE}; }
845*63d4e48fSSadaf Ebrahimi
846*63d4e48fSSadaf Ebrahimi# Returns the state of assert and fail call skipping.
847*63d4e48fSSadaf Ebrahimi#
848*63d4e48fSSadaf Ebrahimi# Args:
849*63d4e48fSSadaf Ebrahimi#   None
850*63d4e48fSSadaf Ebrahimi# Returns:
851*63d4e48fSSadaf Ebrahimi#   boolean: (TRUE/FALSE constant)
852*63d4e48fSSadaf EbrahimiisSkipping() { return ${__shunit_skip}; }
853*63d4e48fSSadaf Ebrahimi
854*63d4e48fSSadaf Ebrahimi#-----------------------------------------------------------------------------
855*63d4e48fSSadaf Ebrahimi# Suite functions.
856*63d4e48fSSadaf Ebrahimi#
857*63d4e48fSSadaf Ebrahimi
858*63d4e48fSSadaf Ebrahimi# Stub. This function should contains all unit test calls to be made.
859*63d4e48fSSadaf Ebrahimi#
860*63d4e48fSSadaf Ebrahimi# DEPRECATED (as of 2.1.0)
861*63d4e48fSSadaf Ebrahimi#
862*63d4e48fSSadaf Ebrahimi# This function can be optionally overridden by the user in their test suite.
863*63d4e48fSSadaf Ebrahimi#
864*63d4e48fSSadaf Ebrahimi# If this function exists, it will be called when shunit2 is sourced. If it
865*63d4e48fSSadaf Ebrahimi# does not exist, shunit2 will search the parent script for all functions
866*63d4e48fSSadaf Ebrahimi# beginning with the word 'test', and they will be added dynamically to the
867*63d4e48fSSadaf Ebrahimi# test suite.
868*63d4e48fSSadaf Ebrahimi#
869*63d4e48fSSadaf Ebrahimi# This function should be overridden by the user in their unit test suite.
870*63d4e48fSSadaf Ebrahimi# Note: see _shunit_mktempFunc() for actual implementation
871*63d4e48fSSadaf Ebrahimi#
872*63d4e48fSSadaf Ebrahimi# Args:
873*63d4e48fSSadaf Ebrahimi#   None
874*63d4e48fSSadaf Ebrahimi#suite() { :; }  # DO NOT UNCOMMENT THIS FUNCTION
875*63d4e48fSSadaf Ebrahimi
876*63d4e48fSSadaf Ebrahimi# Adds a function name to the list of tests schedule for execution.
877*63d4e48fSSadaf Ebrahimi#
878*63d4e48fSSadaf Ebrahimi# This function should only be called from within the suite() function.
879*63d4e48fSSadaf Ebrahimi#
880*63d4e48fSSadaf Ebrahimi# Args:
881*63d4e48fSSadaf Ebrahimi#   function: string: name of a function to add to current unit test suite
882*63d4e48fSSadaf Ebrahimisuite_addTest() {
883*63d4e48fSSadaf Ebrahimi  shunit_func_=${1:-}
884*63d4e48fSSadaf Ebrahimi
885*63d4e48fSSadaf Ebrahimi  __shunit_suite="${__shunit_suite:+${__shunit_suite} }${shunit_func_}"
886*63d4e48fSSadaf Ebrahimi  __shunit_testsTotal=`expr ${__shunit_testsTotal} + 1`
887*63d4e48fSSadaf Ebrahimi
888*63d4e48fSSadaf Ebrahimi  unset shunit_func_
889*63d4e48fSSadaf Ebrahimi}
890*63d4e48fSSadaf Ebrahimi
891*63d4e48fSSadaf Ebrahimi# Stub. This function will be called once before any tests are run.
892*63d4e48fSSadaf Ebrahimi#
893*63d4e48fSSadaf Ebrahimi# Common one-time environment preparation tasks shared by all tests can be
894*63d4e48fSSadaf Ebrahimi# defined here.
895*63d4e48fSSadaf Ebrahimi#
896*63d4e48fSSadaf Ebrahimi# This function should be overridden by the user in their unit test suite.
897*63d4e48fSSadaf Ebrahimi# Note: see _shunit_mktempFunc() for actual implementation
898*63d4e48fSSadaf Ebrahimi#
899*63d4e48fSSadaf Ebrahimi# Args:
900*63d4e48fSSadaf Ebrahimi#   None
901*63d4e48fSSadaf Ebrahimi#oneTimeSetUp() { :; }  # DO NOT UNCOMMENT THIS FUNCTION
902*63d4e48fSSadaf Ebrahimi
903*63d4e48fSSadaf Ebrahimi# Stub. This function will be called once after all tests are finished.
904*63d4e48fSSadaf Ebrahimi#
905*63d4e48fSSadaf Ebrahimi# Common one-time environment cleanup tasks shared by all tests can be defined
906*63d4e48fSSadaf Ebrahimi# here.
907*63d4e48fSSadaf Ebrahimi#
908*63d4e48fSSadaf Ebrahimi# This function should be overridden by the user in their unit test suite.
909*63d4e48fSSadaf Ebrahimi# Note: see _shunit_mktempFunc() for actual implementation
910*63d4e48fSSadaf Ebrahimi#
911*63d4e48fSSadaf Ebrahimi# Args:
912*63d4e48fSSadaf Ebrahimi#   None
913*63d4e48fSSadaf Ebrahimi#oneTimeTearDown() { :; }  # DO NOT UNCOMMENT THIS FUNCTION
914*63d4e48fSSadaf Ebrahimi
915*63d4e48fSSadaf Ebrahimi# Stub. This function will be called before each test is run.
916*63d4e48fSSadaf Ebrahimi#
917*63d4e48fSSadaf Ebrahimi# Common environment preparation tasks shared by all tests can be defined here.
918*63d4e48fSSadaf Ebrahimi#
919*63d4e48fSSadaf Ebrahimi# This function should be overridden by the user in their unit test suite.
920*63d4e48fSSadaf Ebrahimi# Note: see _shunit_mktempFunc() for actual implementation
921*63d4e48fSSadaf Ebrahimi#
922*63d4e48fSSadaf Ebrahimi# Args:
923*63d4e48fSSadaf Ebrahimi#   None
924*63d4e48fSSadaf Ebrahimi#setUp() { :; }  # DO NOT UNCOMMENT THIS FUNCTION
925*63d4e48fSSadaf Ebrahimi
926*63d4e48fSSadaf Ebrahimi# Note: see _shunit_mktempFunc() for actual implementation
927*63d4e48fSSadaf Ebrahimi# Stub. This function will be called after each test is run.
928*63d4e48fSSadaf Ebrahimi#
929*63d4e48fSSadaf Ebrahimi# Common environment cleanup tasks shared by all tests can be defined here.
930*63d4e48fSSadaf Ebrahimi#
931*63d4e48fSSadaf Ebrahimi# This function should be overridden by the user in their unit test suite.
932*63d4e48fSSadaf Ebrahimi# Note: see _shunit_mktempFunc() for actual implementation
933*63d4e48fSSadaf Ebrahimi#
934*63d4e48fSSadaf Ebrahimi# Args:
935*63d4e48fSSadaf Ebrahimi#   None
936*63d4e48fSSadaf Ebrahimi#tearDown() { :; }  # DO NOT UNCOMMENT THIS FUNCTION
937*63d4e48fSSadaf Ebrahimi
938*63d4e48fSSadaf Ebrahimi#------------------------------------------------------------------------------
939*63d4e48fSSadaf Ebrahimi# Internal shUnit2 functions.
940*63d4e48fSSadaf Ebrahimi#
941*63d4e48fSSadaf Ebrahimi
942*63d4e48fSSadaf Ebrahimi# Create a temporary directory to store various run-time files in.
943*63d4e48fSSadaf Ebrahimi#
944*63d4e48fSSadaf Ebrahimi# This function is a cross-platform temporary directory creation tool. Not all
945*63d4e48fSSadaf Ebrahimi# OSes have the `mktemp` function, so one is included here.
946*63d4e48fSSadaf Ebrahimi#
947*63d4e48fSSadaf Ebrahimi# Args:
948*63d4e48fSSadaf Ebrahimi#   None
949*63d4e48fSSadaf Ebrahimi# Outputs:
950*63d4e48fSSadaf Ebrahimi#   string: the temporary directory that was created
951*63d4e48fSSadaf Ebrahimi_shunit_mktempDir() {
952*63d4e48fSSadaf Ebrahimi  # Try the standard `mktemp` function.
953*63d4e48fSSadaf Ebrahimi  if ( exec mktemp -dqt shunit.XXXXXX 2>/dev/null ); then
954*63d4e48fSSadaf Ebrahimi    return
955*63d4e48fSSadaf Ebrahimi  fi
956*63d4e48fSSadaf Ebrahimi
957*63d4e48fSSadaf Ebrahimi  # The standard `mktemp` didn't work. Use our own.
958*63d4e48fSSadaf Ebrahimi  # shellcheck disable=SC2039,SC3028
959*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ -r '/dev/urandom' -a -x '/usr/bin/od' ]; then
960*63d4e48fSSadaf Ebrahimi    _shunit_random_=`/usr/bin/od -vAn -N4 -tx4 </dev/urandom |command sed 's/^[^0-9a-f]*//'`
961*63d4e48fSSadaf Ebrahimi  elif ${__SHUNIT_BUILTIN} [ -n "${RANDOM:-}" ]; then
962*63d4e48fSSadaf Ebrahimi    # $RANDOM works
963*63d4e48fSSadaf Ebrahimi    _shunit_random_=${RANDOM}${RANDOM}${RANDOM}$$
964*63d4e48fSSadaf Ebrahimi  else
965*63d4e48fSSadaf Ebrahimi    # `$RANDOM` doesn't work.
966*63d4e48fSSadaf Ebrahimi    _shunit_date_=`date '+%Y%m%d%H%M%S'`
967*63d4e48fSSadaf Ebrahimi    _shunit_random_=`expr "${_shunit_date_}" / $$`
968*63d4e48fSSadaf Ebrahimi  fi
969*63d4e48fSSadaf Ebrahimi
970*63d4e48fSSadaf Ebrahimi  _shunit_tmpDir_="${TMPDIR:-/tmp}/shunit.${_shunit_random_}"
971*63d4e48fSSadaf Ebrahimi  if ! ( umask 077 && command mkdir "${_shunit_tmpDir_}" ); then
972*63d4e48fSSadaf Ebrahimi    _shunit_fatal 'could not create temporary directory! exiting'
973*63d4e48fSSadaf Ebrahimi  fi
974*63d4e48fSSadaf Ebrahimi
975*63d4e48fSSadaf Ebrahimi  echo "${_shunit_tmpDir_}"
976*63d4e48fSSadaf Ebrahimi  unset _shunit_date_ _shunit_random_ _shunit_tmpDir_
977*63d4e48fSSadaf Ebrahimi}
978*63d4e48fSSadaf Ebrahimi
979*63d4e48fSSadaf Ebrahimi# This function is here to work around issues in Cygwin.
980*63d4e48fSSadaf Ebrahimi#
981*63d4e48fSSadaf Ebrahimi# Args:
982*63d4e48fSSadaf Ebrahimi#   None
983*63d4e48fSSadaf Ebrahimi_shunit_mktempFunc() {
984*63d4e48fSSadaf Ebrahimi  for _shunit_func_ in oneTimeSetUp oneTimeTearDown setUp tearDown suite noexec
985*63d4e48fSSadaf Ebrahimi  do
986*63d4e48fSSadaf Ebrahimi    _shunit_file_="${__shunit_tmpDir}/${_shunit_func_}"
987*63d4e48fSSadaf Ebrahimi    command cat <<EOF >"${_shunit_file_}"
988*63d4e48fSSadaf Ebrahimi#! /bin/sh
989*63d4e48fSSadaf Ebrahimiexit ${SHUNIT_TRUE}
990*63d4e48fSSadaf EbrahimiEOF
991*63d4e48fSSadaf Ebrahimi    command chmod +x "${_shunit_file_}"
992*63d4e48fSSadaf Ebrahimi  done
993*63d4e48fSSadaf Ebrahimi
994*63d4e48fSSadaf Ebrahimi  unset _shunit_file_
995*63d4e48fSSadaf Ebrahimi}
996*63d4e48fSSadaf Ebrahimi
997*63d4e48fSSadaf Ebrahimi# Final cleanup function to leave things as we found them.
998*63d4e48fSSadaf Ebrahimi#
999*63d4e48fSSadaf Ebrahimi# Besides removing the temporary directory, this function is in charge of the
1000*63d4e48fSSadaf Ebrahimi# final exit code of the unit test. The exit code is based on how the script
1001*63d4e48fSSadaf Ebrahimi# was ended (e.g. normal exit, or via Ctrl-C).
1002*63d4e48fSSadaf Ebrahimi#
1003*63d4e48fSSadaf Ebrahimi# Args:
1004*63d4e48fSSadaf Ebrahimi#   name: string: name of the trap called (specified when trap defined)
1005*63d4e48fSSadaf Ebrahimi_shunit_cleanup() {
1006*63d4e48fSSadaf Ebrahimi  _shunit_name_=$1
1007*63d4e48fSSadaf Ebrahimi
1008*63d4e48fSSadaf Ebrahimi  _shunit_signal_=0
1009*63d4e48fSSadaf Ebrahimi  case "${_shunit_name_}" in
1010*63d4e48fSSadaf Ebrahimi    EXIT) ;;
1011*63d4e48fSSadaf Ebrahimi    INT) _shunit_signal_=130 ;;  # 2+128
1012*63d4e48fSSadaf Ebrahimi    TERM) _shunit_signal_=143 ;;  # 15+128
1013*63d4e48fSSadaf Ebrahimi    *)
1014*63d4e48fSSadaf Ebrahimi      _shunit_error "unrecognized trap value (${_shunit_name_})"
1015*63d4e48fSSadaf Ebrahimi      ;;
1016*63d4e48fSSadaf Ebrahimi  esac
1017*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ "${_shunit_name_}" != 'EXIT' ]; then
1018*63d4e48fSSadaf Ebrahimi    _shunit_warn "trapped and now handling the (${_shunit_name_}) signal"
1019*63d4e48fSSadaf Ebrahimi  fi
1020*63d4e48fSSadaf Ebrahimi
1021*63d4e48fSSadaf Ebrahimi  # Do our work.
1022*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ ${__shunit_clean} -eq ${SHUNIT_FALSE} ]; then
1023*63d4e48fSSadaf Ebrahimi    # Ensure tear downs are only called once.
1024*63d4e48fSSadaf Ebrahimi    __shunit_clean=${SHUNIT_TRUE}
1025*63d4e48fSSadaf Ebrahimi
1026*63d4e48fSSadaf Ebrahimi    tearDown || _shunit_warn 'tearDown() returned non-zero return code.'
1027*63d4e48fSSadaf Ebrahimi    oneTimeTearDown || \
1028*63d4e48fSSadaf Ebrahimi        _shunit_warn 'oneTimeTearDown() returned non-zero return code.'
1029*63d4e48fSSadaf Ebrahimi
1030*63d4e48fSSadaf Ebrahimi    command rm -fr "${__shunit_tmpDir}"
1031*63d4e48fSSadaf Ebrahimi  fi
1032*63d4e48fSSadaf Ebrahimi
1033*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ "${_shunit_name_}" != 'EXIT' ]; then
1034*63d4e48fSSadaf Ebrahimi    # Handle all non-EXIT signals.
1035*63d4e48fSSadaf Ebrahimi    trap - 0  # Disable EXIT trap.
1036*63d4e48fSSadaf Ebrahimi    exit ${_shunit_signal_}
1037*63d4e48fSSadaf Ebrahimi  elif ${__SHUNIT_BUILTIN} [ ${__shunit_reportGenerated} -eq ${SHUNIT_FALSE} ]; then
1038*63d4e48fSSadaf Ebrahimi    _shunit_assertFail 'unknown failure encountered running a test'
1039*63d4e48fSSadaf Ebrahimi    _shunit_generateReport
1040*63d4e48fSSadaf Ebrahimi    exit ${SHUNIT_ERROR}
1041*63d4e48fSSadaf Ebrahimi  fi
1042*63d4e48fSSadaf Ebrahimi
1043*63d4e48fSSadaf Ebrahimi  unset _shunit_name_ _shunit_signal_
1044*63d4e48fSSadaf Ebrahimi}
1045*63d4e48fSSadaf Ebrahimi
1046*63d4e48fSSadaf Ebrahimi# configureColor based on user color preference.
1047*63d4e48fSSadaf Ebrahimi#
1048*63d4e48fSSadaf Ebrahimi# Args:
1049*63d4e48fSSadaf Ebrahimi#   color: string: color mode (one of `always`, `auto`, or `never`).
1050*63d4e48fSSadaf Ebrahimi_shunit_configureColor() {
1051*63d4e48fSSadaf Ebrahimi  _shunit_color_=${SHUNIT_FALSE}  # By default, no color.
1052*63d4e48fSSadaf Ebrahimi  case $1 in
1053*63d4e48fSSadaf Ebrahimi    'always') _shunit_color_=${SHUNIT_TRUE} ;;
1054*63d4e48fSSadaf Ebrahimi    'auto')
1055*63d4e48fSSadaf Ebrahimi      if ${__SHUNIT_BUILTIN} [ "`_shunit_colors`" -ge 8 ]; then
1056*63d4e48fSSadaf Ebrahimi        _shunit_color_=${SHUNIT_TRUE}
1057*63d4e48fSSadaf Ebrahimi      fi
1058*63d4e48fSSadaf Ebrahimi      ;;
1059*63d4e48fSSadaf Ebrahimi    'never'|'none') ;;  # Support 'none' to support legacy usage.
1060*63d4e48fSSadaf Ebrahimi    *) _shunit_fatal "unrecognized color option '$1'" ;;
1061*63d4e48fSSadaf Ebrahimi  esac
1062*63d4e48fSSadaf Ebrahimi
1063*63d4e48fSSadaf Ebrahimi  # shellcheck disable=SC2254
1064*63d4e48fSSadaf Ebrahimi  case ${_shunit_color_} in
1065*63d4e48fSSadaf Ebrahimi    ${SHUNIT_TRUE})
1066*63d4e48fSSadaf Ebrahimi      __shunit_ansi_none=${__SHUNIT_ANSI_NONE}
1067*63d4e48fSSadaf Ebrahimi      __shunit_ansi_red=${__SHUNIT_ANSI_RED}
1068*63d4e48fSSadaf Ebrahimi      __shunit_ansi_green=${__SHUNIT_ANSI_GREEN}
1069*63d4e48fSSadaf Ebrahimi      __shunit_ansi_yellow=${__SHUNIT_ANSI_YELLOW}
1070*63d4e48fSSadaf Ebrahimi      __shunit_ansi_cyan=${__SHUNIT_ANSI_CYAN}
1071*63d4e48fSSadaf Ebrahimi      ;;
1072*63d4e48fSSadaf Ebrahimi    ${SHUNIT_FALSE})
1073*63d4e48fSSadaf Ebrahimi      __shunit_ansi_none=''
1074*63d4e48fSSadaf Ebrahimi      __shunit_ansi_red=''
1075*63d4e48fSSadaf Ebrahimi      __shunit_ansi_green=''
1076*63d4e48fSSadaf Ebrahimi      __shunit_ansi_yellow=''
1077*63d4e48fSSadaf Ebrahimi      __shunit_ansi_cyan=''
1078*63d4e48fSSadaf Ebrahimi      ;;
1079*63d4e48fSSadaf Ebrahimi  esac
1080*63d4e48fSSadaf Ebrahimi
1081*63d4e48fSSadaf Ebrahimi  unset _shunit_color_ _shunit_tput_
1082*63d4e48fSSadaf Ebrahimi}
1083*63d4e48fSSadaf Ebrahimi
1084*63d4e48fSSadaf Ebrahimi# colors returns the number of supported colors for the TERM.
1085*63d4e48fSSadaf Ebrahimi_shunit_colors() {
1086*63d4e48fSSadaf Ebrahimi  if _shunit_tput_=`${SHUNIT_CMD_TPUT} colors 2>/dev/null`; then
1087*63d4e48fSSadaf Ebrahimi    echo "${_shunit_tput_}"
1088*63d4e48fSSadaf Ebrahimi  else
1089*63d4e48fSSadaf Ebrahimi    echo 16
1090*63d4e48fSSadaf Ebrahimi  fi
1091*63d4e48fSSadaf Ebrahimi  unset _shunit_tput_
1092*63d4e48fSSadaf Ebrahimi}
1093*63d4e48fSSadaf Ebrahimi
1094*63d4e48fSSadaf Ebrahimi# The actual running of the tests happens here.
1095*63d4e48fSSadaf Ebrahimi#
1096*63d4e48fSSadaf Ebrahimi# Args:
1097*63d4e48fSSadaf Ebrahimi#   None
1098*63d4e48fSSadaf Ebrahimi_shunit_execSuite() {
1099*63d4e48fSSadaf Ebrahimi  for _shunit_test_ in ${__shunit_suite}; do
1100*63d4e48fSSadaf Ebrahimi    __shunit_testSuccess=${SHUNIT_TRUE}
1101*63d4e48fSSadaf Ebrahimi
1102*63d4e48fSSadaf Ebrahimi    # Disable skipping.
1103*63d4e48fSSadaf Ebrahimi    endSkipping
1104*63d4e48fSSadaf Ebrahimi
1105*63d4e48fSSadaf Ebrahimi    # Execute the per-test setUp() function.
1106*63d4e48fSSadaf Ebrahimi    if ! setUp; then
1107*63d4e48fSSadaf Ebrahimi      _shunit_fatal "setUp() returned non-zero return code."
1108*63d4e48fSSadaf Ebrahimi    fi
1109*63d4e48fSSadaf Ebrahimi
1110*63d4e48fSSadaf Ebrahimi    # Execute the test.
1111*63d4e48fSSadaf Ebrahimi    echo "${__SHUNIT_TEST_PREFIX}${_shunit_test_}"
1112*63d4e48fSSadaf Ebrahimi    # shellcheck disable=SC2086
1113*63d4e48fSSadaf Ebrahimi    if ! eval ${_shunit_test_}; then
1114*63d4e48fSSadaf Ebrahimi      _shunit_error "${_shunit_test_}() returned non-zero return code."
1115*63d4e48fSSadaf Ebrahimi      __shunit_testSuccess=${SHUNIT_ERROR}
1116*63d4e48fSSadaf Ebrahimi    fi
1117*63d4e48fSSadaf Ebrahimi
1118*63d4e48fSSadaf Ebrahimi    # Execute the per-test tearDown() function.
1119*63d4e48fSSadaf Ebrahimi    if ! tearDown; then
1120*63d4e48fSSadaf Ebrahimi      _shunit_fatal "tearDown() returned non-zero return code."
1121*63d4e48fSSadaf Ebrahimi    fi
1122*63d4e48fSSadaf Ebrahimi
1123*63d4e48fSSadaf Ebrahimi    # Update stats.
1124*63d4e48fSSadaf Ebrahimi    if ${__SHUNIT_BUILTIN} [ ${__shunit_testSuccess} -eq ${SHUNIT_TRUE} ]; then
1125*63d4e48fSSadaf Ebrahimi      __shunit_testsPassed=`expr ${__shunit_testsPassed} + 1`
1126*63d4e48fSSadaf Ebrahimi    else
1127*63d4e48fSSadaf Ebrahimi      __shunit_testsFailed=`expr ${__shunit_testsFailed} + 1`
1128*63d4e48fSSadaf Ebrahimi    fi
1129*63d4e48fSSadaf Ebrahimi  done
1130*63d4e48fSSadaf Ebrahimi
1131*63d4e48fSSadaf Ebrahimi  unset _shunit_test_
1132*63d4e48fSSadaf Ebrahimi}
1133*63d4e48fSSadaf Ebrahimi
1134*63d4e48fSSadaf Ebrahimi# Generates the user friendly report with appropriate OK/FAILED message.
1135*63d4e48fSSadaf Ebrahimi#
1136*63d4e48fSSadaf Ebrahimi# Args:
1137*63d4e48fSSadaf Ebrahimi#   None
1138*63d4e48fSSadaf Ebrahimi# Output:
1139*63d4e48fSSadaf Ebrahimi#   string: the report of successful and failed tests, as well as totals.
1140*63d4e48fSSadaf Ebrahimi_shunit_generateReport() {
1141*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ "${__shunit_reportGenerated}" -eq ${SHUNIT_TRUE} ]; then
1142*63d4e48fSSadaf Ebrahimi    return
1143*63d4e48fSSadaf Ebrahimi  fi
1144*63d4e48fSSadaf Ebrahimi
1145*63d4e48fSSadaf Ebrahimi  _shunit_ok_=${SHUNIT_TRUE}
1146*63d4e48fSSadaf Ebrahimi
1147*63d4e48fSSadaf Ebrahimi  # If no exit code was provided, determine an appropriate one.
1148*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ "${__shunit_testsFailed}" -gt 0 -o ${__shunit_testSuccess} -eq ${SHUNIT_FALSE} ]; then
1149*63d4e48fSSadaf Ebrahimi    _shunit_ok_=${SHUNIT_FALSE}
1150*63d4e48fSSadaf Ebrahimi  fi
1151*63d4e48fSSadaf Ebrahimi
1152*63d4e48fSSadaf Ebrahimi  echo
1153*63d4e48fSSadaf Ebrahimi  _shunit_msg_="Ran ${__shunit_ansi_cyan}${__shunit_testsTotal}${__shunit_ansi_none}"
1154*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ "${__shunit_testsTotal}" -eq 1 ]; then
1155*63d4e48fSSadaf Ebrahimi    ${__SHUNIT_CMD_ECHO_ESC} "${_shunit_msg_} test."
1156*63d4e48fSSadaf Ebrahimi  else
1157*63d4e48fSSadaf Ebrahimi    ${__SHUNIT_CMD_ECHO_ESC} "${_shunit_msg_} tests."
1158*63d4e48fSSadaf Ebrahimi  fi
1159*63d4e48fSSadaf Ebrahimi
1160*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ ${_shunit_ok_} -eq ${SHUNIT_TRUE} ]; then
1161*63d4e48fSSadaf Ebrahimi    _shunit_msg_="${__shunit_ansi_green}OK${__shunit_ansi_none}"
1162*63d4e48fSSadaf Ebrahimi    if ${__SHUNIT_BUILTIN} [ "${__shunit_assertsSkipped}" -gt 0 ]; then
1163*63d4e48fSSadaf Ebrahimi      _shunit_msg_="${_shunit_msg_} (${__shunit_ansi_yellow}skipped=${__shunit_assertsSkipped}${__shunit_ansi_none})"
1164*63d4e48fSSadaf Ebrahimi    fi
1165*63d4e48fSSadaf Ebrahimi  else
1166*63d4e48fSSadaf Ebrahimi    _shunit_msg_="${__shunit_ansi_red}FAILED${__shunit_ansi_none}"
1167*63d4e48fSSadaf Ebrahimi    _shunit_msg_="${_shunit_msg_} (${__shunit_ansi_red}failures=${__shunit_assertsFailed}${__shunit_ansi_none}"
1168*63d4e48fSSadaf Ebrahimi    if ${__SHUNIT_BUILTIN} [ "${__shunit_assertsSkipped}" -gt 0 ]; then
1169*63d4e48fSSadaf Ebrahimi      _shunit_msg_="${_shunit_msg_},${__shunit_ansi_yellow}skipped=${__shunit_assertsSkipped}${__shunit_ansi_none}"
1170*63d4e48fSSadaf Ebrahimi    fi
1171*63d4e48fSSadaf Ebrahimi    _shunit_msg_="${_shunit_msg_})"
1172*63d4e48fSSadaf Ebrahimi  fi
1173*63d4e48fSSadaf Ebrahimi
1174*63d4e48fSSadaf Ebrahimi  echo
1175*63d4e48fSSadaf Ebrahimi  ${__SHUNIT_CMD_ECHO_ESC} "${_shunit_msg_}"
1176*63d4e48fSSadaf Ebrahimi  __shunit_reportGenerated=${SHUNIT_TRUE}
1177*63d4e48fSSadaf Ebrahimi
1178*63d4e48fSSadaf Ebrahimi  unset _shunit_msg_ _shunit_ok_
1179*63d4e48fSSadaf Ebrahimi}
1180*63d4e48fSSadaf Ebrahimi
1181*63d4e48fSSadaf Ebrahimi# Test for whether a function should be skipped.
1182*63d4e48fSSadaf Ebrahimi#
1183*63d4e48fSSadaf Ebrahimi# Args:
1184*63d4e48fSSadaf Ebrahimi#   None
1185*63d4e48fSSadaf Ebrahimi# Returns:
1186*63d4e48fSSadaf Ebrahimi#   boolean: whether the test should be skipped (TRUE/FALSE constant)
1187*63d4e48fSSadaf Ebrahimi_shunit_shouldSkip() {
1188*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} test ${__shunit_skip} -eq ${SHUNIT_FALSE}; then
1189*63d4e48fSSadaf Ebrahimi    return ${SHUNIT_FALSE}
1190*63d4e48fSSadaf Ebrahimi  fi
1191*63d4e48fSSadaf Ebrahimi  _shunit_assertSkip
1192*63d4e48fSSadaf Ebrahimi}
1193*63d4e48fSSadaf Ebrahimi
1194*63d4e48fSSadaf Ebrahimi# Records a successful test.
1195*63d4e48fSSadaf Ebrahimi#
1196*63d4e48fSSadaf Ebrahimi# Args:
1197*63d4e48fSSadaf Ebrahimi#   None
1198*63d4e48fSSadaf Ebrahimi_shunit_assertPass() {
1199*63d4e48fSSadaf Ebrahimi  __shunit_assertsPassed=`expr ${__shunit_assertsPassed} + 1`
1200*63d4e48fSSadaf Ebrahimi  __shunit_assertsTotal=`expr ${__shunit_assertsTotal} + 1`
1201*63d4e48fSSadaf Ebrahimi}
1202*63d4e48fSSadaf Ebrahimi
1203*63d4e48fSSadaf Ebrahimi# Records a test failure.
1204*63d4e48fSSadaf Ebrahimi#
1205*63d4e48fSSadaf Ebrahimi# Args:
1206*63d4e48fSSadaf Ebrahimi#   message: string: failure message to provide user
1207*63d4e48fSSadaf Ebrahimi_shunit_assertFail() {
1208*63d4e48fSSadaf Ebrahimi  __shunit_testSuccess=${SHUNIT_FALSE}
1209*63d4e48fSSadaf Ebrahimi  _shunit_incFailedCount
1210*63d4e48fSSadaf Ebrahimi
1211*63d4e48fSSadaf Ebrahimi  if ${__SHUNIT_BUILTIN} [ $# -gt 0 ]; then
1212*63d4e48fSSadaf Ebrahimi    ${__SHUNIT_CMD_ECHO_ESC} "${__shunit_ansi_red}ASSERT:${__shunit_ansi_none}$*"
1213*63d4e48fSSadaf Ebrahimi  fi
1214*63d4e48fSSadaf Ebrahimi}
1215*63d4e48fSSadaf Ebrahimi
1216*63d4e48fSSadaf Ebrahimi# Increment the count of failed asserts.
1217*63d4e48fSSadaf Ebrahimi#
1218*63d4e48fSSadaf Ebrahimi# Args:
1219*63d4e48fSSadaf Ebrahimi#   none
1220*63d4e48fSSadaf Ebrahimi_shunit_incFailedCount() {
1221*63d4e48fSSadaf Ebrahimi  __shunit_assertsFailed=`expr "${__shunit_assertsFailed}" + 1`
1222*63d4e48fSSadaf Ebrahimi  __shunit_assertsTotal=`expr "${__shunit_assertsTotal}" + 1`
1223*63d4e48fSSadaf Ebrahimi}
1224*63d4e48fSSadaf Ebrahimi
1225*63d4e48fSSadaf Ebrahimi# Records a skipped test.
1226*63d4e48fSSadaf Ebrahimi#
1227*63d4e48fSSadaf Ebrahimi# Args:
1228*63d4e48fSSadaf Ebrahimi#   None
1229*63d4e48fSSadaf Ebrahimi_shunit_assertSkip() {
1230*63d4e48fSSadaf Ebrahimi  __shunit_assertsSkipped=`expr "${__shunit_assertsSkipped}" + 1`
1231*63d4e48fSSadaf Ebrahimi  __shunit_assertsTotal=`expr "${__shunit_assertsTotal}" + 1`
1232*63d4e48fSSadaf Ebrahimi}
1233*63d4e48fSSadaf Ebrahimi
1234*63d4e48fSSadaf Ebrahimi# Dump the current test metrics.
1235*63d4e48fSSadaf Ebrahimi#
1236*63d4e48fSSadaf Ebrahimi# Args:
1237*63d4e48fSSadaf Ebrahimi#   none
1238*63d4e48fSSadaf Ebrahimi_shunit_metrics() {
1239*63d4e48fSSadaf Ebrahimi  echo "< \
1240*63d4e48fSSadaf Ebrahimitotal: ${__shunit_assertsTotal} \
1241*63d4e48fSSadaf Ebrahimipassed: ${__shunit_assertsPassed} \
1242*63d4e48fSSadaf Ebrahimifailed: ${__shunit_assertsFailed} \
1243*63d4e48fSSadaf Ebrahimiskipped: ${__shunit_assertsSkipped} \
1244*63d4e48fSSadaf Ebrahimi>"
1245*63d4e48fSSadaf Ebrahimi}
1246*63d4e48fSSadaf Ebrahimi
1247*63d4e48fSSadaf Ebrahimi# Prepare a script filename for sourcing.
1248*63d4e48fSSadaf Ebrahimi#
1249*63d4e48fSSadaf Ebrahimi# Args:
1250*63d4e48fSSadaf Ebrahimi#   script: string: path to a script to source
1251*63d4e48fSSadaf Ebrahimi# Returns:
1252*63d4e48fSSadaf Ebrahimi#   string: filename prefixed with ./ (if necessary)
1253*63d4e48fSSadaf Ebrahimi_shunit_prepForSourcing() {
1254*63d4e48fSSadaf Ebrahimi  _shunit_script_=$1
1255*63d4e48fSSadaf Ebrahimi  case "${_shunit_script_}" in
1256*63d4e48fSSadaf Ebrahimi    /*|./*) echo "${_shunit_script_}" ;;
1257*63d4e48fSSadaf Ebrahimi    *) echo "./${_shunit_script_}" ;;
1258*63d4e48fSSadaf Ebrahimi  esac
1259*63d4e48fSSadaf Ebrahimi  unset _shunit_script_
1260*63d4e48fSSadaf Ebrahimi}
1261*63d4e48fSSadaf Ebrahimi
1262*63d4e48fSSadaf Ebrahimi# Extract list of functions to run tests against.
1263*63d4e48fSSadaf Ebrahimi#
1264*63d4e48fSSadaf Ebrahimi# Args:
1265*63d4e48fSSadaf Ebrahimi#   script: string: name of script to extract functions from
1266*63d4e48fSSadaf Ebrahimi# Returns:
1267*63d4e48fSSadaf Ebrahimi#   string: of function names
1268*63d4e48fSSadaf Ebrahimi_shunit_extractTestFunctions() {
1269*63d4e48fSSadaf Ebrahimi  _shunit_script_=$1
1270*63d4e48fSSadaf Ebrahimi
1271*63d4e48fSSadaf Ebrahimi  # Extract the lines with test function names, strip of anything besides the
1272*63d4e48fSSadaf Ebrahimi  # function name, and output everything on a single line.
1273*63d4e48fSSadaf Ebrahimi  _shunit_regex_='^\s*((function test[A-Za-z0-9_-]*)|(test[A-Za-z0-9_-]* *\(\)))'
1274*63d4e48fSSadaf Ebrahimi  # shellcheck disable=SC2196
1275*63d4e48fSSadaf Ebrahimi  egrep "${_shunit_regex_}" "${_shunit_script_}" \
1276*63d4e48fSSadaf Ebrahimi  |command sed 's/^[^A-Za-z0-9_-]*//;s/^function //;s/\([A-Za-z0-9_-]*\).*/\1/g' \
1277*63d4e48fSSadaf Ebrahimi  |xargs
1278*63d4e48fSSadaf Ebrahimi
1279*63d4e48fSSadaf Ebrahimi  unset _shunit_regex_ _shunit_script_
1280*63d4e48fSSadaf Ebrahimi}
1281*63d4e48fSSadaf Ebrahimi
1282*63d4e48fSSadaf Ebrahimi#------------------------------------------------------------------------------
1283*63d4e48fSSadaf Ebrahimi# Main.
1284*63d4e48fSSadaf Ebrahimi#
1285*63d4e48fSSadaf Ebrahimi
1286*63d4e48fSSadaf Ebrahimi# Determine the operating mode.
1287*63d4e48fSSadaf Ebrahimiif ${__SHUNIT_BUILTIN} [ $# -eq 0 -o "${1:-}" = '--' ]; then
1288*63d4e48fSSadaf Ebrahimi  __shunit_script=${__SHUNIT_PARENT}
1289*63d4e48fSSadaf Ebrahimi  __shunit_mode=${__SHUNIT_MODE_SOURCED}
1290*63d4e48fSSadaf Ebrahimielse
1291*63d4e48fSSadaf Ebrahimi  __shunit_script=$1
1292*63d4e48fSSadaf Ebrahimi  if ! ${__SHUNIT_BUILTIN} [ -r "${__shunit_script}" ]; then
1293*63d4e48fSSadaf Ebrahimi    _shunit_fatal "unable to read from ${__shunit_script}"
1294*63d4e48fSSadaf Ebrahimi  fi
1295*63d4e48fSSadaf Ebrahimi  __shunit_mode=${__SHUNIT_MODE_STANDALONE}
1296*63d4e48fSSadaf Ebrahimifi
1297*63d4e48fSSadaf Ebrahimi
1298*63d4e48fSSadaf Ebrahimi# Create a temporary storage location.
1299*63d4e48fSSadaf Ebrahimi__shunit_tmpDir=`_shunit_mktempDir`
1300*63d4e48fSSadaf Ebrahimi
1301*63d4e48fSSadaf Ebrahimi# Provide a public temporary directory for unit test scripts.
1302*63d4e48fSSadaf Ebrahimi# TODO(kward): document this.
1303*63d4e48fSSadaf EbrahimiSHUNIT_TMPDIR="${__shunit_tmpDir}/tmp"
1304*63d4e48fSSadaf Ebrahimiif ! command mkdir "${SHUNIT_TMPDIR}"; then
1305*63d4e48fSSadaf Ebrahimi  _shunit_fatal "error creating SHUNIT_TMPDIR '${SHUNIT_TMPDIR}'"
1306*63d4e48fSSadaf Ebrahimifi
1307*63d4e48fSSadaf Ebrahimi
1308*63d4e48fSSadaf Ebrahimi# Configure traps to clean up after ourselves.
1309*63d4e48fSSadaf Ebrahimitrap '_shunit_cleanup EXIT' 0
1310*63d4e48fSSadaf Ebrahimitrap '_shunit_cleanup INT' 2
1311*63d4e48fSSadaf Ebrahimitrap '_shunit_cleanup TERM' 15
1312*63d4e48fSSadaf Ebrahimi
1313*63d4e48fSSadaf Ebrahimi# Create phantom functions to work around issues with Cygwin.
1314*63d4e48fSSadaf Ebrahimi_shunit_mktempFunc
1315*63d4e48fSSadaf EbrahimiPATH="${__shunit_tmpDir}:${PATH}"
1316*63d4e48fSSadaf Ebrahimi
1317*63d4e48fSSadaf Ebrahimi# Make sure phantom functions are executable. This will bite if `/tmp` (or the
1318*63d4e48fSSadaf Ebrahimi# current `$TMPDIR`) points to a path on a partition that was mounted with the
1319*63d4e48fSSadaf Ebrahimi# 'noexec' option. The noexec command was created with `_shunit_mktempFunc()`.
1320*63d4e48fSSadaf Ebrahiminoexec 2>/dev/null || _shunit_fatal \
1321*63d4e48fSSadaf Ebrahimi    'Please declare TMPDIR with path on partition with exec permission.'
1322*63d4e48fSSadaf Ebrahimi
1323*63d4e48fSSadaf Ebrahimi# We must manually source the tests in standalone mode.
1324*63d4e48fSSadaf Ebrahimiif ${__SHUNIT_BUILTIN} [ "${__shunit_mode}" = "${__SHUNIT_MODE_STANDALONE}" ]; then
1325*63d4e48fSSadaf Ebrahimi  # shellcheck disable=SC1090
1326*63d4e48fSSadaf Ebrahimi  ${__SHUNIT_BUILTIN} . "`_shunit_prepForSourcing \"${__shunit_script}\"`"
1327*63d4e48fSSadaf Ebrahimifi
1328*63d4e48fSSadaf Ebrahimi
1329*63d4e48fSSadaf Ebrahimi# Configure default output coloring behavior.
1330*63d4e48fSSadaf Ebrahimi_shunit_configureColor "${SHUNIT_COLOR}"
1331*63d4e48fSSadaf Ebrahimi
1332*63d4e48fSSadaf Ebrahimi# Execute the oneTimeSetUp function (if it exists).
1333*63d4e48fSSadaf Ebrahimiif ! oneTimeSetUp; then
1334*63d4e48fSSadaf Ebrahimi  _shunit_fatal "oneTimeSetUp() returned non-zero return code."
1335*63d4e48fSSadaf Ebrahimifi
1336*63d4e48fSSadaf Ebrahimi
1337*63d4e48fSSadaf Ebrahimi# Command line selected tests or suite selected tests
1338*63d4e48fSSadaf Ebrahimiif ${__SHUNIT_BUILTIN} [ "$#" -ge 2 ]; then
1339*63d4e48fSSadaf Ebrahimi  # Argument $1 is either the filename of tests or '--'; either way, skip it.
1340*63d4e48fSSadaf Ebrahimi  shift
1341*63d4e48fSSadaf Ebrahimi  # Remaining arguments ($2 .. $#) are assumed to be test function names.
1342*63d4e48fSSadaf Ebrahimi  # Interate through all remaining args in "$@" in a POSIX (likely portable) way.
1343*63d4e48fSSadaf Ebrahimi  # Helpful tip: https://unix.stackexchange.com/questions/314032/how-to-use-arguments-like-1-2-in-a-for-loop
1344*63d4e48fSSadaf Ebrahimi  for _shunit_arg_ do
1345*63d4e48fSSadaf Ebrahimi    suite_addTest "${_shunit_arg_}"
1346*63d4e48fSSadaf Ebrahimi  done
1347*63d4e48fSSadaf Ebrahimi  unset _shunit_arg_
1348*63d4e48fSSadaf Ebrahimielse
1349*63d4e48fSSadaf Ebrahimi  # Execute the suite function defined in the parent test script.
1350*63d4e48fSSadaf Ebrahimi  # DEPRECATED as of 2.1.0.
1351*63d4e48fSSadaf Ebrahimi  suite
1352*63d4e48fSSadaf Ebrahimifi
1353*63d4e48fSSadaf Ebrahimi
1354*63d4e48fSSadaf Ebrahimi# If no tests or suite specified, dynamically build a list of functions.
1355*63d4e48fSSadaf Ebrahimiif ${__SHUNIT_BUILTIN} [ -z "${__shunit_suite}" ]; then
1356*63d4e48fSSadaf Ebrahimi  shunit_funcs_=`_shunit_extractTestFunctions "${__shunit_script}"`
1357*63d4e48fSSadaf Ebrahimi  for shunit_func_ in ${shunit_funcs_}; do
1358*63d4e48fSSadaf Ebrahimi    suite_addTest "${shunit_func_}"
1359*63d4e48fSSadaf Ebrahimi  done
1360*63d4e48fSSadaf Ebrahimifi
1361*63d4e48fSSadaf Ebrahimiunset shunit_func_ shunit_funcs_
1362*63d4e48fSSadaf Ebrahimi
1363*63d4e48fSSadaf Ebrahimi# Execute the suite of unit tests.
1364*63d4e48fSSadaf Ebrahimi_shunit_execSuite
1365*63d4e48fSSadaf Ebrahimi
1366*63d4e48fSSadaf Ebrahimi# Execute the oneTimeTearDown function (if it exists).
1367*63d4e48fSSadaf Ebrahimiif ! oneTimeTearDown; then
1368*63d4e48fSSadaf Ebrahimi  _shunit_fatal "oneTimeTearDown() returned non-zero return code."
1369*63d4e48fSSadaf Ebrahimifi
1370*63d4e48fSSadaf Ebrahimi
1371*63d4e48fSSadaf Ebrahimi# Generate a report summary.
1372*63d4e48fSSadaf Ebrahimi_shunit_generateReport
1373*63d4e48fSSadaf Ebrahimi
1374*63d4e48fSSadaf Ebrahimi# That's it folks.
1375*63d4e48fSSadaf Ebrahimiif ! ${__SHUNIT_BUILTIN} [ "${__shunit_testsFailed}" -eq 0 ]; then
1376*63d4e48fSSadaf Ebrahimi  return ${SHUNIT_FALSE}
1377*63d4e48fSSadaf Ebrahimifi
1378