-
Notifications
You must be signed in to change notification settings - Fork 4
/
assert.sh
304 lines (256 loc) · 9.4 KB
/
assert.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
#!/bin/bash
#
# https://github.com/EngineeringSoftware/gobash/blob/main/LICENSE
#
# Util assert functions.
#
# Assert functions exit using the `exit` function. This can have
# impact on execution when code is in subshells. We use assert
# functions extensively and exclusively in tests (which are
# running in subshells).
if [ -n "${ASSERT_MOD:-}" ]; then return 0; fi
readonly ASSERT_MOD=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
. ${ASSERT_MOD}/bool.sh
. ${ASSERT_MOD}/core.sh
. ${ASSERT_MOD}/sys.sh
# ----------
# Functions.
function assert_fail() {
# Fail (exit) with the given message.
local ctx; is_ctx "${1}" && ctx="${1}" && shift
[ $# -lt 0 ] && { ctx_wn $ctx; exit $EC; }
local -r msg="${1}"
shift 0 || { ctx_wn $ctx; exit $EC; }
local text="ERROR"
[ ! -z "${msg}" ] && text="${text}: (${msg})"
echo "${text}" 1>&2
sys_stack_trace $ctx 1>&2
exit 1
}
function assert_ze() {
# Check that the given value is zero; exit if not true.
local ctx; is_ctx "${1}" && ctx="${1}" && shift
[ $# -lt 1 ] && { ctx_wn $ctx; exit $EC; }
local -r val="${1}"
local -r msg="${2}"
shift 1 || { ctx_wn $ctx; exit $EC; }
local text="ERROR: Expected zero but was ${val}"
[ ! -z "${msg}" ] && text="${text} (${msg})"
if [ ${val} -ne 0 ]; then
echo "${text}" 1>&2
sys_stack_trace $ctx 1>&2
exit 1
fi
}
function assert_nz() {
# Check that the given value is not zero; exit if not true.
local ctx; is_ctx "${1}" && ctx="${1}" && shift
[ $# -lt 1 ] && { ctx_wn $ctx; exit $EC; }
local -r val="${1}"
local -r msg="${2}"
shift 1 || { ctx_wn $ctx; exit $EC; }
local text="ERROR: Expected non-zero outcome but was zero"
[ ! -z "${msg}" ] && text="${text} (${msg})"
if [ ${val} -eq 0 ]; then
echo "${text}" 1>&2
sys_stack_trace $ctx 1>&2
exit 1
fi
}
function assert_eq() {
# Check that two values are equal (lexical); exit if not true.
local ctx; is_ctx "${1}" && ctx="${1}" && shift
[ $# -lt 2 ] && { ctx_wn $ctx; exit $EC; }
local -r one="${1}"
local -r two="${2}"
local -r msg="${3}"
shift 2 || { ctx_wn $ctx; exit $EC; }
local text="ERROR: <${one}> not equal to <${two}>"
[ ! -z "${msg}" ] && text="${text} (${msg})"
if [ "${one}" != "${two}" ]; then
echo "${text}" 1>&2
sys_stack_trace $ctx 1>&2
exit 1
fi
}
function assert_ne() {
# Check that two values are not equal (lexical); exit if yes.
local ctx; is_ctx "${1}" && ctx="${1}" && shift
[ $# -lt 2 ] && { ctx_wn $ctx; exit $EC; }
local -r one="${1}"
local -r two="${2}"
local -r msg="${3}"
shift 2 || { ctx_wn $ctx; exit $EC; }
if [ "${one}" == "${two}" ]; then
echo "ERROR: <${one}> equal to <${two}> (${msg})" 1>&2
sys_stack_trace $ctx 1>&2
exit 1
fi
}
function assert_gt() {
# Exit if the first arg is less or equal to the second (ints).
local ctx; is_ctx "${1}" && ctx="${1}" && shift
[ $# -lt 2 ] && { ctx_wn $ctx; exit $EC; }
local -r one="${1}"
local -r two="${2}"
local -r msg="${3}"
shift 2 || { ctx_wn $ctx; exit $EC; }
if [ "${one}" -le "${two}" ]; then
echo "ERROR: <${one}> not greater than <${two}> (${msg})" 1>&2
sys_stack_trace $ctx 1>&2
exit 1
fi
}
function assert_ge() {
# Exit if the first arg is less than the second (ints).
local ctx; is_ctx "${1}" && ctx="${1}" && shift
[ $# -lt 2 ] && { ctx_wn $ctx; exit $EC; }
local -r one="${1}"
local -r two="${2}"
local -r msg="${3}"
shift 2 || { ctx_wn $ctx; exit $EC; }
if [ "${one}" -lt "${two}" ]; then
echo "ERROR: <${one}> not greater than <${two}> (${msg})" 1>&2
sys_stack_trace $ctx 1>&2
exit 1
fi
}
function assert_lt() {
# Exit if the first arg is greater or equal to second (ints).
local ctx; is_ctx "${1}" && ctx="${1}" && shift
[ $# -lt 2 ] && { ctx_wn $ctx; exit $EC; }
local -r one="${1}"
local -r two="${2}"
local -r msg="${3}"
shift 2 || { ctx_wn $ctx; exit $EC; }
if [ "${one}" -ge "${two}" ]; then
echo "ERROR: <${one}> not less than <${two}> (${msg})" 1>&2
sys_stack_trace $ctx 1>&2
exit 1
fi
}
function assert_bw() {
# Exit if the first arg is not between the next two exclusive
# (ints).
local ctx; is_ctx "${1}" && ctx="${1}" && shift
[ $# -lt 3 ] && { ctx_wn $ctx; exit $EC; }
local -r val="${1}"
local -r min="${2}"
local -r max="${3}"
local -r msg="${4}"
shift 3 || { ctx_wn $ctx; exit $EC; }
if [ "${val}" -lt "${min}" -o "${val}" -gt "${max}" ]; then
echo "ERROR: <${val}> not between <${min}> and <${max}>." 1>&2
sys_stack_trace $ctx 1>&2
exit 1
fi
}
function assert_dir_exists() {
# Exit if directory does not exist.
local ctx; is_ctx "${1}" && ctx="${1}" && shift
[ $# -lt 1 ] && { ctx_wn $ctx; exit $EC; }
local -r dir="${1}"
local -r msg="${2:-}"
shift 1 || { ctx_wn $ctx; exit $EC; }
if [ ! -d "${dir}" ]; then
echo "ERROR: Directory ${dir} does not exist (${msg})." 1>&2
sys_stack_trace $ctx 1>&2
exit 1
fi
}
function assert_file_exists() {
# Exit if file does not exit.
local ctx; is_ctx "${1}" && ctx="${1}" && shift
[ $# -lt 1 ] && { ctx_wn $ctx; exit $EC; }
local -r f="${1}"
local -r msg="${2:-}"
shift 1 || { ctx_wn $ctx; exit $EC; }
if [ ! -f "${f}" ]; then
echo "ERROR: File ${f} does not exist (${msg})" 1>&2
sys_stack_trace $ctx 1>&2
exit 1
fi
}
function assert_has_prefix() {
# Exit if the value does ont have the given prefix.
local ctx; is_ctx "${1}" && ctx="${1}" && shift
[ $# -ne 2 ] && { ctx_wn $ctx; exit $EC; }
local -r val="${1}"
local -r prefix="${2}"
shift 2 || { ctx_wn $ctx; exit $EC; }
if [[ "${val}" != "${prefix}"* ]]; then
echo "ERROR: <${val}> does not start with <${prefix}>"
sys_stack_trace $ctx 1>&2
exit 1
fi
}
function assert_exe_exists() {
# Exit if the executable does not exit.
local ctx; is_ctx "${1}" && ctx="${1}" && shift
[ $# -lt 1 ] && { ctx_wn $ctx; exit $EC; }
local -r exe="${1}"
local msg="${2:-}"
shift 1 || { ctx_wn $ctx; exit $EC; }
! is_exe $ctx "${exe}" && assert_fail $ctx "${msg}"
return 0
}
function assert_port_free() {
# Exit if the given port is not free.
local ctx; is_ctx "${1}" && ctx="${1}" && shift
[ $# -ne 1 ] && { ctx_wn $ctx; exit $EC; }
local -r port="${1}"
shift 1 || { ctx_wn $ctx; exit $EC; }
[ -z "${port}" ] && assert_fail $ctx "Port number is required."
if lsof -i:${port}; then
echo "ERROR: Some processes are listening on ${port}." 1>&2
sys_stack_trace $ctx 1>&2
exit 1
fi
}
function assert_user() {
# Exit if the given name does not match the current user.
local ctx; is_ctx "${1}" && ctx="${1}" && shift
[ $# -lt 1 ] && { ctx_wn $ctx; exit $EC; }
local -r expected="${1}"
local -r msg="${2}"
shift 1 || { ctx_wn $ctx; exit $EC; }
assert_eq $ctx "$(whoami)" "${expected}" "${msg}"
}
function assert_user_starts_with() {
# Exit if the given name is not a prefix of the current user.
local ctx; is_ctx "${1}" && ctx="${1}" && shift
[ $# -lt 1 ] && { ctx_wn $ctx; exit $EC; }
local -r str="${1}"
local -r msg="${2}"
shift 1 || { ctx_wn $ctx; exit $EC; }
[[ $(whoami) == ${str}* ]] || assert_fail $ctx "${msg}"
}
function assert_function_exists() {
# Exit if the given name is not a function.
local ctx; is_ctx "${1}" && ctx="${1}" && shift
[ $# -lt 1 ] && { ctx_wn $ctx; exit $EC; }
local -r func="${1}"
local -r msg="${2}"
shift 1 || { ctx_wn $ctx; exit $EC; }
local name
name=$(type -t "${func}") || assert_fail $ctx "Missing ${func}"
assert_eq $ctx "${name}" "function"
}
function assert_false() {
# Exit if the given value is not false.
local ctx; is_ctx "${1}" && ctx="${1}" && shift
[ $# -lt 1 ] && { ctx_wn $ctx; exit $EC; }
local -r val="${1}"
local -r msg="${2}"
shift 1 || { ctx_wn $ctx; exit $EC; }
is_false $ctx "${val}" || assert_fail $ctx "${msg}"
}
function assert_ec() {
# Exit if the value is not an error as defined by this lib.
local ctx; is_ctx "${1}" && ctx="${1}" && shift
[ $# -lt 1 ] && { ctx_wn $ctx; exit $EC; }
local -r val="${1}"
local -r msg="${2}"
shift 1 || { ctx_wn $ctx; exit $EC; }
[ ${val} -eq $EC ] || assert_fail $ctx "${msg}"
}