Test comparison preparation through provider behavior
This commit is contained in:
@@ -93,8 +93,8 @@ func TestComparisonPreparesEqualSelectionsWithSeparateTypedInputs(t *testing.T)
|
||||
"config", "diff", "--config", "same.yml", "--against-config", "same.yml", "--overlay=",
|
||||
"--enabled=false", "--limit=0", "--tag", "alpha", "--tag", "beta",
|
||||
}, commandkit.Streams{Out: io.Discard, Err: io.Discard})
|
||||
if outcome.Kind == commandkit.OutcomeUsage {
|
||||
t.Fatalf("valid comparison inputs rejected: %#v", outcome)
|
||||
if outcome.Kind != commandkit.OutcomeSuccess {
|
||||
t.Fatalf("valid comparison outcome = %#v", outcome)
|
||||
}
|
||||
if inputCalls != 2 || checkCalls != 2 || stateCalls != 1 {
|
||||
t.Fatalf("preparation calls input=%d check=%d state=%d", inputCalls, checkCalls, stateCalls)
|
||||
@@ -111,53 +111,65 @@ func TestComparisonPreparesEqualSelectionsWithSeparateTypedInputs(t *testing.T)
|
||||
}
|
||||
}
|
||||
|
||||
func TestComparisonPlanStoresPairSeparatelyFromOrdinaryInputs(t *testing.T) {
|
||||
func TestComparisonProviderReceivesCheckedPairAndSharedState(t *testing.T) {
|
||||
type input struct{ ID int }
|
||||
inputCalls, checkCalls, stateCalls := 0, 0, 0
|
||||
prepared := captureSuite(Suite[input, struct{}]{
|
||||
type state struct{ Label string }
|
||||
inputCalls, checkCalls, stateCalls, compareCalls, acquireCalls := 0, 0, 0, 0, 0
|
||||
checked := make(map[Selection]input)
|
||||
shared := &state{Label: "shared"}
|
||||
var request ComparisonRequest[input]
|
||||
app := newConfigTestApp(t, Command(Suite[input, *state]{
|
||||
NewInput: func() input {
|
||||
inputCalls++
|
||||
return input{ID: inputCalls}
|
||||
},
|
||||
NewState: func() struct{} { stateCalls++; return struct{}{} },
|
||||
NewState: func() *state {
|
||||
stateCalls++
|
||||
if checkCalls != 2 {
|
||||
t.Errorf("shared state created after %d input checks", checkCalls)
|
||||
}
|
||||
return shared
|
||||
},
|
||||
CheckInput: func(scope string, selection Selection, value input) error {
|
||||
checkCalls++
|
||||
if scope != "app" || value.ID != checkCalls {
|
||||
return errors.New("comparison inputs were not prepared in order")
|
||||
if scope != "app" {
|
||||
return errors.New("unexpected scope")
|
||||
}
|
||||
checked[selection] = value
|
||||
return nil
|
||||
},
|
||||
Scopes: []Scope[input, struct{}]{{
|
||||
Name: "app", Operations: []Operation{Diff},
|
||||
Compare: func(context.Context, ComparisonRequest[input], struct{}) (commandkit.Acquired[[]configkit.Difference], error) {
|
||||
Scopes: []Scope[input, *state]{{
|
||||
Name: "app", Operations: []Operation{Show, Diff},
|
||||
Acquire: func(context.Context, Request, input, *state) (commandkit.Acquired[View], error) {
|
||||
acquireCalls++
|
||||
return commandkit.Acquired[View]{}, errors.New("ordinary acquisition reached during comparison")
|
||||
},
|
||||
Compare: func(_ context.Context, pair ComparisonRequest[input], value *state) (commandkit.Acquired[[]configkit.Difference], error) {
|
||||
compareCalls++
|
||||
if checkCalls != 2 || stateCalls != 1 || value != shared {
|
||||
t.Errorf("provider reached with checks=%d states=%d shared=%t", checkCalls, stateCalls, value == shared)
|
||||
}
|
||||
request = pair
|
||||
return commandkit.Acquired[[]configkit.Difference]{}, nil
|
||||
},
|
||||
}},
|
||||
})
|
||||
}))
|
||||
outcome := app.Execute(context.Background(), []string{
|
||||
"config", "diff", "--config", "before.yml", "--against-overlay=",
|
||||
}, commandkit.Streams{Out: io.Discard, Err: io.Discard})
|
||||
if outcome.Kind != commandkit.OutcomeSuccess {
|
||||
t.Fatalf("comparison outcome = %#v", outcome)
|
||||
}
|
||||
left := Selection{Config: commandkit.Supplied[string]{Value: "before.yml", Set: true}}
|
||||
right := Selection{Overlay: commandkit.Supplied[string]{Set: true}}
|
||||
commandInput := &configCommandInput[input, struct{}]{
|
||||
selection: left,
|
||||
against: right,
|
||||
format: commandkit.Supplied[string]{Value: "yaml"},
|
||||
right := Selection{Config: left.Config, Overlay: commandkit.Supplied[string]{Set: true}}
|
||||
if request.Left.Selection != left || request.Right.Selection != right {
|
||||
t.Fatalf("provider selections = %#v", request)
|
||||
}
|
||||
if err := prepareConfigOperation(prepared, Diff, commandInput); err != nil {
|
||||
t.Fatal(err)
|
||||
if len(checked) != 2 || request.Left.Input != checked[left] || request.Right.Input != checked[right] {
|
||||
t.Fatalf("provider inputs = %#v, checked = %#v", request, checked)
|
||||
}
|
||||
plan := commandInput.plan
|
||||
if plan == nil || plan.comparison == nil || len(plan.scopes) != 0 {
|
||||
t.Fatalf("comparison was not stored separately: %#v", plan)
|
||||
}
|
||||
if plan.comparison.scope.scope.Name != "app" {
|
||||
t.Fatalf("comparison scope = %q", plan.comparison.scope.scope.Name)
|
||||
}
|
||||
wantRight := Selection{Config: left.Config, Overlay: right.Overlay}
|
||||
request := plan.comparison.request
|
||||
if request.Left.Selection != left || request.Right.Selection != wantRight || request.Left.Input.ID != 1 || request.Right.Input.ID != 2 {
|
||||
t.Fatalf("prepared request = %#v", request)
|
||||
}
|
||||
if inputCalls != 2 || checkCalls != 2 || stateCalls != 0 {
|
||||
t.Fatalf("preparation calls input=%d check=%d state=%d", inputCalls, checkCalls, stateCalls)
|
||||
if inputCalls != 2 || checkCalls != 2 || stateCalls != 1 || compareCalls != 1 || acquireCalls != 0 {
|
||||
t.Fatalf("invocation calls input=%d check=%d state=%d compare=%d acquire=%d", inputCalls, checkCalls, stateCalls, compareCalls, acquireCalls)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user