This commit is contained in:
2026-08-02 15:26:07 +02:00
parent 336b36c8e1
commit b2eb145a6f
415 changed files with 24264 additions and 36 deletions
+8
View File
@@ -0,0 +1,8 @@
@test "BATS_TMPDIR is set" {
[ "${BATS_TMPDIR}" == "${expected:-}" ]
}
@test "BATS_RUN_TMPDIR has BATS_TMPDIR as a prefix" {
local regex="^${BATS_TMPDIR}/.+"
[[ ${BATS_RUN_TMPDIR} =~ ${regex} ]]
}
@@ -0,0 +1,9 @@
@test "BATS_* variables don't contain double slashes" {
for var_name in ${!BATS_@}; do
local var_value="${!var_name-}"
if [[ "$var_value" == *'//'* ]]; then
echo "$var_name contains // ${#var_value}: ${var_value}" && false
fi
done
}
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/env bash
# Fractional timeout supported in bash 4+
if [ "${BASH_VERSINFO[0]}" -lt 4 ]; then
timeout=1
else
timeout=0.01
fi
# Just reading from stdin
while read -r -t $timeout foo; do
if [ "$foo" == "EXIT" ]; then
echo "Found"
exit 0
fi
done
echo "Not found"
exit 1
@@ -0,0 +1,34 @@
function should_be_found { # @test
true
}
function should_be_found_with_trailing_whitespace { # @test
true
}
should_be_found_with_parens() { #@test
true
}
should_be_found_with_parens_and_whitespace() { #@test
true
}
function should_be_found_with_function_and_parens() { #@test
true
}
function should_be_found_with_function_parens_and_whitespace() { #@test
true
}
should_not_be_found() {
# shellcheck disable=SC2317
false
#@test
}
should_not_be_found() {
# shellcheck disable=SC2317
false
} #@test
+3
View File
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
echo "dummy date"
@@ -0,0 +1,3 @@
@test "foo" {
echo "foo"
}
@@ -0,0 +1,13 @@
# This does not fail as expected
@test "gizmo test" {
false
}
@test "gizmo test" "this does fail, as expected" {
false
}
# This overrides any previous test from the suite with the same description
@test "gizmo test" {
true
}
@@ -0,0 +1,28 @@
@test "normal test1" {
true
}
dynamic_test_with_description() {
:
}
bats_test_function --description "Some description" -- dynamic_test_with_description
dynamic_test_without_description() {
:
}
bats_test_function -- dynamic_test_without_description
parametrized_test() {
echo "$BATS_TEST_NAME: $1"
false
}
for val in 1 2 "th ree"; do
bats_test_function -- parametrized_test "$val"
done
@test "normal test2" {
true
}
+1
View File
@@ -0,0 +1 @@
@@ -0,0 +1,10 @@
@test "setting a variable" {
# shellcheck disable=SC2030
variable=1
[ $variable -eq 1 ]
}
@test "variables do not persist across tests" {
# shellcheck disable=SC2031
[ -z "${variable:-}" ]
}
@@ -0,0 +1,5 @@
echo "file1" >>"$TEMPFILE"
@test "test1" {
:
}
@@ -0,0 +1,9 @@
echo "file2" >>"$TEMPFILE"
@test "test 1" {
:
}
@test "test 2" {
:
}
+2
View File
@@ -0,0 +1,2 @@
#!/usr/bin/env bash
exit 11
@@ -0,0 +1,3 @@
@test "$SUITE: test with variable in name" {
true
}
@@ -0,0 +1,8 @@
if exported_function; then
a='exported_function'
fi
@test "failing test" {
echo "a='$a'"
false
}
@@ -0,0 +1,76 @@
load test_helper
# Test various combinations that may fail line number detection in stack trace
# Tests are designed so the first statement succeeds and 2nd fails
# All tests fail on the same line so checking can be automated
@test "Call true function && false stackdepth=1" {
help_me
help_me && false
}
@test "Call true function && return 1 stackdepth=1" {
help_me
help_me && return 1
}
@test "Call true function and invert stackdepth=2" {
help_me
# shellcheck disable=SC2314
! help_me
}
@test "Call false function || false stackdepth=1" {
# shellcheck disable=SC2314
! failing_helper
failing_helper || false
}
@test "Call false function && return 1 stackdepth=1" {
# shellcheck disable=SC2314
! failing_helper
failing_helper || return 1
}
@test "Call false function stackdepth=2" {
# shellcheck disable=SC2314
! failing_helper
failing_helper
}
@test "Call return_0 function && false stackdepth=1" {
return_0
return_0 && false
}
@test "Call return_0 function && return 1 stackdepth=1" {
return_0
return_0 && return 1
}
@test "Call return_0 function and invert stackdepth=2" {
return_0
# shellcheck disable=SC2314
! return_0
}
@test "Call return_1 function || false stackdepth=1" {
# shellcheck disable=SC2314
! return_1
return_1 || false
}
@test "Call return_1 function && return 1 stackdepth=1" {
# shellcheck disable=SC2314
! return_1
return_1 || return 1
}
@test "Call return_1 function stackdepth=2" {
# shellcheck disable=SC2314
! return_1
return_1
}
@@ -0,0 +1,15 @@
setup() {
true
}
teardown() {
true
}
setup_file() {
true
}
teardown_file() {
true
}
@@ -0,0 +1,5 @@
load external_functions
@test test {
true
}
+5
View File
@@ -0,0 +1,5 @@
@test "a failing test" {
true
true
eval "( exit ${STATUS:-1} )"
}
@@ -0,0 +1,7 @@
@test "a failing test" {
false
}
@test "a passing test" {
true
}
@@ -0,0 +1,6 @@
load "test_helper"
@test "failing helper function" {
true
failing_helper
}
@@ -0,0 +1,7 @@
setup() {
false
}
@test "truth" {
true
}
@@ -0,0 +1,7 @@
teardown() {
eval "( exit ${STATUS:-1} )"
}
@test "truth" {
[ "$PASS" = 1 ]
}
@@ -0,0 +1,5 @@
@test "a failing test" {
true
# shellcheck disable=SC2050
[[ 1 == 2 ]]
}
@@ -0,0 +1,4 @@
@test "a failing test" {
true
((1 == 2))
}
@@ -0,0 +1,5 @@
@test "a failing test" {
true
# shellcheck disable=SC2314
! true
}
@@ -0,0 +1,9 @@
helper() {
false
}
helper
@test "everything is ok" {
true
}
+8
View File
@@ -0,0 +1,8 @@
@test "unfocused" {
false
}
# bats test_tags=bats:focus
@test "focused" {
true
}
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
cat >/dev/null # eat up all input
sleep 1
echo "Finished" # mark finish
@@ -0,0 +1,9 @@
setup() {
load '../../concurrent-coordination'
}
@test "test" {
single-use-latch::signal hang_after_run
run true
sleep 10
}
@@ -0,0 +1,8 @@
setup() {
load '../../concurrent-coordination'
}
@test "test" {
single-use-latch::signal hang_in_run
run sleep 10
}
@@ -0,0 +1,9 @@
setup_file() {
load '../../concurrent-coordination'
single-use-latch::signal hang_in_setup_file
sleep 10
}
@test "empty" {
:
}
@@ -0,0 +1,9 @@
teardown() {
load '../../concurrent-coordination'
single-use-latch::signal hang_in_teardown
sleep 10
}
@test "empty" {
:
}
@@ -0,0 +1,9 @@
teardown_file() {
load '../../concurrent-coordination'
single-use-latch::signal hang_in_teardown_file
sleep 10
}
@test "empty" {
:
}
@@ -0,0 +1,9 @@
setup() {
load '../../concurrent-coordination'
}
@test "test" {
single-use-latch::signal hang_in_test
sleep 10
echo "after sleep" # this should not be printed
}
+6
View File
@@ -0,0 +1,6 @@
@test "dash-e on beginning of line" {
run cat - <<INPUT
-e
INPUT
test "$output" = "-e"
}
+103
View File
@@ -0,0 +1,103 @@
#!/usr/bin/env bats
function bgfunc {
get_open_fds
echo "${FUNCNAME[1]} fds before: (${open_fds[*]})" >>"${LOG_FILE}"
close_non_std_fds
get_open_fds
echo "${FUNCNAME[1]} fds after: (${open_fds[*]})" >>"${LOG_FILE}"
sleep 10
echo "bgfunc done"
return 0
}
# store the list of open FDs in array open_fds
function get_open_fds() {
open_fds=() # reset output array in case it was already set
if [[ ${BASH_VERSINFO[0]} == 3 ]]; then
local BASHPID
BASHPID=$(bash -c 'echo $PPID')
fi
local tmpfile
tmpfile=$(mktemp "$BATS_SUITE_TMPDIR/fds-XXXXXX")
# Avoid opening a new fd to read fds: Don't use <(), glob expansion.
# Instead, redirect stdout to file which does not create an extra FD.
if [[ -d /proc/$BASHPID/fd ]]; then # Linux
ls -1 "/proc/$BASHPID/fd" >"$tmpfile"
IFS=$'\n' read -d '' -ra open_fds <"$tmpfile" || true
elif command -v lsof >/dev/null; then # MacOS
local -a fds
lsof -F f -p "$BASHPID" >"$tmpfile"
IFS=$'\n' read -d '' -ra fds <"$tmpfile" || true
for fd in "${fds[@]}"; do
case $fd in
f[0-9]*) # filter non fd entries (mainly pid?)
open_fds+=("${fd#f}") # cut off f prefix
;;
esac
done
elif command -v procstat >/dev/null; then # BSDs
local -a columns header
procstat fds "$BASHPID" >"$tmpfile"
{
read -r -a header
local fd_column_index=-1
for ((i = 0; i < ${#header[@]}; ++i)); do
if [[ ${header[$i]} == *FD* ]]; then
fd_column_index=$i
break
fi
done
if [[ $fd_column_index -eq -1 ]]; then
printf "Could not find FD column in procstat" >&2
exit 1
fi
while read -r -a columns; do
local fd=${columns[$fd_column_index]}
if [[ $fd == [0-9]* ]]; then # only take up numeric entries
open_fds+=("$fd")
fi
done
} <"$tmpfile"
else
# TODO: MSYS (Windows)
printf "Neither FD discovery mechanism available\n" >&2
exit 1
fi
}
function close_non_std_fds() {
local open_fds non_std_fds=()
get_open_fds
for fd in "${open_fds[@]}"; do
if [[ $fd -gt 2 ]]; then
non_std_fds+=("$fd")
fi
done
close_fds "${non_std_fds[@]}"
}
function close_fds() { # <fds...>
for fd in "$@"; do
eval "exec $fd>&-"
done
}
function otherfunc {
bgfunc &
PID=$!
disown
return 0
}
setup_file() { # see issue #530
bgfunc &
}
@test "min bg" {
echo "sec: $SECONDS"
otherfunc
sleep 1 # leave some space for the background job to print/fail early
kill -s 0 -- $PID # fail it the process already finished due to error!
echo "sec: $SECONDS"
}
@@ -0,0 +1,7 @@
@test "1" {
sleep 1
}
@test "2" {
sleep 1
}
@@ -0,0 +1,7 @@
@test "11" {
sleep 1
}
@test "12" {
sleep 1
}
@@ -0,0 +1,3 @@
@test "no unprefixed variables" {
declare -p >"${BATS_DECLARED_VARIABLES_FILE?}"
}
+6
View File
@@ -0,0 +1,6 @@
[ -n "$HELPER_NAME" ] || HELPER_NAME="test_helper"
load "$HELPER_NAME"
@test "calling a loaded helper" {
help_me
}
@@ -0,0 +1,16 @@
# see issue #89
loop_func() {
local search="none one two tree"
local d
for d in $search; do
echo "$d"
done
}
@test "loop_func" {
run loop_func
[[ "${lines[3]}" == 'tree' ]]
run loop_func
[[ "${lines[2]}" == 'two' ]]
}
@@ -0,0 +1,15 @@
@test "a passing test" {
true
}
@test "another passing test" {
true
}
@test "a failing test" {
false
}
@test "yet another passing test" {
true
}
@@ -0,0 +1,9 @@
@test "error in test" {
printf 'foo\nbar'
false
}
@test "test function returns nonzero" {
printf 'foo\nbar'
return 1
}
+19
View File
@@ -0,0 +1,19 @@
@test "success writing to stdout" {
echo "success stdout 1"
echo "success stdout 2"
}
@test "success writing to stderr" {
echo "success stderr" >&2
}
@test "failure writing to stdout" {
echo "failure stdout 1"
echo "failure stdout 2"
false
}
@test "failure writing to stderr" {
echo "failure stderr" >&2
false
}
@@ -0,0 +1,11 @@
setup() {
export PATH
PATH="$(dirname "$BATS_TEST_FILENAME"):$PATH"
}
@test "dummy" {
echo "$PATH"
run -0 date
echo "$output"
[ "${output}" = 'dummy date' ]
}
+39
View File
@@ -0,0 +1,39 @@
@test "slow test 1" {
sleep 3s
}
@test "slow test 2" {
sleep 3s
}
@test "slow test 3" {
sleep 3s
}
@test "slow test 4" {
sleep 3s
}
@test "slow test 5" {
sleep 3s
}
@test "slow test 6" {
sleep 3s
}
@test "slow test 7" {
sleep 3s
}
@test "slow test 8" {
sleep 3s
}
@test "slow test 9" {
sleep 3s
}
@test "slow test 10" {
sleep 3s
}
+3
View File
@@ -0,0 +1,3 @@
@test "a passing test" {
true
}
@@ -0,0 +1,7 @@
@test "a passing test" {
true
}
@test "a failing test" {
false
}
@@ -0,0 +1,11 @@
@test "a passing test" {
true
}
@test "a skipped test with no reason" {
skip
}
@test "a skipped test with a reason" {
skip "for a really good reason"
}
@@ -0,0 +1,11 @@
@test "a passing test" {
true
}
@test "a skipping test" {
skip
}
@test "a failing test" {
false
}
@@ -0,0 +1,8 @@
check_ifs() {
if [[ "$IFS" != $' \t\n' ]]; then
echo "${FUNCNAME[*]}"
echo "${BASH_SOURCE[*]}"
hexdump -c <<<"$IFS"
exit 1
fi >&2
}
@@ -0,0 +1,11 @@
load helper.bash
check_ifs
teardown_suite() {
check_ifs
}
setup_suite() {
check_ifs
}
@@ -0,0 +1,15 @@
load helper.bash
check_ifs
setup_file() {
check_ifs
}
teardown_file() {
check_ifs
}
@test test {
check_ifs
}
@@ -0,0 +1,12 @@
@test "no failure prints no output" {
run echo success
}
bats_require_minimum_version 1.5.0 # don't be fooled by order, this will run before the test above!
@test "failure prints output" {
run echo "fail hard"
false
}
@test "empty output on failure" {
false
}
@@ -0,0 +1,13 @@
@test "no failure prints no output" {
run echo success
}
@test "failure prints output" {
bats_require_minimum_version 1.5.0
run --separate-stderr bash -c 'echo "fail hard"; echo with stderr >&2'
false
}
@test "empty output on failure" {
false
}
@@ -0,0 +1,11 @@
@test 'single-quoted name' {
true
}
@test "double-quoted name" {
true
}
@test unquoted name {
true
}
@@ -0,0 +1,21 @@
#!/usr/bin/env bats
@test "test 1" {
# Don't print anything
run bash -c "$BATS_TEST_DIRNAME/cmd_using_stdin.bash"
[ "$status" -eq 1 ]
[ "$output" = "Not found" ]
}
@test "test 2 with TAB in name" {
run bash -c "echo EXIT | $BATS_TEST_DIRNAME/cmd_using_stdin.bash"
[ "$status" -eq 0 ]
echo "$output"
[ "$output" = "Found" ]
}
@test "test 3" {
run bash -c "echo EXIT | $BATS_TEST_DIRNAME/cmd_using_stdin.bash"
[ "$status" -eq 0 ]
[ "$output" = "Found" ]
}
@@ -0,0 +1,5 @@
@test "referencing unset parameter fails" {
set -u
# shellcheck disable=SC2154
echo "$unset_parameter"
}
@@ -0,0 +1,14 @@
setup() {
set -u
# shellcheck disable=SC2154
echo "$unset_parameter"
}
teardown() {
echo "should not capture the next line"
false
}
@test "referencing unset parameter fails in setup" {
:
}
@@ -0,0 +1,9 @@
teardown() {
set -u
# shellcheck disable=SC2154
echo "$unset_parameter"
}
@test "referencing unset parameter fails in teardown" {
:
}
+38
View File
@@ -0,0 +1,38 @@
BATS_TEST_RETRIES=2 # means three tries per test
log_caller() {
printf "%s %s %s\n" "${BATS_TEST_NAME:-}" "${FUNCNAME[1]}" "${BATS_TEST_TRY_NUMBER:-}" >>"${LOG?}"
}
setup_file() {
log_caller
}
teardown_file() {
log_caller
}
setup() {
log_caller
}
teardown() {
log_caller
}
@test "Fail all" {
log_caller
false
}
@test "Fail once" {
log_caller
((BATS_TEST_TRY_NUMBER > 1)) || false
}
@test "Override retries" {
log_caller
# shellcheck disable=SC2034
BATS_TEST_RETRIES=1
((BATS_TEST_TRY_NUMBER > 2)) || false
}
@@ -0,0 +1,6 @@
# shellcheck disable=SC2034
BATS_TEST_RETRIES=2 # means three tries per test
@test "Fail once" {
((BATS_TEST_TRY_NUMBER > 1)) || false
}
@@ -0,0 +1,3 @@
@test "run long command" {
run sleep 3
}
@@ -0,0 +1,23 @@
setup() {
set -eu
}
teardown() {
set -eu
}
@test "skipped test" {
skip
}
@test "skipped test with reason" {
skip "reason"
}
@test "passing test" {
run true
}
@test "failing test" {
false
}
+17
View File
@@ -0,0 +1,17 @@
LOG="$BATS_TEST_SUITE_TMPDIR/setup.log"
setup() {
echo "$BATS_TEST_NAME" >>"$LOG"
}
@test "one" {
[ "$(tail -n 1 "$LOG")" = "test_one" ]
}
@test "two" {
[ "$(tail -n 1 "$LOG")" = "test_two" ]
}
@test "three" {
[ "$(tail -n 1 "$LOG")" = "test_three" ]
}
@@ -0,0 +1,3 @@
@test "test" {
echo output
}
@@ -0,0 +1,11 @@
@test "failing" {
if [[ -z "${DONT_ABORT:-}" ]]; then
# emulate CTRL-C by sending SIGINT to the whole process group
kill -SIGINT -- -"$BATS_ROOT_PID"
fi
false
}
@test "passing" {
:
}
@@ -0,0 +1,9 @@
@test "empty" { }
@test "passing" { true; }
@test "input redirection" { diff - <(echo hello); } <<EOS
hello
EOS
@test "failing" { false; }
+7
View File
@@ -0,0 +1,7 @@
@test "a skipped test" {
skip
}
@test "a skipped test with a reason" {
skip "a reason"
}
@@ -0,0 +1,3 @@
@test "a skipped test with parentheses in the reason" {
skip "a reason (with parentheses)"
}
@@ -0,0 +1,4 @@
@test "sourcing nonexistent file fails" {
# shellcheck disable=SC1091
source "nonexistent file"
}
@@ -0,0 +1,13 @@
setup() {
# shellcheck disable=SC1091
source "nonexistent file"
}
teardown() {
echo "should not capture the next line"
false
}
@test "sourcing nonexistent file fails in setup" {
:
}
@@ -0,0 +1,8 @@
teardown() {
# shellcheck disable=SC1091
source "nonexistent file"
}
@test "sourcing nonexistent file fails in teardown" {
:
}
@@ -0,0 +1,3 @@
@test "test" {
:
}
+17
View File
@@ -0,0 +1,17 @@
LOG="$BATS_TEST_SUITE_TMPDIR/teardown.log"
teardown() {
echo "$BATS_TEST_NAME" >>"$LOG"
}
@test "one" {
true
}
@test "two" {
false
}
@test "three" {
true
}
@@ -0,0 +1,9 @@
teardown_file() {
# shellcheck disable=SC2034
status=${STATUS?}
return "${TEARDOWN_RETURN_CODE?}"
}
@test "return expected code" {
return "${TEST_RETURN_CODE?}"
}
@@ -0,0 +1,8 @@
teardown() {
status=${STATUS?}
return "${TEARDOWN_RETURN_CODE?}"
}
@test "return expected code" {
return "${TEST_RETURN_CODE?}"
}
@@ -0,0 +1,9 @@
setup_suite() {
:
}
teardown_suite() {
# shellcheck disable=SC2034
status=${STATUS?}
return "${TEARDOWN_RETURN_CODE?}"
}
@@ -0,0 +1,3 @@
@test test {
return "${TEST_RETURN_CODE?}"
}
@@ -0,0 +1,19 @@
help_me() {
true
}
failing_helper() {
false
}
return_0() {
# Just return 0. Intentional assignment to boost line numbers
result=0
return $result
}
return_1() {
# Just return 0. Intentional assignment to boost line numbers
result=1
return $result
}
@@ -0,0 +1,3 @@
@test "test with / in / name" {
true
}
@@ -0,0 +1,16 @@
set -u
# This file is used to test line number offsets. Any changes to lines will affect tests
@test "access unbound variable" {
unset unset_variable
# Add a line for checking line number
# shellcheck disable=SC2154
foo=$unset_variable
}
@test "access second unbound variable" {
unset second_unset_variable
# shellcheck disable=SC2034,SC2154
foo=$second_unset_variable
}
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
@@ -0,0 +1,4 @@
load unofficial_bash_strict_mode
@test "unofficial Bash strict mode conditions met" {
:
}
@@ -0,0 +1,6 @@
PATH="/usr/local/bin:/usr/bin:/bin"
@test "PATH is reset" {
echo "$PATH"
false
}
@@ -0,0 +1,4 @@
@test "test" {
bats_require_minimum_version 1.5.0
run ! echo test
}
@@ -0,0 +1,33 @@
@test "no extra whitespace" {
:
}
@test "tab at beginning of line" {
:
}
@test "tab before description" {
:
}
@test "tab before opening brace" {
:
}
@test "tabs at beginning of line and before description" {
:
}
@test "tabs at beginning, before description, before brace" {
:
}
@test "extra whitespace around single-line test" { :; }
@test "no extra whitespace around single-line test" {:;}
@test parse unquoted name between extra whitespace {:;}
@test { {:;} # unquote single brace is a valid description
@test ' {:;} # empty name from single quote
@@ -0,0 +1,3 @@
@test "truth" {
true
}
@@ -0,0 +1,11 @@
setup_file() {
false
}
teardown_file() {
false
}
@test dummy {
:
}
@@ -0,0 +1,3 @@
@test "test" {
true
}
@@ -0,0 +1,3 @@
@test "first" {
true
}
@@ -0,0 +1,11 @@
setup_file() {
echo "$BATS_TEST_FILENAME" >>"$LOG"
}
@test "Test 1" {
true
}
@test "Test 2" {
true
}
@@ -0,0 +1,7 @@
setup_file() {
echo "$BATS_TEST_FILENAME" >>"$LOG"
}
@test "test" {
true
}
@@ -0,0 +1,7 @@
setup_file() {
export SETUP_FILE_VAR="$BATS_TEST_FILENAME"
}
@test "test" {
true
}
@@ -0,0 +1,3 @@
@test "test" {
[[ "${SETUP_FILE_VAR-"NOT_SET"}" == "NOT_SET" ]]
}
@@ -0,0 +1,7 @@
setup_file() {
echo "$BATS_TEST_FILENAME" >>"$LOG"
}
@test "test" {
skip "We only want to see if setup file runs"
}
@@ -0,0 +1,11 @@
setup_file() {
false
}
@test "test 1" {
true
}
@test "test 2" {
true
}
@@ -0,0 +1,9 @@
setup_file() {
true
false
true
}
@test "test" {
true
}
@@ -0,0 +1,11 @@
teardown_file() {
echo "$BATS_TEST_FILENAME" >>"$LOG"
}
@test "first" {
true
}
@test "second" {
true
}

Some files were not shown because too many files have changed in this diff Show More