Browse Source
New per-argument key -choiceunavailable <list>: names recognised but not
available in the current runtime/context. Entries display among the
choices under a dedicated "Unavailable (recognised, not selectable
here)" group (one rendering-side injection - both renderers,
choicelabels notes, choiceinfo markers, trie prefix marking and
value-in-effect exclusion all inherited) and join the prefix pools;
synopsis literals and goodchoice marking never include them. Resolve
-time validation: no collision with choices/alias names/reservelist,
-default may not be unavailable, requires -choices/-choicegroups.
choiceword_match gains an optional 8th argument and an 'unavailable'
result key (matched stays 0 - matched-only consumers unaffected):
exact, nocase and unique-prefix landings carry the name as canonical; a
prefix shared with an available choice stays plain-ambiguous.
Validation rejects a landing with the tailored PUNKARGS VALIDATION
{choiceunavailable <name> choices <list>} error (-badarg/-badval;
private::unavailable_choice_msg names the supplied word, the resolved
entry, its choicelabel note and the available values; shared by final
validation and both G-082 overflow raise sites via rejection kind
'unavailable' from the allocation screen). Ambiguity messages annotate
unavailable longer matches '(recognised but unavailable)';
-choicerestricted 0 keeps full passthrough.
tclcore 'string is' adoption: curated forward list {dict} ('unicode'
deliberately excluded) diffed against the define-time harvest; labels
and per-class virtual ids extend to unavailable classes. On Tcl 8.6:
dict displays with its "(class not present in Tcl 8.6)" note,
'string is dict' rejects informatively, 'string is di' is ambiguous
(deliberately stricter than real 8.6 - recorded as a user-sanctioned
parity exemption; full words parity-true), and 'i string is dict'
documents via the virtual id. punk::ns cmd_traverse passes the key at
both resolver sites (doc-walk parity; the choice-traverse comment now
documents the choice-resolution vs doc-addressing axes split). tclcore
moduledoc requires punk::args 0.16.0-.
Tests: new choiceunavailable.test (10 tests); usagemarking.test gains
the goodchoice-exclusion pin; tclcoreparity.test gains forward-class
adoption invariants and the sanctioned 'di' strictness exemption, with
the version_notes pin deliberately flipped (dict's label now renders on
every runtime). Green: the three suites 37/37 on native Tcl 8.6.10
(luck runtime), 8.7a6 and 9.0.3; punk/args subtree 293/290/3 skips/0
fail on 9.0.3 AND 8.7; modules/punk sweep green except the three
documented pre-existing box-baseline failures (grepstr x2, nslist x1);
ns cmdhelp/corp 58/58 after the comment clarification.
Goals: G-073 flipped achieved 2026-08-05 + archived (index record
moved, detail file to goals/archive with Progress/verification and 3
follow-ons). G-166 drafted [proposed] at user direction (approved
wording): cmdinfo availability key + cmdhelp marking + tclcore leading
note + prefix-landing decision; the enacted G-073 follow-on flipped
=> goal G-166, the G-055 pattern follow-on => goal G-055 with a Notes
pointer added there. goals_lint clean. punkshell 0.54.0 + CHANGELOG.
Bootsupport/vfscommon snapshots unchanged until promotion + bake.
Claude-Session: https://claude.ai/code/session_01QgaxV27VZkmEec7oNbEVFc
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
16 changed files with 823 additions and 38 deletions
@ -0,0 +1,84 @@
|
||||
# G-166 cmdinfo/cmdhelp surface recognised-but-unavailable landings distinctly |
||||
|
||||
Status: proposed |
||||
Scope: src/modules/punk/ns-999999.0a1.0.tm (cmdinfo result key, cmd_traverse landing attribution, cmdhelp render marking + advisory-parse presentation); src/modules/punk/args/moduledoc/tclcore-999999.0a1.0.tm (virtual ids lead with the unavailability note on affected runtimes); src/tests/modules/punk/ns/testsuites/ns/ (cmdinfo/cmdhelp pins incl the deliberate key-list flip); src/tests/modules/punk/args/testsuites/args/tclcoreparity.test (8.6-arm pins) |
||||
Goal: cmdinfo/cmdhelp surface recognised-but-unavailable landings: cmdinfo gains an availability key (empty, or the canonical unavailable word) populated wherever resolution addresses a -choiceunavailable word (exact space-form docid landings and the choice traverse), cmdhelp marks such subjects visibly in all return forms and its advisory parse no longer presents them as cleanly usable, the tclcore virtual ids lead with the unavailability note on affected runtimes, and the doc walk's treatment of a unique prefix landing on an unavailable name (currently: resolves no documentation) is decided and pinned within this goal - with the enacted G-073 follow-on items dispositioned accordingly. |
||||
Acceptance: on a runtime where the tclcore model declares dict unavailable (Tcl 8.6), cmdinfo for 'string is dict' (direct and decomposed invocation forms) reports the new availability key carrying 'dict' while 'string is true' reports it empty, with cmdtype remaining 'doconly' for both (the command-kind axis is not overloaded); the key is present on every cmdinfo result and the cmdhelp.test cmdinfo key-list pin is flipped deliberately; cmdhelp output for an unavailable subject is visibly distinguished in table, text and dict return forms (the dict form carries the key; table/text carry a marking naming the unavailability), and an argument tail such as 'string is dict 5' no longer renders as a cleanly usable command line; the walk's unique-prefix landing on an unavailable name ('i string is dic' on 8.6) has a decided, pinned behaviour consistent with the marking (either resolving the virtual docid WITH the marking, or documented-conservative non-resolution); tclcore virtual ids for unavailable classes lead their rendered help with the unavailability statement on affected runtimes (first description line, not buried mid-prose) while modern runtimes render those ids unchanged; definitions without -choiceunavailable and existing cmdinfo/cmdhelp consumers behave unchanged (full punk/ns and punk/args suites green apart from deliberately flipped pins); the enacted G-073 Follow-on lines carry => goal G-166 dispositions. |
||||
|
||||
## Context |
||||
|
||||
Found 2026-08-05 immediately after G-073 achieved (user probes): on Tcl 8.6, |
||||
'i ::tcl::string::is dict' (unavailable class) and 'i ::tcl::string::is true' |
||||
(real class) produce indistinguishable machine shapes - cmdinfo reports |
||||
cmdtype 'doconly' with identical key sets for both, and cmdhelp's advisory |
||||
parse of an argument tail ('string is dict 5') succeeds against the virtual id |
||||
so the render presents the unavailable class exactly like a usable one. The |
||||
only difference is the "(class not present in Tcl 8.6)" sentence mid-way |
||||
through the description prose. |
||||
|
||||
Half of this is G-073's intent: documentation REACHABILITY for unavailable |
||||
words (via exact space-form virtual docids) is an acceptance requirement, and |
||||
doc addressing has always been deliberately broader than parse acceptance |
||||
(per-class ids like 'string is true' document argument words that were never |
||||
subcommands). The INDISTINGUISHABILITY is emergent, not specified: nothing |
||||
structural tells a consumer - human or machine - that the documented word is |
||||
rejected by this runtime's parse. |
||||
|
||||
Axis decision (assessed 2026-08-05, to be confirmed in the work): a NEW |
||||
cmdinfo key, not a cmdtype refinement such as 'doconly_unavailable'. cmdtype |
||||
answers "what kind of executable thing did resolution land on"; availability |
||||
is a property of the resolved word at its level. Today they co-occur with |
||||
doconly only incidentally (unavailable entries never have real commands behind |
||||
them), and overloading the value breaks consumers switching on |
||||
cmdtype eq "doconly". The two-axes distinction is recorded in the cmd_traverse |
||||
choice-traverse comment (ns 0.9.3). |
||||
|
||||
## Approach |
||||
|
||||
- New cmdinfo result key (spelling decided in the work; candidate |
||||
'unavailable' - empty string normally, the canonical unavailable word when |
||||
the resolution addressed one). Population is nearly free: the choice |
||||
traverse already holds the resolver's matchinfo (its 'unavailable' key, |
||||
punk::args 0.16.0), and the exact space-form id landing branches can consult |
||||
the level's choices-bearing arginfo the same way the space-form prefix-parity |
||||
branch (G-051, achieved 2026-07-13 - see |
||||
goals/archive/G-051-cmdinfo-pseudo-and-prefix.md) already does |
||||
(Dict_getdef -choiceunavailable + membership check). |
||||
- cmdhelp derives the render marking from the same data: a visible |
||||
unavailability statement in table/text forms (warn styling; placement decided |
||||
in the work - title line marker and/or a leading line), the key in -return |
||||
dict, and the advisory-parse presentation adjusted so an accepted parse |
||||
against an unavailable subject's virtual id is not shown as a cleanly usable |
||||
command line. |
||||
- tclcore generator: on runtimes where a forward class is unavailable, the |
||||
per-class virtual id's help LEADS with the unavailability statement (the |
||||
static description follows); modern runtimes generate the id unchanged. |
||||
- Prefix-landing decision: either the walk resolves a unique prefix landing to |
||||
the virtual docid and relies on the marking to carry the rejection story |
||||
(parse gives the tailored "resolves to 'dict'" report for the same word), or |
||||
the current conservative non-resolution is kept and pinned as deliberate. |
||||
Decided in the work; the G-073 follow-on line flips accordingly. |
||||
|
||||
## Notes |
||||
|
||||
- Related: G-073 (achieved 2026-08-05, archived - |
||||
goals/archive/G-073-punkargs-unavailable-choices.md) - this goal enacts its |
||||
open follow-on on doc-walk prefix landings and resolves the |
||||
indistinguishability its acceptance did not specify; the -choiceunavailable |
||||
key, resolver indication and tailored parse rejection this goal consumes all |
||||
landed there (punk::args 0.16.0, tclcore moduledoc 0.4.0, ns 0.9.3). |
||||
- Related: G-050 (punk::ns::synopsis argument-validity marking and |
||||
status-aware returns) - sibling display-marking surface; whichever lands |
||||
second should reuse the first's marking vocabulary/styling decisions. |
||||
- Related: G-044 (completion/hinting) - a future consumer: completion over |
||||
choices should be able to exclude or annotate unavailable words from the |
||||
same data rather than re-deriving. |
||||
- Related: G-055 (tclcore moduledoc regeneration workflow) - the tclcore |
||||
virtual-id leading-note change lands in the moduledoc G-055's workflow |
||||
governs; its guidance gains the forward-class pattern per the G-073 |
||||
follow-on already dispositioned => goal G-055. |
||||
- Overlap survey 2026-08-05: goals_xref paths src/modules/punk/ns-999999.0a1.0.tm |
||||
- G-044/G-050/G-052/G-075/G-085 surfaced; G-052 (TclOO autodef) and G-085 |
||||
(cmdtrace) are same-file unrelated concerns; G-075 ((package) ids) is |
||||
sibling docid territory with no word-availability interaction - deliberate |
||||
non-overlap. |
||||
@ -0,0 +1,272 @@
|
||||
|
||||
package require tcltest |
||||
package require punk::args |
||||
package require punk::ansi |
||||
|
||||
#added 2026-08-05 (agent, G-073) - -choiceunavailable: recognised-but-unavailable choice |
||||
#names (goals/G-073-punkargs-unavailable-choices.md). Covers the shared resolver's |
||||
#distinct 'unavailable' indication (punk::args::choiceword_match 8th argument), |
||||
#definition-resolve validation, the tailored choiceunavailable rejection at final |
||||
#validation and via the G-082 allocation-rejection seam, prefix-ambiguity |
||||
#participation, -choicerestricted 0 passthrough, parse_status classification/marking, |
||||
#renderer display (dedicated Unavailable group in table and string forms), synopsis |
||||
#choice-literal exclusion and value-in-effect exclusion. The in-tree adopter (tclcore |
||||
#'string is' forward classes) is pinned in tclcoreparity.test. |
||||
namespace eval ::testspace { |
||||
namespace import ::tcltest::* |
||||
variable common { |
||||
set result "" |
||||
} |
||||
|
||||
#SGR colour generation is gated by punk::console colour state (e.g NO_COLOR env) - |
||||
#force colour on for deterministic value-in-effect marking output (as usagemarking.test) |
||||
catch {package require punk::console} |
||||
if {[info commands ::punk::console::colour] ne ""} { |
||||
punk::console::colour on |
||||
} |
||||
|
||||
#slim an errorcode: classification triple plus -badarg/-badval extras (drop -argspecs) |
||||
proc cu_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 cu_resolver_indication {choiceword_match reports unavailable landings distinctly: exact/unique-prefix/nocase land, shared prefixes stay plain ambiguous non-matches, 7-arg calls are unchanged}\ |
||||
-setup $common -body { |
||||
#exact landing |
||||
lappend result [punk::args::choiceword_match dict 0 {digit double} {} 1 {} {} {dict}] |
||||
#unique prefix landing |
||||
lappend result [punk::args::choiceword_match dic 0 {digit double} {} 1 {} {} {dict}] |
||||
#prefix shared between available (digit) and unavailable (dict): plain ambiguous |
||||
lappend result [punk::args::choiceword_match di 0 {digit double} {} 1 {} {} {dict}] |
||||
#available word matching is unaffected by the pool addition |
||||
lappend result [punk::args::choiceword_match do 0 {digit double} {} 1 {} {} {dict}] |
||||
#nocase exact + nocase prefix landings report the defined casing |
||||
lappend result [punk::args::choiceword_match DICT 1 {digit double} {} 1 {} {} {dict}] |
||||
lappend result [punk::args::choiceword_match DIC 1 {digit double} {} 1 {} {} {dict}] |
||||
#-choiceprefix 0: exact landing only - a prefix word is a plain non-match |
||||
lappend result [punk::args::choiceword_match dict 0 {digit double} {} 0 {} {} {dict}] |
||||
lappend result [punk::args::choiceword_match dic 0 {digit double} {} 0 {} {} {dict}] |
||||
#backward-compat: 7-argument call shape (no unavailablelist) |
||||
lappend result [punk::args::choiceword_match digit 0 {digit double} {} 1 {} {}] |
||||
}\ |
||||
-cleanup { |
||||
}\ |
||||
-result [list\ |
||||
{matched 0 exact 0 canonical dict unavailable 1}\ |
||||
{matched 0 exact 0 canonical dict unavailable 1}\ |
||||
{matched 0 exact 0 canonical {} unavailable 0}\ |
||||
{matched 1 exact 0 canonical double unavailable 0}\ |
||||
{matched 0 exact 0 canonical dict unavailable 1}\ |
||||
{matched 0 exact 0 canonical dict unavailable 1}\ |
||||
{matched 0 exact 0 canonical dict unavailable 1}\ |
||||
{matched 0 exact 0 canonical {} unavailable 0}\ |
||||
{matched 1 exact 1 canonical digit unavailable 0}\ |
||||
] |
||||
|
||||
test cu_resolve_validation_errors {definition resolve rejects colliding/orphaned -choiceunavailable declarations and an unavailable -default}\ |
||||
-setup $common -body { |
||||
#resolve is lazy - parsing a valid word forces it |
||||
foreach {label def} { |
||||
collision {{class -type string -choices {digit dict} -choiceunavailable {dict}}} |
||||
nochoices {{class -type string -choiceunavailable {dict}}} |
||||
default {{class -type string -choices {digit} -default dict -choiceunavailable {dict}}} |
||||
alias {{class -type string -choices {digit} -choicealiases {dict digit} -choiceunavailable {dict}}} |
||||
reserve {{class -type string -choices {digit} -choiceprefixreservelist {dict} -choiceunavailable {dict}}} |
||||
} { |
||||
set docid ::testspace::cu_badresolve_$label |
||||
punk::args::define [list @id -id $docid] @values {*}$def |
||||
set err [catch {punk::args::parse {digit} withid $docid} msg] |
||||
lappend result $label:$err:[string match "*-choiceunavailable*" $msg][string match "*punk::args::resolve*" $msg] |
||||
punk::args::undefine $docid 1 |
||||
} |
||||
set result |
||||
}\ |
||||
-cleanup { |
||||
}\ |
||||
-result [list collision:1:11 nochoices:1:11 default:1:11 alias:1:11 reserve:1:11] |
||||
|
||||
test cu_required_tailored_rejection {a word landing on an unavailable name (exact or unique prefix; leader, value or option position) reports the tailored choiceunavailable error naming the entry and its choicelabel note}\ |
||||
-setup $common -body { |
||||
set docid1 ::testspace::cu_reqleader |
||||
set docid2 ::testspace::cu_reqvalue |
||||
set docid3 ::testspace::cu_reqopt |
||||
set docids [list $docid1 $docid2 $docid3] |
||||
punk::args::define [list @id -id $docid1] {@leaders -min 1 -max 1} {class -type string -choices {digit double integer} -choicelabels {dict " (class not present in\n this runtime)"} -choiceunavailable {dict}} {@values -min 1 -max 1} {str -type string -optional 0} |
||||
punk::args::define [list @id -id $docid2] {@values -min 1 -max 1} {kind -type string -choices {alpha beta} -choicelabels {gamma "(requires the frobnitz build)"} -choiceunavailable {gamma}} |
||||
punk::args::define [list @id -id $docid3] @opts {-mode -type string -choices {fast safe} -choiceunavailable {turbo}} {@values -min 0 -max 0} |
||||
|
||||
#exact landing - leader position |
||||
set err [catch {punk::args::parse {dict xxx} withid $docid1} msg opts] |
||||
lappend result $err {*}[cu_ecinfo $opts] |
||||
lappend result [string match "*'dict' is a recognised name here, but is not available*" $msg] |
||||
lappend result [string match "*class not present in*" $msg] |
||||
|
||||
#unique-prefix landing - message names both the supplied word and the resolved entry |
||||
set err [catch {punk::args::parse {dic xxx} withid $docid1} msg opts] |
||||
lappend result $err {*}[cu_ecinfo $opts] |
||||
lappend result [string match "*'dic' resolves to 'dict'*not available*" $msg] |
||||
|
||||
#value position, with the note steering to the why |
||||
set err [catch {punk::args::parse {gamma} withid $docid2} msg opts] |
||||
lappend result $err {*}[cu_ecinfo $opts] |
||||
lappend result [string match "*requires the frobnitz build*" $msg] |
||||
|
||||
#option-value position |
||||
set err [catch {punk::args::parse {-mode turbo} withid $docid3} msg opts] |
||||
lappend result $err {*}[cu_ecinfo $opts] |
||||
}\ |
||||
-cleanup { |
||||
foreach id $docids { |
||||
punk::args::undefine $id 1 |
||||
} |
||||
}\ |
||||
-result [list\ |
||||
1 {PUNKARGS VALIDATION {choiceunavailable dict choices {digit double integer}}} {-badarg class -badval dict} 1 1\ |
||||
1 {PUNKARGS VALIDATION {choiceunavailable dict choices {digit double integer}}} {-badarg class -badval dic} 1\ |
||||
1 {PUNKARGS VALIDATION {choiceunavailable gamma choices {alpha beta}}} {-badarg kind -badval gamma} 1\ |
||||
1 {PUNKARGS VALIDATION {choiceunavailable turbo choices {fast safe}}} {-badarg -mode -badval turbo}\ |
||||
] |
||||
|
||||
test cu_shared_prefix_ambiguous {a prefix shared between an available and an unavailable name is rejected as an ambiguous choiceviolation, with the unavailable match annotated in the message}\ |
||||
-setup $common -body { |
||||
set docid ::testspace::cu_ambig |
||||
set docids [list $docid] |
||||
punk::args::define [list @id -id $docid] {@leaders -min 1 -max 1} {class -type string -choices {digit double integer} -choiceunavailable {dict}} {@values -min 1 -max 1} {str -type string -optional 0} |
||||
|
||||
set err [catch {punk::args::parse {di xxx} withid $docid} msg opts] |
||||
lappend result $err [lindex [lindex [dict get $opts -errorcode] 2] 0] |
||||
lappend result [string match "*ambiguous prefix*" $msg] |
||||
lappend result [string match "*dict (recognised but unavailable)*" $msg] |
||||
#an unknown word keeps the plain listed-values choiceviolation |
||||
set err [catch {punk::args::parse {zebra xxx} withid $docid} msg opts] |
||||
lappend result $err [lindex [lindex [dict get $opts -errorcode] 2] 0] |
||||
lappend result [string match "*must be one of the listed values*" $msg] |
||||
}\ |
||||
-cleanup { |
||||
foreach id $docids { |
||||
punk::args::undefine $id 1 |
||||
} |
||||
}\ |
||||
-result [list 1 choiceviolation 1 1 1 choiceviolation 1] |
||||
|
||||
test cu_optional_overflow_seam {an OPTIONAL argument's unavailable landing surfaces the tailored error through the G-082 allocation-rejection seam instead of the generic overflow}\ |
||||
-setup $common -body { |
||||
set docid ::testspace::cu_optseam |
||||
set docids [list $docid] |
||||
punk::args::define [list @id -id $docid] {@values -min 0 -max -1} {kind -type string -optional 1 -choices {alpha beta} -choiceunavailable {gamma}} |
||||
|
||||
set err [catch {punk::args::parse {gamma} withid $docid} msg opts] |
||||
lappend result $err {*}[cu_ecinfo $opts] |
||||
lappend result [string match "*'gamma' is a recognised name here, but is not available*" $msg] |
||||
#a plain unknown word keeps the G-082 pointed choiceviolation |
||||
set err [catch {punk::args::parse {zebra} withid $docid} msg opts] |
||||
lappend result $err [lindex [lindex [dict get $opts -errorcode] 2] 0] |
||||
}\ |
||||
-cleanup { |
||||
foreach id $docids { |
||||
punk::args::undefine $id 1 |
||||
} |
||||
}\ |
||||
-result [list\ |
||||
1 {PUNKARGS VALIDATION {choiceunavailable gamma choices {alpha beta}}} {-badarg kind -badval gamma} 1\ |
||||
1 choiceviolation\ |
||||
] |
||||
|
||||
test cu_choicerestricted0_passthrough {with -choicerestricted 0 an unavailable name passes through as an ordinary value - no tailored rejection}\ |
||||
-setup $common -body { |
||||
set docid ::testspace::cu_unrestricted |
||||
set docids [list $docid] |
||||
punk::args::define [list @id -id $docid] {@values -min 1 -max 1} {word -type string -choices {alpha} -choicerestricted 0 -choiceunavailable {gamma}} |
||||
set argd [punk::args::parse {gamma} withid $docid] |
||||
lappend result [dict get $argd values] |
||||
}\ |
||||
-cleanup { |
||||
foreach id $docids { |
||||
punk::args::undefine $id 1 |
||||
} |
||||
}\ |
||||
-result [list {word gamma}] |
||||
|
||||
test cu_parse_status_classification {parse_status reports an unavailable landing as invalid/choiceunavailable with the argument badarg-marked}\ |
||||
-setup $common -body { |
||||
set docid ::testspace::cu_pstat |
||||
set docids [list $docid] |
||||
punk::args::define [list @id -id $docid] {@values -min 1 -max 1} {kind -type string -choices {alpha beta} -choiceunavailable {gamma}} |
||||
set ps [punk::args::parse_status {gamma} withid $docid] |
||||
lappend result [dict get $ps ok] [dict get $ps status] [dict get $ps scheme] |
||||
lappend result [dict get $ps failureclass] [dict get $ps badarg] |
||||
lappend result [dict get $ps argstatus kind status] [dict get $ps argstatus kind failureclass] |
||||
}\ |
||||
-cleanup { |
||||
foreach id $docids { |
||||
punk::args::undefine $id 1 |
||||
} |
||||
}\ |
||||
-result [list 0 invalid error choiceunavailable kind bad choiceunavailable] |
||||
|
||||
test cu_render_group_and_note {both renderers display unavailable entries among the choices under the dedicated Unavailable group heading with their choicelabel notes}\ |
||||
-setup $common -body { |
||||
set docid ::testspace::cu_render |
||||
set docids [list $docid] |
||||
punk::args::define [list @id -id $docid] {@values -min 1 -max 1} {kind -type string -choices {alpha beta} -choicelabels {gamma "(requires the frobnitz build)"} -choiceunavailable {gamma}} |
||||
set tbl [punk::ansi::ansistrip [punk::args::arg_error "" [punk::args::get_spec $docid] -aserror 0]] |
||||
lappend result [string match "*Unavailable (recognised, not selectable here)*" $tbl] |
||||
lappend result [string match "*gamma*" $tbl] |
||||
lappend result [string match "*requires the frobnitz build*" $tbl] |
||||
set str [punk::ansi::ansistrip [punk::args::arg_error "" [punk::args::get_spec $docid] -aserror 0 -return string]] |
||||
lappend result [string match "*Group 'Unavailable (recognised, not selectable here)':*" $str] |
||||
lappend result [string match "*- `gamma`*" $str] |
||||
lappend result [string match "*requires the frobnitz build*" $str] |
||||
}\ |
||||
-cleanup { |
||||
foreach id $docids { |
||||
punk::args::undefine $id 1 |
||||
} |
||||
}\ |
||||
-result [list 1 1 1 1 1 1] |
||||
|
||||
test cu_synopsis_literal_exclusion {synopsis choice-literal display excludes unavailable entries (a small available set still renders as literal alternates)}\ |
||||
-setup $common -body { |
||||
set docid ::testspace::cu_syn |
||||
set docids [list $docid] |
||||
punk::args::define [list @id -id $docid] {@cmd -name testspace::cu_syn} {@values -min 1 -max 1} {kind -type string -choices {alpha beta} -choiceunavailable {gamma}} |
||||
set syn [punk::ansi::ansistrip [punk::args::synopsis $docid]] |
||||
lappend result [string match "*alpha|beta*" $syn] |
||||
lappend result [string match "*gamma*" $syn] |
||||
}\ |
||||
-cleanup { |
||||
foreach id $docids { |
||||
punk::args::undefine $id 1 |
||||
} |
||||
}\ |
||||
-result [list 1 0] |
||||
|
||||
#value-in-effect/goodchoice highlighting exclusion is pinned in usagemarking.test |
||||
#(usagemarking_goodchoice_unavailable_never_marked) - the SGR-marking helpers live |
||||
#there. The structural half of the guarantee is pinned here: an unavailable name can |
||||
#be neither a parsed value (tailored rejection above) nor a -default |
||||
#(cu_resolve_validation_errors 'default' case). |
||||
test cu_parse_result_never_carries_unavailable {successful parses of every non-rejecting shape yield values from the available set only}\ |
||||
-setup $common -body { |
||||
set docid ::testspace::cu_novalue |
||||
set docids [list $docid] |
||||
punk::args::define [list @id -id $docid] {@values -min 0 -max -1} {kind -type string -optional 1 -choices {alpha beta} -default alpha -choiceunavailable {gamma}} |
||||
#unsupplied: default in effect |
||||
lappend result [dict get [punk::args::parse {} withid $docid] values kind] |
||||
#supplied available choice |
||||
lappend result [dict get [punk::args::parse {beta} withid $docid] values kind] |
||||
}\ |
||||
-cleanup { |
||||
foreach id $docids { |
||||
punk::args::undefine $id 1 |
||||
} |
||||
}\ |
||||
-result [list alpha beta] |
||||
} |
||||
tcltest::cleanupTests ;#needed to produce test summary line. |
||||
Loading…
Reference in new issue