From d6ce55ad7e01a51acb8a2a909383366ecc89d0b2 Mon Sep 17 00:00:00 2001 From: Steve Bennett Date: Sat, 17 Jun 2023 10:44:05 +1000 Subject: tcltest: rework constraint system Now 'constraint cmd|package' is like 'needs' but sets a constraint The command to 'needs cmd' and 'constraint cmd' can now take a subcommand to check. Add 'constraint|needs eval|expr' to make some constraint checks simpler. Signed-off-by: Steve Bennett --- tcltest.tcl | 122 +++++++++++++++++++++++++++++++++++++++----------- tests/aio.test | 4 +- tests/binary.test | 4 +- tests/clock.test | 17 +++---- tests/coverage.test | 10 ++--- tests/debug.test | 2 + tests/dict.test | 1 + tests/dict2.test | 1 + tests/ensemble.test | 1 + tests/event.test | 20 ++------- tests/exec.test | 6 +-- tests/exec2.test | 13 +++--- tests/exists.test | 2 +- tests/expr-old.test | 10 ++--- tests/expr-pow.test | 6 +-- tests/file.test | 45 +++++++++---------- tests/filecopy.test | 2 +- tests/glob2.test | 4 +- tests/history.test | 2 +- tests/jim.test | 5 ++- tests/lock.test | 3 +- tests/lsearch.test | 3 +- tests/nsensemble.test | 2 +- tests/pid.test | 19 ++++---- tests/posix.test | 5 ++- tests/prefix.test | 2 +- tests/regcount.test | 3 +- tests/regexp.test | 2 +- tests/regexp2.test | 3 +- tests/regmin.test | 3 +- tests/runall.tcl | 2 +- tests/signal.test | 2 +- tests/socket.test | 14 +----- tests/tty.test | 7 +-- tests/util.test | 4 +- 35 files changed, 188 insertions(+), 163 deletions(-) diff --git a/tcltest.tcl b/tcltest.tcl index 9478dcd..1f13365 100644 --- a/tcltest.tcl +++ b/tcltest.tcl @@ -25,50 +25,120 @@ if {[lsearch $argv "-stoponerror"] >= 0 || [info exists env(stoponerror)]} { incr testinfo(stoponerror) } -proc needs {type what {packages {}}} { +proc needscmdcheck {what {packages {}}} { + # Does it exist already? + if {[info commands $what] ne ""} { + return 1 + } + if {$packages eq ""} { + # e.g. exec command is in exec package + set packages $what + } + foreach p $packages { + catch {package require $p} + } + if {[info commands $what] ne ""} { + return 1 + } + return 0 +} + +# Verifies the constraint/need +# Returns 1 if the check passes or 0 if not +proc needcheck {type what args} { + # Returns 1 if the check passed or 0 if not if {$type eq "constraint"} { - if {![info exists ::tcltest::testConstraints($what)]} { - set ::tcltest::testConstraints($what) 0 - } - if {![set ::tcltest::testConstraints($what)]} { - skiptest " (constraint $what)" + if {[info exists ::tcltest::testConstraints($what)] && $::tcltest::testConstraints($what)} { + return 1 } - return + return 0 } if {$type eq "cmd"} { - # Does it exist already? - if {[info commands $what] ne ""} { - return + lassign $what cmd subcmd + if {![needscmdcheck $cmd $args]} { + return 0 } - if {$packages eq ""} { - # e.g. exec command is in exec package - set packages $what - } - foreach p $packages { - catch {package require $p} - } - if {[info commands $what] ne ""} { - return + if {$subcmd ne ""} { + if {[testConstraint jim]} { + if {$subcmd ni [$cmd -commands]} { + return 0 + } + } else { + if {[catch {$cmd $subcmd}]} { + return 0 + } + } } - skiptest " (command $what)" + return 1 } if {$type eq "package"} { if {[catch {package require $what}]} { - skiptest " (package $what)" + return 0 + } + return 1 + } + if {$type eq "expr"} { + return [uplevel #0 [list expr [lindex $args 0]]] + } + if {$type eq "eval"} { + try { + uplevel #0 [lindex $args 0] + return 1 + } on error msg { + return 0 } - return } error "Unknown needs type: $type" } -# Simplify setting constraints for whether commands exist -proc testCmdConstraints {args} { - foreach cmd $args { - testConstraint $cmd [expr {[info commands $cmd] ne {}}] +# needs skips all tests in the file if the requirement isn't met +# constrains sets a constraint to 1 or 0 based on if the requirement is met. +# +# needs|constraint cmd {cmd ?subcmd?} ?packages? +# +# Checks that the command 'cmd' (and possibly 'cmd subcmd') exists +# If necessary, loads the given packages +# If used as a constraint, the constraint name is $cmd or $cmd-$subcmd +# +# needs constraint name +# +# Checks that the given constraint is set and is met (true) +# If the constraint hasn't been set, this check fails (returns false) +# +# needs|constraint expr name +# +# Checks that the expression evaluates to true. +# If used as a constraint, the constraint name is $name +# +# needs|constraint eval name