Files
opentf/internal/command/views/providers_test.go
2026-03-26 17:19:27 +02:00

140 lines
4.2 KiB
Go

// Copyright (c) The OpenTofu Authors
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2023 HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package views
import (
"testing"
"github.com/google/go-cmp/cmp"
"github.com/opentofu/opentofu/internal/addrs"
"github.com/opentofu/opentofu/internal/configs"
"github.com/opentofu/opentofu/internal/getproviders"
"github.com/opentofu/opentofu/internal/tfdiags"
)
func TestProvidersView(t *testing.T) {
tests := map[string]struct {
viewCall func(v Providers)
wantStdout string
wantStderr string
}{
// Diagnostics
"warning": {
viewCall: func(v Providers) {
diags := tfdiags.Diagnostics{
tfdiags.Sourceless(tfdiags.Warning, "A warning occurred", "foo bar"),
}
v.Diagnostics(diags)
},
wantStdout: withNewline("\nWarning: A warning occurred\n\nfoo bar"),
wantStderr: "",
},
"error": {
viewCall: func(v Providers) {
diags := tfdiags.Diagnostics{
tfdiags.Sourceless(tfdiags.Error, "An error occurred", "foo bar"),
}
v.Diagnostics(diags)
},
wantStdout: "",
wantStderr: withNewline("\nError: An error occurred\n\nfoo bar"),
},
"multiple_diagnostics": {
viewCall: func(v Providers) {
diags := tfdiags.Diagnostics{
tfdiags.Sourceless(tfdiags.Warning, "A warning", "foo bar warning"),
tfdiags.Sourceless(tfdiags.Error, "An error", "foo bar error"),
}
v.Diagnostics(diags)
},
wantStdout: withNewline("\nWarning: A warning\n\nfoo bar warning"),
wantStderr: withNewline("\nError: An error\n\nfoo bar error"),
},
"module requirements": {
viewCall: func(v Providers) {
reqs := &configs.ModuleRequirements{
Name: "root",
Requirements: getproviders.Requirements{
addrs.NewDefaultProvider("aws"): getproviders.MustParseVersionConstraints(">= 3.0.0"),
},
Children: map[string]*configs.ModuleRequirements{
"vpc": {
Name: "vpc",
Requirements: getproviders.Requirements{
addrs.NewDefaultProvider("random"): getproviders.MustParseVersionConstraints("~> 3.1.0"),
},
Children: map[string]*configs.ModuleRequirements{},
Tests: map[string]*configs.TestFileModuleRequirements{},
},
},
Tests: map[string]*configs.TestFileModuleRequirements{
"main.tftest.hcl": {
Requirements: getproviders.Requirements{
addrs.NewDefaultProvider("aws"): getproviders.MustParseVersionConstraints(">= 3.2.0"),
},
Runs: map[string]*configs.ModuleRequirements{
"apply": {
Requirements: map[addrs.Provider]getproviders.VersionConstraints{
addrs.NewDefaultProvider("aws"): getproviders.MustParseVersionConstraints(">= 3.3.0"),
},
},
},
},
},
}
v.ModuleRequirements(reqs)
},
wantStdout: `
Providers required by configuration:
.
├── provider[registry.opentofu.org/hashicorp/aws] >= 3.0.0
├── test.main
│ ├── provider[registry.opentofu.org/hashicorp/aws] >= 3.2.0
│ └── run.
│ └── provider[registry.opentofu.org/hashicorp/aws] >= 3.3.0
└── module.vpc
└── provider[registry.opentofu.org/hashicorp/random] ~> 3.1.0
`,
},
"state requirements": {
viewCall: func(v Providers) {
stateReqs := getproviders.Requirements{
addrs.NewDefaultProvider("aws"): getproviders.MustParseVersionConstraints(">= 3.0.0"),
addrs.NewDefaultProvider("random"): getproviders.MustParseVersionConstraints("~> 3.1.0"),
}
v.StateRequirements(stateReqs)
},
wantStdout: `Providers required by state:
provider[registry.opentofu.org/hashicorp/aws]
provider[registry.opentofu.org/hashicorp/random]
`,
},
}
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
testProvidersHuman(t, tc.viewCall, tc.wantStdout, tc.wantStderr)
})
}
}
func testProvidersHuman(t *testing.T, call func(v Providers), wantStdout, wantStderr string) {
view, done := testView(t)
v := NewProviders(view)
call(v)
output := done(t)
if diff := cmp.Diff(wantStderr, output.Stderr()); diff != "" {
t.Errorf("invalid stderr (-want, +got):\n%s", diff)
}
if diff := cmp.Diff(wantStdout, output.Stdout()); diff != "" {
t.Errorf("invalid stdout (-want, +got):\n%s", diff)
}
}