1
0
mirror of https://github.com/sstephenson/bats.git synced 2026-02-26 17:58:09 +01:00

Pretty test output for terminals

This commit is contained in:
Sam Stephenson
2013-10-21 12:03:45 -05:00
parent b0606bc8cd
commit a3229efbfa
4 changed files with 292 additions and 39 deletions

View File

@@ -5,6 +5,27 @@ version() {
echo "Bats 0.2.0"
}
usage() {
version
echo "Usage: bats [-c] [-p | -t] <test> [<test> ...]"
}
help() {
usage
echo
echo " <test> is the path to a Bats test file, or the path to a directory"
echo " containing Bats test files."
echo
echo " -c, --count Count the number of test cases without running any tests"
echo " -h, --help Display this help message"
echo " -p, --pretty Show results in pretty format (default for terminals)"
echo " -t, --tap Show results in TAP format"
echo " -v, --version Display the version number"
echo
echo " For more information, see https://github.com/sstephenson/bats"
echo
}
resolve_link() {
$(type -p greadlink readlink | head -1) "$1"
}
@@ -35,26 +56,61 @@ BATS_LIBEXEC="$(abs_dirname "$0")"
export BATS_PREFIX="$(abs_dirname "$BATS_LIBEXEC")"
export PATH="$BATS_LIBEXEC:$PATH"
if [ "$1" = "-v" ] || [ "$1" = "--version" ]; then
version
exit 0
fi
options=()
arguments=()
for arg in "$@"; do
if [ "${arg:0:1}" = "-" ]; then
if [ "${arg:1:1}" = "-" ]; then
options[${#options[*]}]="${arg:2}"
else
index=1
while option="${arg:$index:1}"; do
[ -n "$option" ] || break
options[${#options[*]}]="$option"
index=$(($index+1))
done
fi
else
arguments[${#arguments[*]}]="$arg"
fi
done
count_only=""
if [ "$1" = "-c" ]; then
count_only="-c"
shift
fi
unset count_flag pretty
[ -t 0 ] && [ -t 1 ] && pretty="1"
if [ -z "$1" ]; then
{ version
echo "usage: $0 [-c] <filename> [<filename> ...]"
} >&2
for option in "${options[@]}"; do
case "$option" in
"h" | "help" )
help
exit 0
;;
"v" | "version" )
version
exit 0
;;
"c" | "count" )
count_flag="-c"
;;
"t" | "tap" )
pretty=""
;;
"p" | "pretty" )
pretty="1"
;;
* )
usage >&2
exit 1
;;
esac
done
if [ "${#arguments[@]}" -eq 0 ]; then
usage >&2
exit 1
fi
filenames=()
for filename in "$@"; do
for filename in "${arguments[@]}"; do
if [ -d "$filename" ]; then
shopt -s nullglob
for suite_filename in "$(expand_path "$filename")"/*.bats; do
@@ -67,7 +123,18 @@ for filename in "$@"; do
done
if [ "${#filenames[@]}" -eq 1 ]; then
exec bats-exec-test $count_only "${filenames[0]}"
command="bats-exec-test"
else
exec bats-exec-suite $count_only "${filenames[@]}"
command="bats-exec-suite"
fi
if [ -n "$pretty" ]; then
extended_syntax_flag="-x"
formatter="bats-format-tap-stream"
else
extended_syntax_flag=""
formatter="cat"
fi
set -o pipefail execfail
exec "$command" $count_flag $extended_syntax_flag "${filenames[@]}" | "$formatter"

154
libexec/bats-format-tap-stream Executable file
View File

@@ -0,0 +1,154 @@
#!/usr/bin/env bash
set -e
# Just stream the TAP output (sans extended syntax) if tput is missing
command -v tput >/dev/null || exec grep -v "^begin "
IFS= read -r header # 1..n
count="${header:3}"
index=0
failures=0
name=""
count_column_width=$(( ${#count} * 2 + 2 ))
update_screen_width() {
screen_width="$(tput cols)"
count_column_left=$(( $screen_width - $count_column_width ))
}
trap update_screen_width WINCH
update_screen_width
begin() {
go_to_column 0
printf_with_truncation $(( $count_column_left - 1 )) " %s" "$name"
clear_to_end_of_line
go_to_column $count_column_left
printf "%${#count}s/${count}" "$index"
go_to_column 1
}
pass() {
go_to_column 0
printf " ✓ %s" "$name"
advance
}
skip() {
local reason="$1"
[ -z "$reason" ] || reason=": $reason"
go_to_column 0
printf " - %s (skipped%s)" "$name" "$reason"
advance
}
fail() {
go_to_column 0
set_color 1 bold
printf " ✗ %s" "$name"
advance
}
log() {
set_color 1
printf " %s\n" "$1"
clear_color
}
summary() {
printf "\n%d test%s, %d failure%s\n" \
"$count" "$(plural "$count")" \
"$failures" "$(plural "$failures")"
}
printf_with_truncation() {
local width="$1"
shift
local string="$(printf "$@")"
if [ "${#string}" -gt "$width" ]; then
printf "%s..." "${string:0:$(( $width - 4 ))}"
else
printf "%s" "$string"
fi
}
go_to_column() {
local column="$1"
tput hpa "$column"
}
clear_to_end_of_line() {
tput el
}
advance() {
clear_to_end_of_line
echo
clear_color
}
set_color() {
local color="$1"
local weight="$2"
tput setaf "$color"
[ -z "$weight" ] || tput "$weight"
}
clear_color() {
tput sgr0
}
plural() {
[ "$1" -eq 1 ] || echo "s"
}
_buffer=""
buffer() {
_buffer="${_buffer}$("$@")"
}
flush() {
printf "%s" "$_buffer"
_buffer=""
}
finish() {
flush
printf "\n"
}
trap finish EXIT
while IFS= read -r line; do
case "$line" in
"begin "* )
index=$(( $index + 1 ))
name="${line#* $index }"
buffer begin
flush
;;
"ok "* )
skip_expr="ok $index # skip (\(([^)]*)\))?"
if [[ "$line" =~ $skip_expr ]]; then
buffer skip "${BASH_REMATCH[2]}"
else
buffer pass
fi
;;
"not ok "* )
failures=$(( $failures + 1 ))
buffer fail
;;
"# "* )
buffer log "${line:5}"
;;
"# "* )
buffer log "${line:2}"
;;
esac
done
buffer summary