From 6c57395ef3adf70a0e1e149e00713c2ffe73cd23 Mon Sep 17 00:00:00 2001 From: Paddy Carver Date: Thu, 18 Feb 2021 02:06:45 -0800 Subject: [PATCH] Test empty diagnostics. Add a test for a diagnostic with no steps to make sure it still gets associated with the resource in the config. Follow up to #27710 using @alisdair's suggested testing. --- plugin/convert/diagnostics_test.go | 44 ++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/plugin/convert/diagnostics_test.go b/plugin/convert/diagnostics_test.go index b8574dc4d..604c98d57 100644 --- a/plugin/convert/diagnostics_test.go +++ b/plugin/convert/diagnostics_test.go @@ -6,6 +6,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" + "github.com/hashicorp/hcl/v2" + "github.com/hashicorp/hcl/v2/hclsyntax" proto "github.com/hashicorp/terraform/internal/tfplugin5" "github.com/hashicorp/terraform/tfdiags" "github.com/zclconf/go-cty/cty" @@ -365,3 +367,45 @@ func TestDiagnostics(t *testing.T) { }) } } + +// Test that a diagnostic with a present but empty attribute results in a +// whole body diagnostic. We verify this by inspecting the resulting Subject +// from the diagnostic when considered in the context of a config body. +func TestProtoDiagnostics_emptyAttributePath(t *testing.T) { + protoDiags := []*proto.Diagnostic{ + { + Severity: proto.Diagnostic_ERROR, + Summary: "error 1", + Detail: "error 1 detail", + Attribute: &proto.AttributePath{ + Steps: []*proto.AttributePath_Step{ + // this slice is intentionally left empty + }, + }, + }, + } + tfDiags := ProtoToDiagnostics(protoDiags) + + testConfig := `provider "test" { + foo = "bar" +}` + f, parseDiags := hclsyntax.ParseConfig([]byte(testConfig), "test.tf", hcl.Pos{Line: 1, Column: 1}) + if parseDiags.HasErrors() { + t.Fatal(parseDiags) + } + diags := tfDiags.InConfigBody(f.Body) + + if len(tfDiags) != 1 { + t.Fatalf("expected 1 diag, got %d", len(tfDiags)) + } + got := diags[0].Source().Subject + want := &tfdiags.SourceRange{ + Filename: "test.tf", + Start: tfdiags.SourcePos{Line: 1, Column: 1}, + End: tfdiags.SourcePos{Line: 1, Column: 1}, + } + + if !cmp.Equal(got, want, typeComparer, valueComparer) { + t.Fatal(cmp.Diff(got, want, typeComparer, valueComparer)) + } +}