Prepare configuration scope metadata
This commit is contained in:
@@ -85,6 +85,77 @@ func TestConfigInputDefaultsToAppAndRetainsAbsentSelections(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegisterConfigOwnsPreparedScopeAndSelectorMetadata(t *testing.T) {
|
||||
type selectorInput struct{ Region Supplied[string] }
|
||||
var acquired selectorInput
|
||||
suite := ConfigSuite[selectorInput]{
|
||||
Selectors: []Selector[selectorInput]{{
|
||||
Binding: ValueFlag[selectorInput](FlagMeta{Name: "region"}, nil, parseString, func(input *selectorInput, value Supplied[string]) { input.Region = value }),
|
||||
Scopes: []string{"app"},
|
||||
}},
|
||||
Scopes: []ConfigScope[selectorInput]{{
|
||||
Name: "app",
|
||||
Operations: []ConfigOperation{ConfigValidate},
|
||||
Acquire: func(_ context.Context, _ ConfigRequest, input selectorInput) (Acquired[ConfigView], error) {
|
||||
acquired = input
|
||||
return Acquired[ConfigView]{}, nil
|
||||
},
|
||||
}},
|
||||
}
|
||||
app, err := New(Identity{Name: "example"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := RegisterConfig(app, suite); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
suite.Scopes[0].Name = "renamed"
|
||||
suite.Scopes[0].Operations[0] = ConfigShow
|
||||
suite.Selectors[0].Scopes[0] = "renamed"
|
||||
|
||||
var inventory bytes.Buffer
|
||||
if result := app.Execute(context.Background(), []string{"config", "scopes"}, Streams{Out: &inventory}); result.Kind != OutcomeSuccess {
|
||||
t.Fatalf("scope inventory outcome = %#v", result)
|
||||
}
|
||||
if got := inventory.String(); got != "app: validate\n" {
|
||||
t.Fatalf("scope inventory after caller mutation = %q", got)
|
||||
}
|
||||
if result := app.Execute(context.Background(), []string{"config", "validate", "--scope=app", "--region=west"}, Streams{}); result.Kind != OutcomeSuccess {
|
||||
t.Fatalf("registered scope execution after caller mutation = %#v", result)
|
||||
}
|
||||
if acquired.Region != (Supplied[string]{Value: "west", Set: true}) {
|
||||
t.Fatalf("acquired selector after caller mutation = %#v", acquired)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegisterConfigRejectsDuplicateSelectorNamesAndShorts(t *testing.T) {
|
||||
type selectorInput struct{ First, Second string }
|
||||
tests := []struct {
|
||||
name string
|
||||
firstMeta FlagMeta
|
||||
secondMeta FlagMeta
|
||||
}{
|
||||
{name: "name", firstMeta: FlagMeta{Name: "region", Short: "r"}, secondMeta: FlagMeta{Name: "region", Short: "g"}},
|
||||
{name: "short", firstMeta: FlagMeta{Name: "region", Short: "r"}, secondMeta: FlagMeta{Name: "group", Short: "r"}},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
app, err := New(Identity{Name: "example"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
suite := ConfigSuite[selectorInput]{Selectors: []Selector[selectorInput]{
|
||||
{Binding: ValueFlag[selectorInput](test.firstMeta, nil, parseString, func(input *selectorInput, value Supplied[string]) { input.First = value.Value })},
|
||||
{Binding: ValueFlag[selectorInput](test.secondMeta, nil, parseString, func(input *selectorInput, value Supplied[string]) { input.Second = value.Value })},
|
||||
}}
|
||||
if err := RegisterConfig(app, suite); err == nil || !strings.Contains(err.Error(), "duplicate configuration selector flag") {
|
||||
t.Fatalf("RegisterConfig error = %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegisterConfigRejectsInvalidSuitesAndCollisions(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -147,13 +218,14 @@ func TestConfigSelectorPreflightAndScopedContextProjection(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
preparedSuite := prepareConfigSuite(normalized)
|
||||
spec := CommandSpec[configInput[selectorInput]]{Flags: configInputFlags(normalized, "text")}
|
||||
prepared, err := prepareInput(spec, [][]string{{"all"}, {"text"}, {""}, nil, {"0"}, {"false"}, nil}, nil, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
input := prepared.build()
|
||||
scopeNames, err := preflightConfig(normalized, input, ConfigValidate)
|
||||
scopeNames, err := preflightConfig(preparedSuite, input, ConfigValidate)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -167,7 +239,7 @@ func TestConfigSelectorPreflightAndScopedContextProjection(t *testing.T) {
|
||||
t.Fatalf("NewContext called during preflight %d times", baseContextCalls)
|
||||
}
|
||||
|
||||
contexts := contextsForScopes(normalized, input, scopeNames)
|
||||
contexts := contextsForScopes(preparedSuite, input, scopeNames)
|
||||
if baseContextCalls != 1 {
|
||||
t.Fatalf("NewContext calls = %d, want one", baseContextCalls)
|
||||
}
|
||||
@@ -194,11 +266,12 @@ func TestConfigPreflightRejectsUnsupportedAggregateAndInapplicableSelector(t *te
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
preparedSuite := prepareConfigSuite(normalized)
|
||||
prepared, err := prepareInput(CommandSpec[configInput[selectorInput]]{Flags: configInputFlags(normalized, "text")}, [][]string{{"all"}, {"text"}, nil, nil, nil}, nil, true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := preflightConfig(normalized, prepared.build(), ConfigValidate); err == nil || !strings.Contains(err.Error(), "does not support validate") {
|
||||
if _, err := preflightConfig(preparedSuite, prepared.build(), ConfigValidate); err == nil || !strings.Contains(err.Error(), "does not support validate") {
|
||||
t.Fatalf("unsupported aggregate error = %v", err)
|
||||
}
|
||||
if newContextCalls != 0 {
|
||||
@@ -209,7 +282,7 @@ func TestConfigPreflightRejectsUnsupportedAggregateAndInapplicableSelector(t *te
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := preflightConfig(normalized, prepared.build(), ConfigValidate); err == nil || !strings.Contains(err.Error(), "not applicable") {
|
||||
if _, err := preflightConfig(preparedSuite, prepared.build(), ConfigValidate); err == nil || !strings.Contains(err.Error(), "not applicable") {
|
||||
t.Fatalf("inapplicable selector error = %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user