2026-10-07 13:30:24 +00:00
package commandkit_test
import (
"bytes"
"context"
"errors"
"io"
2026-10-07 13:37:57 +00:00
"strconv"
2026-10-07 13:30:24 +00:00
"strings"
"testing"
commandkit "gitea.maximumdirect.net/eric/CommandKit"
configkit "gitea.maximumdirect.net/eric/ConfigKit"
)
func TestExecuteRunsTypedCommandsWithFreshInvocationState ( t * testing . T ) {
type input struct {
name commandkit . Supplied [ string ]
ids commandkit . Supplied [ [ ] string ]
}
var inputs [ ] input
var contexts [ ] context . Context
var streams [ ] commandkit . Streams
2026-10-09 01:42:03 +00:00
firstContext := context . WithValue ( context . Background ( ) , struct { } { } , "first" )
secondContext := context . WithValue ( context . Background ( ) , struct { } { } , "second" )
var firstOut , secondOut , firstDiagnostic , secondDiagnostic bytes . Buffer
2026-10-07 13:30:24 +00:00
command , err := commandkit . NewCommand ( commandkit . CommandSpec [ input ] {
Name : "run" ,
Flags : [ ] commandkit . Flag [ input ] {
commandkit . ValueFlag ( commandkit . FlagMeta { Name : "name" } , ( * string ) ( nil ) , func ( value string ) ( string , error ) { return value , nil } , func ( target * input , value commandkit . Supplied [ string ] ) { target . name = value } ) ,
commandkit . RepeatFlag ( commandkit . FlagMeta { Name : "id" } , nil , func ( value string ) ( string , error ) { return value , nil } , func ( target * input , value commandkit . Supplied [ [ ] string ] ) { target . ids = value } ) ,
} ,
Run : func ( invocation commandkit . Invocation , value input ) commandkit . Outcome {
inputs = append ( inputs , value )
contexts = append ( contexts , invocation . Context )
streams = append ( streams , invocation . Streams )
return commandkit . Success ( )
} ,
} )
if err != nil {
t . Fatal ( err )
}
app , err := commandkit . New ( commandkit . Identity { Name : "example" } , command )
if err != nil {
t . Fatal ( err )
}
2026-10-09 01:42:03 +00:00
first := app . Execute ( firstContext , [ ] string { "run" , "--name=first" , "--id=a,b" , "--id=c" } , commandkit . Streams { Out : & firstOut , Err : & firstDiagnostic } )
second := app . Execute ( secondContext , [ ] string { "run" } , commandkit . Streams { Out : & secondOut , Err : & secondDiagnostic } )
third := app . Execute ( context . Background ( ) , [ ] string { "run" } , commandkit . Streams { } )
2026-10-07 13:30:24 +00:00
if first . Kind != commandkit . OutcomeSuccess || second . Kind != commandkit . OutcomeSuccess || third . Kind != commandkit . OutcomeSuccess {
t . Fatalf ( "outcomes = %#v, %#v, and %#v" , first , second , third )
}
if len ( inputs ) != 3 || inputs [ 0 ] . name . Value != "first" || ! inputs [ 0 ] . name . Set || len ( inputs [ 0 ] . ids . Value ) != 2 || inputs [ 0 ] . ids . Value [ 0 ] != "a,b" || inputs [ 0 ] . ids . Value [ 1 ] != "c" {
t . Fatalf ( "first input = %#v" , inputs )
}
if inputs [ 1 ] . name . Set || inputs [ 1 ] . name . Value != "" || inputs [ 1 ] . ids . Set {
t . Fatalf ( "second invocation inherited state: %#v" , inputs [ 1 ] )
}
if streams [ 2 ] . Out != io . Discard || streams [ 2 ] . Err != io . Discard {
t . Fatalf ( "nil streams were not replaced with io.Discard: %#v" , streams [ 2 ] )
}
2026-10-09 01:42:03 +00:00
if contexts [ 0 ] != firstContext || contexts [ 1 ] != secondContext || streams [ 0 ] . Out != & firstOut || streams [ 0 ] . Err != & firstDiagnostic || streams [ 1 ] . Out != & secondOut || streams [ 1 ] . Err != & secondDiagnostic {
t . Fatalf ( "handler invocation contexts or streams were not forwarded independently" )
}
}
func TestExecuteUsesFreshSessionForHelpAfterFlagBearingInvocation ( t * testing . T ) {
type input struct {
name commandkit . Supplied [ string ]
enabled commandkit . Supplied [ bool ]
}
var received [ ] input
command , err := commandkit . NewCommand ( commandkit . CommandSpec [ input ] {
Name : "run" ,
Flags : [ ] commandkit . Flag [ input ] {
commandkit . ValueFlag ( commandkit . FlagMeta { Name : "name" } , ( * string ) ( nil ) , func ( value string ) ( string , error ) {
return value , nil
} , func ( target * input , value commandkit . Supplied [ string ] ) { target . name = value } ) ,
commandkit . BoolFlag ( commandkit . FlagMeta { Name : "enabled" } , false , func ( target * input , value commandkit . Supplied [ bool ] ) { target . enabled = value } ) ,
} ,
Run : func ( _ commandkit . Invocation , value input ) commandkit . Outcome {
received = append ( received , value )
return commandkit . Success ( )
} ,
} )
if err != nil {
t . Fatal ( err )
}
app , err := commandkit . New ( commandkit . Identity { Name : "example" } , command )
if err != nil {
t . Fatal ( err )
}
var firstOutput , secondOutput , diagnostic bytes . Buffer
first := app . Execute ( context . Background ( ) , [ ] string { "run" , "--name=chosen" , "--enabled=false" } , commandkit . Streams { Out : & firstOutput , Err : & diagnostic } )
if first . Kind != commandkit . OutcomeSuccess {
t . Fatalf ( "flag-bearing invocation = %#v" , first )
}
help := app . Execute ( context . Background ( ) , [ ] string { "run" , "--name=" , "--help" } , commandkit . Streams { Out : & secondOutput , Err : & diagnostic } )
if help . Kind != commandkit . OutcomeSuccess || ! strings . Contains ( secondOutput . String ( ) , "--enabled" ) {
t . Fatalf ( "help invocation = %#v, output %q" , help , secondOutput . String ( ) )
}
last := app . Execute ( context . Background ( ) , [ ] string { "run" } , commandkit . Streams { } )
if last . Kind != commandkit . OutcomeSuccess {
t . Fatalf ( "omitted-value invocation = %#v" , last )
}
if len ( received ) != 2 || received [ 0 ] . name . Value != "chosen" || ! received [ 0 ] . name . Set || received [ 0 ] . enabled . Value || ! received [ 0 ] . enabled . Set {
t . Fatalf ( "first input = %#v" , received )
}
if received [ 1 ] . name . Set || received [ 1 ] . name . Value != "" || received [ 1 ] . enabled . Set {
t . Fatalf ( "later invocation inherited flag state: %#v" , received [ 1 ] )
}
}
func TestExecutePresentsHandlerUsageAfterRegisteringCommand ( t * testing . T ) {
usageCause := errors . New ( "handler requests usage" )
var app * commandkit . App
var calls int
late , err := commandkit . NewCommand ( commandkit . CommandSpec [ struct { } ] {
Name : "late" ,
Run : func ( commandkit . Invocation , struct { } ) commandkit . Outcome { return commandkit . Success ( ) } ,
} )
if err != nil {
t . Fatal ( err )
}
command , err := commandkit . NewCommand ( commandkit . CommandSpec [ struct { } ] {
Name : "run" ,
Run : func ( commandkit . Invocation , struct { } ) commandkit . Outcome {
calls ++
if err := app . Register ( late ) ; err != nil {
return commandkit . Failure ( err )
}
return commandkit . Usage ( usageCause )
} ,
} )
if err != nil {
t . Fatal ( err )
}
app , err = commandkit . New ( commandkit . Identity { Name : "example" } , command )
if err != nil {
t . Fatal ( err )
}
var diagnostic bytes . Buffer
result := app . Execute ( context . Background ( ) , [ ] string { "run" } , commandkit . Streams { Err : & diagnostic } )
if result . Kind != commandkit . OutcomeUsage || ! errors . Is ( result . Cause , usageCause ) || calls != 1 {
t . Fatalf ( "handler usage = %#v, calls %d" , result , calls )
}
if ! strings . Contains ( diagnostic . String ( ) , "Usage: example run" ) {
t . Fatalf ( "handler usage diagnostic = %q" , diagnostic . String ( ) )
}
if result := app . Execute ( context . Background ( ) , [ ] string { "late" } , commandkit . Streams { } ) ; result . Kind != commandkit . OutcomeSuccess {
t . Fatalf ( "registered command execution = %#v" , result )
2026-10-07 13:30:24 +00:00
}
}
func TestExecuteReturnsUsageForParsingRequirementsAndInputChecks ( t * testing . T ) {
type input struct { count commandkit . Supplied [ int ] }
parseFailure := errors . New ( "bad count" )
checkFailure := errors . New ( "incompatible inputs" )
command , err := commandkit . NewCommand ( commandkit . CommandSpec [ input ] {
Name : "run" ,
Flags : [ ] commandkit . Flag [ input ] { commandkit . ValueFlag ( commandkit . FlagMeta { Name : "count" , Required : true } , nil , func ( value string ) ( int , error ) {
if value == "bad" {
return 0 , parseFailure
}
return 0 , nil
} , func ( target * input , value commandkit . Supplied [ int ] ) { target . count = value } ) } ,
Arguments : [ ] commandkit . Argument [ input ] { commandkit . ValueArgument ( commandkit . ArgumentMeta { Name : "id" } , true , func ( value string ) ( string , error ) { return value , nil } , func ( * input , commandkit . Supplied [ string ] ) { } ) } ,
CheckInput : func ( input ) error { return checkFailure } ,
Run : func ( commandkit . Invocation , input ) commandkit . Outcome { return commandkit . Success ( ) } ,
} )
if err != nil {
t . Fatal ( err )
}
app , err := commandkit . New ( commandkit . Identity { Name : "example" } , command )
if err != nil {
t . Fatal ( err )
}
var diagnostic bytes . Buffer
missing := app . Execute ( context . Background ( ) , [ ] string { "run" } , commandkit . Streams { Err : & diagnostic } )
if missing . Kind != commandkit . OutcomeUsage || missing . Status != 2 || ! strings . Contains ( diagnostic . String ( ) , "Usage: example run" ) {
t . Fatalf ( "missing required input = %#v, diagnostics %q" , missing , diagnostic . String ( ) )
}
malformed := app . Execute ( context . Background ( ) , [ ] string { "run" , "--count=bad" , "id" } , commandkit . Streams { Err : & diagnostic } )
if malformed . Kind != commandkit . OutcomeUsage || ! errors . Is ( malformed . Cause , parseFailure ) {
t . Fatalf ( "parser failure = %#v" , malformed )
}
checked := app . Execute ( context . Background ( ) , [ ] string { "run" , "--count=1" , "id" } , commandkit . Streams { Err : & diagnostic } )
if checked . Kind != commandkit . OutcomeUsage || ! errors . Is ( checked . Cause , checkFailure ) {
t . Fatalf ( "input check failure = %#v" , checked )
}
}
func TestExecutePreservesDomainOutcomesAndWarningDiagnostics ( t * testing . T ) {
domainCause := errors . New ( "domain rejected the request" )
warning := commandkit . MessageDiagnostic ( configkit . SeverityWarning , "review needed" )
command , err := commandkit . NewCommand ( commandkit . CommandSpec [ struct { } ] {
Name : "run" ,
Run : func ( commandkit . Invocation , struct { } ) commandkit . Outcome {
outcome := commandkit . Domain ( "sample" , 2 , domainCause )
outcome . Diagnostics = [ ] commandkit . Diagnostic { warning }
return outcome
} ,
} )
if err != nil {
t . Fatal ( err )
}
app , err := commandkit . New ( commandkit . Identity { Name : "example" } , command )
if err != nil {
t . Fatal ( err )
}
var diagnostic bytes . Buffer
outcome := app . Execute ( context . Background ( ) , [ ] string { "run" } , commandkit . Streams { Err : & diagnostic } )
if outcome . Kind != commandkit . OutcomeDomain || outcome . Domain != "sample" || outcome . Status != 2 || ! errors . Is ( outcome . Cause , domainCause ) {
t . Fatalf ( "domain outcome changed: %#v" , outcome )
}
if diagnostic . String ( ) != "review needed\ndomain rejected the request\n" || outcome . DiagnosticDelivery != commandkit . DeliveryComplete {
t . Fatalf ( "warning delivery = %q, %#v" , diagnostic . String ( ) , outcome )
}
warningOnly , err := commandkit . NewCommand ( commandkit . CommandSpec [ struct { } ] {
Name : "warn" ,
Run : func ( commandkit . Invocation , struct { } ) commandkit . Outcome {
result := commandkit . Success ( )
result . Diagnostics = [ ] commandkit . Diagnostic { warning }
return result
} ,
} )
if err != nil {
t . Fatal ( err )
}
app , err = commandkit . New ( commandkit . Identity { Name : "example" } , warningOnly )
if err != nil {
t . Fatal ( err )
}
diagnostic . Reset ( )
outcome = app . Execute ( context . Background ( ) , [ ] string { "warn" } , commandkit . Streams { Err : & diagnostic } )
if outcome . Kind != commandkit . OutcomeSuccess || diagnostic . String ( ) != "review needed\n" {
t . Fatalf ( "warning-only outcome = %#v, diagnostics %q" , outcome , diagnostic . String ( ) )
}
}
func TestExecuteDoesNotRepeatCompletedDiagnosticsOrPresentedCauses ( t * testing . T ) {
cause := errors . New ( "already shown" )
command , err := commandkit . NewCommand ( commandkit . CommandSpec [ struct { } ] {
Name : "run" ,
Run : func ( commandkit . Invocation , struct { } ) commandkit . Outcome {
outcome := commandkit . Domain ( "sample" , 2 , cause )
outcome . Diagnostics = [ ] commandkit . Diagnostic { { Severity : configkit . SeverityError , Write : func ( writer io . Writer ) error {
_ , err := io . WriteString ( writer , "presented\n" )
return err
} } }
return outcome
} ,
} )
if err != nil {
t . Fatal ( err )
}
app , err := commandkit . New ( commandkit . Identity { Name : "example" } , command )
if err != nil {
t . Fatal ( err )
}
var diagnostic bytes . Buffer
outcome := app . Execute ( context . Background ( ) , [ ] string { "run" } , commandkit . Streams { Err : & diagnostic } )
if outcome . Kind != commandkit . OutcomeDomain || diagnostic . String ( ) != "presented\n" {
t . Fatalf ( "presented cause was duplicated: %#v, %q" , outcome , diagnostic . String ( ) )
}
diagnostic . Reset ( )
completed := commandkit . Domain ( "sample" , 2 , cause )
completed . DiagnosticDelivery = commandkit . DeliveryComplete
command , err = commandkit . NewCommand ( commandkit . CommandSpec [ struct { } ] { Name : "done" , Run : func ( commandkit . Invocation , struct { } ) commandkit . Outcome { return completed } } )
if err != nil {
t . Fatal ( err )
}
app , err = commandkit . New ( commandkit . Identity { Name : "example" } , command )
if err != nil {
t . Fatal ( err )
}
outcome = app . Execute ( context . Background ( ) , [ ] string { "done" } , commandkit . Streams { Err : & diagnostic } )
if diagnostic . Len ( ) != 0 || outcome . DiagnosticDelivery != commandkit . DeliveryComplete {
t . Fatalf ( "completed diagnostics were repeated: %#v, %q" , outcome , diagnostic . String ( ) )
}
}
func TestExecuteRetainsOperationAndDiagnosticDeliveryFailures ( t * testing . T ) {
operationFailure := context . Canceled
writeFailure := errors . New ( "writer failed" )
command , err := commandkit . NewCommand ( commandkit . CommandSpec [ struct { } ] {
Name : "run" ,
Run : func ( commandkit . Invocation , struct { } ) commandkit . Outcome {
outcome := commandkit . Failure ( operationFailure )
outcome . ReportIncomplete = true
return outcome
} ,
} )
if err != nil {
t . Fatal ( err )
}
app , err := commandkit . New ( commandkit . Identity { Name : "example" } , command )
if err != nil {
t . Fatal ( err )
}
outcome := app . Execute ( context . Background ( ) , [ ] string { "run" } , commandkit . Streams { Err : failingWriter { err : writeFailure } } )
if outcome . Kind != commandkit . OutcomeOperational || outcome . Status != 1 || outcome . DiagnosticDelivery != commandkit . DeliveryIncomplete || ! outcome . ReportIncomplete || ! errors . Is ( outcome . Cause , operationFailure ) || ! errors . Is ( outcome . DeliveryError , writeFailure ) {
t . Fatalf ( "combined operation and delivery failure = %#v" , outcome )
}
short := app . Execute ( context . Background ( ) , [ ] string { "run" } , commandkit . Streams { Err : shortWriter { } } )
if ! errors . Is ( short . DeliveryError , io . ErrShortWrite ) || short . DiagnosticDelivery != commandkit . DeliveryIncomplete {
t . Fatalf ( "short write was not detected: %#v" , short )
}
}
func TestExecuteHelpSkipsRequiredInputsAndRejectsNilContext ( t * testing . T ) {
type input struct { id commandkit . Supplied [ string ] }
factoryCalls , checkCalls , runCalls := 0 , 0 , 0
command , err := commandkit . NewCommand ( commandkit . CommandSpec [ input ] {
Name : "run" ,
NewInput : func ( ) input {
factoryCalls ++
return input { }
} ,
Arguments : [ ] commandkit . Argument [ input ] { commandkit . ValueArgument ( commandkit . ArgumentMeta { Name : "id" } , true , func ( value string ) ( string , error ) { return value , nil } , func ( target * input , value commandkit . Supplied [ string ] ) { target . id = value } ) } ,
CheckInput : func ( input ) error { checkCalls ++ ; return nil } ,
Run : func ( commandkit . Invocation , input ) commandkit . Outcome { runCalls ++ ; return commandkit . Success ( ) } ,
} )
if err != nil {
t . Fatal ( err )
}
app , err := commandkit . New ( commandkit . Identity { Name : "example" } , command )
if err != nil {
t . Fatal ( err )
}
help := app . Execute ( context . Background ( ) , [ ] string { "run" , "--help" } , commandkit . Streams { } )
if help . Kind != commandkit . OutcomeSuccess || factoryCalls != 0 || checkCalls != 0 || runCalls != 0 {
t . Fatalf ( "help request invoked execution path: %#v calls=%d/%d/%d" , help , factoryCalls , checkCalls , runCalls )
}
invalid := app . Execute ( nil , [ ] string { "run" } , commandkit . Streams { } )
if invalid . Kind != commandkit . OutcomeOperational || invalid . Status != 1 || invalid . Cause == nil {
t . Fatalf ( "nil context outcome = %#v" , invalid )
}
}
2026-10-09 03:03:10 +00:00
func TestExecuteRunsApplicationOwnedNestedHelp ( t * testing . T ) {
type input struct { topic commandkit . Supplied [ string ] }
var received [ ] input
domainCause := errors . New ( "application help result" )
help , err := commandkit . NewCommand ( commandkit . CommandSpec [ input ] {
Name : "help" ,
Description : "Explain a session topic." ,
Arguments : [ ] commandkit . Argument [ input ] { commandkit . ValueArgument (
commandkit . ArgumentMeta { Name : "TOPIC" } , true ,
func ( value string ) ( string , error ) { return value , nil } ,
func ( target * input , value commandkit . Supplied [ string ] ) { target . topic = value } ,
) } ,
Run : func ( _ commandkit . Invocation , value input ) commandkit . Outcome {
received = append ( received , value )
return commandkit . Domain ( "session-help" , 7 , domainCause )
} ,
} )
if err != nil {
t . Fatal ( err )
}
session , err := commandkit . Group ( "session" , "Session commands." , help )
if err != nil {
t . Fatal ( err )
}
app , err := commandkit . New ( commandkit . Identity { Name : "example" } , session )
if err != nil {
t . Fatal ( err )
}
var diagnostic bytes . Buffer
outcome := app . Execute ( context . Background ( ) , [ ] string { "session" , "help" , "restore" } , commandkit . Streams { Err : & diagnostic } )
if outcome . Kind != commandkit . OutcomeDomain || outcome . Domain != "session-help" || outcome . Status != 7 || ! errors . Is ( outcome . Cause , domainCause ) {
t . Fatalf ( "nested help handler outcome = %#v, diagnostics %q" , outcome , diagnostic . String ( ) )
}
if len ( received ) != 1 || received [ 0 ] . topic != ( commandkit . Supplied [ string ] { Value : "restore" , Set : true } ) {
t . Fatalf ( "nested help handler input = %#v" , received )
}
for _ , args := range [ ] [ ] string { { "session" , "help" , "--help" } , { "help" , "session" , "help" } } {
t . Run ( strings . Join ( args , " " ) , func ( t * testing . T ) {
var output , diagnostics bytes . Buffer
outcome := app . Execute ( context . Background ( ) , args , commandkit . Streams { Out : & output , Err : & diagnostics } )
if outcome . Kind != commandkit . OutcomeSuccess || outcome . Status != 0 || diagnostics . Len ( ) != 0 {
t . Fatalf ( "metadata help outcome = %#v, diagnostics %q" , outcome , diagnostics . String ( ) )
}
if ! strings . Contains ( output . String ( ) , "Explain a session topic." ) || ! strings . Contains ( output . String ( ) , "TOPIC" ) {
t . Fatalf ( "metadata help omitted nested command details: %q" , output . String ( ) )
}
if len ( received ) != 1 {
t . Fatalf ( "metadata help invoked the application handler: %#v" , received )
}
} )
}
}
2026-10-07 13:37:57 +00:00
func TestHelpRendersRegisteredMetadataAndResolvesExactPaths ( t * testing . T ) {
type input struct {
count commandkit . Supplied [ int ]
tags commandkit . Supplied [ [ ] string ]
}
factoryCalls , runCalls := 0 , 0
show , err := commandkit . NewCommand ( commandkit . CommandSpec [ input ] {
Name : "show" ,
Summary : "Show one item." ,
Description : "Display the selected item in detail." ,
NewInput : func ( ) input {
factoryCalls ++
return input { }
} ,
Flags : [ ] commandkit . Flag [ input ] {
commandkit . ValueFlag ( commandkit . FlagMeta { Name : "count" , Usage : "number of items" , Required : true } , nil , func ( value string ) ( int , error ) {
return strconv . Atoi ( value )
} , func ( target * input , value commandkit . Supplied [ int ] ) { target . count = value } ) ,
commandkit . RepeatFlag ( commandkit . FlagMeta { Name : "tag" , Usage : "item tag" } , [ ] string { "base" } , func ( value string ) ( string , error ) { return value , nil } , func ( target * input , value commandkit . Supplied [ [ ] string ] ) { target . tags = value } ) ,
} ,
Arguments : [ ] commandkit . Argument [ input ] { commandkit . RepeatArgument ( commandkit . ArgumentMeta { Name : "ID" , Usage : "item identifier" } , 1 , 3 , func ( value string ) ( string , error ) { return value , nil } , func ( * input , commandkit . Supplied [ [ ] string ] ) { } ) } ,
Run : func ( commandkit . Invocation , input ) commandkit . Outcome { runCalls ++ ; return commandkit . Success ( ) } ,
} )
if err != nil {
t . Fatal ( err )
}
config , err := commandkit . Group ( "config" , "Inspect configuration." , show )
if err != nil {
t . Fatal ( err )
}
now , err := commandkit . NewCommand ( commandkit . CommandSpec [ struct { } ] { Name : "now" , Summary : "Deploy immediately." , Run : func ( commandkit . Invocation , struct { } ) commandkit . Outcome { return commandkit . Success ( ) } } )
if err != nil {
t . Fatal ( err )
}
deployParent , err := commandkit . NewCommand ( commandkit . CommandSpec [ struct { } ] { Name : "deploy" , Summary : "Deploy artifacts." , Run : func ( commandkit . Invocation , struct { } ) commandkit . Outcome { runCalls ++ ; return commandkit . Success ( ) } } )
if err != nil {
t . Fatal ( err )
}
deploy , err := commandkit . WithChildren ( deployParent , now )
if err != nil {
t . Fatal ( err )
}
app , err := commandkit . New ( commandkit . Identity { Name : "example" } , config , deploy )
if err != nil {
t . Fatal ( err )
}
var out , diagnostic bytes . Buffer
root := app . Execute ( context . Background ( ) , [ ] string { "--help" } , commandkit . Streams { Out : & out , Err : & diagnostic } )
if root . Kind != commandkit . OutcomeSuccess || ! strings . Contains ( out . String ( ) , "Available Commands:" ) {
t . Fatalf ( "root help = %#v, output %q" , root , out . String ( ) )
}
for _ , name := range [ ] string { "config" , "help" , "version" } {
if ! strings . Contains ( out . String ( ) , name ) {
t . Fatalf ( "root help omitted %q: %q" , name , out . String ( ) )
}
}
for _ , earlier := range [ ] string { "config" , "deploy" , "help" } {
if strings . Index ( out . String ( ) , earlier ) > strings . Index ( out . String ( ) , "version" ) {
t . Fatalf ( "root help commands are not sorted: %q" , out . String ( ) )
}
}
out . Reset ( )
bare := app . Execute ( context . Background ( ) , nil , commandkit . Streams { Out : & out , Err : & diagnostic } )
if bare . Kind != commandkit . OutcomeSuccess || ! strings . Contains ( out . String ( ) , "Available Commands:" ) {
t . Fatalf ( "bare root help = %#v, output %q" , bare , out . String ( ) )
}
out . Reset ( )
helpCommand := app . Execute ( context . Background ( ) , [ ] string { "help" } , commandkit . Streams { Out : & out , Err : & diagnostic } )
if helpCommand . Kind != commandkit . OutcomeSuccess || ! strings . Contains ( out . String ( ) , "Available Commands:" ) {
t . Fatalf ( "root help command = %#v, output %q" , helpCommand , out . String ( ) )
}
out . Reset ( )
group := app . Execute ( context . Background ( ) , [ ] string { "config" } , commandkit . Streams { Out : & out , Err : & diagnostic } )
if group . Kind != commandkit . OutcomeSuccess || ! strings . Contains ( out . String ( ) , "show" ) {
t . Fatalf ( "group help = %#v, output %q" , group , out . String ( ) )
}
out . Reset ( )
parentHelp := app . Execute ( context . Background ( ) , [ ] string { "deploy" , "--help" } , commandkit . Streams { Out : & out , Err : & diagnostic } )
if parentHelp . Kind != commandkit . OutcomeSuccess || ! strings . Contains ( out . String ( ) , "now" ) || strings . Contains ( out . String ( ) , "Usage: example deploy now" ) {
t . Fatalf ( "runnable parent help = %#v, output %q" , parentHelp , out . String ( ) )
}
out . Reset ( )
selected := app . Execute ( context . Background ( ) , [ ] string { "help" , "config" , "show" } , commandkit . Streams { Out : & out , Err : & diagnostic } )
if selected . Kind != commandkit . OutcomeSuccess {
t . Fatalf ( "selected help = %#v, error %q" , selected , diagnostic . String ( ) )
}
for _ , expected := range [ ] string { "Display the selected item in detail." , "Usage:" , "ID{1..3}" , "Arguments:" , "min 1, max 3" , "--count" , "required" , "default: 0" , "--tag" , "repeatable" , "default: [base]" , "--help" } {
if ! strings . Contains ( out . String ( ) , expected ) {
t . Fatalf ( "selected help omitted %q: %q" , expected , out . String ( ) )
}
}
if factoryCalls != 0 || runCalls != 0 {
t . Fatalf ( "help invoked execution callbacks: factories=%d runs=%d" , factoryCalls , runCalls )
}
badValue := app . Execute ( context . Background ( ) , [ ] string { "config" , "show" , "--count=bad" , "--help" } , commandkit . Streams { Out : & out , Err : & diagnostic } )
if badValue . Kind != commandkit . OutcomeUsage || factoryCalls != 0 {
t . Fatalf ( "help skipped conversion of supplied values: %#v" , badValue )
}
out . Reset ( )
versionOutcome := app . Execute ( context . Background ( ) , [ ] string { "version" } , commandkit . Streams { Out : & out , Err : & diagnostic } )
if versionOutcome . Kind != commandkit . OutcomeSuccess || factoryCalls != 0 || runCalls != 0 {
t . Fatalf ( "version invoked an application command: %#v calls=%d/%d" , versionOutcome , factoryCalls , runCalls )
}
failed := app . Execute ( context . Background ( ) , [ ] string { "config" , "show" , "--help" } , commandkit . Streams { Out : shortWriter { } , Err : & diagnostic } )
if failed . Kind != commandkit . OutcomeOperational || ! failed . ReportIncomplete || ! errors . Is ( failed . DeliveryError , io . ErrShortWrite ) {
t . Fatalf ( "failed help delivery = %#v" , failed )
}
out . Reset ( )
unknown := app . Execute ( context . Background ( ) , [ ] string { "help" , "config" , "missing" } , commandkit . Streams { Out : & out , Err : & diagnostic } )
if unknown . Kind != commandkit . OutcomeUsage || ! strings . Contains ( diagnostic . String ( ) , "unknown help path" ) {
t . Fatalf ( "unknown help path = %#v, diagnostics %q" , unknown , diagnostic . String ( ) )
}
badFlag := app . Execute ( context . Background ( ) , [ ] string { "config" , "show" , "--unknown" , "--help" } , commandkit . Streams { Out : & out , Err : & diagnostic } )
if badFlag . Kind != commandkit . OutcomeUsage {
t . Fatalf ( "help accepted an unknown flag: %#v" , badFlag )
}
}
func TestVersionCommandFormatsApplicationAndCommandKitIdentity ( t * testing . T ) {
app , err := commandkit . New ( commandkit . Identity { Name : "ExampleApp" , Revision : "abc123" } )
if err != nil {
t . Fatal ( err )
}
var out , diagnostic bytes . Buffer
textOutcome := app . Execute ( context . Background ( ) , [ ] string { "version" } , commandkit . Streams { Out : & out , Err : & diagnostic } )
if textOutcome . Kind != commandkit . OutcomeSuccess || out . String ( ) != "ExampleApp dev (abc123)\n" {
t . Fatalf ( "default version = %#v, output %q" , textOutcome , out . String ( ) )
}
out . Reset ( )
yamlOutcome := app . Execute ( context . Background ( ) , [ ] string { "version" , "--format=yaml" } , commandkit . Streams { Out : & out , Err : & diagnostic } )
if yamlOutcome . Kind != commandkit . OutcomeSuccess || out . String ( ) != "name: ExampleApp\nversion: dev\nrevision: abc123\n" {
t . Fatalf ( "YAML version = %#v, output %q" , yamlOutcome , out . String ( ) )
}
out . Reset ( )
component := app . Execute ( context . Background ( ) , [ ] string { "version" , "--scope=commandkit" } , commandkit . Streams { Out : & out , Err : & diagnostic } )
if component . Kind != commandkit . OutcomeSuccess || ! strings . HasPrefix ( out . String ( ) , "CommandKit " ) || ! strings . HasSuffix ( out . String ( ) , "\n" ) {
t . Fatalf ( "CommandKit version = %#v, output %q" , component , out . String ( ) )
}
out . Reset ( )
invalid := app . Execute ( context . Background ( ) , [ ] string { "version" , "--scope=unknown" } , commandkit . Streams { Out : & out , Err : & diagnostic } )
if invalid . Kind != commandkit . OutcomeUsage || out . Len ( ) != 0 {
t . Fatalf ( "invalid version scope = %#v, output %q" , invalid , out . String ( ) )
}
failed := app . Execute ( context . Background ( ) , [ ] string { "version" } , commandkit . Streams { Out : shortWriter { } , Err : & diagnostic } )
if failed . Kind != commandkit . OutcomeOperational || ! failed . ReportIncomplete || ! errors . Is ( failed . DeliveryError , io . ErrShortWrite ) {
t . Fatalf ( "failed version delivery = %#v" , failed )
}
}
2026-10-07 13:30:24 +00:00
type failingWriter struct { err error }
func ( w failingWriter ) Write ( [ ] byte ) ( int , error ) { return 0 , w . err }
type shortWriter struct { }
func ( shortWriter ) Write ( data [ ] byte ) ( int , error ) {
if len ( data ) == 0 {
return 0 , nil
}
return len ( data ) - 1 , nil
}
2026-10-07 16:47:55 +00:00
func TestHelpEntryFormsPresentReportAndDiagnosticFailures ( t * testing . T ) {
group , err := commandkit . Group ( "notes" , "Notes metadata." )
if err != nil {
t . Fatal ( err )
}
app , err := commandkit . New ( commandkit . Identity { Name : "example" } , group )
if err != nil {
t . Fatal ( err )
}
reportErr := errors . New ( "report failed" )
diagnosticErr := errors . New ( "diagnostic failed" )
for _ , args := range [ ] [ ] string { nil , { "notes" } , { "--help" } , { "-h" } , { "notes" , "--help" } , { "help" } , { "help" , "notes" } } {
var diagnostics bytes . Buffer
result := app . Execute ( context . Background ( ) , args , commandkit . Streams { Out : failingWriter { reportErr } , Err : & diagnostics } )
if result . Kind != commandkit . OutcomeOperational || ! result . ReportIncomplete || ! errors . Is ( result . Cause , reportErr ) || ! errors . Is ( result . DeliveryError , reportErr ) || result . DiagnosticDelivery != commandkit . DeliveryComplete || strings . Count ( diagnostics . String ( ) , reportErr . Error ( ) ) != 1 {
t . Fatalf ( "%v: result=%#v diagnostics=%q" , args , result , diagnostics . String ( ) )
}
result = app . Execute ( context . Background ( ) , args , commandkit . Streams { Out : failingWriter { reportErr } , Err : failingWriter { diagnosticErr } } )
if result . DiagnosticDelivery != commandkit . DeliveryIncomplete || ! errors . Is ( result . Cause , reportErr ) || ! errors . Is ( result . DeliveryError , reportErr ) || ! errors . Is ( result . DeliveryError , diagnosticErr ) {
t . Fatalf ( "%v: result=%#v" , args , result )
}
}
}
2026-10-07 16:49:21 +00:00
func TestExecuteNormalizesOutcomeDefaultsAndPreservesDomainValues ( t * testing . T ) {
cause := errors . New ( "domain cause" )
for _ , tc := range [ ] struct {
outcome commandkit . Outcome
kind commandkit . OutcomeKind
status int
domain string
cause error
} {
{ commandkit . Outcome { } , commandkit . OutcomeSuccess , 0 , "" , nil } ,
{ commandkit . Outcome { Kind : commandkit . OutcomeDomain , Status : 2 , Domain : "needs action" , Cause : cause } , commandkit . OutcomeDomain , 2 , "needs action" , cause } ,
{ commandkit . Outcome { Kind : commandkit . OutcomeDomain , Status : 0 , Domain : "complete" } , commandkit . OutcomeDomain , 0 , "complete" , nil } ,
} {
command , err := commandkit . NewCommand ( commandkit . CommandSpec [ struct { } ] { Name : "run" , Run : func ( commandkit . Invocation , struct { } ) commandkit . Outcome { return tc . outcome } } )
if err != nil {
t . Fatal ( err )
}
app , err := commandkit . New ( commandkit . Identity { Name : "example" } , command )
if err != nil {
t . Fatal ( err )
}
result := app . Execute ( context . Background ( ) , [ ] string { "run" } , commandkit . Streams { } )
wantDelivery := commandkit . DeliveryNone
if tc . cause != nil {
wantDelivery = commandkit . DeliveryComplete
}
if result . Kind != tc . kind || result . Status != tc . status || result . Domain != tc . domain || result . Cause != tc . cause || result . DiagnosticDelivery != wantDelivery {
t . Fatalf ( "result=%#v expected=%#v" , result , tc )
}
}
}
2026-10-07 16:49:56 +00:00
func TestNilDiagnosticWritersHaveNoOutputAndDoNotHideCauses ( t * testing . T ) {
cause := errors . New ( "operation failed" )
for _ , base := range [ ] commandkit . Outcome { commandkit . Success ( ) , commandkit . Domain ( "needs action" , 2 , nil ) , commandkit . Failure ( cause ) } {
base . Diagnostics = [ ] commandkit . Diagnostic { { } , { Severity : configkit . SeverityWarning } , { Severity : configkit . SeverityError } }
command , err := commandkit . NewCommand ( commandkit . CommandSpec [ struct { } ] { Name : "run" , Run : func ( commandkit . Invocation , struct { } ) commandkit . Outcome { return base } } )
if err != nil {
t . Fatal ( err )
}
app , err := commandkit . New ( commandkit . Identity { Name : "example" } , command )
if err != nil {
t . Fatal ( err )
}
var diagnostics bytes . Buffer
result := app . Execute ( context . Background ( ) , [ ] string { "run" } , commandkit . Streams { Err : & diagnostics } )
want := commandkit . DeliveryNone
if base . Cause != nil {
want = commandkit . DeliveryComplete
}
if result . Kind != base . Kind || result . Status != base . Status || result . Domain != base . Domain || result . Cause != base . Cause || result . DeliveryError != nil || result . DiagnosticDelivery != want {
t . Fatalf ( "result=%#v base=%#v" , result , base )
}
if base . Cause == nil && diagnostics . Len ( ) != 0 {
t . Fatalf ( "unexpected output=%q" , diagnostics . String ( ) )
}
if base . Cause != nil && strings . Count ( diagnostics . String ( ) , cause . Error ( ) ) != 1 {
t . Fatalf ( "cause output=%q" , diagnostics . String ( ) )
}
if base . Cause != nil {
result = app . Execute ( context . Background ( ) , [ ] string { "run" } , commandkit . Streams { Err : failingWriter { io . ErrClosedPipe } } )
if ! errors . Is ( result . Cause , cause ) || ! errors . Is ( result . DeliveryError , io . ErrClosedPipe ) || result . DiagnosticDelivery != commandkit . DeliveryIncomplete {
t . Fatalf ( "failed delivery=%#v" , result )
}
}
}
}
2026-10-07 16:52:58 +00:00
func TestParentHelpDiscoversMetadataOnlyGroups ( t * testing . T ) {
leaf , err := commandkit . Group ( "notes" , "Read notes metadata." )
if err != nil {
t . Fatal ( err )
}
parent , err := commandkit . Group ( "topics" , "Browse topic metadata." , leaf )
if err != nil {
t . Fatal ( err )
}
app , err := commandkit . New ( commandkit . Identity { Name : "example" } , parent )
if err != nil {
t . Fatal ( err )
}
loads := 0
if err := commandkit . RegisterConfig ( app , commandkit . ConfigSuite [ struct { } ] { Scopes : [ ] commandkit . ConfigScope [ struct { } ] { { Name : "app" , Operations : [ ] commandkit . ConfigOperation { commandkit . ConfigValidate } , Acquire : func ( context . Context , commandkit . ConfigRequest , struct { } ) ( commandkit . Acquired [ commandkit . ConfigView ] , error ) {
loads ++
return commandkit . Acquired [ commandkit . ConfigView ] { } , nil
} } } } ) ; err != nil {
t . Fatal ( err )
}
for _ , tc := range [ ] struct {
args [ ] string
content string
} {
{ nil , "Browse topic metadata." } ,
{ [ ] string { "topics" } , "Read notes metadata." } ,
{ [ ] string { "topics" , "--help" } , "Read notes metadata." } ,
{ [ ] string { "help" , "topics" } , "Read notes metadata." } ,
{ [ ] string { "topics" , "notes" } , "Read notes metadata." } ,
{ [ ] string { "help" , "topics" , "notes" } , "Read notes metadata." } ,
} {
var out bytes . Buffer
result := app . Execute ( context . Background ( ) , tc . args , commandkit . Streams { Out : & out } )
if result . Kind != commandkit . OutcomeSuccess || ! strings . Contains ( out . String ( ) , tc . content ) || loads != 0 {
t . Fatalf ( "%v: result=%#v output=%q loads=%d" , tc . args , result , out . String ( ) , loads )
}
if len ( tc . args ) == 1 && ( ! strings . Contains ( out . String ( ) , "Available Commands:" ) || ! strings . Contains ( out . String ( ) , "[command]" ) ) {
t . Fatalf ( "missing child inventory/usage: %q" , out . String ( ) )
}
}
var diagnostic bytes . Buffer
result := app . Execute ( context . Background ( ) , [ ] string { "topics" , "unknown" } , commandkit . Streams { Err : & diagnostic } )
if result . Kind != commandkit . OutcomeUsage || ! strings . Contains ( diagnostic . String ( ) , "[command]" ) {
t . Fatalf ( "result=%#v diagnostic=%q" , result , diagnostic . String ( ) )
}
}