#!/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 " setglobal header_pattern = ''[0-9]+\.\.[0-9]+'' env IFS= read -r header if [[ "$header" =~ $header_pattern ]] { setglobal count = $(header:3) setglobal index = '0' setglobal failures = '0' setglobal skipped = '0' setglobal name = ''"" setglobal count_column_width = $shExpr(' ${#count} * 2 + 2 ') } else { # If the first line isn't a TAP plan, print it and pass the rest through printf "%s\n" $header exec cat } proc update_screen_width { setglobal screen_width = $[tput cols] setglobal count_column_left = $shExpr(' $screen_width - $count_column_width ') } trap update_screen_width WINCH update_screen_width proc begin { go_to_column 0 printf_with_truncation $shExpr(' $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 } proc pass { go_to_column 0 printf " ✓ %s" $name advance } proc skip { var reason = $1 test -z $reason || set reason = "": $reason"" go_to_column 0 printf " - %s (skipped%s)" $name $reason advance } proc fail { go_to_column 0 set_color 1 bold printf " ✗ %s" $name advance } proc log { set_color 1 printf " %s\n" $1 clear_color } proc summary { printf "\n%d test%s" $count $[plural $count] printf ", %d failure%s" $failures $[plural $failures] if test $skipped -gt 0 { printf ", %d skipped" $skipped } printf "\n" } proc printf_with_truncation { var width = $1 shift var string = $[printf @Argv] if test $(#string) -gt $width { printf "%s..." $(string:0:$(( $width - 4 ))) } else { printf "%s" $string } } proc go_to_column { var column = $1 printf "\x1B[%dG" $shExpr(' $column + 1 ') } proc clear_to_end_of_line { printf "\x1B[K" } proc advance { clear_to_end_of_line echo clear_color } proc set_color { var color = $1 var weight = $2 printf "\x1B[%d;%dm" $shExpr(' 30 + $color ') $[ test $weight = "bold" && echo 1 || echo 22] } proc clear_color { printf "\x1B[0m" } proc plural { test $1 -eq 1 || echo "s" } setglobal _buffer = ''"" proc buffer { setglobal _buffer = ""$(_buffer)$[@Argv]"" } proc flush { printf "%s" $_buffer setglobal _buffer = ''"" } proc finish { flush printf "\n" } trap finish EXIT while env IFS= read -r line { match $line { with "begin "* let index+=1 setglobal name = $(line#* $index ) buffer begin flush with "ok "* setglobal skip_expr = ""ok $index # skip (\(([^)]*)\))?"" if [[ "$line" =~ $skip_expr ]] { let skipped+=1 buffer skip $(BASH_REMATCH[2]) } else { buffer pass } with "not ok "* let failures+=1 buffer fail with "# "* buffer log $(line:2) } } buffer summary