1#! /bin/sh
2# vim:et:ft=sh:sts=2:sw=2
3#
4# shFlags unit tests for the internal functions.
5#
6# Copyright 2008-2018 Kate Ward. All Rights Reserved.
7# Released under the Apache 2.0 license.
8#
9# Author: kate.ward@forestent.com (Kate Ward)
10# https://github.com/kward/shflags
11#
12### ShellCheck (http://www.shellcheck.net/)
13# Disable source following.
14#   shellcheck disable=SC1090,SC1091
15# expr may be antiquated, but it is the only solution in some cases.
16#   shellcheck disable=SC2003
17# $() are not fully portable (POSIX != portable).
18#   shellcheck disable=SC2006
19
20# These variables will be overridden by the test helpers.
21stdoutF="${TMPDIR:-/tmp}/STDOUT"
22stderrF="${TMPDIR:-/tmp}/STDERR"
23
24# Load test helpers.
25. ./shflags_test_helpers
26
27testColumns() {
28  cols=`_flags_columns`
29  value=`expr "${cols}" : '\([0-9]*\)'`
30  assertNotNull "unexpected screen width (${cols})" "${value}"
31}
32
33testGetoptVers() {
34  # shellcheck disable=SC2162
35  while read desc mock want; do
36    assertEquals "${desc}" "$(_flags_getopt_vers "${mock}")" "${want}"
37  done <<EOF
38standard mock_getopt_std ${__FLAGS_GETOPT_VERS_STD}
39enhanced mock_getopt_enh ${__FLAGS_GETOPT_VERS_ENH}
40EOF
41}
42
43### The mock_getopt_* commands behave like "getopt -lfoo '' --foo" was called.
44# macOS 10.13.0.
45mock_getopt_std() { echo ' -- --foo'; return 0; }
46# Ubuntu 16.04.3
47mock_getopt_enh() { echo ' --foo --'; return 0; }
48
49testGenOptStr() {
50  _testGenOptStr '' ''
51
52  DEFINE_boolean bool false 'boolean value' b
53  _testGenOptStr 'b' 'bool'
54
55  DEFINE_float float 0.0 'float value' f
56  _testGenOptStr 'bf:' 'bool,float:'
57
58  DEFINE_integer int 0 'integer value' i
59  _testGenOptStr 'bf:i:' 'bool,float:,int:'
60
61  DEFINE_string str 0 'string value' s
62  _testGenOptStr 'bf:i:s:' 'bool,float:,int:,str:'
63
64  DEFINE_boolean help false 'show help' h
65  _testGenOptStr 'bf:i:s:h' 'bool,float:,int:,str:,help'
66}
67
68_testGenOptStr() {
69  short=$1
70  long=$2
71
72  result=`_flags_genOptStr "${__FLAGS_OPTSTR_SHORT}"`
73  assertTrue 'short option string generation failed' $?
74  assertEquals "${short}" "${result}"
75
76  result=`_flags_genOptStr "${__FLAGS_OPTSTR_LONG}"`
77  assertTrue 'long option string generation failed' $?
78  assertEquals "${long}" "${result}"
79}
80
81testGetFlagInfo() {
82  __flags_blah_foobar='1234'
83
84  rslt=`_flags_getFlagInfo 'blah' 'foobar'`
85  assertTrue 'request for valid flag info failed' $?
86  assertEquals 'invalid flag info returned' "${__flags_blah_foobar}" "${rslt}"
87
88  rslt=`_flags_getFlagInfo 'blah' 'hubbabubba' >"${stdoutF}" 2>"${stderrF}"`
89  assertEquals 'invalid flag did not result in an error' "${FLAGS_ERROR}" $?
90  assertErrorMsg 'missing flag info variable'
91}
92
93testItemInList() {
94  list='this is a test'
95  # shellcheck disable=SC2162
96  while read desc item want; do
97    _flags_itemInList "${item}" "${list}"
98    got=$?
99    assertEquals "${desc}: itemInList(${item})" "${got}" "${want}"
100  done <<EOF
101lead_item         this    ${FLAGS_TRUE}
102middle_item       is      ${FLAGS_TRUE}
103last_item         test    ${FLAGS_TRUE}
104missing_item      asdf    ${FLAGS_FALSE}
105test_partial_te   te      ${FLAGS_FALSE}
106test_partial_es   es      ${FLAGS_FALSE}
107test_partial_st   st      ${FLAGS_FALSE}
108empty_item        ''      ${FLAGS_FALSE}
109EOF
110
111  _flags_itemInList 'item' ''
112  assertFalse 'empty lists should not match' $?
113}
114
115testUnderscoreName() {
116  # shellcheck disable=SC2162
117  while read desc name want; do
118    got=`_flags_underscoreName "${name}"`
119    assertEquals "${desc}: underscoreName(${name})" "${got}" "${want}"
120  done <<EOF
121with_dashes        name-with-dashes      name_with_dashes
122with_underscores   name_with_underscores name_with_underscores
123just_alpha_numeric abc123                abc123
124empty              ""                    ""
125EOF
126}
127
128testValidBool() {
129  # Valid values.
130  for value in ${TH_BOOL_VALID}; do
131    _flags_validBool "${value}"
132    assertTrue "valid value (${value}) did not validate" $?
133  done
134
135  # Invalid values.
136  for value in ${TH_BOOL_INVALID}; do
137    _flags_validBool "${value}"
138    assertFalse "invalid value (${value}) validated" $?
139  done
140}
141
142_testValidFloat() {
143  # Valid values.
144  for value in ${TH_INT_VALID} ${TH_FLOAT_VALID}; do
145    _flags_validFloat "${value}"
146    assertTrue "valid value (${value}) did not validate" $?
147  done
148
149  # Invalid values.
150  for value in ${TH_FLOAT_INVALID}; do
151    _flags_validFloat "${value}"
152    assertFalse "invalid value (${value}) validated" $?
153  done
154}
155
156testValidFloatBuiltin() {
157  _flags_useBuiltin || startSkipping
158  _testValidFloat
159}
160
161testValidFloatExpr() {
162  (
163    _flags_useBuiltin() { return "${FLAGS_FALSE}"; }
164    _testValidFloat
165  )
166}
167
168_testValidInt() {
169  # Valid values.
170  for value in ${TH_INT_VALID}; do
171    _flags_validInt "${value}"
172    assertTrue "valid value (${value}) did not validate" $?
173  done
174
175  # Invalid values.
176  for value in ${TH_INT_INVALID}; do
177    _flags_validInt "${value}"
178    assertFalse "invalid value (${value}) should not validate" $?
179  done
180}
181
182testValidIntBuiltin() {
183  _flags_useBuiltin || startSkipping
184  _testValidInt
185}
186
187testValidIntExpr() {
188  (
189    _flags_useBuiltin() { return "${FLAGS_FALSE}"; }
190    _testValidInt
191  )
192}
193
194_testMath() {
195  result=`_flags_math 1`
196  assertTrue '1 failed' $?
197  assertEquals '1' 1 "${result}"
198
199  result=`_flags_math '1 + 2'`
200  assertTrue '1+2 failed' $?
201  assertEquals '1+2' 3 "${result}"
202
203  result=`_flags_math '1 + 2 + 3'`
204  assertTrue '1+2+3 failed' $?
205  assertEquals '1+2+3' 6 "${result}"
206
207  result=`_flags_math`
208  assertFalse 'missing math succeeded' $?
209}
210
211testMathBuiltin() {
212  _flags_useBuiltin || startSkipping
213  _testMath
214}
215
216testMathExpr() {
217  (
218    _flags_useBuiltin() { return "${FLAGS_FALSE}"; }
219    _testMath
220  )
221}
222
223_testStrlen() {
224  len=`_flags_strlen`
225  assertTrue 'missing argument failed' $?
226  assertEquals 'missing argument' 0 "${len}"
227
228  len=`_flags_strlen ''`
229  assertTrue 'empty argument failed' $?
230  assertEquals 'empty argument' 0 "${len}"
231
232  len=`_flags_strlen abc123`
233  assertTrue 'single-word failed' $?
234  assertEquals 'single-word' 6 "${len}"
235
236  len=`_flags_strlen 'This is a test'`
237  assertTrue 'multi-word failed' $?
238  assertEquals 'multi-word' 14 "${len}"
239}
240
241testStrlenBuiltin() {
242  _flags_useBuiltin || startSkipping
243  _testStrlen
244}
245
246testStrlenExpr() {
247  (
248    _flags_useBuiltin() { return "${FLAGS_FALSE}"; }
249    _testStrlen
250  )
251}
252
253oneTimeSetUp() {
254  th_oneTimeSetUp
255
256  _flags_useBuiltin || \
257    th_warn 'Shell built-ins not supported. Some tests will be skipped.'
258}
259
260tearDown() {
261  flags_reset
262}
263
264# Load and run shUnit2.
265# shellcheck disable=SC2034
266[ -n "${ZSH_VERSION:-}" ] && SHUNIT_PARENT=$0
267. "${TH_SHUNIT}"
268