Skip to content

Commit

Permalink
Merge pull request #337 from martin-schulze-vireso/feature/tap_compli…
Browse files Browse the repository at this point in the history
…ant_timing

TAP13 compliant timing
  • Loading branch information
sublimino committed Sep 16, 2020
2 parents bf9db8d + 126a094 commit b705e05
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 29 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -211,7 +211,7 @@ Usage: bats [OPTIONS] <tests>
-c, --count Count test cases without running any tests
-f, --filter <regex> Only run tests that match the regular expression
-F, --formatter <type> Switch between formatters: pretty (default),
tap (default w/o term), junit
tap (default w/o term), tap13, junit
-h, --help Display this help message
-j, --jobs <jobs> Number of parallel jobs (requires GNU parallel)
--no-tempdir-cleanup Preserve test output temporary directory
Expand Down
4 changes: 2 additions & 2 deletions libexec/bats-core/bats
Expand Up @@ -30,7 +30,7 @@ HELP_TEXT_HEADER
-c, --count Count test cases without running any tests
-f, --filter <regex> Only run tests that match the regular expression
-F, --formatter <type> Switch between formatters: pretty (default),
tap (default w/o term), junit
tap (default w/o term), tap13, junit
-h, --help Display this help message
-j, --jobs <jobs> Number of parallel jobs (requires GNU parallel)
--no-tempdir-cleanup Preserve test output temporary directory
Expand Down Expand Up @@ -131,7 +131,7 @@ while [[ "$#" -ne 0 ]]; do
;;
-F | --formatter)
shift
if [[ $1 =~ ^(pretty|junit|tap)$ ]]; then
if [[ $1 =~ ^(pretty|junit|tap|tap13)$ ]]; then
formatter="$1"
else
printf "Unknown formatter '%s', valid options are pretty, junit, tap\n" "$1"
Expand Down
17 changes: 15 additions & 2 deletions libexec/bats-core/bats-exec-test
Expand Up @@ -80,9 +80,9 @@ bats_exit_trap() {
fi
fi

BATS_TEST_TIME=""
BATS_TEST_TIME=''
if [[ -z "${skipped}" && -n "$BATS_ENABLE_TIMING" ]]; then
BATS_TEST_TIME=" in "$((SECONDS - BATS_TEST_START_TIME))"sec"
BATS_TEST_TIME=" in "$(( $(get_mills_since_epoch) - BATS_TEST_START_TIME ))"ms"
fi

if [[ -z "$BATS_TEST_COMPLETED" || -z "$BATS_TEARDOWN_COMPLETED" ]]; then
Expand Down Expand Up @@ -120,6 +120,18 @@ bats_exit_trap() {
exit "$status"
}

get_mills_since_epoch() {
local ms_since_epoch
ms_since_epoch=$(date +%s%N)
if [[ "$ms_since_epoch" == *N ]]; then
ms_since_epoch=$(( $(date +%s) * 1000 ))
else
ms_since_epoch=$(( ms_since_epoch / 1000000 ))
fi

printf "%d\n" "$ms_since_epoch"
}

bats_perform_test() {
export BATS_TEST_NAME="$1"
export BATS_SUITE_TEST_NUMBER="$2"
Expand Down Expand Up @@ -149,6 +161,7 @@ bats_perform_test() {
# mark this call as trap call
trap 'bats_teardown_trap as-exit-trap' EXIT

BATS_TEST_START_TIME=$(get_mills_since_epoch)
"$BATS_TEST_NAME" >>"$BATS_OUT" 2>&1

BATS_TEST_COMPLETED=1
Expand Down
4 changes: 2 additions & 2 deletions libexec/bats-core/bats-format-junit
Expand Up @@ -126,7 +126,7 @@ while IFS= read -r line; do
"ok "*)
echo "$line"
((count += 1))
expr_ok="ok $index .* in ([0-9]+)sec"
expr_ok="ok $index .* in ([0-9]+)ms"
expr_skip="ok $index .* # skip[ ]?(.*)"
if [[ "$line" =~ $expr_skip ]]; then
((skipped += 1))
Expand All @@ -145,7 +145,7 @@ while IFS= read -r line; do
echo "$line"
((count += 1))
((failures += 1))
expr_notok="not ok $index .* in ([0-9]+)sec"
expr_notok="not ok $index .* in ([0-9]+)ms"
if [[ "$line" =~ $expr_notok ]]; then
test_exec_time="${BASH_REMATCH[1]}"
suitetest_exec_time=$((suitetest_exec_time + test_exec_time))
Expand Down
14 changes: 7 additions & 7 deletions libexec/bats-core/bats-format-pretty
Expand Up @@ -66,10 +66,10 @@ begin() {

pass() {
go_to_column 0
buffer ' ✓ %s' "$name"
if [[ -n "$BATS_ENABLE_TIMING" ]]; then
buffer ' ✓ %s [%s]' "$name" "$1"
else
buffer ' ✓ %s ' "$name"
set_color 2
buffer ' [%s]' "$1"
fi
advance
}
Expand All @@ -87,10 +87,10 @@ skip() {
fail() {
go_to_column 0
set_color 1 bold
buffer ' ✗ %s' "$name"
if [[ -n "$BATS_ENABLE_TIMING" ]]; then
buffer ' ✗ %s [%s]' "$name" "$1"
else
buffer ' ✗ %s' "$name"
set_color 2
buffer ' [%s]' "$1"
fi
advance
}
Expand Down Expand Up @@ -194,7 +194,7 @@ finish() {

trap finish EXIT

timing_expr="in (([0-9]+sec))$"
timing_expr="in (([0-9]+ms))$"

while IFS= read -r line; do
case "$line" in
Expand Down
87 changes: 87 additions & 0 deletions libexec/bats-core/bats-format-tap13
@@ -0,0 +1,87 @@
#!/usr/bin/env bash
set -e

while [[ "$#" -ne 0 ]]; do
case "$1" in
-T)
BATS_ENABLE_TIMING="-T"
;;
esac
shift
done

header_pattern='[0-9]+\.\.[0-9]+'
IFS= read -r header

if [[ "$header" =~ $header_pattern ]]; then
printf "TAP version 13\n"
printf "%s\n" "$header"
else
# If the first line isn't a TAP plan, print it and pass the rest through
printf '%s\n' "$header"
exec cat
fi

yaml_block_open=''
add_yaml_entry() {
if [[ -z "$yaml_block_open" ]]; then
printf " ...\n"
fi
printf " %s: %s\n" "$1" "$2"
yaml_block_open=1
}

close_previous_yaml_block() {
if [[ -n "$yaml_block_open" ]]; then
printf " ...\n"
yaml_block_open=''
fi
}

while IFS= read -r line; do
case "$line" in
'begin '*) ;;
'ok '*)
close_previous_yaml_block
number_of_printed_log_lines_for_this_test_so_far=0
if [[ -n "$BATS_ENABLE_TIMING" ]]; then
timing_expr="(ok [0-9]+ .+) in ([0-9]+)ms$"
if [[ "$line" =~ $timing_expr ]]; then
printf "%s\n" "${BASH_REMATCH[1]}"
add_yaml_entry "duration_ms" "${BASH_REMATCH[2]}"
else
echo "Could not match output line to timing regex: $line" >&2
exit 1
fi
else
printf "%s\n" "${line}"
fi
;;
'not ok '*)
close_previous_yaml_block
number_of_printed_log_lines_for_this_test_so_far=0
timing_expr="not ok [0-9]+ (.)+ in ([0-9])+ms$"
if [[ -n "$BATS_ENABLE_TIMING" ]]; then
if [[ "$line" =~ $timing_expr ]]; then
printf "%s\n" "${BATS_REMATCH[1]}"
add_yaml_entry "duration_ms" "${BASH_REMATCH[2]}"
else
echo "Could not match failure line to timing regex: $line" >&2
exit 1
fi
else
printf "%s\n" "${line}"
fi
;;
'# '*)
if [[ $number_of_printed_log_lines_for_this_test_so_far -eq 0 ]]; then
add_yaml_entry "message" "|" # use a multiline string for this entry
fi
((++number_of_printed_log_lines_for_this_test_so_far))
printf " %s\n" "$(echo "\"${line}\"" | cut -b 3-)"
;;
'suite '*) ;;
esac
done
# close the final block if there was one
close_previous_yaml_block
5 changes: 1 addition & 4 deletions man/bats.1
Expand Up @@ -45,10 +45,7 @@ You can invoke the \fBbats\fR interpreter with multiple test file arguments, or
\fB\-h\fR, \fB\-\-help\fR: Display this help message
.
.IP "\(bu" 4
\fB\-j\fR, \fB\-\-jobs <jobs>\fR: Number of parallel jobs (requires GNU parallel)
.
.IP "\(bu" 4
\fB\-\-parallel\-preserve\-environment\fR: Preserve the current environment for "\-\-jobs" (run \fBparallel \-\-record\-env\fR before)
\fB\-j\fR, \fB\-\-jobs <jobs>\fR: Number of parallel jobs
.
.IP "\(bu" 4
\fB\-\-no\-tempdir\-cleanup\fR: Preserve test output temporary directory
Expand Down
2 changes: 1 addition & 1 deletion man/bats.1.ronn
Expand Up @@ -52,7 +52,7 @@ OPTIONS
* `-f`, `--filter <regex>`:
Filter test cases by names matching the regular expression
* `-F`, `--formatter <type>`:
Switch between formatters: pretty (default), tap (default w/o term), junit
Switch between formatters: pretty (default), tap (default w/o term), tap13, junit
* `-h`, `--help`:
Display this help message
* `-j`, `--jobs <jobs>`:
Expand Down
8 changes: 4 additions & 4 deletions test/bats.bats
Expand Up @@ -338,9 +338,9 @@ teardown() {
run bats -T "$FIXTURE_ROOT/failing_and_passing.bats"
echo "$output"
[ $status -eq 1 ]
regex='not ok 1 a failing test in [0-1]sec'
regex='not ok 1 a failing test in [0-9]+ms'
[[ "${lines[1]}" =~ $regex ]]
regex='ok 2 a passing test in [0-1]sec'
regex='ok 2 a passing test in [0-9]+ms'
[[ "${lines[4]}" =~ $regex ]]
}

