2026-10-19 17:37:59 +00:00
package commandkit
import (
"bytes"
"context"
2026-10-19 19:46:22 +00:00
"errors"
"fmt"
2026-10-19 17:37:59 +00:00
"io"
"reflect"
2026-10-19 19:31:23 +00:00
"strings"
2026-10-19 17:37:59 +00:00
"testing"
)
2026-10-20 00:22:25 +00:00
func TestCommandContextSurvivesIncompleteAndInvalidOperandCounts ( t * testing . T ) {
for _ , spelling := range [ ] string { "run" , "r" } {
for _ , test := range [ ] struct {
name string
args [ ] string
help bool
usage bool
} {
{ name : "interspersed alias" , args : [ ] string { "first" , "--fmt=yaml" , "second" } } ,
{ name : "interspersed canonical flag" , args : [ ] string { "first" , "--format=yaml" , "second" } } ,
{ name : "partial help" , args : [ ] string { "first" , "--help" } , help : true } ,
{ name : "partial help with flag alias" , args : [ ] string { "first" , "--fmt=yaml" , "--help" } , help : true } ,
{ name : "excess operands" , args : [ ] string { "first" , "second" , "third" , "--fmt=yaml" } , usage : true } ,
{ name : "missing operands" , args : [ ] string { "first" , "--fmt=yaml" } , usage : true } ,
} {
t . Run ( spelling + "/" + test . name , func ( t * testing . T ) {
type input struct {
operands [ ] string
format Supplied [ string ]
}
built , ran := 0 , false
command := NewCommand ( CommandSpec [ input ] {
Name : "run" , NewInput : func ( ) input { built ++ ; return input { } } ,
Flags : [ ] Flag [ input ] { ValueFlag ( FlagMeta { Name : "format" } , ( * string ) ( nil ) ,
func ( value string ) ( string , error ) { return value , nil } ,
func ( target * input , value Supplied [ string ] ) { target . format = value } ) } ,
Arguments : [ ] Argument [ input ] { RepeatArgument ( ArgumentMeta { Name : "ARG" } , 2 , 2 ,
func ( value string ) ( string , error ) { return value , nil } ,
func ( target * input , value Supplied [ [ ] string ] ) { target . operands = value . Value } ) } ,
Run : func ( inv Invocation , value input ) Outcome {
ran = true
if inv . EnteredPath ( ) != spelling || inv . CanonicalPath ( ) != "run" {
t . Errorf ( "invocation paths = %q / %q" , inv . EnteredPath ( ) , inv . CanonicalPath ( ) )
}
if ! reflect . DeepEqual ( value . operands , [ ] string { "first" , "second" } ) || ! value . format . Set || value . format . Value != "yaml" {
t . Errorf ( "input = %#v" , value )
}
return Success ( )
} ,
} )
app , err := New ( Identity { Name : "Demo" } , command , Alias ( "r" , "run" ) , FlagAliasFor ( "run" , "--fmt" , "--format" ) )
if err != nil {
t . Fatal ( err )
}
var output , diagnostics bytes . Buffer
outcome := app . Execute ( context . Background ( ) , append ( [ ] string { spelling } , test . args ... ) , Streams { Out : & output , Err : & diagnostics } )
if test . usage {
if outcome . Kind != OutcomeUsage || strings . Contains ( diagnostics . String ( ) , "unknown flag" ) || ! strings . Contains ( diagnostics . String ( ) , "Demo " + spelling + " ARG" ) {
t . Fatalf ( "invalid arity outcome = %v, diagnostics %q" , outcome . Kind , diagnostics . String ( ) )
}
} else if outcome . Kind != OutcomeSuccess {
t . Fatalf ( "outcome = %#v, diagnostics %q" , outcome , diagnostics . String ( ) )
}
if test . help && ( ! strings . Contains ( output . String ( ) , "Demo " + spelling + " ARG" ) || ! strings . Contains ( output . String ( ) , "--fmt → --format" ) ) {
t . Errorf ( "command help = %q" , output . String ( ) )
}
if test . help || test . usage {
if built != 0 || ran {
t . Fatal ( "help or invalid arity initialized input or ran a handler" )
}
} else if built != 1 || ! ran {
t . Fatal ( "valid invocation did not run once" )
}
} )
}
}
}
func TestRunnableCommandCanHaveAliasOnlyDiscoveryPrefixes ( t * testing . T ) {
ran := false
app , err := New ( Identity { Name : "Demo" } ,
NewCommand ( CommandSpec [ struct { } ] { Name : "box" , Run : func ( Invocation , struct { } ) Outcome { ran = true ; return Success ( ) } } ) ,
simpleRunnable ( "inspect" ) , Alias ( "box admin pick" , "inspect" ) )
if err != nil {
t . Fatal ( err )
}
var output bytes . Buffer
outcome := app . Execute ( context . Background ( ) , [ ] string { "box" , "admin" , "--help" } , Streams { Out : & output , Err : io . Discard } )
if outcome . Kind != OutcomeSuccess || ! strings . Contains ( output . String ( ) , "pick → inspect" ) || ran {
t . Fatalf ( "discovery outcome = %v, help %q, ran %t" , outcome . Kind , output . String ( ) , ran )
}
}
2026-10-20 00:23:19 +00:00
func TestExplicitHelpRequiresAnExactResolvedTarget ( t * testing . T ) {
initialized := false
run := NewCommand ( CommandSpec [ struct { } ] {
Name : "run" , NewInput : func ( ) struct { } { initialized = true ; return struct { } { } } ,
Arguments : [ ] Argument [ struct { } ] { RepeatArgument ( ArgumentMeta { Name : "ARG" } , 2 , 2 ,
func ( value string ) ( string , error ) { return value , nil } , func ( * struct { } , Supplied [ [ ] string ] ) { } ) } ,
Run : func ( Invocation , struct { } ) Outcome { t . Error ( "help ran the command" ) ; return Success ( ) } ,
} )
app , err := New ( Identity { Name : "Demo" } , run , Group ( "box" , "Box" , simpleRunnable ( "show" ) ) ,
Alias ( "r" , "run" ) , Alias ( "b" , "box" ) , Alias ( "list show" , "box show" ) )
if err != nil {
t . Fatal ( err )
}
for _ , args := range [ ] [ ] string {
{ "help" , "run" , "first" , "second" } , { "help" , "r" , "first" } ,
{ "help" , "r" , "first" , "second" } , { "help" , "r" , "first" , "second" , "third" } ,
} {
var output , diagnostics bytes . Buffer
outcome := app . Execute ( context . Background ( ) , args , Streams { Out : & output , Err : & diagnostics } )
if outcome . Kind != OutcomeUsage || output . Len ( ) != 0 {
t . Errorf ( "Execute(%q) = %v, output %q, diagnostics %q" , args , outcome . Kind , output . String ( ) , diagnostics . String ( ) )
}
}
for _ , args := range [ ] [ ] string {
{ "help" , "run" } , { "help" , "r" } , { "help" , "box" } , { "help" , "b" } ,
{ "help" , "list" } , { "r" , "first" , "second" , "--help" } ,
} {
var output , diagnostics bytes . Buffer
outcome := app . Execute ( context . Background ( ) , args , Streams { Out : & output , Err : & diagnostics } )
if outcome . Kind != OutcomeSuccess || ! strings . Contains ( output . String ( ) , "Usage:" ) {
t . Errorf ( "Execute(%q) = %v, output %q, diagnostics %q" , args , outcome . Kind , output . String ( ) , diagnostics . String ( ) )
}
}
if initialized {
t . Fatal ( "help initialized command input" )
}
}
2026-10-19 17:37:59 +00:00
func routeTestApp ( t * testing . T , extra ... Declaration ) * App {
t . Helper ( )
collections := simpleRunnable ( "collections" )
list := Group ( "list" , "List" , collections )
testCommand := runnableWithOperands ( "test" , 0 , 1 )
promptkit := Group ( "promptkit" , "PromptKit" , list , testCommand )
run := runnableWithOperands ( "run" , 0 , 1 )
inspect := runnableWithOperands ( "inspect" , 1 , 1 )
declarations := [ ] Declaration {
promptkit ,
run ,
inspect ,
Alias ( "collections" , "list collections" ) ,
Alias ( "list collections" , "promptkit list collections" ) ,
Alias ( "pk" , "promptkit" ) ,
Alias ( "promptkit list bundles" , "promptkit list collections" ) ,
Alias ( "smoke" , "promptkit test" ) ,
Alias ( "r" , "run" ) ,
Alias ( "r full" , "inspect" ) ,
}
declarations = append ( declarations , extra ... )
app , err := New ( Identity { Name : "Example" } , declarations ... )
if err != nil {
t . Fatal ( err )
}
return app
}
func TestEnteredRoutesResolveChainsAndPreserveTokenOrigins ( t * testing . T ) {
app := routeTestApp ( t )
snapshot := app . routeSnapshot ( )
for _ , test := range [ ] struct {
name string
args [ ] string
entered string
canonical string
wantArgs [ ] string
wantKind routeKind
} {
{
name : "command alias chain" ,
args : [ ] string { "collections" , "--tag" , "first" } ,
entered : "collections" ,
canonical : "promptkit list collections" ,
wantArgs : [ ] string { "promptkit" , "list" , "collections" , "--tag" , "first" } ,
wantKind : routeCanonical ,
} ,
{
name : "group alias composition" ,
args : [ ] string { "pk" , "list" , "bundles" } ,
entered : "pk list bundles" ,
canonical : "promptkit list collections" ,
wantArgs : [ ] string { "promptkit" , "list" , "collections" } ,
wantKind : routeCanonical ,
} ,
{
name : "smoke operand" ,
args : [ ] string { "smoke" , "all" } ,
entered : "smoke" ,
canonical : "promptkit test" ,
wantArgs : [ ] string { "promptkit" , "test" , "all" } ,
wantKind : routeCanonical ,
} ,
{
name : "explicit longer alternate spelling" ,
args : [ ] string { "r" , "full" } ,
entered : "r full" ,
canonical : "inspect" ,
wantArgs : [ ] string { "inspect" } ,
wantKind : routeCanonical ,
} ,
{
name : "canonical runnable operand" ,
args : [ ] string { "run" , "full" } ,
entered : "run" ,
canonical : "run" ,
wantArgs : [ ] string { "run" , "full" } ,
wantKind : routeCanonical ,
} ,
{
name : "single dash remains an operand" ,
args : [ ] string { "run" , "-" } ,
entered : "run" ,
canonical : "run" ,
wantArgs : [ ] string { "run" , "-" } ,
wantKind : routeCanonical ,
} ,
{
name : "unknown path" ,
args : [ ] string { "missing" , "route" } ,
entered : "missing route" ,
wantArgs : [ ] string { "missing" , "route" } ,
wantKind : routeUnknown ,
} ,
{
name : "space-containing token is not split" ,
args : [ ] string { "collections list" } ,
entered : "collections list" ,
wantArgs : [ ] string { "collections list" } ,
wantKind : routeUnknown ,
} ,
{
name : "flag values and spaced tokens" ,
args : [ ] string { "collections" , "--message" , "--hlep" , "--text=two words" } ,
entered : "collections" ,
canonical : "promptkit list collections" ,
wantArgs : [ ] string { "promptkit" , "list" , "collections" , "--message" , "--hlep" , "--text=two words" } ,
wantKind : routeCanonical ,
} ,
{
name : "terminator stops command matching" ,
args : [ ] string { "collections" , "--" , "r" , "full" } ,
entered : "collections" ,
canonical : "promptkit list collections" ,
wantArgs : [ ] string { "promptkit" , "list" , "collections" , "--" , "r" , "full" } ,
wantKind : routeCanonical ,
} ,
} {
t . Run ( test . name , func ( t * testing . T ) {
got := resolveEnteredRoute ( test . args , snapshot )
if got . kind != test . wantKind {
t . Fatalf ( "route kind = %d, want %d" , got . kind , test . wantKind )
}
if got . enteredPath . String ( ) != test . entered {
t . Errorf ( "entered path = %q, want %q" , got . enteredPath . String ( ) , test . entered )
}
if got . canonicalPath . String ( ) != test . canonical {
t . Errorf ( "canonical path = %q, want %q" , got . canonicalPath . String ( ) , test . canonical )
}
if ! reflect . DeepEqual ( got . args , test . wantArgs ) {
t . Errorf ( "routed args = %q, want %q" , got . args , test . wantArgs )
}
} )
}
}
func TestLongerRouteSelectionDoesNotFallBackAfterTargetParsingFails ( t * testing . T ) {
app := routeTestApp ( t )
result := resolveEnteredRoute ( [ ] string { "r" , "full" } , app . routeSnapshot ( ) )
if got , want := result . canonicalPath . String ( ) , "inspect" ; got != want {
t . Fatalf ( "canonical path = %q, want %q" , got , want )
}
var diagnostics bytes . Buffer
outcome := app . Execute ( context . Background ( ) , [ ] string { "r" , "full" } , Streams { Out : io . Discard , Err : & diagnostics } )
if outcome . Kind != OutcomeUsage {
t . Fatalf ( "outcome kind = %v, want usage; diagnostics: %s" , outcome . Kind , diagnostics . String ( ) )
}
}
func TestEnteredAliasCanSelectExplicitLongerMapping ( t * testing . T ) {
app := routeTestApp ( t , Alias ( "pk list bundles" , "inspect" ) )
result := resolveEnteredRoute ( [ ] string { "pk" , "list" , "bundles" } , app . routeSnapshot ( ) )
if got , want := result . canonicalPath . String ( ) , "inspect" ; got != want {
t . Fatalf ( "canonical path = %q, want %q" , got , want )
}
if got , want := result . enteredPath . String ( ) , "pk list bundles" ; got != want {
t . Fatalf ( "entered path = %q, want %q" , got , want )
}
}
func TestExecuteDispatchesEnteredAliasToCanonicalRunner ( t * testing . T ) {
runs := 0
command := NewCommand ( CommandSpec [ struct { } ] {
Name : "canonical" , Summary : "Canonical" ,
Run : func ( Invocation , struct { } ) Outcome {
runs ++
return Success ( )
} ,
} )
app , err := New ( Identity { Name : "Example" } , command , Alias ( "shortcut" , "canonical" ) )
if err != nil {
t . Fatal ( err )
}
outcome := app . Execute ( context . Background ( ) , [ ] string { "shortcut" } , Streams { Out : io . Discard , Err : io . Discard } )
if outcome . Kind != OutcomeSuccess || runs != 1 {
t . Fatalf ( "alias execution = (%v, runs %d), want success and one canonical run" , outcome . Kind , runs )
}
}
2026-10-19 19:33:49 +00:00
func TestInvocationReportsEnteredAndCanonicalPathsPerCall ( t * testing . T ) {
type input struct {
label Supplied [ string ]
values Supplied [ [ ] string ]
}
type observed struct {
entered string
canonical string
label string
values [ ] string
}
var calls [ ] observed
command := NewCommand ( CommandSpec [ input ] {
Name : "run" ,
Flags : [ ] Flag [ input ] { ValueFlag ( FlagMeta { Name : "label" } , ( * string ) ( nil ) ,
func ( value string ) ( string , error ) { return value , nil } ,
func ( target * input , label Supplied [ string ] ) { target . label = label } ,
) } ,
Arguments : [ ] Argument [ input ] { RepeatArgument ( ArgumentMeta { Name : "value" } , 0 , - 1 ,
func ( value string ) ( string , error ) { return value , nil } ,
func ( target * input , values Supplied [ [ ] string ] ) { target . values = values } ,
) } ,
Run : func ( inv Invocation , value input ) Outcome {
calls = append ( calls , observed {
entered : inv . EnteredPath ( ) ,
canonical : inv . CanonicalPath ( ) ,
label : value . label . Value ,
values : append ( [ ] string ( nil ) , value . values . Value ... ) ,
} )
return Success ( )
} ,
} )
shortcut := Alias ( "shortcut" , "workspace run" )
app , err := New ( Identity { Name : "Example" } , Group ( "workspace" , "Workspace" , command ) , shortcut )
if err != nil {
t . Fatal ( err )
}
for _ , args := range [ ] [ ] string { { "workspace" , "run" , "--label=first" , "first" } , { "shortcut" , "--label=second" , "second" } , { "workspace" , "run" } } {
if outcome := app . Execute ( context . Background ( ) , args , Streams { Out : io . Discard , Err : io . Discard } ) ; outcome . Kind != OutcomeSuccess {
t . Fatalf ( "Execute(%q) = %v, want success" , args , outcome . Kind )
}
}
if len ( calls ) != 3 {
t . Fatalf ( "handler calls = %d, want 3" , len ( calls ) )
}
want := [ ] observed {
{ entered : "workspace run" , canonical : "workspace run" , label : "first" , values : [ ] string { "first" } } ,
{ entered : "shortcut" , canonical : "workspace run" , label : "second" , values : [ ] string { "second" } } ,
{ entered : "workspace run" , canonical : "workspace run" } ,
}
if ! reflect . DeepEqual ( calls , want ) {
t . Fatalf ( "handler invocations = %#v, want %#v" , calls , want )
}
secondApp , err := New ( Identity { Name : "Another" } , Group ( "workspace" , "Workspace" , command ) , shortcut )
if err != nil {
t . Fatal ( err )
}
if outcome := secondApp . Execute ( context . Background ( ) , [ ] string { "shortcut" } , Streams { Out : io . Discard , Err : io . Discard } ) ; outcome . Kind != OutcomeSuccess {
t . Fatalf ( "reused declaration execution = %v, want success" , outcome . Kind )
}
if got := calls [ 3 ] ; got . entered != "shortcut" || got . canonical != "workspace run" || len ( got . values ) != 0 {
t . Fatalf ( "reused declaration invocation = %#v" , got )
}
var zero Invocation
if zero . EnteredPath ( ) != "" || zero . CanonicalPath ( ) != "" {
t . Fatalf ( "zero Invocation paths = (%q, %q), want empty paths" , zero . EnteredPath ( ) , zero . CanonicalPath ( ) )
}
}
func TestPrivateCommandCallbacksReceiveResolvedInvocationPaths ( t * testing . T ) {
var calls [ ] Invocation
command := Command { record : & commandRecord {
name : "inspect" ,
payload : typedCommand [ struct { } ] {
spec : CommandSpec [ struct { } ] { Name : "inspect" } ,
privateRun : func ( exec commandExecution , _ struct { } ) Outcome {
calls = append ( calls , exec . invocation )
return Success ( )
} ,
} ,
} }
app , err := New ( Identity { Name : "Example" } , command , Alias ( "shortcut" , "inspect" ) )
if err != nil {
t . Fatal ( err )
}
for _ , args := range [ ] [ ] string { { "inspect" } , { "shortcut" } } {
if outcome := app . Execute ( context . Background ( ) , args , Streams { Out : io . Discard , Err : io . Discard } ) ; outcome . Kind != OutcomeSuccess {
t . Fatalf ( "Execute(%q) = %v, want success" , args , outcome . Kind )
}
}
if len ( calls ) != 2 || calls [ 0 ] . EnteredPath ( ) != "inspect" || calls [ 0 ] . CanonicalPath ( ) != "inspect" || calls [ 1 ] . EnteredPath ( ) != "shortcut" || calls [ 1 ] . CanonicalPath ( ) != "inspect" {
t . Fatalf ( "private callback invocations = %#v" , calls )
}
}
2026-10-19 19:31:23 +00:00
func TestExecuteAppliesCanonicalCommandFlagAliasesAfterRouting ( t * testing . T ) {
type input struct { color string }
var got string
command := NewCommand ( CommandSpec [ input ] {
Name : "inspect" ,
Flags : [ ] Flag [ input ] { ValueFlag ( FlagMeta { Name : "color" , Short : "c" } , ( * string ) ( nil ) ,
func ( value string ) ( string , error ) { return value , nil } ,
func ( target * input , supplied Supplied [ string ] ) { target . color = supplied . Value } ,
) } ,
Run : func ( _ Invocation , value input ) Outcome {
got = value . color
return Success ( )
} ,
} )
app , err := New ( Identity { Name : "Example" } , command ,
Alias ( "shortcut" , "inspect" ) ,
FlagAliasFor ( "inspect" , "--colour" , "-c" ) ,
)
if err != nil {
t . Fatal ( err )
}
outcome := app . Execute ( context . Background ( ) , [ ] string { "shortcut" , "--colour=blue" } , Streams { Out : io . Discard , Err : io . Discard } )
if outcome . Kind != OutcomeSuccess || got != "blue" {
t . Fatalf ( "alias flag execution = (%v, color %q), want success and blue" , outcome . Kind , got )
}
}
2026-10-19 19:46:22 +00:00
func TestAliasConversionErrorsRetainOccurrenceAndEnteredUsage ( t * testing . T ) {
colorFailure := errors . New ( "invalid color" )
tagFailure := errors . New ( "invalid tag" )
type input struct {
color Supplied [ string ]
tags Supplied [ [ ] string ]
}
command := NewCommand ( CommandSpec [ input ] {
Name : "inspect" ,
Flags : [ ] Flag [ input ] {
ValueFlag ( FlagMeta { Name : "color" } , ( * string ) ( nil ) , func ( value string ) ( string , error ) {
if value == "bad" {
return "" , colorFailure
}
return value , nil
} , func ( target * input , value Supplied [ string ] ) { target . color = value } ) ,
RepeatFlag ( FlagMeta { Name : "tag" } , nil , func ( value string ) ( string , error ) {
if value == "bad" {
return "" , tagFailure
}
return value , nil
} , func ( target * input , value Supplied [ [ ] string ] ) { target . tags = value } ) ,
} ,
Run : func ( Invocation , input ) Outcome { return Success ( ) } ,
} )
app , err := New ( Identity { Name : "Example" } , command ,
Alias ( "shortcut" , "inspect" ) ,
FlagAliasFor ( "inspect" , "--colour" , "--color" ) ,
FlagAliasFor ( "inspect" , "--labels" , "--tag" ) ,
)
if err != nil {
t . Fatal ( err )
}
for _ , test := range [ ] struct {
name string
args [ ] string
cause error
binding string
spelling string
occurrence int
} {
{
name : "invalid scalar before valid overwrite" ,
args : [ ] string { "shortcut" , "--colour=bad" , "--color=good" } ,
cause : colorFailure ,
binding : "color" ,
spelling : "--colour" ,
occurrence : 1 ,
} ,
{
name : "invalid repeat occurrence after mixed spelling" ,
args : [ ] string { "shortcut" , "--labels=first" , "--tag=bad" } ,
cause : tagFailure ,
binding : "tag" ,
spelling : "--tag" ,
occurrence : 2 ,
} ,
} {
t . Run ( test . name , func ( t * testing . T ) {
var diagnostics bytes . Buffer
outcome := app . Execute ( context . Background ( ) , test . args , Streams { Out : io . Discard , Err : & diagnostics } )
if outcome . Kind != OutcomeUsage {
t . Fatalf ( "outcome kind = %v, want usage" , outcome . Kind )
}
if ! errors . Is ( outcome . Cause , test . cause ) {
t . Fatalf ( "outcome cause = %v, want wrapped %v" , outcome . Cause , test . cause )
}
var conversionErr * flagConversionError
if ! errors . As ( outcome . Cause , & conversionErr ) {
t . Fatalf ( "outcome cause %T does not expose flag conversion context" , outcome . Cause )
}
if conversionErr . binding != test . binding || conversionErr . spelling != test . spelling || conversionErr . occurrence != test . occurrence {
t . Fatalf ( "conversion error = %#v, want binding/spelling/occurrence for %s %d" , conversionErr , test . spelling , test . occurrence )
}
for _ , fragment := range [ ] string { fmt . Sprintf ( "flag %s occurrence %d: %s" , test . spelling , test . occurrence , test . cause ) , "Usage: Example shortcut" , "Alias for: Example inspect" } {
if ! strings . Contains ( diagnostics . String ( ) , fragment ) {
t . Errorf ( "diagnostics %q do not contain %q" , diagnostics . String ( ) , fragment )
}
}
} )
}
}
func TestAliasUsageSurvivesRegistrationDuringExecution ( t * testing . T ) {
for _ , test := range [ ] struct {
name string
register func ( * App ) error
wantErr bool
} {
{
name : "successful registration" ,
register : func ( app * App ) error {
return app . Register ( NewCommand ( CommandSpec [ struct { } ] { Name : "late" , Run : func ( Invocation , struct { } ) Outcome { return Success ( ) } } ) )
} ,
} ,
{
name : "failed registration" ,
register : func ( app * App ) error { return app . Register ( Alias ( "shortcut" , "other" ) ) } ,
wantErr : true ,
} ,
} {
t . Run ( test . name , func ( t * testing . T ) {
var app * App
var registrationErr error
command := NewCommand ( CommandSpec [ struct { } ] {
Name : "inspect" ,
Run : func ( Invocation , struct { } ) Outcome {
registrationErr = test . register ( app )
return Usage ( errors . New ( "operation rejected" ) )
} ,
} )
var err error
app , err = New ( Identity { Name : "Example" } , command , Alias ( "shortcut" , "inspect" ) )
if err != nil {
t . Fatal ( err )
}
var diagnostics bytes . Buffer
outcome := app . Execute ( context . Background ( ) , [ ] string { "shortcut" } , Streams { Out : io . Discard , Err : & diagnostics } )
if outcome . Kind != OutcomeUsage {
t . Fatalf ( "outcome kind = %v, want usage" , outcome . Kind )
}
if ( registrationErr != nil ) != test . wantErr {
t . Fatalf ( "registration error = %v, want error %t" , registrationErr , test . wantErr )
}
for _ , fragment := range [ ] string { "operation rejected" , "Usage: Example shortcut" , "Alias for: Example inspect" } {
if ! strings . Contains ( diagnostics . String ( ) , fragment ) {
t . Errorf ( "diagnostics %q do not contain %q" , diagnostics . String ( ) , fragment )
}
}
} )
}
}
func TestUnresolvedRouteUsageHasNoCanonicalAliasAnnotation ( t * testing . T ) {
app := routeTestApp ( t )
var diagnostics bytes . Buffer
outcome := app . Execute ( context . Background ( ) , [ ] string { "missing" , "route" } , Streams { Out : io . Discard , Err : & diagnostics } )
if outcome . Kind != OutcomeUsage {
t . Fatalf ( "outcome kind = %v, want usage" , outcome . Kind )
}
if strings . Contains ( diagnostics . String ( ) , "Alias for:" ) {
t . Fatalf ( "unresolved route diagnostics invented a canonical target: %q" , diagnostics . String ( ) )
}
diagnostics . Reset ( )
outcome = app . Execute ( context . Background ( ) , [ ] string { "r" , "full" , "--unknown" } , Streams { Out : io . Discard , Err : & diagnostics } )
if outcome . Kind != OutcomeUsage {
t . Fatalf ( "unknown flag outcome kind = %v, want usage" , outcome . Kind )
}
for _ , fragment := range [ ] string { "unknown flag" , "Usage: Example r full" , "Alias for: Example inspect" } {
if ! strings . Contains ( diagnostics . String ( ) , fragment ) {
t . Errorf ( "unknown flag diagnostics %q do not contain %q" , diagnostics . String ( ) , fragment )
}
}
}
2026-10-19 19:31:23 +00:00
func TestExecuteAppliesGlobalHelpAliasAtApplicationRoot ( t * testing . T ) {
app , err := New ( Identity { Name : "Example" } , FlagAlias ( "--hlep" , "--help" ) )
if err != nil {
t . Fatal ( err )
}
var output bytes . Buffer
outcome := app . Execute ( context . Background ( ) , [ ] string { "--hlep" } , Streams { Out : & output , Err : io . Discard } )
if outcome . Kind != OutcomeSuccess || ! strings . Contains ( output . String ( ) , "Usage:" ) {
t . Fatalf ( "root help alias outcome = %v, output %q" , outcome . Kind , output . String ( ) )
}
}
2026-10-19 17:37:59 +00:00
func TestAliasOnlyPrefixProducesDiscoveryRoute ( t * testing . T ) {
app , err := New ( Identity { Name : "Example" } ,
Group ( "promptkit" , "PromptKit" , Group ( "list" , "List" , simpleRunnable ( "collections" ) ) ) ,
Alias ( "list collections" , "promptkit list collections" ) ,
)
if err != nil {
t . Fatal ( err )
}
result := resolveEnteredRoute ( [ ] string { "list" , "--help" } , app . routeSnapshot ( ) )
if result . kind != routeDiscovery {
t . Fatalf ( "route kind = %d, want discovery" , result . kind )
}
if got , want := result . discoveryPath . String ( ) , "list" ; got != want {
t . Fatalf ( "discovery path = %q, want %q" , got , want )
}
if got , want := result . enteredPath . String ( ) , "list" ; got != want {
t . Fatalf ( "entered path = %q, want %q" , got , want )
}
2026-10-19 19:40:55 +00:00
if ! reflect . DeepEqual ( result . args , [ ] string { "--help" } ) {
t . Fatalf ( "discovery args = %q, want [--help]" , result . args )
}
}
func TestAliasHelpTargetsGroupsAndDiscoveryViews ( t * testing . T ) {
var inputBuilds , promptRuns int
showPrompt := NewCommand ( CommandSpec [ struct { } ] {
Name : "prompt" ,
NewInput : func ( ) struct { } {
inputBuilds ++
return struct { } { }
} ,
Flags : [ ] Flag [ struct { } ] { ValueFlag ( FlagMeta { Name : "format" } , ( * string ) ( nil ) ,
func ( value string ) ( string , error ) { return value , nil } ,
func ( * struct { } , Supplied [ string ] ) { } ,
) } ,
Run : func ( Invocation , struct { } ) Outcome {
promptRuns ++
return Success ( )
} ,
} )
commands := Group ( "promptkit" , "PromptKit" ,
Group ( "list" , "List" , simpleRunnable ( "collections" ) ) ,
Group ( "show" , "Show" , showPrompt ) ,
)
app , err := New ( Identity { Name : "example" } , commands ,
Alias ( "list collections" , "promptkit list collections" ) ,
Alias ( "promptkit list bundles" , "promptkit list collections" ) ,
Alias ( "pk" , "promptkit" ) ,
Alias ( "pk list bundles" , "promptkit show prompt" ) ,
FlagAlias ( "--hlep" , "--help" ) ,
FlagAliasFor ( "promptkit show prompt" , "--fmt" , "--format" ) ,
)
if err != nil {
t . Fatal ( err )
}
for _ , test := range [ ] struct {
name string
args [ ] string
want [ ] string
omit [ ] string
} {
{
name : "explicit command help resolves entered target" ,
args : [ ] string { "help" , "list" , "collections" } ,
want : [ ] string { "Usage:\n example list collections" , "Alias for: example promptkit list collections" } ,
} ,
{
name : "aliased help flag uses entered command path" ,
args : [ ] string { "list" , "collections" , "--hlep" } ,
want : [ ] string { "Usage:\n example list collections" , "Alias for: example promptkit list collections" , "--hlep → --help" } ,
} ,
{
name : "canonical group shows direct aliases" ,
args : [ ] string { "help" , "promptkit" , "list" } ,
want : [ ] string { "Command Aliases:" , "bundles → promptkit list collections" } ,
} ,
{
name : "group shortcut shows more-specific override" ,
args : [ ] string { "pk" , "--help" } ,
want : [ ] string { "Usage:\n example pk [flags]" , "Alias for: example promptkit" , "list bundles → promptkit show prompt" } ,
omit : [ ] string { "list bundles → promptkit list collections" } ,
} ,
{
name : "explicit discovery target" ,
args : [ ] string { "help" , "list" } ,
want : [ ] string { "Usage:\n example list [command]" , "Available Aliases:" , "collections → promptkit list collections" , "--hlep → --help" } ,
omit : [ ] string { "--fmt" } ,
} ,
{
name : "discovery help flag" ,
args : [ ] string { "list" , "--hlep" } ,
want : [ ] string { "Usage:\n example list [command]" , "collections → promptkit list collections" } ,
} ,
{
name : "scoped flag alias appears on canonical command help" ,
args : [ ] string { "promptkit" , "show" , "prompt" , "--hlep" } ,
want : [ ] string { "--fmt → --format" } ,
} ,
{
name : "group excludes descendant scoped flag aliases" ,
args : [ ] string { "promptkit" , "--help" } ,
want : [ ] string { "Command Aliases:" } ,
omit : [ ] string { "--fmt → --format" } ,
} ,
{
name : "root lists explicit command aliases separately" ,
args : [ ] string { "--help" } ,
want : [ ] string { "Available Commands:" , "Command Aliases:" , "list collections → promptkit list collections" , "pk → promptkit" } ,
} ,
} {
t . Run ( test . name , func ( t * testing . T ) {
var output bytes . Buffer
outcome := app . Execute ( context . Background ( ) , test . args , Streams { Out : & output , Err : io . Discard } )
if outcome . Kind != OutcomeSuccess {
t . Fatalf ( "Execute(%q) = %#v; output %q" , test . args , outcome , output . String ( ) )
}
for _ , fragment := range test . want {
if ! strings . Contains ( output . String ( ) , fragment ) {
t . Errorf ( "help output %q does not contain %q" , output . String ( ) , fragment )
}
}
for _ , fragment := range test . omit {
if strings . Contains ( output . String ( ) , fragment ) {
t . Errorf ( "help output %q unexpectedly contains %q" , output . String ( ) , fragment )
}
}
} )
}
var diagnostics bytes . Buffer
outcome := app . Execute ( context . Background ( ) , [ ] string { "list" } , Streams { Out : io . Discard , Err : & diagnostics } )
if outcome . Kind != OutcomeUsage || ! strings . Contains ( outcome . Cause . Error ( ) , "--help" ) {
t . Fatalf ( "bare discovery prefix = %#v, diagnostics %q; want usage pointing to list --help" , outcome , diagnostics . String ( ) )
}
if inputBuilds != 0 || promptRuns != 0 {
t . Fatalf ( "help built %d inputs and ran %d commands" , inputBuilds , promptRuns )
2026-10-19 17:37:59 +00:00
}
}