2026-11-08 14:59:37 +00:00
|
|
|
package commandkit_test
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"io"
|
|
|
|
|
"sync"
|
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
|
|
commandkit "go.maximumdirect.net/commandkit"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestInvocationReportingMode(t *testing.T) {
|
|
|
|
|
if got := (commandkit.Invocation{}).ReportingMode(); got != commandkit.ReportingModeOrdinary {
|
|
|
|
|
t.Fatalf("zero invocation mode = %v", got)
|
|
|
|
|
}
|
|
|
|
|
var retained commandkit.Invocation
|
|
|
|
|
var observed commandkit.ReportingMode
|
|
|
|
|
command := commandkit.NewCommand(commandkit.CommandSpec[struct{}]{Name: "run", Run: func(inv commandkit.Invocation, _ struct{}) commandkit.Outcome {
|
|
|
|
|
retained = inv
|
|
|
|
|
observed = inv.ReportingMode()
|
|
|
|
|
return commandkit.Success()
|
|
|
|
|
}})
|
|
|
|
|
app, err := commandkit.New(commandkit.Identity{Name: "example"}, command)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
for _, tc := range []struct {
|
|
|
|
|
flag string
|
|
|
|
|
want commandkit.ReportingMode
|
|
|
|
|
}{{"", commandkit.ReportingModeOrdinary}, {"--quiet", commandkit.ReportingModeQuiet}, {"--verbose", commandkit.ReportingModeVerbose}, {"--debug", commandkit.ReportingModeDebug}, {"", commandkit.ReportingModeOrdinary}} {
|
|
|
|
|
args := []string{"run"}
|
|
|
|
|
if tc.flag != "" {
|
|
|
|
|
args = append(args, tc.flag)
|
|
|
|
|
}
|
|
|
|
|
result := app.Execute(context.Background(), args, commandkit.Streams{Out: io.Discard, Err: io.Discard})
|
|
|
|
|
if result.Kind != commandkit.OutcomeSuccess || observed != tc.want || retained.ReportingMode() != tc.want {
|
|
|
|
|
t.Fatalf("%q: outcome=%#v mode=%v", tc.flag, result, retained.ReportingMode())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestInvocationReportingModeConcurrentReads(t *testing.T) {
|
|
|
|
|
command := commandkit.NewCommand(commandkit.CommandSpec[struct{}]{Name: "run", Run: func(inv commandkit.Invocation, _ struct{}) commandkit.Outcome {
|
|
|
|
|
start := make(chan struct{})
|
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
|
for i := 0; i < 4; i++ {
|
|
|
|
|
wg.Add(1)
|
|
|
|
|
go func() {
|
|
|
|
|
defer wg.Done()
|
|
|
|
|
<-start
|
|
|
|
|
for j := 0; j < 100; j++ {
|
|
|
|
|
if inv.ReportingMode() != commandkit.ReportingModeDebug {
|
|
|
|
|
t.Error("mode changed")
|
|
|
|
|
}
|
|
|
|
|
_ = inv.Reporter().Debug("diagnostic")
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
}
|
|
|
|
|
close(start)
|
|
|
|
|
wg.Wait()
|
|
|
|
|
return commandkit.Success()
|
|
|
|
|
}})
|
|
|
|
|
app, err := commandkit.New(commandkit.Identity{Name: "example"}, command)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
if outcome := app.Execute(context.Background(), []string{"run", "--debug"}, commandkit.Streams{Out: io.Discard, Err: io.Discard}); outcome.Kind != commandkit.OutcomeSuccess {
|
|
|
|
|
t.Fatal(outcome)
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-11-08 15:02:00 +00:00
|
|
|
|
|
|
|
|
func TestSharedDebugBindingAndReportingMode(t *testing.T) {
|
|
|
|
|
type input struct {
|
|
|
|
|
debug commandkit.Supplied[bool]
|
|
|
|
|
before, after commandkit.Supplied[string]
|
|
|
|
|
operand commandkit.Supplied[string]
|
|
|
|
|
}
|
|
|
|
|
var received input
|
|
|
|
|
var mode commandkit.ReportingMode
|
|
|
|
|
factories, calls := 0, 0
|
|
|
|
|
parse := func(s string) (string, error) { return s, nil }
|
|
|
|
|
cmd := commandkit.NewCommand(commandkit.CommandSpec[input]{Name: "run", NewInput: func() input { factories++; return input{} }, Flags: []commandkit.Flag[input]{
|
|
|
|
|
commandkit.ValueFlag(commandkit.FlagMeta{Name: "before"}, (*string)(nil), parse, func(i *input, v commandkit.Supplied[string]) { i.before = v }),
|
|
|
|
|
commandkit.BoolFlag(commandkit.FlagMeta{Name: "debug", Short: "d"}, false, func(i *input, v commandkit.Supplied[bool]) { i.debug = v }),
|
|
|
|
|
commandkit.ValueFlag(commandkit.FlagMeta{Name: "after"}, (*string)(nil), parse, func(i *input, v commandkit.Supplied[string]) { i.after = v }),
|
|
|
|
|
}, Arguments: []commandkit.Argument[input]{commandkit.ValueArgument(commandkit.ArgumentMeta{Name: "operand"}, false, parse, func(i *input, v commandkit.Supplied[string]) { i.operand = v })}, Run: func(inv commandkit.Invocation, i input) commandkit.Outcome {
|
|
|
|
|
calls++
|
|
|
|
|
received = i
|
|
|
|
|
mode = inv.ReportingMode()
|
|
|
|
|
return commandkit.Success()
|
|
|
|
|
}})
|
|
|
|
|
app, err := commandkit.New(commandkit.Identity{Name: "example"}, cmd, commandkit.FlagAlias("-x", "--debug"))
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
for _, tc := range []struct {
|
|
|
|
|
args []string
|
|
|
|
|
value, set bool
|
|
|
|
|
mode commandkit.ReportingMode
|
|
|
|
|
}{
|
|
|
|
|
{nil, false, false, commandkit.ReportingModeOrdinary}, {[]string{"--debug"}, true, true, commandkit.ReportingModeDebug}, {[]string{"--debug", "--quiet"}, true, true, commandkit.ReportingModeQuiet}, {[]string{"--quiet", "--debug"}, true, true, commandkit.ReportingModeDebug}, {[]string{"--debug", "--verbose"}, true, true, commandkit.ReportingModeVerbose}, {[]string{"--debug", "--debug=false"}, false, true, commandkit.ReportingModeOrdinary}, {[]string{"--verbose", "--debug", "--debug=false"}, false, true, commandkit.ReportingModeOrdinary}, {[]string{"--debug", "--quiet=false"}, true, true, commandkit.ReportingModeDebug}, {[]string{"--debug", "--progress=false"}, true, true, commandkit.ReportingModeDebug}, {[]string{"-x"}, true, true, commandkit.ReportingModeDebug}, {[]string{"-d=false"}, false, true, commandkit.ReportingModeOrdinary},
|
|
|
|
|
} {
|
|
|
|
|
args := append([]string{"run", "--before=one", "--after=two"}, tc.args...)
|
|
|
|
|
got := app.Execute(context.Background(), args, commandkit.Streams{Out: io.Discard, Err: io.Discard})
|
|
|
|
|
if got.Kind != commandkit.OutcomeSuccess || received.debug.Value != tc.value || received.debug.Set != tc.set || mode != tc.mode || received.before.Value != "one" || received.after.Value != "two" {
|
|
|
|
|
t.Fatalf("%v: result=%#v input=%#v mode=%v", tc.args, got, received, mode)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for _, value := range []string{"--debug=", "--debug=invalid"} {
|
|
|
|
|
beforeFactories, beforeCalls := factories, calls
|
|
|
|
|
got := app.Execute(context.Background(), []string{"run", value}, commandkit.Streams{Out: io.Discard, Err: io.Discard})
|
|
|
|
|
if got.Kind != commandkit.OutcomeUsage || factories != beforeFactories || calls != beforeCalls {
|
|
|
|
|
t.Fatalf("%s result=%#v factories=%d calls=%d", value, got, factories, calls)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
got := app.Execute(context.Background(), []string{"run", "--before", "--debug"}, commandkit.Streams{Out: io.Discard, Err: io.Discard})
|
|
|
|
|
if got.Kind != commandkit.OutcomeSuccess || received.before.Value != "--debug" || received.debug.Set || mode != commandkit.ReportingModeOrdinary {
|
|
|
|
|
t.Fatalf("option-looking value: %#v %#v mode=%v", got, received, mode)
|
|
|
|
|
}
|
|
|
|
|
got = app.Execute(context.Background(), []string{"run", "--", "--debug"}, commandkit.Streams{Out: io.Discard, Err: io.Discard})
|
|
|
|
|
if got.Kind != commandkit.OutcomeSuccess || received.operand.Value != "--debug" || received.debug.Set || mode != commandkit.ReportingModeOrdinary {
|
|
|
|
|
t.Fatalf("operand after terminator: %#v %#v mode=%v", got, received, mode)
|
|
|
|
|
}
|
|
|
|
|
}
|