Browse Source
First 'i <ensemble>' in a fresh shell (e.g 'i ansistring') rendered the autogenerated ensemble help without subcommand-help markers/choicelabels: ensemble_subcommands_definition tested punk::args::id_exists against argdocs whose registered namespace (::punk::args::register::NAMESPACES) had not yet been lazily loaded - the punk::ns doc-lookup entry path only loads the ensemble command's parent namespace. The generator now runs update_definitions for the namespaces its id checks could resolve in. Self-healed on later calls (autodef regenerates per 'i' invocation), which is why the defect went unnoticed; no prior test pinned the load ordering. Tests: punk/args ensembledef.test (new), punk/ns cmdhelp.test cmdhelp_ensemble_lazy_registered_argdocs. Project 0.4.14. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.commaster
6 changed files with 144 additions and 2 deletions
@ -1,3 +1,3 @@ |
|||||||
[project] |
[project] |
||||||
name = "punkshell" |
name = "punkshell" |
||||||
version = "0.4.13" |
version = "0.4.14" |
||||||
|
|||||||
@ -0,0 +1,81 @@ |
|||||||
|
package require tcltest |
||||||
|
|
||||||
|
package require punk::args |
||||||
|
package require punk::ns |
||||||
|
package require punk::ansi |
||||||
|
|
||||||
|
#ensemble_subcommands_definition lazy-argdoc ordering - added 2026-07-10 (defect found |
||||||
|
#via 'i ansistring' in a fresh shell: the autogenerated ensemble help rendered without |
||||||
|
#subcommand-help markers/choicelabels until punk::args::update_definitions was run for |
||||||
|
#::punk::ansi::ansistring by some other path). |
||||||
|
#Root cause: punk::args::ensemble_subcommands_definition decides subhelp/doctype-punkargs |
||||||
|
#choiceinfo entries and synopsis choicelabels via bare punk::args::id_exists checks, and |
||||||
|
#id_exists only sees definitions already loaded. Registered argdocs |
||||||
|
#(::punk::args::register::NAMESPACES) load lazily, and the punk::ns doc-lookup entry path |
||||||
|
#only loads [namespace qualifiers $ensemblecommand] - the parent namespace - never the |
||||||
|
#ensemble's own registered namespace where subcommand argdocs conventionally live. |
||||||
|
#The generator must load the namespaces its id checks could resolve in before testing. |
||||||
|
|
||||||
|
namespace eval ::testspace { |
||||||
|
namespace import ::tcltest::* |
||||||
|
variable common { |
||||||
|
set result "" |
||||||
|
} |
||||||
|
|
||||||
|
#fixture: module-style ensemble whose subcommand argdocs are registered for lazy |
||||||
|
#loading (as punk::ansi does for ::punk::ansi::ansistring) but never explicitly |
||||||
|
#loaded by this file before the generator runs. |
||||||
|
namespace eval ::testspace::ensdeflazy { |
||||||
|
namespace export alpha beta |
||||||
|
namespace eval argdoc { |
||||||
|
variable PUNKARGS |
||||||
|
lappend PUNKARGS [list { |
||||||
|
@id -id ::testspace::ensdeflazy::alpha |
||||||
|
@cmd -name testspace::ensdeflazy::alpha -summary\ |
||||||
|
"Lazy ensemble alpha fixture."\ |
||||||
|
-help\ |
||||||
|
"alpha help." |
||||||
|
@values -min 1 -max 1 |
||||||
|
zzduration -type integer -help\ |
||||||
|
"distinctive argument name for rendered-output assertions." |
||||||
|
}] |
||||||
|
} |
||||||
|
proc alpha {zzduration} {return alpha-$zzduration} |
||||||
|
proc beta {} {return beta} |
||||||
|
namespace ensemble create |
||||||
|
} |
||||||
|
lappend ::punk::args::register::NAMESPACES ::testspace::ensdeflazy |
||||||
|
|
||||||
|
test ensembledef_lazy_registered_argdocs_first_call {first ensemble_subcommands_definition call loads registered-but-unloaded subcommand argdocs itself: documented subcommand gets subhelp/doctype-punkargs choiceinfo, undocumented does not}\ |
||||||
|
-setup $common -body { |
||||||
|
#precondition: argdoc registered but not yet loaded (id_exists is a pure |
||||||
|
#cache lookup with no loading side effect) |
||||||
|
lappend result [punk::args::id_exists ::testspace::ensdeflazy::alpha] |
||||||
|
set vline [punk::args::ensemble_subcommands_definition -columns 1 ::testspace::ensdeflazy] |
||||||
|
#the generator itself must have loaded the registered definitions |
||||||
|
lappend result [punk::args::id_exists ::testspace::ensdeflazy::alpha] |
||||||
|
#documented subcommand marked |
||||||
|
lappend result [string match {*subhelp ::testspace::ensdeflazy::alpha*} $vline] |
||||||
|
lappend result [string match {*doctype punkargs*} $vline] |
||||||
|
#undocumented subcommand not marked |
||||||
|
lappend result [string match {*subhelp ::testspace::ensdeflazy::beta*} $vline] |
||||||
|
#choicelabel (synopsis) generated for the documented subcommand |
||||||
|
lappend result [string match {*zzduration*} $vline] |
||||||
|
}\ |
||||||
|
-cleanup { |
||||||
|
}\ |
||||||
|
-result [list 0 1 1 1 0 1] |
||||||
|
|
||||||
|
test ensembledef_loaded_argdocs_stable {a repeat call after the definitions are loaded produces the same marked definition (loaded-path regression guard)}\ |
||||||
|
-setup $common -body { |
||||||
|
punk::args::update_definitions [list ::testspace::ensdeflazy] |
||||||
|
set vline [punk::args::ensemble_subcommands_definition -columns 1 ::testspace::ensdeflazy] |
||||||
|
lappend result [string match {*subhelp ::testspace::ensdeflazy::alpha*} $vline] |
||||||
|
lappend result [string match {*doctype punkargs*} $vline] |
||||||
|
lappend result [string match {*zzduration*} $vline] |
||||||
|
}\ |
||||||
|
-cleanup { |
||||||
|
}\ |
||||||
|
-result [list 1 1 1] |
||||||
|
} |
||||||
|
tcltest::cleanupTests ;#needed to produce test summary line. |
||||||
Loading…
Reference in new issue