commit 8256f5dffdca364cde5c43fcaa001bfe255f4fcd from: Sven M. Hallberg date: Sun Jul 20 17:50:21 2025 UTC add -n option (dry run) commit - 9d3bc9e22e36abc872ea2082e4bad194d395cdf4 commit + 8256f5dffdca364cde5c43fcaa001bfe255f4fcd blob - 78fc2082dc1554a3a5beb1ad0275fe109b350328 blob + 9446a3b3d20d03a46d354f149a677ed155005458 --- exercise +++ exercise @@ -10,6 +10,7 @@ package require Tcl 8.4 # config options set opts(-B) . ;# basedir set opts(-j) 1 ;# number of concurrent jobs +set opts(-n) 0 ;# dry run set opts(-pd) {*} ;# pattern for test search directories set opts(-ps) {*.ts} ;# pattern for test suite executable files set opts(-pt) {*.t} ;# pattern for test executable files @@ -28,6 +29,8 @@ set opts(-v) 0 ;# verbose mode # sequential operation. If set to non-blocking, an event handler should be set # up that resumes the coroutine whenever the channel becomes readable. When # the coroutine ends, the channel is closed and any event handler vanishes. +# In dry runs, the routine terminates before executing the test and returns +# a bogus result of "error", to signal only that no job was started. proc execute_test {job basedir path} { global opts counters set args {} @@ -51,8 +54,12 @@ proc execute_test {job basedir path} { # Pass stderr through when calling test suites. set errfile @stderr - # Pass -v(v) on to test suites. - if {$opts(-v) > 0} {set args "-[string repeat v $opts(-v)] $args"} + # Pass -v(v) and -n on to test suites. + if {$opts(-v) > 0} {set args "-[string repeat v $opts(-v)] $args"} + if {$opts(-n)} {set args "-n $args"} + } elseif {$opts(-n)} { + # Dry run requested; stop here. + return error ;# dummy to signal we did not create a channel } else { # Capture stderr in a temporary file. # Unfortunately, 'chan pipe' only appears in Tcl 8.6. :( @@ -441,9 +448,9 @@ proc main {argc argv} { if {[info exists env(EXERCISEDIR)]} {set opts(-D) $env(EXERCISEDIR)} # handle command line options - set u {[-qv] [-B dir] [-C dir] [-D dir] [-j n] [-p k=pattern] [path ...]} + set u {[-nqv] [-B dir] [-C dir] [-D dir] [-j n] [-p k=pattern] [path ...]} set prog [file tail $::argv0] - while {[getopt argv {B:C:D:j:p:qv} opt arg]} { + while {[getopt argv {B:C:D:j:np:qv} opt arg]} { if {$opt eq "?"} { puts stderr "usage: $prog $u" exit 1 @@ -523,6 +530,7 @@ proc main {argc argv} { exit 127 } + if {$opts(-n)} {exit 0} ;# dry run exit [notok $counters] } blob - 24b4a6ffedbf654c6f198a9cc8b3e051a1f9450f blob + ec62f029162839840dd8b1b2f2416f79e5bc8650 --- exercise.1 +++ exercise.1 @@ -8,7 +8,7 @@ . .Sh SYNOPSIS .Nm exercise -.Op Fl qv +.Op Fl nqv .Op Fl B Ar dir .Op Fl C Ar dir .Op Fl D Ar dir @@ -70,6 +70,14 @@ contains common helper or data files for the tests to Execute up to .Ar n test jobs concurrently. +.It Fl n +Dry run. +Do not execute the tests. +Test suite executables +.Em are +called, with the +.Fl n +option passed on to them. .It Fl p Sy d= Ns Ar pattern When searching for tests, only descend into directories that match the given pattern. @@ -131,9 +139,17 @@ Consequently, the utility can be used as a (nested) test suite runner if desired. .Pp A test suite must admit the +.Fl n +and .Fl v -option. -It may honor it by printing test names to its standard output, +options. +It must honor +.Fl n +by performing a dry run, reporting status as usual +without actually executing any tests. +In addition, it may honor the +.Fl v +option by printing test names to its standard output, prefixed with .Dq ". " to distinguish them from regular status lines. blob - 012ad1fc058bde22aa41aa231fb36d9baab8d986 blob + 63a4c86af485f4ff8efa935e36dadf3eeea2aae7 --- support/adapt-tst +++ support/adapt-tst @@ -3,7 +3,7 @@ # This script adapts a test suite that exposes the simple report protocol of # test.h for use with exercise. # -# Usage: adapt-tst cmd [-v] [arg ...] +# Usage: adapt-tst cmd [-nv] [arg ...] # # Example: Given a test suite in 'foo.tst.c' that is built into an executable # 'foo.tst', create the script 'foo.ts' containing the following: @@ -16,10 +16,12 @@ cmd="$1" shift # handle command line flags +nflag=0 vflag=0 -while getopts v ch +while getopts nv ch do case $ch in + n) nflag=1 ;; v) vflag=$(($vflag + 1)) ;; ?) echo "usage: adapt-tst cmd [-v] [arg ...]" esac @@ -35,12 +37,32 @@ trap "rm -f $tmp" EXIT # clear the flag variables for the test executable unset D V K X -[ $vflag -ge 2 ] && export V=1 # determine the total number of tests by performing a dry run D=1 "$cmd" "$@" >$tmp || exit 127 run=$(echo $(wc -l <$tmp)) +# was a dry run requested in the first place? +if [ $nflag -eq 1 ] +then + if [ $vflag -ge 1 ] + then + # just dump the test names + IFS= + while read -r line + do + echo ". $line" + done <$tmp + fi + + # succeed with a plain count + echo "run $run ok 0 fail 0 error 0" + exit 0 +fi + +# let -vv set V, but not for dry runs +[ $vflag -ge 2 ] && export V=1 + # run the tests in the background, redirecting output to a fifo rm -f $tmp mkfifo $tmp || exit 127 blob - /dev/null blob + 3d4dffafc2e6a23ee1786320e3ac01e1f57301c8 (mode 755) --- /dev/null +++ tests/exercise/flag/n.t @@ -0,0 +1,58 @@ +#!/bin/sh + +set -e + +./assert-exercise $0 \ + "run 1 ok 0 fail 0 error 0\n" \ + '' \ + -n < hallo\nrun 1 ok 0 fail 0 error 0\n" \ + '' \ + -nvv < hallo" + echo "run 1 ok 0 fail 0 error 0" + test "\$1" = "-n" -a "\$2" = "-vv" +EOF blob - 366dc8f8ffb7e1bda6ee182c13795b2854bf6ba6 blob + ecdb3353b3508b43c2d7028dbf7a266ec4e00433 --- tests/support/adapt-tst.t +++ tests/support/adapt-tst.t @@ -6,6 +6,7 @@ cat >$tmp <<-"EOF" #!/bin/sh if [ -n "$D" ] then + [ -n "$V" ] && echo "foo() -" echo "test_1()" echo "test_2()" echo "test_3()" @@ -50,3 +51,32 @@ run 3 ok 2 fail 1 error 0\n" \ #!/bin/sh exec ../../support/adapt-tst $tmp "\$@" EOF + +./assert-exercise $0 \ + "run 3 ok 0 fail 0 error 0\n" \ + '' \ + -n \ + <<-EOF + #!/bin/sh + exec ../../support/adapt-tst $tmp "\$@" + EOF + +./assert-exercise $0 \ + ". $tst\n. . test_1()\n. . test_2()\n. . test_3()\n\ +run 3 ok 0 fail 0 error 0\n" \ + '' \ + -nv \ + <<-EOF + #!/bin/sh + exec ../../support/adapt-tst $tmp "\$@" + EOF + +./assert-exercise $0 \ + ". $tst\n. . test_1()\n\ +. . test_2()\n. . test_3()\nrun 3 ok 0 fail 0 error 0\n" \ + '' \ + -nvv \ + <<-EOF + #!/bin/sh + exec ../../support/adapt-tst $tmp "\$@" + EOF