@bats-hardened/bats 1.14.1-alpha02
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +53 -0
- package/README.md +135 -0
- package/bin/bats +75 -0
- package/install.sh +29 -0
- package/lib/bats-core/common.bash +278 -0
- package/lib/bats-core/formatter.bash +151 -0
- package/lib/bats-core/preprocessing.bash +19 -0
- package/lib/bats-core/semaphore.bash +113 -0
- package/lib/bats-core/test_functions.bash +539 -0
- package/lib/bats-core/tracing.bash +425 -0
- package/lib/bats-core/validator.bash +37 -0
- package/lib/bats-core/warnings.bash +44 -0
- package/libexec/bats-core/bats +555 -0
- package/libexec/bats-core/bats-exec-file +402 -0
- package/libexec/bats-core/bats-exec-suite +346 -0
- package/libexec/bats-core/bats-exec-test +383 -0
- package/libexec/bats-core/bats-format-cat +6 -0
- package/libexec/bats-core/bats-format-junit +293 -0
- package/libexec/bats-core/bats-format-pretty +360 -0
- package/libexec/bats-core/bats-format-tap +55 -0
- package/libexec/bats-core/bats-format-tap13 +89 -0
- package/libexec/bats-core/bats-gather-tests +402 -0
- package/libexec/bats-core/bats-preprocess +118 -0
- package/man/Makefile +23 -0
- package/man/README.md +5 -0
- package/man/bats.1 +143 -0
- package/man/bats.1.ronn +201 -0
- package/man/bats.7 +300 -0
- package/man/bats.7.ronn +404 -0
- package/package.json +36 -0
- package/uninstall.sh +63 -0
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# this must be called for each test file!
|
|
4
|
+
_bats_test_functions_setup() { # <BATS_TEST_NUMBER>
|
|
5
|
+
BATS_TEST_DIRNAME="${BATS_TEST_FILENAME%/*}"
|
|
6
|
+
BATS_TEST_NAMES=()
|
|
7
|
+
# shellcheck disable=SC2034
|
|
8
|
+
BATS_TEST_NUMBER=${1?}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
# shellcheck source=lib/bats-core/warnings.bash
|
|
12
|
+
source "$BATS_ROOT/$BATS_LIBDIR/bats-core/warnings.bash"
|
|
13
|
+
|
|
14
|
+
# find_in_bats_lib_path echoes the first recognized load path to
|
|
15
|
+
# a library in BATS_LIB_PATH or relative to BATS_TEST_DIRNAME.
|
|
16
|
+
#
|
|
17
|
+
# Libraries relative to BATS_TEST_DIRNAME take precedence over
|
|
18
|
+
# BATS_LIB_PATH.
|
|
19
|
+
#
|
|
20
|
+
# If no library is found find_in_bats_lib_path returns 1.
|
|
21
|
+
find_in_bats_lib_path() { # <return-var> <library-name>
|
|
22
|
+
local return_var="${1:?}"
|
|
23
|
+
local library_name="${2:?}"
|
|
24
|
+
|
|
25
|
+
local -a bats_lib_paths
|
|
26
|
+
IFS=: read -ra bats_lib_paths <<<"$BATS_LIB_PATH"
|
|
27
|
+
|
|
28
|
+
for path in "${bats_lib_paths[@]}"; do
|
|
29
|
+
if [[ -f "$path/$library_name" ]]; then
|
|
30
|
+
printf -v "$return_var" "%s" "$path/$library_name"
|
|
31
|
+
# A library load path was found, return
|
|
32
|
+
return 0
|
|
33
|
+
elif [[ -f "$path/$library_name/load.bash" ]]; then
|
|
34
|
+
printf -v "$return_var" "%s" "$path/$library_name/load.bash"
|
|
35
|
+
# A library load path was found, return
|
|
36
|
+
return 0
|
|
37
|
+
fi
|
|
38
|
+
done
|
|
39
|
+
|
|
40
|
+
return 1
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
# bats_internal_load expects an absolute path that is a library load path.
|
|
44
|
+
#
|
|
45
|
+
# If the library load path points to a file (a library loader) it is
|
|
46
|
+
# sourced.
|
|
47
|
+
#
|
|
48
|
+
# If it points to a directory all files ending in .bash inside of the
|
|
49
|
+
# directory are sourced.
|
|
50
|
+
#
|
|
51
|
+
# If the sourcing of the library loader or of a file in a library
|
|
52
|
+
# directory fails bats_internal_load prints an error message and returns 1.
|
|
53
|
+
#
|
|
54
|
+
# If the passed library load path is not absolute or is not a valid file
|
|
55
|
+
# or directory bats_internal_load prints an error message and returns 1.
|
|
56
|
+
bats_internal_load() {
|
|
57
|
+
local library_load_path="${1:?}"
|
|
58
|
+
|
|
59
|
+
if [[ "${library_load_path:0:1}" != / ]]; then
|
|
60
|
+
printf "Passed library load path is not an absolute path: %s\n" "$library_load_path" >&2
|
|
61
|
+
return 1
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
# library_load_path is a library loader
|
|
65
|
+
if [[ -f "$library_load_path" ]]; then
|
|
66
|
+
# shellcheck disable=SC1090
|
|
67
|
+
if ! source "$library_load_path"; then
|
|
68
|
+
printf "Error while sourcing library loader at '%s'\n" "$library_load_path" >&2
|
|
69
|
+
return 1
|
|
70
|
+
fi
|
|
71
|
+
return 0
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
printf "Passed library load path is neither a library loader nor library directory: %s\n" "$library_load_path" >&2
|
|
75
|
+
return 1
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
# bats_load_safe accepts an argument called 'slug' and attempts to find and
|
|
79
|
+
# source a library based on the slug.
|
|
80
|
+
#
|
|
81
|
+
# A slug can be an absolute path or a relative path.
|
|
82
|
+
#
|
|
83
|
+
# If the slug is not an absolute path it is resolved relative to
|
|
84
|
+
# BATS_TEST_DIRNAME
|
|
85
|
+
#
|
|
86
|
+
# The resolved slug is passed to bats_internal_load.
|
|
87
|
+
# If bats_internal_load fails bats_load_safe returns 1.
|
|
88
|
+
#
|
|
89
|
+
# If no library load path can be found bats_load_safe prints an error message
|
|
90
|
+
# and returns 1.
|
|
91
|
+
bats_load_safe() {
|
|
92
|
+
local slug="${1:?}"
|
|
93
|
+
if [[ ${slug:0:1} != / ]]; then # relative paths are relative to BATS_TEST_DIRNAME
|
|
94
|
+
slug="$BATS_TEST_DIRNAME/$slug"
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
if [[ -f "$slug.bash" ]]; then
|
|
98
|
+
bats_internal_load "$slug.bash"
|
|
99
|
+
return $?
|
|
100
|
+
elif [[ -f "$slug" ]]; then
|
|
101
|
+
bats_internal_load "$slug"
|
|
102
|
+
return $?
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
# loading from PATH (retained for backwards compatibility)
|
|
106
|
+
if [[ ! -f "$1" ]] && type -P "$1" >/dev/null; then
|
|
107
|
+
# shellcheck disable=SC1090
|
|
108
|
+
source "$1"
|
|
109
|
+
return $?
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
# No library load path can be found
|
|
113
|
+
printf "bats_load_safe: Could not find '%s'[.bash]\n" "$slug" >&2
|
|
114
|
+
return 1
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
bats_load_library_safe() { # <slug>
|
|
118
|
+
local slug="${1:?}" library_path
|
|
119
|
+
|
|
120
|
+
# Check for library load paths in BATS_TEST_DIRNAME and BATS_LIB_PATH
|
|
121
|
+
if [[ ${slug:0:1} != / ]]; then
|
|
122
|
+
if ! find_in_bats_lib_path library_path "$slug"; then
|
|
123
|
+
printf "Could not find library '%s' relative to test file or in BATS_LIB_PATH\n" "$slug" >&2
|
|
124
|
+
return 1
|
|
125
|
+
fi
|
|
126
|
+
else
|
|
127
|
+
# absolute paths are taken as is
|
|
128
|
+
library_path="$slug"
|
|
129
|
+
if [[ ! -f "$library_path" ]]; then
|
|
130
|
+
printf "Could not find library on absolute path '%s'\n" "$library_path" >&2
|
|
131
|
+
return 1
|
|
132
|
+
fi
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
bats_internal_load "$library_path"
|
|
136
|
+
return $?
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
# immediately exit on error, use bats_load_library_safe to catch and handle errors
|
|
140
|
+
bats_load_library() { # <slug>
|
|
141
|
+
if ! bats_load_library_safe "$@"; then
|
|
142
|
+
exit 1
|
|
143
|
+
fi
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
# load acts like bats_load_safe but exits the shell instead of returning 1.
|
|
147
|
+
load() {
|
|
148
|
+
if ! bats_load_safe "$@"; then
|
|
149
|
+
exit 1
|
|
150
|
+
fi
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
bats_redirect_stderr_into_file() {
|
|
154
|
+
"$@" 2>>"$bats_run_separate_stderr_file" # use >> to see collisions' content
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
bats_merge_stdout_and_stderr() {
|
|
158
|
+
"$@" 2>&1
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
# write separate lines from <input-var> into <output-array>
|
|
162
|
+
bats_separate_lines() { # <output-array> <input-var>
|
|
163
|
+
local -r output_array_name="$1"
|
|
164
|
+
local -r input_var_name="$2"
|
|
165
|
+
local input="${!input_var_name}"
|
|
166
|
+
if [[ $keep_empty_lines ]]; then
|
|
167
|
+
local bats_separate_lines_lines=()
|
|
168
|
+
if [[ -n "$input" ]]; then # avoid getting an empty line for empty input
|
|
169
|
+
# remove one trailing \n if it exists to compensate its addition by <<<
|
|
170
|
+
input=${input%$'\n'}
|
|
171
|
+
while IFS= read -r line; do
|
|
172
|
+
bats_separate_lines_lines+=("$line")
|
|
173
|
+
done <<<"${input}"
|
|
174
|
+
fi
|
|
175
|
+
eval "${output_array_name}=(\"\${bats_separate_lines_lines[@]}\")"
|
|
176
|
+
else
|
|
177
|
+
# shellcheck disable=SC2034,SC2206
|
|
178
|
+
IFS=$'\n' read -d '' -r -a "$output_array_name" <<<"${!input_var_name}" || true # don't fail due to EOF
|
|
179
|
+
fi
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
bats_errexit_subshell() { # <command with args...>
|
|
183
|
+
(
|
|
184
|
+
set -eET
|
|
185
|
+
"$@"
|
|
186
|
+
)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
bats_pipe() { # [-N] [--] command0 [ \| command1 [ \| command2 [...]]]
|
|
190
|
+
# This will run each command given, piping them appropriately.
|
|
191
|
+
# Meant to be used in combination with `run` helper to allow piped commands
|
|
192
|
+
# to be used.
|
|
193
|
+
# Note that `\|` must be used, not `|`.
|
|
194
|
+
# By default, the exit code of this command will be the last failure in the
|
|
195
|
+
# chain of piped commands (similar to `set -o pipefail`).
|
|
196
|
+
# Supplying -N (e.g. -0) will instead always use the exit code of the command
|
|
197
|
+
# at that position in the chain.
|
|
198
|
+
# --returned-status=N could be used as an alternative to -N. This also allows
|
|
199
|
+
# for negative values (which count from the end in reverse order).
|
|
200
|
+
|
|
201
|
+
local pipestatus_position=
|
|
202
|
+
|
|
203
|
+
# parse options starting with -
|
|
204
|
+
while [[ $# -gt 0 ]] && [[ $1 == -* ]]; do
|
|
205
|
+
case "$1" in
|
|
206
|
+
-[0-9]*)
|
|
207
|
+
pipestatus_position="${1#-}"
|
|
208
|
+
;;
|
|
209
|
+
--returned-status*)
|
|
210
|
+
if [ "$1" = "--returned-status" ]; then
|
|
211
|
+
pipestatus_position="$2"
|
|
212
|
+
shift
|
|
213
|
+
elif [[ "$1" =~ ^--returned-status= ]]; then
|
|
214
|
+
pipestatus_position="${1#--returned-status=}"
|
|
215
|
+
else
|
|
216
|
+
printf "Usage error: unknown flag '%s'" "$1" >&2
|
|
217
|
+
return 1
|
|
218
|
+
fi
|
|
219
|
+
;;
|
|
220
|
+
--)
|
|
221
|
+
shift # eat the -- before breaking away
|
|
222
|
+
break
|
|
223
|
+
;;
|
|
224
|
+
*)
|
|
225
|
+
printf "Usage error: unknown flag '%s'" "$1" >&2
|
|
226
|
+
return 1
|
|
227
|
+
;;
|
|
228
|
+
esac
|
|
229
|
+
shift
|
|
230
|
+
done
|
|
231
|
+
|
|
232
|
+
# parse and validate arguments, escape as necessary
|
|
233
|
+
local -a commands_and_args=("$@")
|
|
234
|
+
local -a escaped_args=()
|
|
235
|
+
local -i pipe_count=0
|
|
236
|
+
local -i previous_pipe_index=-1
|
|
237
|
+
local -i index=0
|
|
238
|
+
for (( index = 0; index < $#; index++ )); do
|
|
239
|
+
local current_command_or_arg="${commands_and_args[$index]}"
|
|
240
|
+
local escaped_arg="$current_command_or_arg"
|
|
241
|
+
if [[ "$current_command_or_arg" != '|' ]]; then
|
|
242
|
+
# escape args to protect them when eval'd (e.g. if they contain whitespace).
|
|
243
|
+
printf -v escaped_arg "%q" "$current_command_or_arg"
|
|
244
|
+
elif [ "$current_command_or_arg" = "|" ]; then
|
|
245
|
+
if [ "$index" -eq 0 ]; then
|
|
246
|
+
printf "Usage error: Cannot have leading \`\\|\`.\n" >&2
|
|
247
|
+
return 1
|
|
248
|
+
fi
|
|
249
|
+
if (( (previous_pipe_index + 1) >= index )); then
|
|
250
|
+
printf "Usage error: Cannot have consecutive \`\\|\`. Found at argument position '%s'.\n" "$index" >&2
|
|
251
|
+
return 1
|
|
252
|
+
fi
|
|
253
|
+
(( ++pipe_count ))
|
|
254
|
+
previous_pipe_index="$index"
|
|
255
|
+
fi
|
|
256
|
+
escaped_args+=("$escaped_arg")
|
|
257
|
+
done
|
|
258
|
+
|
|
259
|
+
if (( (previous_pipe_index > 0) && (previous_pipe_index == ($# - 1)) )); then
|
|
260
|
+
printf "Usage error: Cannot have trailing \`\\|\`.\n" >&2
|
|
261
|
+
return 1
|
|
262
|
+
fi
|
|
263
|
+
|
|
264
|
+
if (( pipe_count == 0 )); then
|
|
265
|
+
# Don't allow for no pipes. This might be a typo in the test,
|
|
266
|
+
# e.g. `run bats_pipe command0 | command1`
|
|
267
|
+
# instead of `run bats_pipe command0 \| command1`
|
|
268
|
+
# Unfortunately, we can't catch `run bats_pipe command0 \| command1 | command2`.
|
|
269
|
+
# But this check is better than just allowing no pipes.
|
|
270
|
+
printf "Usage error: No \`\\|\`s found. Is this an error?\n" >&2
|
|
271
|
+
return 1
|
|
272
|
+
fi
|
|
273
|
+
|
|
274
|
+
# there will be pipe_count + 1 entries in PIPE_STATUS (pipe_count number of \|'s between each entry).
|
|
275
|
+
# valid indices are [-(pipe_count + 1), pipe_count]
|
|
276
|
+
if [ -n "$pipestatus_position" ] && (( (pipestatus_position > pipe_count) || (-pipestatus_position > (pipe_count + 1)) )); then
|
|
277
|
+
printf "Usage error: Too large of -N argument (or --returned-status) given. Argument value: '%s'.\n" "$pipestatus_position" >&2
|
|
278
|
+
return 1
|
|
279
|
+
fi
|
|
280
|
+
|
|
281
|
+
# run commands and return appropriate pipe status
|
|
282
|
+
local -a __bats_pipe_eval_pipe_status=()
|
|
283
|
+
eval "${escaped_args[*]}" '; __bats_pipe_eval_pipe_status=(${PIPESTATUS[@]})'
|
|
284
|
+
|
|
285
|
+
local result_status=
|
|
286
|
+
if [ -z "$pipestatus_position" ]; then
|
|
287
|
+
# if we are performing default "last failure" behavior,
|
|
288
|
+
# iterate backwards through pipe_status to find the last error.
|
|
289
|
+
result_status=0
|
|
290
|
+
for index in "${!__bats_pipe_eval_pipe_status[@]}"; do
|
|
291
|
+
# OSX bash doesn't support negative indexing.
|
|
292
|
+
local backward_iter_index="$((${#__bats_pipe_eval_pipe_status[@]} - index - 1))"
|
|
293
|
+
local status_at_backward_iter_index="${__bats_pipe_eval_pipe_status[$backward_iter_index]}"
|
|
294
|
+
if (( status_at_backward_iter_index != 0 )); then
|
|
295
|
+
result_status="$status_at_backward_iter_index"
|
|
296
|
+
break;
|
|
297
|
+
fi
|
|
298
|
+
done
|
|
299
|
+
elif (( pipestatus_position >= 0 )); then
|
|
300
|
+
result_status="${__bats_pipe_eval_pipe_status[$pipestatus_position]}"
|
|
301
|
+
else
|
|
302
|
+
# Must use positive values for some bash's (like OSX).
|
|
303
|
+
local backward_iter_index="$((${#__bats_pipe_eval_pipe_status[@]} + pipestatus_position))"
|
|
304
|
+
result_status="${__bats_pipe_eval_pipe_status[$backward_iter_index]}"
|
|
305
|
+
fi
|
|
306
|
+
|
|
307
|
+
return "$result_status"
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
run() { # [!|-N] [--keep-empty-lines] [--separate-stderr] [--] <command to run...>
|
|
311
|
+
local expected_rc=
|
|
312
|
+
local keep_empty_lines=
|
|
313
|
+
local output_case=merged
|
|
314
|
+
local has_flags=
|
|
315
|
+
# parse options starting with -
|
|
316
|
+
while [[ $# -gt 0 ]] && [[ $1 == -* || $1 == '!' ]]; do
|
|
317
|
+
has_flags=1
|
|
318
|
+
case "$1" in
|
|
319
|
+
'!')
|
|
320
|
+
expected_rc=-1
|
|
321
|
+
;;
|
|
322
|
+
-[0-9]*)
|
|
323
|
+
expected_rc=${1#-}
|
|
324
|
+
if [[ $expected_rc =~ [^0-9] ]]; then
|
|
325
|
+
printf "Usage error: run: '-NNN' requires numeric NNN (got: %s)\n" "$expected_rc" >&2
|
|
326
|
+
return 1
|
|
327
|
+
elif [[ $expected_rc -gt 255 ]]; then
|
|
328
|
+
printf "Usage error: run: '-NNN': NNN must be <= 255 (got: %d)\n" "$expected_rc" >&2
|
|
329
|
+
return 1
|
|
330
|
+
fi
|
|
331
|
+
;;
|
|
332
|
+
--keep-empty-lines)
|
|
333
|
+
keep_empty_lines=1
|
|
334
|
+
;;
|
|
335
|
+
--separate-stderr)
|
|
336
|
+
output_case="separate"
|
|
337
|
+
;;
|
|
338
|
+
--)
|
|
339
|
+
shift # eat the -- before breaking away
|
|
340
|
+
break
|
|
341
|
+
;;
|
|
342
|
+
*)
|
|
343
|
+
printf "Usage error: unknown flag '%s'" "$1" >&2
|
|
344
|
+
return 1
|
|
345
|
+
;;
|
|
346
|
+
esac
|
|
347
|
+
shift
|
|
348
|
+
done
|
|
349
|
+
|
|
350
|
+
local saved_traps
|
|
351
|
+
saved_traps=$(trap -p INT ERR DEBUG)
|
|
352
|
+
# This has to be restored on return from this function to avoid leaking our trap INT into surrounding code.
|
|
353
|
+
# Non zero exits won't restore under the assumption that they will fail the test before it can be aborted,
|
|
354
|
+
# which allows us to avoid duplicating the restore code on every exit path
|
|
355
|
+
trap bats_interrupt_trap_in_run INT
|
|
356
|
+
trap - ERR DEBUG
|
|
357
|
+
|
|
358
|
+
if [[ -n $has_flags ]]; then
|
|
359
|
+
bats_warn_minimum_guaranteed_version "Using flags on \`run\`" 1.5.0
|
|
360
|
+
fi
|
|
361
|
+
|
|
362
|
+
local -a pre_command=()
|
|
363
|
+
# make sure tmpdir exists in case run() is called outside a @test
|
|
364
|
+
local tmpdir=${BATS_TEST_TMPDIR:-${BATS_FILE_TMPDIR:-${BATS_RUN_TMPDIR}}}
|
|
365
|
+
|
|
366
|
+
case "$output_case" in
|
|
367
|
+
merged) # redirects stderr into stdout and fills only $output/$lines
|
|
368
|
+
pre_command=(bats_merge_stdout_and_stderr)
|
|
369
|
+
;;
|
|
370
|
+
separate) # splits stderr into own file and fills $stderr/$stderr_lines too
|
|
371
|
+
local bats_run_separate_stderr_file
|
|
372
|
+
bats_run_separate_stderr_file="$(mktemp "${tmpdir}/separate-stderr-XXXXXX")"
|
|
373
|
+
pre_command=(bats_redirect_stderr_into_file)
|
|
374
|
+
;;
|
|
375
|
+
esac
|
|
376
|
+
|
|
377
|
+
if [[ -n "${BATS_RUN_ERREXIT:-}" ]]; then
|
|
378
|
+
pre_command=(bats_errexit_subshell "${pre_command[@]}")
|
|
379
|
+
fi
|
|
380
|
+
|
|
381
|
+
local origFlags="$-"
|
|
382
|
+
set +eET
|
|
383
|
+
|
|
384
|
+
if [[ $keep_empty_lines ]]; then
|
|
385
|
+
# 'output', 'status', 'lines' are global variables available to tests.
|
|
386
|
+
# preserve trailing newlines by appending . and removing it later
|
|
387
|
+
# shellcheck disable=SC2034
|
|
388
|
+
output="$(
|
|
389
|
+
"${pre_command[@]}" "$@"
|
|
390
|
+
status=$?
|
|
391
|
+
printf .
|
|
392
|
+
exit $status
|
|
393
|
+
)"
|
|
394
|
+
status=$?
|
|
395
|
+
output="${output%.}"
|
|
396
|
+
else
|
|
397
|
+
# 'output', 'status', 'lines' are global variables available to tests.
|
|
398
|
+
# shellcheck disable=SC2034
|
|
399
|
+
output="$("${pre_command[@]}" "$@")"
|
|
400
|
+
status=$?
|
|
401
|
+
fi
|
|
402
|
+
|
|
403
|
+
bats_separate_lines lines output
|
|
404
|
+
|
|
405
|
+
if [[ "$output_case" == separate ]]; then
|
|
406
|
+
# shellcheck disable=SC2034
|
|
407
|
+
read -d '' -r stderr <"$bats_run_separate_stderr_file" || true
|
|
408
|
+
bats_separate_lines stderr_lines stderr
|
|
409
|
+
else
|
|
410
|
+
unset stderr stderr_lines
|
|
411
|
+
fi
|
|
412
|
+
|
|
413
|
+
# shellcheck disable=SC2034
|
|
414
|
+
BATS_RUN_COMMAND="${*}"
|
|
415
|
+
set "-$origFlags"
|
|
416
|
+
|
|
417
|
+
bats_run_print_output() {
|
|
418
|
+
if [[ -n "$output" ]]; then
|
|
419
|
+
printf "%s\n" "$output"
|
|
420
|
+
fi
|
|
421
|
+
if [[ "$output_case" == separate && -n "$stderr" ]]; then
|
|
422
|
+
printf "stderr:\n%s\n" "$stderr"
|
|
423
|
+
fi
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
if [[ -n "$expected_rc" ]]; then
|
|
427
|
+
if [[ "$expected_rc" = "-1" ]]; then
|
|
428
|
+
if [[ "$status" -eq 0 ]]; then
|
|
429
|
+
BATS_ERROR_SUFFIX=", expected nonzero exit code!"
|
|
430
|
+
bats_run_print_output
|
|
431
|
+
eval "$saved_traps"
|
|
432
|
+
return 1
|
|
433
|
+
fi
|
|
434
|
+
elif [ "$status" -ne "$expected_rc" ]; then
|
|
435
|
+
# shellcheck disable=SC2034
|
|
436
|
+
BATS_ERROR_SUFFIX=", expected exit code $expected_rc, got $status"
|
|
437
|
+
bats_run_print_output
|
|
438
|
+
eval "$saved_traps"
|
|
439
|
+
return 1
|
|
440
|
+
fi
|
|
441
|
+
elif [[ "$status" -eq 127 ]]; then # "command not found"
|
|
442
|
+
bats_generate_warning 1 "$BATS_RUN_COMMAND"
|
|
443
|
+
fi
|
|
444
|
+
|
|
445
|
+
if [[ ${BATS_VERBOSE_RUN:-} ]]; then
|
|
446
|
+
bats_run_print_output
|
|
447
|
+
fi
|
|
448
|
+
|
|
449
|
+
# don't leak our trap into surrounding code
|
|
450
|
+
eval "$saved_traps"
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
setup() {
|
|
454
|
+
return 0
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
teardown() {
|
|
458
|
+
return 0
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
skip() {
|
|
462
|
+
# if this is a skip in teardown ...
|
|
463
|
+
if [[ -n "${BATS_TEARDOWN_STARTED-}" ]]; then
|
|
464
|
+
# ... we want to skip the rest of teardown.
|
|
465
|
+
# communicate to bats_exit_trap that the teardown was completed without error
|
|
466
|
+
# shellcheck disable=SC2034
|
|
467
|
+
BATS_TEARDOWN_COMPLETED=1
|
|
468
|
+
# if we are already in the exit trap (e.g. due to previous skip) ...
|
|
469
|
+
if [[ "$BATS_TEARDOWN_STARTED" == as-exit-trap ]]; then
|
|
470
|
+
# ... we need to do the rest of the tear_down_trap that would otherwise be skipped after the next call to exit
|
|
471
|
+
bats_exit_trap
|
|
472
|
+
# and then do the exit (at the end of this function)
|
|
473
|
+
fi
|
|
474
|
+
# if we aren't in exit trap, the normal exit handling should suffice
|
|
475
|
+
else
|
|
476
|
+
# ... this is either skip in test or skip in setup.
|
|
477
|
+
# Following variables are used in bats-exec-test which sources this file
|
|
478
|
+
# shellcheck disable=SC2034
|
|
479
|
+
BATS_TEST_SKIPPED="${1:-1}"
|
|
480
|
+
# shellcheck disable=SC2034
|
|
481
|
+
BATS_TEST_COMPLETED=1
|
|
482
|
+
fi
|
|
483
|
+
exit 0
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
bats_test_function() {
|
|
487
|
+
local tags=() current_tags=()
|
|
488
|
+
while (( $# > 0 )); do
|
|
489
|
+
case "$1" in
|
|
490
|
+
--description)
|
|
491
|
+
local test_description=
|
|
492
|
+
# use eval to resolve variable references in test names
|
|
493
|
+
eval "printf -v test_description '%s' \"$2\""
|
|
494
|
+
shift 2
|
|
495
|
+
;;
|
|
496
|
+
--tags)
|
|
497
|
+
if [[ "$2" != "" ]]; then # avoid unbound variable with set -u Bash 3
|
|
498
|
+
IFS=',' read -ra current_tags <<<"$2"
|
|
499
|
+
tags+=("${current_tags[@]}")
|
|
500
|
+
fi
|
|
501
|
+
shift 2
|
|
502
|
+
;;
|
|
503
|
+
--)
|
|
504
|
+
shift
|
|
505
|
+
break
|
|
506
|
+
;;
|
|
507
|
+
*)
|
|
508
|
+
printf "ERROR: unknown option %s for bats_test_function" "$1" >&2
|
|
509
|
+
exit 1
|
|
510
|
+
;;
|
|
511
|
+
esac
|
|
512
|
+
done
|
|
513
|
+
|
|
514
|
+
if (( ${#tags[@]} > 1 )); then # avoid unbound variable with set -u Bash 3
|
|
515
|
+
bats_sort tags "${tags[@]}"
|
|
516
|
+
fi
|
|
517
|
+
|
|
518
|
+
BATS_TEST_NAMES+=("$*")
|
|
519
|
+
local quoted_parameters
|
|
520
|
+
printf -v quoted_parameters " %q" "$@"
|
|
521
|
+
quoted_parameters=${quoted_parameters:1} # cut off leading space
|
|
522
|
+
|
|
523
|
+
# if this is the currently selected test, set tags and name
|
|
524
|
+
# this should only be entered from bats-exec-test
|
|
525
|
+
if [[ ${BATS_TEST_NAME-} == "$quoted_parameters" ]]; then
|
|
526
|
+
# shellcheck disable=SC2034
|
|
527
|
+
BATS_TEST_TAGS=("${tags[@]+${tags[@]}}")
|
|
528
|
+
export BATS_TEST_DESCRIPTION="${test_description-$*}"
|
|
529
|
+
# shellcheck disable=SC2034
|
|
530
|
+
BATS_TEST_COMMAND=("$@")
|
|
531
|
+
fi
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
# decides whether a failed test should be run again
|
|
535
|
+
bats_should_retry_test() {
|
|
536
|
+
# test try number starts at 1
|
|
537
|
+
# 0 retries means run only first try
|
|
538
|
+
((BATS_TEST_TRY_NUMBER <= BATS_TEST_RETRIES))
|
|
539
|
+
}
|