Cover shared debug binding composition
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Shared debug binding implementation plan
|
||||
|
||||
Status: in progress; Stages 1–3 complete.
|
||||
Status: in progress; Stages 1–4 complete.
|
||||
Baseline: `6727d22ce6e1ac668b56a3e6d8fa5f7a06e54d88`.
|
||||
Execution audience: Luna coding agent.
|
||||
|
||||
@@ -185,6 +185,12 @@ parse, without changing unrelated input indexes, grammar, or failure handling.
|
||||
|
||||
## Stage 4 — Preserve composition, defaults, and alias behavior
|
||||
|
||||
**Complete.** Existing capture and rename machinery retains the boolean
|
||||
identity and requiredness without production changes. Focused public tests
|
||||
cover true defaults, explicit false, direct and captured requiredness, both
|
||||
application methods, renaming in both directions, and an alias to the local
|
||||
short spelling; capture and alias tests pass offline with Go 1.27.0.
|
||||
|
||||
Primary files: [flag_values.go](../../flag_values.go),
|
||||
[binding.go](../../binding.go), [flag_aliases.go](../../flag_aliases.go).
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user