Skip to content

Commit 57148ba

Browse files
committed
add unit test for existing extra
1 parent af53414 commit 57148ba

File tree

2 files changed

+55
-5
lines changed

2 files changed

+55
-5
lines changed

types/diagnostics.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ type DiagnosticExtra struct {
1010
Code string `json:"code"`
1111

1212
// If there was a previous extra, store it here for unwrapping.
13-
wrapped any
13+
Wrapped any
1414
}
1515

1616
var _ hcl.DiagnosticExtraUnwrapper = DiagnosticExtra{}
1717

1818
func (e DiagnosticExtra) UnwrapDiagnosticExtra() interface{} {
19-
return e.wrapped
19+
return e.Wrapped
2020
}
2121

2222
func ExtractDiagnosticExtra(diag *hcl.Diagnostic) DiagnosticExtra {
@@ -29,16 +29,17 @@ func SetDiagnosticExtra(diag *hcl.Diagnostic, extra DiagnosticExtra) {
2929
existing, ok := hcl.DiagnosticExtra[DiagnosticExtra](diag)
3030
if ok {
3131
// If an existing extra is present, we will keep the underlying
32-
// wrapped. This is not perfect, as any parents are lost.
32+
// Wrapped. This is not perfect, as any parents are lost.
3333
// So try to avoid calling 'SetDiagnosticExtra' more than once.
34-
extra.wrapped = existing.wrapped
34+
// TODO: Fix this so we maintain the parents too. Maybe use a pointer?
35+
extra.Wrapped = existing.Wrapped
3536
diag.Extra = extra
3637
return
3738
}
3839

3940
// Maintain any existing extra fields.
4041
if diag.Extra != nil {
41-
extra.wrapped = diag.Extra
42+
extra.Wrapped = diag.Extra
4243
}
4344
diag.Extra = extra
4445
}

types/diagnostics_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,44 @@ func TestDiagnosticExtra(t *testing.T) {
3535
require.Equal(t, "bazz", extra.Code)
3636
}
3737

38+
// TestDiagnosticExtraExisting is a test case where the DiagnosticExtra
39+
// is already set in the wrapped chain of diagnostics.
40+
// The `parent` wrapped is lost here, so calling `SetDiagnosticExtra` is
41+
// lossy. In practice, we only call this once, so it's ok.
42+
// TODO: Fix SetDiagnosticExtra to maintain the parents
43+
// if the DiagnosticExtra already exists in the chain.
44+
func TestDiagnosticExtraExisting(t *testing.T) {
45+
diag := &hcl.Diagnostic{
46+
Severity: hcl.DiagWarning,
47+
Summary: "Some summary",
48+
Detail: "Some detail",
49+
// parent -> existing -> child
50+
Extra: wrappedDiagnostic{
51+
name: "parent",
52+
wrapped: types.DiagnosticExtra{
53+
Code: "foobar",
54+
Wrapped: wrappedDiagnostic{
55+
name: "child",
56+
wrapped: nil,
57+
},
58+
},
59+
},
60+
}
61+
62+
extra := types.DiagnosticExtra{
63+
Code: "foo",
64+
}
65+
types.SetDiagnosticExtra(diag, extra)
66+
67+
// The parent wrapped is lost
68+
isExtra, ok := diag.Extra.(types.DiagnosticExtra)
69+
require.True(t, ok)
70+
require.Equal(t, "foo", isExtra.Code)
71+
wrapped, ok := isExtra.UnwrapDiagnosticExtra().(wrappedDiagnostic)
72+
require.True(t, ok)
73+
require.Equal(t, wrapped.name, "child")
74+
}
75+
3876
func TestDiagnosticsJSON(t *testing.T) {
3977
diags := types.Diagnostics{
4078
{
@@ -64,3 +102,14 @@ func TestDiagnosticsJSON(t *testing.T) {
64102

65103
require.Equal(t, diags, newDiags)
66104
}
105+
106+
type wrappedDiagnostic struct {
107+
name string
108+
wrapped any
109+
}
110+
111+
var _ hcl.DiagnosticExtraUnwrapper = wrappedDiagnostic{}
112+
113+
func (e wrappedDiagnostic) UnwrapDiagnosticExtra() interface{} {
114+
return e.wrapped
115+
}

0 commit comments

Comments
 (0)