Browse Source

tcltestrun 0.2.0: preserve errorinfo/result_was/result_expected in failed tests, fix multi-word test name extraction

parse_testrun now keeps the full Tcl errorInfo in testcase_fails entries for ERROR-status failures (previously parsed then discarded), and captures the actual vs expected result blocks for FAILED-status result mismatches via a new result_stage sub-state. Test name extraction in the took/PASSED/SKIPPED handlers is fixed to use the full substring between the structural delimiters instead of lindex \ 1, which corrupted timing associations and testcase_passes/testcase_constraintskips keys for any test name containing spaces; the took handler uses string last to allow test names that themselves contain the word 'took'. The closing-FAILED microseconds lookup now keys on \ (authoritative) instead of the stale \. New dict keys are additive; existing consumers using dict exists/dict get are unaffected.
master
Julian Noble 2 weeks ago
parent
commit
02e24ddbfd
  1. 59
      src/modules/punk/tcltestrun-999999.0a1.0.tm
  2. 4
      src/modules/punk/tcltestrun-buildversion.txt

59
src/modules/punk/tcltestrun-999999.0a1.0.tm

@ -93,14 +93,18 @@ tcl::namespace::eval punk::tcltestrun {
#'took' lines can occur for both passing and failing tests, but will occur before the ++++ PASSED or ==== FAILED lines for a test case,
if {[string match "++++ * took * µs" $ln_trimright]} {
dict append results out "<stdout><$pkg> $ln" \n
set nm [lindex $ln 1]
# The test name may itself contain the word "took", so locate the " took " delimiter from the right (last occurrence).
# Name is the substring between "++++ " (5 chars) and the last " took ".
set took_pos [string last " took " $ln_trimright]
set nm [string range $ln_trimright 5 [expr {$took_pos - 1}]]
dict set test_case_time $nm [dict create microseconds [lindex $ln end-1]]
continue
}
if {[string match "++++ * PASSED" $ln_trimright]} {
dict append results out "<stdout><$pkg> $ln" \n
set nm [lindex $ln 1]
# " PASSED" is terminal (7 chars); trim "++++ " (5 chars) from front and " PASSED" from end to get the full name.
set nm [string range $ln_trimright 5 end-7]
if {[dict exists $test_case_time $nm]} {
dict set results testcase_passes $nm [dict get $test_case_time $nm]
} else {
@ -111,8 +115,11 @@ tcl::namespace::eval punk::tcltestrun {
# ++++ <testname_words> SKIPPED: <constraint/reason>
if {[string match "++++ * SKIPPED: *" $ln_trimright]} {
dict append results out "<stdout><$pkg> $ln" \n
set nm [lindex $ln 1]
set reason [string trim [string range $ln [expr {[string first "SKIPPED:" $ln] + 8}] end]]
# Anchor on " SKIPPED:" (with leading space) so the name is extracted as the substring before it.
# Leftmost occurrence is used because the reason is free text after the delimiter and may itself contain "SKIPPED:".
set skip_pos [string first " SKIPPED:" $ln_trimright]
set nm [string range $ln_trimright 5 [expr {$skip_pos - 1}]]
set reason [string trim [string range $ln_trimright [expr {$skip_pos + 9}] end]]
dict set results testcase_constraintskips $nm [list reason $reason]
continue
}
@ -222,6 +229,33 @@ tcl::namespace::eval punk::tcltestrun {
}
# Result capture for FAILED (non-error) tests: grab "---- Result was:" and "---- Result should have been" blocks.
if {$fail_stage eq "contents"} {
if {[dict exists $test_case_fail result_stage] && [dict get $test_case_fail result_stage] ne ""} {
if {[string match "---- *" $ln] || [string match "==== * FAILED" $ln_trimright] || [string match "++++ *" $ln]} {
dict set test_case_fail result_stage ""
# fall through to normal handling below (do not continue)
} else {
dict append test_case_fail [dict get $test_case_fail result_stage] "$ln\n"
dict append results out "<stdout><$pkg> $ln" \n
continue
}
} elseif {[string match "---- Result was:*" $ln]} {
dict set test_case_fail result_stage "result_was"
if {![dict exists $test_case_fail result_was]} {
dict set test_case_fail result_was ""
}
dict append results out "<stdout><$pkg> $ln" \n
continue
} elseif {[string match "---- Result should have been*" $ln]} {
dict set test_case_fail result_stage "result_expected"
if {![dict exists $test_case_fail result_expected]} {
dict set test_case_fail result_expected ""
}
dict append results out "<stdout><$pkg> $ln" \n
continue
}
}
if {$fail_stage eq "contents" && ![string match "---- *" $ln] && ![string match "++++ *" $ln] && ![string match "==== * FAILED" $ln_trimright]} {
dict append test_case_fail test_body "$ln\n"
dict append results out "<stdout><$pkg> $ln" \n
@ -247,8 +281,17 @@ tcl::namespace::eval punk::tcltestrun {
} errorcode [dict get $test_case_fail errorcode] {*}{
}
]
if {[dict exists $test_case_time $nm]} {
dict set results testcase_fails $nm microseconds [dict get $test_case_time $nm microseconds]
if {[dict exists $test_case_time $test_name]} {
dict set results testcase_fails $test_name microseconds [dict get $test_case_time $test_name microseconds]
}
if {[dict exists $test_case_fail errorinfo] && [dict get $test_case_fail errorinfo] ne ""} {
dict set results testcase_fails $test_name errorinfo [dict get $test_case_fail errorinfo]
}
if {[dict exists $test_case_fail result_was] && [dict get $test_case_fail result_was] ne ""} {
dict set results testcase_fails $test_name result_was [dict get $test_case_fail result_was]
}
if {[dict exists $test_case_fail result_expected] && [dict get $test_case_fail result_expected] ne ""} {
dict set results testcase_fails $test_name result_expected [dict get $test_case_fail result_expected]
}
dict set test_case_fail stage ""
@ -257,6 +300,10 @@ tcl::namespace::eval punk::tcltestrun {
dict set test_case_fail test_body ""
dict set test_case_fail returncode ""
dict set test_case_fail errorcode ""
dict unset test_case_fail errorinfo
dict unset test_case_fail result_was
dict unset test_case_fail result_expected
dict unset test_case_fail result_stage
dict append results out "<stdout><$pkg> $ln" \n
continue ;#skip to next line.

4
src/modules/punk/tcltestrun-buildversion.txt

@ -1,3 +1,5 @@
0.1.0
0.2.0
#First line must be a semantic version number
#all other lines are ignored.
#0.2.0 - parse_testrun now preserves errorinfo, result_was, result_expected in testcase_fails entries (backward-compatible additive keys)
#0.2.0 - fix test name extraction: took/PASSED/SKIPPED handlers and microseconds lookup now key by the full test name instead of the first word (lindex $ln 1), which corrupted timing associations and testcase_passes/testcase_constraintskips keys for multi-word test names

Loading…
Cancel
Save