Browse Source
Set G-082 active (user-directed). New errorselection.test pins current
single-form error selection before the fix:
- _GAP pins: an optional choice-restricted leader (make.tcl dispatch shape),
an optional choice-restricted value, and an optional typed (int) value each
reject a word that then overflows - all report generic
{toomanyarguments N index I} with no -badarg/-badval attribution,
discarding the specific rejection (regression vs punk::args 0.5.0)
- reference pins: the -optional 0 equivalents report pointed choiceviolation
with -badarg/-badval and Leading/Trailing argument messages
- guards: genuine surplus stays toomanyarguments; a rejected word consumed by
a later slot parses cleanly; multiform failures still route through
rank_form_failures (noformmatch)
Verified: 7/7 pass against the unfixed module under Tcl 9.0.3.
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
3 changed files with 180 additions and 2 deletions
@ -0,0 +1,178 @@ |
|||||||
|
|
||||||
|
package require tcltest |
||||||
|
|
||||||
|
#added 2026-07-14 (agent, G-082) - single-form parse error selection. |
||||||
|
#Characterizes the error reported when a word rejected by an OPTIONAL argument's |
||||||
|
#allocation screen (restricted choices, basic type) subsequently overflows the |
||||||
|
#argument list. Current 0.12.x behaviour: the specific rejection is discarded and a |
||||||
|
#generic toomanyarguments overflow is reported (regression vs punk::args 0.5.0 - |
||||||
|
#see goals/G-082-punkargs-error-selection.md). The _GAP pins here encode that |
||||||
|
#current behaviour and are to be flipped deliberately by the G-082 fix. |
||||||
|
namespace eval ::testspace { |
||||||
|
namespace import ::tcltest::* |
||||||
|
variable common { |
||||||
|
set result "" |
||||||
|
} |
||||||
|
|
||||||
|
#slim an errorcode: classification triple plus -badarg/-badval extras (drop -argspecs) |
||||||
|
proc ecinfo {opts} { |
||||||
|
set ec [dict get $opts -errorcode] |
||||||
|
set extras [dict create] |
||||||
|
foreach {k v} [lrange $ec 3 end] { |
||||||
|
if {$k eq "-argspecs"} {break} |
||||||
|
dict set extras $k $v |
||||||
|
} |
||||||
|
return [list [lrange $ec 0 2] $extras] |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
test errsel_leader_optional_choice_reject_GAP {GAP: optional choice-restricted leader rejecting a word reports generic overflow (make.tcl dispatch shape)}\ |
||||||
|
-setup $common -body { |
||||||
|
set docid ::testspace::errsel_leader_optional_choice |
||||||
|
set docids [list $docid] |
||||||
|
punk::args::define [list @id -id $docid] {@leaders -min 0 -max 1} {subcommand -type string -optional 1 -choices {build test help}} |
||||||
|
|
||||||
|
set err [catch {punk::args::parse {frobnicate} withid $docid} msg opts] |
||||||
|
lappend result $err {*}[ecinfo $opts] |
||||||
|
}\ |
||||||
|
-cleanup { |
||||||
|
foreach id $docids { |
||||||
|
punk::args::undefine $id 1 |
||||||
|
} |
||||||
|
}\ |
||||||
|
-result [list\ |
||||||
|
1 {PUNKARGS VALIDATION {toomanyarguments 1 index 0}} {} |
||||||
|
] |
||||||
|
|
||||||
|
|
||||||
|
test errsel_value_optional_choice_reject_GAP {GAP: optional choice-restricted value rejecting a word reports generic overflow}\ |
||||||
|
-setup $common -body { |
||||||
|
set docid ::testspace::errsel_value_optional_choice |
||||||
|
set docids [list $docid] |
||||||
|
punk::args::define [list @id -id $docid] @values {subject -type string -optional 1 -choices {build test help}} |
||||||
|
|
||||||
|
set err [catch {punk::args::parse {frobnicate} withid $docid} msg opts] |
||||||
|
lappend result $err {*}[ecinfo $opts] |
||||||
|
}\ |
||||||
|
-cleanup { |
||||||
|
foreach id $docids { |
||||||
|
punk::args::undefine $id 1 |
||||||
|
} |
||||||
|
}\ |
||||||
|
-result [list\ |
||||||
|
1 {PUNKARGS VALIDATION {toomanyarguments 1 index 0}} {} |
||||||
|
] |
||||||
|
|
||||||
|
|
||||||
|
test errsel_value_optional_type_reject_GAP {GAP: optional typed (int) value rejecting a word reports generic overflow}\ |
||||||
|
-setup $common -body { |
||||||
|
set docid ::testspace::errsel_value_optional_type |
||||||
|
set docids [list $docid] |
||||||
|
punk::args::define [list @id -id $docid] @values {num -type integer -optional 1} |
||||||
|
|
||||||
|
set err [catch {punk::args::parse {notanumber} withid $docid} msg opts] |
||||||
|
lappend result $err {*}[ecinfo $opts] |
||||||
|
}\ |
||||||
|
-cleanup { |
||||||
|
foreach id $docids { |
||||||
|
punk::args::undefine $id 1 |
||||||
|
} |
||||||
|
}\ |
||||||
|
-result [list\ |
||||||
|
1 {PUNKARGS VALIDATION {toomanyarguments 1 index 0}} {} |
||||||
|
] |
||||||
|
|
||||||
|
|
||||||
|
test errsel_required_choice_reference {Reference: required choice-restricted args report pointed choiceviolation (leader and value)}\ |
||||||
|
-setup $common -body { |
||||||
|
set docid1 ::testspace::errsel_required_leader |
||||||
|
set docid2 ::testspace::errsel_required_value |
||||||
|
set docids [list $docid1 $docid2] |
||||||
|
punk::args::define [list @id -id $docid1] {@leaders -min 0 -max 1} {subcommand -type string -optional 0 -choices {build test help}} |
||||||
|
punk::args::define [list @id -id $docid2] @values {subject -type string -optional 0 -choices {build test help}} |
||||||
|
|
||||||
|
set err [catch {punk::args::parse {frobnicate} withid $docid1} msg opts] |
||||||
|
lappend result $err {*}[ecinfo $opts] |
||||||
|
lappend result [string match "Leading argument 'subcommand' for*must be one of the listed values:*Received: 'frobnicate'*" $msg] |
||||||
|
|
||||||
|
set err [catch {punk::args::parse {frobnicate} withid $docid2} msg opts] |
||||||
|
lappend result $err {*}[ecinfo $opts] |
||||||
|
lappend result [string match "Trailing argument 'subject' for*must be one of the listed values:*Received: 'frobnicate'*" $msg] |
||||||
|
}\ |
||||||
|
-cleanup { |
||||||
|
foreach id $docids { |
||||||
|
punk::args::undefine $id 1 |
||||||
|
} |
||||||
|
}\ |
||||||
|
-result [list\ |
||||||
|
1 {PUNKARGS VALIDATION {choiceviolation frobnicate choices {build test help}}} {-badarg subcommand -badval frobnicate} 1\ |
||||||
|
1 {PUNKARGS VALIDATION {choiceviolation frobnicate choices {build test help}}} {-badarg subject -badval frobnicate} 1 |
||||||
|
] |
||||||
|
|
||||||
|
|
||||||
|
test errsel_genuine_surplus {Genuinely-surplus words still report toomanyarguments (all optionals satisfied or none defined)}\ |
||||||
|
-setup $common -body { |
||||||
|
set docid1 ::testspace::errsel_surplus_after_choice |
||||||
|
set docid2 ::testspace::errsel_surplus_no_names |
||||||
|
set docids [list $docid1 $docid2] |
||||||
|
punk::args::define [list @id -id $docid1] @values {subject -type string -optional 1 -choices {build test help}} |
||||||
|
punk::args::define [list @id -id $docid2] @values |
||||||
|
|
||||||
|
#subject satisfied by 'build' - 'extra' is genuinely surplus |
||||||
|
set err [catch {punk::args::parse {build extra} withid $docid1} msg opts] |
||||||
|
lappend result $err {*}[ecinfo $opts] |
||||||
|
|
||||||
|
#no value names defined at all |
||||||
|
set err [catch {punk::args::parse {extra} withid $docid2} msg opts] |
||||||
|
lappend result $err {*}[ecinfo $opts] |
||||||
|
}\ |
||||||
|
-cleanup { |
||||||
|
foreach id $docids { |
||||||
|
punk::args::undefine $id 1 |
||||||
|
} |
||||||
|
}\ |
||||||
|
-result [list\ |
||||||
|
1 {PUNKARGS VALIDATION {toomanyarguments 2 index 1}} {}\ |
||||||
|
1 {PUNKARGS VALIDATION {toomanyarguments 1 index 0}} {} |
||||||
|
] |
||||||
|
|
||||||
|
|
||||||
|
test errsel_rejected_word_lands_later {A word rejected by an optional choice arg but consumed by a later slot parses cleanly}\ |
||||||
|
-setup $common -body { |
||||||
|
set docid ::testspace::errsel_word_lands_later |
||||||
|
set docids [list $docid] |
||||||
|
punk::args::define [list @id -id $docid] @values {subject -type string -optional 1 -choices {build test help}} {other -type string -optional 1} |
||||||
|
|
||||||
|
set argd [punk::args::parse {frobnicate} withid $docid] |
||||||
|
lappend result [dict get $argd values] |
||||||
|
}\ |
||||||
|
-cleanup { |
||||||
|
foreach id $docids { |
||||||
|
punk::args::undefine $id 1 |
||||||
|
} |
||||||
|
}\ |
||||||
|
-result [list\ |
||||||
|
{other frobnicate} |
||||||
|
] |
||||||
|
|
||||||
|
|
||||||
|
test errsel_multiform_selection {Multiform failures still route through rank_form_failures (noformmatch)}\ |
||||||
|
-setup $common -body { |
||||||
|
set docid ::testspace::errsel_multiform |
||||||
|
set docids [list $docid] |
||||||
|
punk::args::define [list @id -id $docid] {@form -form {A B}} {@leaders -form A -min 0 -max 1} {subcommand -form A -type string -optional 1 -choices {build test help}} {@values -form B -min 1 -max 1} {num -form B -type int} |
||||||
|
|
||||||
|
set err [catch {punk::args::parse {frobnicate} withid $docid} msg opts] |
||||||
|
set ec [dict get $opts -errorcode] |
||||||
|
lappend result $err [lrange $ec 0 1] [lindex $ec 2 0] |
||||||
|
}\ |
||||||
|
-cleanup { |
||||||
|
foreach id $docids { |
||||||
|
punk::args::undefine $id 1 |
||||||
|
} |
||||||
|
}\ |
||||||
|
-result [list\ |
||||||
|
1 {PUNKARGS VALIDATION} noformmatch |
||||||
|
] |
||||||
|
} |
||||||
|
tcltest::cleanupTests ;#needed to produce test summary line. |
||||||
Loading…
Reference in new issue