mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-30 10:47:14 -06:00
a851566c56
Most of the time we're converting from HCL diagnostics to tfdiags as we expose diagnostics directly from HCL, but occasionally we need to to the reverse. For example, our configs package uses hcl.Diagnostics by convention because it's primarily working with HCL, but sometimes it interacts with functions elsewhere (like in the "addrs" package) that return tfdiags.Diagnostics, where they need to be adapted to return in an HCL shape. This should be used with some care because, similar to Diagnostics.ForRPC, it forces immediate flattening of all of the diagnostics to a single type and so can potentially lose internal tracking information that appears in other tfdiags.Diagnostic information, such as the additional metadata tracked in the ConsolidateWarnings result to allow later appending to existing groups.
100 lines
2.6 KiB
Go
100 lines
2.6 KiB
Go
package tfdiags
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"github.com/google/go-cmp/cmp/cmpopts"
|
|
"github.com/hashicorp/hcl/v2"
|
|
"github.com/zclconf/go-cty/cty"
|
|
)
|
|
|
|
func TestDiagnosticsToHCL(t *testing.T) {
|
|
var diags Diagnostics
|
|
diags = diags.Append(Sourceless(
|
|
Error,
|
|
"A sourceless diagnostic",
|
|
"...that has a detail",
|
|
))
|
|
diags = diags.Append(fmt.Errorf("a diagnostic promoted from an error"))
|
|
diags = diags.Append(SimpleWarning("A diagnostic from a simple warning"))
|
|
diags = diags.Append(&hcl.Diagnostic{
|
|
Severity: hcl.DiagWarning,
|
|
Summary: "A diagnostic from HCL",
|
|
Detail: "...that has a detail and source information",
|
|
Subject: &hcl.Range{
|
|
Filename: "test.tf",
|
|
Start: hcl.Pos{Line: 1, Column: 2, Byte: 1},
|
|
End: hcl.Pos{Line: 1, Column: 3, Byte: 2},
|
|
},
|
|
Context: &hcl.Range{
|
|
Filename: "test.tf",
|
|
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
|
|
End: hcl.Pos{Line: 1, Column: 4, Byte: 3},
|
|
},
|
|
EvalContext: &hcl.EvalContext{},
|
|
Expression: &fakeHCLExpression{},
|
|
})
|
|
|
|
got := diags.ToHCL()
|
|
want := hcl.Diagnostics{
|
|
{
|
|
Severity: hcl.DiagError,
|
|
Summary: "A sourceless diagnostic",
|
|
Detail: "...that has a detail",
|
|
},
|
|
{
|
|
Severity: hcl.DiagError,
|
|
Summary: "a diagnostic promoted from an error",
|
|
},
|
|
{
|
|
Severity: hcl.DiagWarning,
|
|
Summary: "A diagnostic from a simple warning",
|
|
},
|
|
{
|
|
Severity: hcl.DiagWarning,
|
|
Summary: "A diagnostic from HCL",
|
|
Detail: "...that has a detail and source information",
|
|
Subject: &hcl.Range{
|
|
Filename: "test.tf",
|
|
Start: hcl.Pos{Line: 1, Column: 2, Byte: 1},
|
|
End: hcl.Pos{Line: 1, Column: 3, Byte: 2},
|
|
},
|
|
Context: &hcl.Range{
|
|
Filename: "test.tf",
|
|
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
|
|
End: hcl.Pos{Line: 1, Column: 4, Byte: 3},
|
|
},
|
|
EvalContext: &hcl.EvalContext{},
|
|
Expression: &fakeHCLExpression{},
|
|
},
|
|
}
|
|
|
|
if diff := cmp.Diff(want, got, cmpopts.IgnoreUnexported(hcl.EvalContext{})); diff != "" {
|
|
t.Errorf("incorrect result\n%s", diff)
|
|
}
|
|
}
|
|
|
|
// We have this here just to give us something easy to compare in the test
|
|
// above, because we only care that the expression passes through, not about
|
|
// how exactly it is shaped.
|
|
type fakeHCLExpression struct {
|
|
}
|
|
|
|
func (e *fakeHCLExpression) Range() hcl.Range {
|
|
return hcl.Range{}
|
|
}
|
|
|
|
func (e *fakeHCLExpression) StartRange() hcl.Range {
|
|
return hcl.Range{}
|
|
}
|
|
|
|
func (e *fakeHCLExpression) Variables() []hcl.Traversal {
|
|
return nil
|
|
}
|
|
|
|
func (e *fakeHCLExpression) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
|
|
return cty.DynamicVal, nil
|
|
}
|