-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTESTALL
More file actions
executable file
·98 lines (90 loc) · 3.53 KB
/
TESTALL
File metadata and controls
executable file
·98 lines (90 loc) · 3.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/bin/bash
# a simple regression test framework for my bash advent-of-code solutions
USAGE='TESTALL [-v] [-t] [scripts...]
Runs the test on a solution (script name or number), or on all tests if no
argument.
To define a test, in a script put comments like:
#TEST: input-name expected-value
This program will then run the script for each #TEST: line, with
script.input-name as argument, expecting expected-value (a number) as the last
line of output (so the script can print extra info before)
Nothing is printed in case of success, unless -v is used.
Lines starting with #TEST: but not in the proper syntax are ignored, e.g. with
a missing or non-numeric value.
Comments can be added at the end of line, like:
#TEST: mini 17 # the simplest value, runs with dNN.mini
#TEST: huge 51275276 # stress test with dNN.huge
E.g:
in a file d06-2.sh, the line "#TEST: input 365131" means that calling
"./TEST d06-2.sh" (or "./TEST 6") will run "d06-2.sh d06.input" and expect
that the last line of output will be 365131
Note: adding a comment #TEST_EXCLUDED: prevents the script to be run with ALL
Options:
-v verbose, prints what tests are being done after it
-t times, print the time taken by each test
'
#TEST_EXCLUDED:
nl=$'\n'
shopt -s nullglob
verbose=false
export timer=false
V(){ "$verbose" && echo "$*";}
export TIMEFORMAT=' Time: %3R s'
# runs all the tests of a script. Returns the number of failed tests
runtest(){
local script="$1"
grep -q '^[[:space:]]*#TEST_EXCLUDED:' "$script" && return 0
local name value result fails=0 radix="$script"
[[ $script =~ ^(d[0-9]+).*-[0-9](.*)[.]sh$ ]] && radix="${BASH_REMATCH[1]}"
V "Running tests in $script"
while read -r name value; do
V " TEST $radix.$name"
if "$timer"; then
"$verbose" || export TIMEFORMAT=" Time: %3R s for $script $radix.$name"
result=$(time ./"$script" "$radix.$name" | tail -1)
else
result=$(./"$script" "$radix.$name" | tail -1)
fi
if [[ $result != "$value" ]]; then
echo "***TEST ERROR: $script $radix.$name: found \"$result\", expecting \"$value\""
(( fails++ ))
else
V " OK"
fi
done < <(grep -oP '^[[:space:]]*#TEST:[[:space:]]*\K[-_[:alnum:]]+[[:space:]]+[[:digit:]]+' "$script")
return "$fails"
}
errors=0
default=ALL; for arg in "$@"; do [[ $arg =~ ^- ]] || { default=; break;}; done
for arg in "$@" $default; do
if [[ $arg == '-v' ]]; then
verbose=true
elif [[ $arg == '-t' ]]; then
timer=true
elif [[ $arg == '-tv' ]] || [[ $arg == '-vt' ]]; then
timer=true; verbose=true
elif [[ $arg =~ ^- ]]; then # any option ==> usage
echo "USAGE: $USAGE"; exit 1
elif [[ $arg == ALL ]]; then # run all tests found in d*.sh files
# shellcheck disable=SC2013
for script in $(grep -l '^[[:space:]]*#TEST:' d*.sh); do
runtest "$script"
(( errors += $? ))
done
elif [[ $arg =~ ^[[:digit:]]+$ ]]; then # run all the tests of the day
[[ $arg =~ ^[[:digit:]]$ ]] && n="0$arg" || n="$arg"
# shellcheck disable=SC2231
for script in d${n}-*.sh; do
runtest "$script"
(( errors += $? ))
done
elif [[ -e $arg ]]; then # run tests for a single script
runtest "$arg"
(( errors += $? ))
else
echo "***ERROR: Script not found: $arg.${nl}${nl}USAGE=$USAGE"
exit 1
fi
done
[[ $errors != 0 ]] && echo "$errors Tests failed!"
exit "$errors"