Browse Source
Engine-primitive pins landed green ahead of activating the launcher definition/documentation/help-depth goals (args subtree 321 tests: 318 pass, 3 known-bug skips, 0 fail on native tclsh90 9.0.3 and tcl87): - forms.test: candidacy fencing/fall-through group (G-168 pre-work) - regexprefail-fenced autoselection fixture pin (args-tier twin of the G-150 cmdhelp.test pins), a -regexprefail rejection on an OPTIONAL value slot is form-fatal with NO re-landing on later permissive slots (contrast optional-choice rejection), unknown-option / dangling-option / option-satisfied-but-values-unmet failures fall through to sibling forms as successful parses, option-VALUE fences participate in candidacy, and the documented per-word limit: a complete '-encoding <name> <file>' line double-matches a fenced scriptfile form vs a dash-tolerant stdin form (stock's scriptfile-wins-when-complete priority is not expressible per-word - multipleformmatches per the G-041 contract). - formviability.test: dangling-OPTIONAL-option verdict conservatism - the G-164 re-probe re-seats only words naming missing REQUIRED options, so the tclsh '-encoding' dangling class stays invalid although completable. - errorselection.test: a dangling optional value-taking option word seats as a trailing value and overflows a zero-value window as plain toomanyarguments (no -badarg attribution). - formcheck.test: GAP before-state pins of the punkexe launch definitions - unsanctioned structural overlaps for script file/oneliner and tclsh scriptfile/stdin, and every primary launch line double-matching; flipped deliberately when G-168 lands per its Acceptance. - docpackages.test (new): registered-namespace lazy definition loading characterization (G-169 pre-work) - inert registration with scan-vs-load split, id_exists never triggers loading, real_id/usage lazily resolve tag-prefixed script-level id families, duplicate definers resolve last-loaded-wins with only a stderr undefine notice (the engine's recorded detect-duplicates todo), degraded paths clean. Goal notes (non-contract): pre-test findings recorded in G-168 (including the '-e'-must-be-a-required-flag declaration constraint and the residual-overlap design limit) and G-169 (handover must withdraw the moduledoc entry in the same change-set - no duplicate warning surface exists); G-170<->G-151 Related: cross-links added both ways - the dry-run arm renders G-151's punk::args-level landing report, a link the path-based overlap surveys could not surface. src/tests/modules AGENTS.md punk/args bullet extended for the new coverage. goals_lint clean (84 active, 86 archived). Claude-Session: https://claude.ai/code/session_0156PuejSCGjgeGb7jiABrDU Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.commaster
10 changed files with 569 additions and 1 deletions
@ -0,0 +1,176 @@
|
||||
package require tcltest |
||||
|
||||
package require punk::args |
||||
|
||||
#Registered-namespace lazy definition loading (docpackages) characterization - |
||||
#added 2026-08-05 ahead of G-169 (app-owned launch-subcommand documentation). |
||||
#A package registers its namespace in ::punk::args::register::NAMESPACES; its |
||||
#PUNKARGS definition lists are then id-SCANNED (cheap, no definition evaluation) |
||||
#on the next punk::args::update_definitions call, and definitions documenting a |
||||
#namespace other than the registering one (moduledoc pattern, including |
||||
#tag-prefixed script-level families like (script)::punkexe::*) are recorded in |
||||
#namespace_docpackages and LOADED only when a query names the documented |
||||
#namespace - punk::args::real_id (and the usage/get_spec surfaces that route |
||||
#through it) trigger the load; punk::args::id_exists never does (documented). |
||||
#Duplicate ids: the engine carries a recorded todo ("detect duplicate ids - |
||||
#last will silently win.. should be reported somewhere") - the last-loaded |
||||
#definition wins, and a redefinition of an id that is already loaded emits a |
||||
#stderr notice from punk::args::undefine ("clearing existing data for id:..."). |
||||
#These pins record the mechanism G-169's app-owned registration + single-definer |
||||
#handover leans on. |
||||
#Fixture registrations mutate the punk::args register state; runtests gives each |
||||
#test file its own testinterp/child, so the registrations stay contained here |
||||
#(ids are undefined in cleanup; namespace registrations are left in place). |
||||
|
||||
namespace eval ::testspace { |
||||
namespace import ::tcltest::* |
||||
variable common { |
||||
set result "" |
||||
} |
||||
|
||||
#added 2026-08-05 (agent, G-169) |
||||
test docpackages_registration_inert {registering a doc-source namespace is inert: an unrelated update_definitions call scans it (id inventory) but loads no definitions and the id stays invisible to id_exists}\ |
||||
-setup $common -body { |
||||
namespace eval ::testspace::dpsrc1 { |
||||
variable PUNKARGS |
||||
lappend PUNKARGS [list { |
||||
@id -id (testdoc)::dpexe::sub |
||||
@cmd -name "dpexe sub" -summary "DOCPKG-SRC1" |
||||
@values -min 0 -max 0 |
||||
}] |
||||
} |
||||
lappend result [punk::args::id_exists (testdoc)::dpexe::sub] |
||||
lappend ::punk::args::register::NAMESPACES ::testspace::dpsrc1 |
||||
lappend result [punk::args::id_exists (testdoc)::dpexe::sub] |
||||
punk::args::update_definitions [list ::testspace::dp_unrelated] |
||||
lappend result [expr {"::testspace::dpsrc1" in $::punk::args::register::scanned_packages}] |
||||
lappend result [expr {"::testspace::dpsrc1" in $::punk::args::register::loaded_packages}] |
||||
lappend result [punk::args::id_exists (testdoc)::dpexe::sub] |
||||
}\ |
||||
-cleanup { |
||||
}\ |
||||
-result [list 0 0 1 0 0] |
||||
|
||||
#added 2026-08-05 (agent, G-169) |
||||
test docpackages_query_triggers_load {a real_id query for the documented (tag-prefixed) id family loads the registered doc-source's definitions and the id becomes resolvable}\ |
||||
-setup $common -body { |
||||
lappend result [punk::args::real_id (testdoc)::dpexe::sub] |
||||
lappend result [expr {"::testspace::dpsrc1" in $::punk::args::register::loaded_packages}] |
||||
lappend result [punk::args::id_exists (testdoc)::dpexe::sub] |
||||
lappend result [string match "*DOCPKG-SRC1*" [punk::args::usage (testdoc)::dpexe::sub]] |
||||
}\ |
||||
-cleanup { |
||||
punk::args::undefine (testdoc)::dpexe::sub 1 |
||||
}\ |
||||
-result [list (testdoc)::dpexe::sub 1 1 1] |
||||
|
||||
#added 2026-08-05 (agent, G-169) |
||||
test docpackages_usage_alone_resolves {punk::args::usage on a never-loaded registered id resolves it lazily with no prior update_definitions call}\ |
||||
-setup $common -body { |
||||
namespace eval ::testspace::dpsrc2 { |
||||
variable PUNKARGS |
||||
lappend PUNKARGS [list { |
||||
@id -id (testdoc)::dpexe::uonly |
||||
@cmd -name "dpexe uonly" -summary "DOCPKG-UONLY" |
||||
@values -min 0 -max 0 |
||||
}] |
||||
} |
||||
lappend ::punk::args::register::NAMESPACES ::testspace::dpsrc2 |
||||
lappend result [punk::args::id_exists (testdoc)::dpexe::uonly] |
||||
lappend result [string match "*DOCPKG-UONLY*" [punk::args::usage (testdoc)::dpexe::uonly]] |
||||
lappend result [punk::args::id_exists (testdoc)::dpexe::uonly] |
||||
}\ |
||||
-cleanup { |
||||
punk::args::undefine (testdoc)::dpexe::uonly 1 |
||||
}\ |
||||
-result [list 0 1 1] |
||||
|
||||
#added 2026-08-05 (agent, G-169) - the engine's recorded duplicate-id todo in |
||||
#action: two registered sources defining the SAME id resolve to the |
||||
#last-registered source's definition (load order follows registration order; |
||||
#the overwriting define emits the stderr 'clearing existing data' notice). |
||||
#This is the class G-169's single-definer handover must not walk through |
||||
#blind - the moduledoc entry is withdrawn when app-ownership lands. |
||||
test docpackages_duplicate_definers_last_registered_wins {two registered doc-sources defining the same id: the last-registered source's definition wins}\ |
||||
-setup $common -body { |
||||
namespace eval ::testspace::dpsrc3 { |
||||
variable PUNKARGS |
||||
lappend PUNKARGS [list { |
||||
@id -id (testdoc)::dpexe::dup |
||||
@cmd -name "dpexe dup" -summary "DUP-FROM-EARLIER" |
||||
@values -min 0 -max 0 |
||||
}] |
||||
} |
||||
namespace eval ::testspace::dpsrc4 { |
||||
variable PUNKARGS |
||||
lappend PUNKARGS [list { |
||||
@id -id (testdoc)::dpexe::dup |
||||
@cmd -name "dpexe dup" -summary "DUP-FROM-LATER" |
||||
@values -min 0 -max 0 |
||||
}] |
||||
} |
||||
lappend ::punk::args::register::NAMESPACES ::testspace::dpsrc3 ::testspace::dpsrc4 |
||||
set u [punk::args::usage (testdoc)::dpexe::dup] |
||||
lappend result [string match "*DUP-FROM-LATER*" $u] |
||||
lappend result [string match "*DUP-FROM-EARLIER*" $u] |
||||
}\ |
||||
-cleanup { |
||||
}\ |
||||
-result [list 1 0] |
||||
|
||||
#added 2026-08-05 (agent, G-169) |
||||
test docpackages_explicit_define_supersedes_loaded {an explicit punk::args::define of an id already loaded from a registered source replaces that definition}\ |
||||
-setup $common -body { |
||||
punk::args::define { |
||||
@id -id (testdoc)::dpexe::dup |
||||
@cmd -name "dpexe dup" -summary "DUP-EXPLICIT" |
||||
@values -min 0 -max 0 |
||||
} |
||||
lappend result [string match "*DUP-EXPLICIT*" [punk::args::usage (testdoc)::dpexe::dup]] |
||||
}\ |
||||
-cleanup { |
||||
punk::args::undefine (testdoc)::dpexe::dup 1 |
||||
}\ |
||||
-result [list 1] |
||||
|
||||
#added 2026-08-05 (agent, G-169) |
||||
test docpackages_same_source_duplicate_last_entry_wins {two PUNKARGS entries in ONE registered source with the same id: the later entry wins}\ |
||||
-setup $common -body { |
||||
namespace eval ::testspace::dpsrc5 { |
||||
variable PUNKARGS |
||||
lappend PUNKARGS [list { |
||||
@id -id (testdoc)::dpexe::samesrc |
||||
@cmd -name "dpexe samesrc" -summary "SAMESRC-FIRST" |
||||
@values -min 0 -max 0 |
||||
}] |
||||
lappend PUNKARGS [list { |
||||
@id -id (testdoc)::dpexe::samesrc |
||||
@cmd -name "dpexe samesrc" -summary "SAMESRC-SECOND" |
||||
@values -min 0 -max 0 |
||||
}] |
||||
} |
||||
lappend ::punk::args::register::NAMESPACES ::testspace::dpsrc5 |
||||
set u [punk::args::usage (testdoc)::dpexe::samesrc] |
||||
lappend result [string match "*SAMESRC-SECOND*" $u] |
||||
lappend result [string match "*SAMESRC-FIRST*" $u] |
||||
}\ |
||||
-cleanup { |
||||
punk::args::undefine (testdoc)::dpexe::samesrc 1 |
||||
}\ |
||||
-result [list 1 0] |
||||
|
||||
#added 2026-08-05 (agent, G-169) |
||||
test docpackages_degraded_paths {a registered namespace with no PUNKARGS variable is tolerated by the scan, and an id no source documents resolves to empty (real_id) with usage raising cleanly}\ |
||||
-setup $common -body { |
||||
namespace eval ::testspace::dpempty {} |
||||
lappend ::punk::args::register::NAMESPACES ::testspace::dpempty |
||||
lappend result [catch {punk::args::update_definitions [list ::testspace::dp_unrelated2]}] |
||||
lappend result [expr {"::testspace::dpempty" in $::punk::args::register::scanned_packages}] |
||||
lappend result [punk::args::real_id (testdoc)::dpexe::nosuch] |
||||
lappend result [catch {punk::args::usage (testdoc)::dpexe::nosuch}] |
||||
}\ |
||||
-cleanup { |
||||
}\ |
||||
-result [list 0 1 {} 1] |
||||
} |
||||
tcltest::cleanupTests ;#needed to produce test summary line. |
||||
Loading…
Reference in new issue