diff --git a/src/modules/punk/tcltestrun-999999.0a1.0.tm b/src/modules/punk/tcltestrun-999999.0a1.0.tm index 78b13020..e3223fdc 100644 --- a/src/modules/punk/tcltestrun-999999.0a1.0.tm +++ b/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 "<$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 "<$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 { # ++++ SKIPPED: if {[string match "++++ * SKIPPED: *" $ln_trimright]} { dict append results out "<$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 "<$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 "<$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 "<$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 "<$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 "<$pkg> $ln" \n continue ;#skip to next line. diff --git a/src/modules/punk/tcltestrun-buildversion.txt b/src/modules/punk/tcltestrun-buildversion.txt index f47d01c8..05b75f17 100644 --- a/src/modules/punk/tcltestrun-buildversion.txt +++ b/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