Skip to content

Commit

Permalink
bats: color formatter in CI
Browse files Browse the repository at this point in the history
  • Loading branch information
mmetc committed Feb 9, 2024
1 parent 332af5d commit 102c465
Show file tree
Hide file tree
Showing 5 changed files with 353 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/bats-hub.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
- name: "Run hub tests"
run: |
./test/bin/generate-hub-tests
./test/run-tests test/dyn-bats/${{ matrix.test-file }}
./test/run-tests ./test/dyn-bats/${{ matrix.test-file }} --formatter ./test/lib/color-formatter
- name: "Collect hub coverage"
run: ./test/bin/collect-hub-coverage >> $GITHUB_ENV
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/bats-mysql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
MYSQL_USER: root

- name: "Run tests"
run: make bats-test
run: ./test/run-tests ./test/bats --formatter ./test/lib/color-formatter
env:
DB_BACKEND: mysql
MYSQL_HOST: 127.0.0.1
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/bats-postgres.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ jobs:
PGUSER: postgres

- name: "Run tests (DB_BACKEND: pgx)"
run: make bats-test
run: ./test/run-tests ./test/bats --formatter ./test/lib/color-formatter
env:
DB_BACKEND: pgx
PGHOST: 127.0.0.1
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/bats-sqlite-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
make clean bats-build bats-fixture BUILD_STATIC=1
- name: "Run tests"
run: make bats-test
run: ./test/run-tests ./test/bats --formatter ./test/lib/color-formatter

- name: "Collect coverage data"
run: |
Expand Down
349 changes: 349 additions & 0 deletions test/lib/color-formatter
Original file line number Diff line number Diff line change
@@ -0,0 +1,349 @@
#!/usr/bin/env bash
set -e

# shellcheck source=lib/bats-core/formatter.bash
source "$BATS_ROOT/lib/bats-core/formatter.bash"

BASE_PATH=.
BATS_ENABLE_TIMING=

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

