diff --git a/.travis.yml b/.travis.yml index db06d9d7..72c775c0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ language: c -script: bin/bats --tap test +script: + ./test-with-all-bashes.sh notifications: email: on_success: never diff --git a/README.md b/README.md index 235bf1ee..fb709371 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ Bash's `errexit` (`set -e`) option when running test cases. If every command in the test case exits with a `0` status code (success), the test passes. In this way, each line is an assertion of truth. +Bats supports Bash version 3.1 and later. ## Running tests diff --git a/libexec/bats b/libexec/bats index 71f392f7..3bf5a795 100755 --- a/libexec/bats +++ b/libexec/bats @@ -116,11 +116,11 @@ for filename in "${arguments[@]}"; do if [ -d "$filename" ]; then shopt -s nullglob for suite_filename in "$(expand_path "$filename")"/*.bats; do - filenames["${#filenames[@]}"]="$suite_filename" + filenames[${#filenames[@]}]="$suite_filename" done shopt -u nullglob else - filenames["${#filenames[@]}"]="$(expand_path "$filename")" + filenames[${#filenames[@]}]="$(expand_path "$filename")" fi done diff --git a/libexec/bats-exec-test b/libexec/bats-exec-test index 8f3bd510..473028b8 100755 --- a/libexec/bats-exec-test +++ b/libexec/bats-exec-test @@ -89,7 +89,7 @@ bats_test_begin() { bats_test_function() { local test_name="$1" - BATS_TEST_NAMES["${#BATS_TEST_NAMES[@]}"]="$test_name" + BATS_TEST_NAMES[${#BATS_TEST_NAMES[@]}]="$test_name" } bats_capture_stack_trace() { @@ -104,7 +104,7 @@ bats_capture_stack_trace() { local index=1 while frame="$(caller "$index")"; do - BATS_CURRENT_STACK_TRACE["${#BATS_CURRENT_STACK_TRACE[@]}"]="$frame" + BATS_CURRENT_STACK_TRACE[${#BATS_CURRENT_STACK_TRACE[@]}]="$frame" if [[ "$frame" = *"$test_pattern" || \ "$frame" = *"$setup_pattern" || \ "$frame" = *"$teardown_pattern" ]]; then diff --git a/libexec/bats-preprocess b/libexec/bats-preprocess index 04297ed0..0098bc51 100755 --- a/libexec/bats-preprocess +++ b/libexec/bats-preprocess @@ -40,7 +40,7 @@ while IFS= read -r line; do body="${BASH_REMATCH[2]}" name="$(eval echo "$quoted_name")" encoded_name="$(encode_name "$name")" - tests["${#tests[@]}"]="$encoded_name" + tests[${#tests[@]}]="$encoded_name" echo "${encoded_name}() { bats_test_begin ${quoted_name} ${index}; ${body}" else printf "%s\n" "$line" diff --git a/test-with-all-bashes.sh b/test-with-all-bashes.sh new file mode 100755 index 00000000..953c09f7 --- /dev/null +++ b/test-with-all-bashes.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +set -e + +run_with_bash() { + # shellcheck disable=SC2016 + printf 'Running tests with bash %s\n\n' "$("$1/bash" -c 'echo $BASH_VERSION')" + + ( + PATH="$1":$PATH bin/bats --tap test + PATH="$1":$PATH bin/bats --pretty test + ) + + printf '\n' +} + +for v in 3.1 3.2 4.0 4.1 4.2 4.3 4.4 ; do + printf 'Building bash %s\n\n' $v + + wget --quiet https://ftp.gnu.org/gnu/bash/bash-$v.tar.gz + tar -xf bash-$v.tar.gz + rm bash-$v.tar.gz + + ( + cd bash-$v + ./configure > /dev/null 2>&1 + make > /dev/null 2>&1 + ) + + run_with_bash bash-$v + + printf 'Rebuilding bash %s with latest patch level\n\n' $v + ( + cd bash-$v + wget -q --cut-dirs=100 -r --no-parent https://ftp.gnu.org/gnu/bash/bash-$v-patches/ + mv ftp.gnu.org bash-$v-patches/ + ( cd bash-$v-patches && cat bash??-??? ) | patch -s -p0 || exit 1 + make > /dev/null 2>&1 + ) + + run_with_bash bash-$v + + rm -rf bash-$v +done diff --git a/test/bats.bats b/test/bats.bats index f1aff293..ad04aff5 100755 --- a/test/bats.bats +++ b/test/bats.bats @@ -131,8 +131,9 @@ fixtures bats PASS=1 run bats "$FIXTURE_ROOT/failing_teardown.bats" [ $status -eq 1 ] [ "${lines[1]}" = 'not ok 1 truth' ] - [ "${lines[2]}" = "# (from function \`teardown' in test file $RELATIVE_FIXTURE_ROOT/failing_teardown.bats, line 2)" ] - [ "${lines[3]}" = "# \`eval \"( exit \${STATUS:-1} )\"' failed" ] + # some versions of bash 4.0.x format this error slightly differently + [ "${lines[2]}" = "# (from function \`teardown' in test file $RELATIVE_FIXTURE_ROOT/failing_teardown.bats, line 1)" ] || [ "${lines[2]}" = "# (from function \`teardown' in test file $RELATIVE_FIXTURE_ROOT/failing_teardown.bats, line 2)" ] + [ "${lines[3]}" = "# \`teardown() {' failed" ] || [ "${lines[3]}" = "# \`eval \"( exit \${STATUS:-1} )\"' failed" ] } @test "failing test with teardown failure" { @@ -146,7 +147,8 @@ fixtures bats @test "teardown failure with significant status" { PASS=1 STATUS=2 run bats "$FIXTURE_ROOT/failing_teardown.bats" [ $status -eq 1 ] - [ "${lines[3]}" = "# \`eval \"( exit \${STATUS:-1} )\"' failed with status 2" ] + # some versions of bash 4.0.x format this error slightly differently + [ "${lines[3]}" = "# \`eval \"( exit \${STATUS:-1} )\"' failed with status 2" ] || [ "${lines[3]}" = "# \`teardown() {' failed with status 2" ] } @test "failing test file outside of BATS_CWD" {