Expand All @@ -349,11 +349,11 @@ teardown() {
run bats-exec-suite -x -T "$FIXTURE_ROOT/failing_and_passing.bats"
echo "$output"
[ $status -eq 1 ]
regex="not ok 1 a failing test in [0-1]sec"
regex="not ok 1 a failing test in [0-9]+ms"
[ "${lines[2]}" = 'begin 1 a failing test' ]
[[ "${lines[3]}" =~ $regex ]]
[ "${lines[6]}" = 'begin 2 a passing test' ]
regex="ok 2 a passing test in [0-1]sec"
regex="ok 2 a passing test in [0-9]+ms"
[[ "${lines[7]}" =~ $regex ]]
}

Expand Down
12 changes: 6 additions & 6 deletions test/suite.bats
Expand Up @@ -73,11 +73,11 @@ fixtures suite
echo "$output"
[ $status -eq 1 ]
[ "${lines[0]}" = "1..3" ]
regex="ok 1 truth in [0-1]sec"
regex="ok 1 truth in [0-9]+ms"
[[ "${lines[1]}" =~ $regex ]]
regex="ok 2 more truth in [0-1]sec"
regex="ok 2 more truth in [0-9]+ms"
[[ "${lines[2]}" =~ $regex ]]
regex="not ok 3 quasi-truth in [0-1]sec"
regex="not ok 3 quasi-truth in [0-9]+ms"
[[ "${lines[3]}" =~ $regex ]]
}

Expand All @@ -89,14 +89,14 @@ fixtures suite
[ "${lines[0]}" = "1..3" ]
[ "${lines[1]}" = "suite a.bats" ]
[ "${lines[2]}" = "begin 1 truth" ]
regex="ok 1 truth in [0-1]sec"
regex="ok 1 truth in [0-9]+ms"
[[ "${lines[3]}" =~ $regex ]]
[ "${lines[4]}" = "suite b.bats" ]
[ "${lines[5]}" = "begin 2 more truth" ]
regex="ok 2 more truth in [0-1]sec"
regex="ok 2 more truth in [0-9]+ms"
[[ "${lines[6]}" =~ $regex ]]
[ "${lines[7]}" = "begin 3 quasi-truth" ]
regex="not ok 3 quasi-truth in [0-1]sec"
regex="not ok 3 quasi-truth in [0-9]+ms"
[[ "${lines[8]}" =~ $regex ]]
}

Expand Down

0 comments on commit b705e05

Please sign in to comment.