@@ -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+
3876func 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