Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
- A failure message containing a ``` fence no longer breaks the `--report-md` summary. The message is fenced unescaped, which is right only while the fence is longer than any run of backticks inside it — a hook printing a bare fence closed the block early, so the text after it rendered as prose and the trailing fence opened an unterminated one, swallowing every later section of the page appended to `$GITHUB_STEP_SUMMARY` (#1305)
### Fixed
- A comma or colon in a test title no longer breaks its GitHub Actions annotation. GitHub splits an annotation's properties on `,`, so a `set_test_title` holding one ended the title there and turned the rest into an invented property; a file path containing a comma did the same. Property values now encode `:` and `,` as the spec requires, on top of the `%`, `\r` and `\n` the message already encoded (#1307)
### Fixed
- `--output tap` now escapes a `#` in a test description, as `--report-tap` already did. TAP reads an unescaped `#` as the start of a directive, so a failing test titled `... # SKIP ...` was handed to the consumer as a skip — a `not ok` carrying a SKIP directive is not a failure, and it left CI silently. The `# SKIP` and `# TODO` directives bashunit writes itself are unaffected (#1309)

### Removed
- `bashunit learn`, the interactive tutorial. Nobody used it, and it was broken for most of the nine months it shipped without anyone reporting it. Learning bashunit belongs in the docs at https://bashunit.com, not in a subsystem inside the runner — which is also 6% of the distributable. Calling it now says it was removed and points there (#1256, #1258)
Expand Down
25 changes: 17 additions & 8 deletions src/console/line.sh
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,20 @@ function bashunit::console_results::print_tap_line() {
test_name=$(printf "%s" "$test_name" | \
sed 's/[[:space:]]*[0-9][0-9]*m\{0,1\}[[:space:]]*[0-9.]*[ms]*[[:space:]]*$//')

# TAP 13 reads an unescaped `#` on a test line as the start of a directive, so
# a title holding one hands the consumer a directive bashunit never meant -- a
# failing test titled "... # SKIP ..." is read as not-a-failure and leaves CI
# silently. Only the description is escaped; the directives below are ours.
# `--report-tap` has done this since #1119 via the same helper.
local tap_name
tap_name=$(bashunit::reports::__tap_description "$test_name")

case "$type" in
successful)
printf "ok %d - %s\n" "$_BASHUNIT_TOTAL_TESTS_COUNT" "$test_name"
printf "ok %d - %s\n" "$_BASHUNIT_TOTAL_TESTS_COUNT" "$tap_name"
;;
failure | failed | failed_snapshot | error)
printf "not ok %d - %s\n" "$_BASHUNIT_TOTAL_TESTS_COUNT" "$test_name"
printf "not ok %d - %s\n" "$_BASHUNIT_TOTAL_TESTS_COUNT" "$tap_name"
local detail_line
printf " ---\n"
while IFS= read -r detail_line; do
Expand All @@ -104,27 +112,28 @@ function bashunit::console_results::print_tap_line() {
skip_reason="${skip_reason#"${skip_reason%%[![:space:]]*}"}"
if [ -n "$skip_reason" ]; then
printf "ok %d - %s # SKIP %s\n" \
"$_BASHUNIT_TOTAL_TESTS_COUNT" "$skip_name" "$skip_reason"
"$_BASHUNIT_TOTAL_TESTS_COUNT" \
"$(bashunit::reports::__tap_description "$skip_name")" "$skip_reason"
else
printf "ok %d - %s # SKIP\n" \
"$_BASHUNIT_TOTAL_TESTS_COUNT" "$test_name"
"$_BASHUNIT_TOTAL_TESTS_COUNT" "$tap_name"
fi
;;
incomplete)
printf "ok %d - %s # TODO incomplete\n" \
"$_BASHUNIT_TOTAL_TESTS_COUNT" "$test_name"
"$_BASHUNIT_TOTAL_TESTS_COUNT" "$tap_name"
;;
snapshot)
printf "ok %d - %s # snapshot\n" \
"$_BASHUNIT_TOTAL_TESTS_COUNT" "$test_name"
"$_BASHUNIT_TOTAL_TESTS_COUNT" "$tap_name"
;;
risky)
printf "ok %d - %s # RISKY no assertions\n" \
"$_BASHUNIT_TOTAL_TESTS_COUNT" "$test_name"
"$_BASHUNIT_TOTAL_TESTS_COUNT" "$tap_name"
;;
*)
printf "not ok %d - %s\n" \
"$_BASHUNIT_TOTAL_TESTS_COUNT" "$test_name"
"$_BASHUNIT_TOTAL_TESTS_COUNT" "$tap_name"
;;
esac
}
29 changes: 29 additions & 0 deletions tests/acceptance/bashunit_tap_output_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,32 @@ function test_tap_output_exits_non_zero_on_failure() {

assert_general_error "$(./bashunit --no-parallel --env "$TEST_ENV_FILE" --output tap "$test_file" 2>&1)"
}

# TAP 13 reads an unescaped `#` on a test line as the start of a directive, so a
# title holding one hands the consumer a directive bashunit never meant. The
# dangerous direction is a FAILING test titled "... # SKIP ...": every consumer
# reads `not ok` with a SKIP directive as not-a-failure, and the failure leaves
# CI silently.
#
# `--report-tap` has escaped this since #1119; the `--output tap` stream, which
# a different emitter writes, never did.
function test_output_tap_escapes_a_hash_in_the_description() {
local dir
dir="$(bashunit::temp_dir tap_hash)"
{
printf 'function test_titled() {\n'
printf ' bashunit::set_test_title "validates input # SKIP unsupported"\n'
printf ' assert_same "expected" "actual"\n'
printf '}\n'
} >"$dir/hash_test.sh"

local output
output=$(./bashunit --no-parallel --no-color --env "$TEST_ENV_FILE" \
--output tap "$dir/hash_test.sh" 2>/dev/null) || true

local line
line=$(printf '%s\n' "$output" | grep -E '^not ok' | head -1)

assert_contains '\#' "$line"
assert_not_contains ' # SKIP' "$line"
}
Loading