Cover shared debug binding composition

This commit is contained in:
2026-11-08 15:03:24 +00:00
parent 7aff296c86
commit a54ff03aef
2 changed files with 88 additions and 1 deletions

View File

@@ -2,6 +2,7 @@ package commandkit_test
import (
"context"
"errors"
"io"
"sync"
"testing"
@@ -122,3 +123,83 @@ func TestSharedDebugBindingAndReportingMode(t *testing.T) {
t.Fatalf("operand after terminator: %#v %#v mode=%v", got, received, mode)
}
}
func TestSharedDebugCapturedDefaultsAndRequiredness(t *testing.T) {
type inner struct{ debug commandkit.Supplied[bool] }
type outer struct{ flags commandkit.FlagValues[inner] }
for _, required := range []bool{false, true} {
flag := commandkit.BoolFlag(commandkit.FlagMeta{Name: "debug", Short: "d", Required: required}, true, func(i *inner, v commandkit.Supplied[bool]) { i.debug = v })
captured := commandkit.CaptureFlags([]commandkit.Flag[inner]{flag}, func(i *outer) *commandkit.FlagValues[inner] { return &i.flags })
var applied, supplied inner
var applyErr error
var mode commandkit.ReportingMode
cmd := commandkit.NewCommand(commandkit.CommandSpec[outer]{Name: "run", Flags: captured, Run: func(inv commandkit.Invocation, i outer) commandkit.Outcome {
mode = inv.ReportingMode()
applied = inner{}
supplied = inner{debug: commandkit.Supplied[bool]{Value: true, Set: true}}
applyErr = i.flags.ApplyTo(&applied, flag)
if err := i.flags.ApplySuppliedTo(&supplied, flag); err != nil && applyErr == nil {
applyErr = err
}
return commandkit.Success()
}})
app, err := commandkit.New(commandkit.Identity{Name: "example"}, cmd, commandkit.FlagAliasFor("run", "-x", "-d"))
if err != nil {
t.Fatal(err)
}
result := app.Execute(context.Background(), []string{"run"}, commandkit.Streams{})
if result.Kind != commandkit.OutcomeSuccess || mode != commandkit.ReportingModeOrdinary {
t.Fatalf("omission=%#v mode=%v", result, mode)
}
if required {
if !errors.Is(applyErr, commandkit.ErrFlagInput) {
t.Fatalf("missing required: %v", applyErr)
}
} else if applyErr != nil || !applied.debug.Value || applied.debug.Set || !supplied.debug.Value || !supplied.debug.Set {
t.Fatalf("defaults=%#v %#v %v", applied, supplied, applyErr)
}
result = app.Execute(context.Background(), []string{"run", "-x=false"}, commandkit.Streams{})
if result.Kind != commandkit.OutcomeSuccess || applyErr != nil || applied.debug.Value || !applied.debug.Set || supplied.debug.Value || !supplied.debug.Set || mode != commandkit.ReportingModeOrdinary {
t.Fatalf("false=%#v %#v %#v mode=%v err=%v", result, applied, supplied, mode, applyErr)
}
}
}
func TestSharedDebugDirectRequiredAndRenamedBinding(t *testing.T) {
type input struct{ debug commandkit.Supplied[bool] }
var got input
var mode commandkit.ReportingMode
original := commandkit.BoolFlag(commandkit.FlagMeta{Name: "debug", Required: true}, true, func(i *input, v commandkit.Supplied[bool]) { i.debug = v })
required := commandkit.NewCommand(commandkit.CommandSpec[input]{Name: "required", Flags: []commandkit.Flag[input]{original}, Run: func(inv commandkit.Invocation, i input) commandkit.Outcome {
got = i
mode = inv.ReportingMode()
return commandkit.Success()
}})
renamed := commandkit.NewCommand(commandkit.CommandSpec[input]{Name: "renamed", Flags: []commandkit.Flag[input]{commandkit.RenameFlag(original, "trace")}, Run: func(inv commandkit.Invocation, i input) commandkit.Outcome {
got = i
mode = inv.ReportingMode()
return commandkit.Success()
}})
ordinary := commandkit.BoolFlag(commandkit.FlagMeta{Name: "local"}, false, func(i *input, v commandkit.Supplied[bool]) { i.debug = v })
attached := commandkit.NewCommand(commandkit.CommandSpec[input]{Name: "attached", Flags: []commandkit.Flag[input]{commandkit.RenameFlag(ordinary, "debug")}, Run: func(inv commandkit.Invocation, i input) commandkit.Outcome {
got = i
mode = inv.ReportingMode()
return commandkit.Success()
}})
app, err := commandkit.New(commandkit.Identity{Name: "example"}, required, renamed, attached)
if err != nil {
t.Fatal(err)
}
if r := app.Execute(context.Background(), []string{"required"}, commandkit.Streams{}); r.Kind != commandkit.OutcomeUsage {
t.Fatalf("required omission=%#v", r)
}
if r := app.Execute(context.Background(), []string{"required", "--debug=false"}, commandkit.Streams{}); r.Kind != commandkit.OutcomeSuccess || got.debug.Value || !got.debug.Set || mode != commandkit.ReportingModeOrdinary {
t.Fatalf("explicit false=%#v %#v", r, got)
}
if r := app.Execute(context.Background(), []string{"renamed", "--trace=false", "--debug"}, commandkit.Streams{}); r.Kind != commandkit.OutcomeSuccess || got.debug.Value || !got.debug.Set || mode != commandkit.ReportingModeDebug {
t.Fatalf("renamed=%#v %#v mode=%v", r, got, mode)
}
if r := app.Execute(context.Background(), []string{"attached", "--debug"}, commandkit.Streams{}); r.Kind != commandkit.OutcomeSuccess || !got.debug.Value || !got.debug.Set || mode != commandkit.ReportingModeDebug {
t.Fatalf("renamed to debug=%#v %#v mode=%v", r, got, mode)
}
}