update_count_column_width() {
count_column_width=$((${#count} * 2 + 2))
if [[ -n "$BATS_ENABLE_TIMING" ]]; then
# additional space for ' in %s sec'
count_column_width=$((count_column_width + ${#SECONDS} + 8))
fi
# also update dependent value
update_count_column_left
}

update_screen_width() {
screen_width="$(tput cols)"
# also update dependent value
update_count_column_left
}

update_count_column_left() {
count_column_left=$((screen_width - count_column_width))
}

# avoid unset variables
count=0
screen_width=80
update_count_column_width
update_screen_width
test_result=

trap update_screen_width WINCH

begin() {
test_result= # reset to avoid carrying over result state from previous test
line_backoff_count=0
#go_to_column 0
#update_count_column_width
#buffer_with_truncation $((count_column_left - 1)) ' %s' "$name"
#clear_to_end_of_line
#go_to_column $count_column_left
#if [[ -n "$BATS_ENABLE_TIMING" ]]; then
# buffer "%${#count}s/${count} in %s sec" "$index" "$SECONDS"
#else
# buffer "%${#count}s/${count}" "$index"
#fi
#go_to_column 1
buffer "%${#count}s" "$index"
}

finish_test() {
#move_up $line_backoff_count
#go_to_column 0
buffer "$@"
if [[ -n "${TIMEOUT-}" ]]; then
set_color 2
if [[ -n "$BATS_ENABLE_TIMING" ]]; then
buffer ' [%s (timeout: %s)]' "$TIMING" "$TIMEOUT"
else
buffer ' [timeout: %s]' "$TIMEOUT"
fi
else
if [[ -n "$BATS_ENABLE_TIMING" ]]; then
set_color 2
buffer ' [%s]' "$TIMING"
fi
fi
advance
move_down $((line_backoff_count - 1))
}

pass() {
local TIMING="${1:-}"
finish_test ' ✓ %s' "$name"
test_result=pass
}

skip() {
local reason="$1" TIMING="${2:-}"
if [[ -n "$reason" ]]; then
reason=": $reason"
fi
finish_test ' - %s (skipped%s)' "$name" "$reason"
test_result=skip
}

fail() {
local TIMING="${1:-}"
set_color 1 bold
finish_test ' ✗ %s' "$name"
test_result=fail
}

timeout() {
local TIMING="${1:-}"
set_color 3 bold
TIMEOUT="${2:-}" finish_test ' ✗ %s' "$name"
test_result=timeout
}

log() {
case ${test_result} in
pass)
clear_color
;;
fail)
set_color 1
;;
timeout)
set_color 3
;;
esac
buffer ' %s\n' "$1"
clear_color
}

summary() {
if [ "$failures" -eq 0 ]; then
set_color 2 bold
else
set_color 1 bold
fi

buffer '\n%d test' "$count"
if [[ "$count" -ne 1 ]]; then
buffer 's'
fi

buffer ', %d failure' "$failures"
if [[ "$failures" -ne 1 ]]; then
buffer 's'
fi

if [[ "$skipped" -gt 0 ]]; then
buffer ', %d skipped' "$skipped"
fi

if ((timed_out > 0)); then
buffer ', %d timed out' "$timed_out"
fi

not_run=$((count - passed - failures - skipped - timed_out))
if [[ "$not_run" -gt 0 ]]; then
buffer ', %d not run' "$not_run"
fi

if [[ -n "$BATS_ENABLE_TIMING" ]]; then
buffer " in $SECONDS seconds"
fi

buffer '\n'
clear_color
}

buffer_with_truncation() {
local width="$1"
shift
local string

# shellcheck disable=SC2059
printf -v 'string' -- "$@"

if [[ "${#string}" -gt "$width" ]]; then
buffer '%s...' "${string:0:$((width - 4))}"
else
buffer '%s' "$string"
fi
}

move_up() {
if [[ $1 -gt 0 ]]; then # avoid moving if we got 0
buffer '\x1B[%dA' "$1"
fi
}

move_down() {
if [[ $1 -gt 0 ]]; then # avoid moving if we got 0
buffer '\x1B[%dB' "$1"
fi
}

go_to_column() {
local column="$1"
buffer '\x1B[%dG' $((column + 1))
}

clear_to_end_of_line() {
buffer '\x1B[K'
}

advance() {
clear_to_end_of_line
buffer '\n'
clear_color
}

set_color() {
local color="$1"
local weight=22

if [[ "${2:-}" == 'bold' ]]; then
weight=1
fi
buffer '\x1B[%d;%dm' "$((30 + color))" "$weight"
}

clear_color() {
buffer '\x1B[0m'
}

_buffer=

buffer() {
local content
# shellcheck disable=SC2059
printf -v content -- "$@"
_buffer+="$content"
}

prefix_buffer_with() {
local old_buffer="$_buffer"
_buffer=''
"$@"
_buffer="$_buffer$old_buffer"
}

flush() {
printf '%s' "$_buffer"
_buffer=
}

finish() {
flush
printf '\n'
}

trap finish EXIT
trap '' INT

bats_tap_stream_plan() {
count="$1"
index=0
passed=0
failures=0
skipped=0
timed_out=0
name=
update_count_column_width
}

bats_tap_stream_begin() {
index="$1"
name="$2"
begin
flush
}

bats_tap_stream_ok() {
index="$1"
name="$2"
((++passed))

pass "${BATS_FORMATTER_TEST_DURATION:-}"
}

bats_tap_stream_skipped() {
index="$1"
name="$2"
((++skipped))
skip "$3" "${BATS_FORMATTER_TEST_DURATION:-}"
}

bats_tap_stream_not_ok() {
index="$1"
name="$2"

if [[ ${BATS_FORMATTER_TEST_TIMEOUT-x} != x ]]; then
timeout "${BATS_FORMATTER_TEST_DURATION:-}" "${BATS_FORMATTER_TEST_TIMEOUT}s"
((++timed_out))
else
fail "${BATS_FORMATTER_TEST_DURATION:-}"
((++failures))
fi

}

bats_tap_stream_comment() { # <comment> <scope>
local scope=$2
# count the lines we printed after the begin text,
if [[ $line_backoff_count -eq 0 && $scope == begin ]]; then
# if this is the first line after begin, go down one line
buffer "\n"
((++line_backoff_count)) # prefix-increment to avoid "error" due to returning 0
fi

((++line_backoff_count))
((line_backoff_count += ${#1} / screen_width)) # account for linebreaks due to length
log "$1"
}

bats_tap_stream_suite() {
#test_file="$1"
line_backoff_count=0
index=
# indicate filename for failures
local file_name="${1#"$BASE_PATH"}"
name="File $file_name"
set_color 4 bold
buffer "%s\n" "$file_name"
clear_color
}

line_backoff_count=0
bats_tap_stream_unknown() { # <full line> <scope>
local scope=$2
# count the lines we printed after the begin text, (or after suite, in case of syntax errors)
if [[ $line_backoff_count -eq 0 && ($scope == begin || $scope == suite) ]]; then
# if this is the first line after begin, go down one line
buffer "\n"
((++line_backoff_count)) # prefix-increment to avoid "error" due to returning 0
fi

((++line_backoff_count))
((line_backoff_count += ${#1} / screen_width)) # account for linebreaks due to length
buffer "%s\n" "$1"
flush
}

bats_parse_internal_extended_tap

summary

0 comments on commit 102c465

Please sign in to comment.