Compile configuration selector metadata during capture

This commit is contained in:
2026-10-11 13:05:22 +00:00
parent fba917f5bd
commit cec4da69d3
4 changed files with 115 additions and 79 deletions

View File

@@ -47,6 +47,60 @@ func TestScopeDiscoveryIsOrderedAndDoesNotUseSuiteFactories(t *testing.T) {
}
}
func TestOperationSelectorsAreCapturedForSupportedScopes(t *testing.T) {
type input struct{ Tenant, Campaign commandkit.Supplied[string] }
tenant := commandkit.ValueFlag(commandkit.FlagMeta{Name: "tenant", Required: true}, (*string)(nil), parseConfigString,
func(target *input, value commandkit.Supplied[string]) { target.Tenant = value })
campaign := commandkit.ValueFlag(commandkit.FlagMeta{Name: "campaign", Required: true}, (*string)(nil), parseConfigString,
func(target *input, value commandkit.Supplied[string]) { target.Campaign = value })
calls := 0
suite := Suite[input, struct{}]{
Selectors: []Selector[input]{{Binding: tenant, Scopes: []string{"app"}}, {Binding: campaign, Scopes: []string{"promptkit"}}},
Scopes: []Scope[input, struct{}]{
{Name: "app", Operations: []Operation{Validate}, Acquire: func(_ context.Context, _ Request, value input, _ struct{}) (commandkit.Acquired[View], error) {
calls++
if !value.Tenant.Set || value.Tenant.Value != "team" || value.Campaign.Set {
t.Errorf("app input = %#v", value)
}
return commandkit.Acquired[View]{}, nil
}},
{Name: "promptkit", Operations: []Operation{Sources}, Acquire: func(_ context.Context, _ Request, value input, _ struct{}) (commandkit.Acquired[View], error) {
calls++
if !value.Campaign.Set || value.Campaign.Value != "spring" || value.Tenant.Set {
t.Errorf("promptkit input = %#v", value)
}
return commandkit.Acquired[View]{Value: View{Sources: &sourceInventory{}}}, nil
}},
},
}
app := newConfigTestApp(t, Command(suite))
// Captured capabilities, applicability, and handles survive source edits.
suite.Scopes[0].Operations[0] = Sources
suite.Selectors[0].Scopes[0] = "promptkit"
suite.Selectors[1].Binding = commandkit.Flag[input]{}
for _, args := range [][]string{
{"config", "validate", "--tenant", "team"},
{"config", "sources", "--scope", "promptkit", "--campaign", "spring"},
} {
outcome := app.Execute(context.Background(), args, commandkit.Streams{Out: io.Discard, Err: io.Discard})
if outcome.Kind != commandkit.OutcomeSuccess {
t.Fatalf("%v: %#v", args, outcome)
}
}
for _, args := range [][]string{
{"config", "validate", "--campaign", "spring"},
{"config", "sources", "--scope", "promptkit", "--tenant", "team"},
} {
outcome := app.Execute(context.Background(), args, commandkit.Streams{Out: io.Discard, Err: io.Discard})
if outcome.Kind != commandkit.OutcomeUsage {
t.Fatalf("selector for another operation accepted: %v: %#v", args, outcome)
}
}
if calls != 2 {
t.Fatalf("acquisition calls = %d, want 2", calls)
}
}
func TestValidationPreparesIndependentScopeInputsAndOneSharedState(t *testing.T) {
type inspectInput struct {
Campaign commandkit.Supplied[string]