github.com/opentofu/opentofu@v1.7.1/internal/tfdiags/consolidate_warnings_test.go (about) 1 // Copyright (c) The OpenTofu Authors 2 // SPDX-License-Identifier: MPL-2.0 3 // Copyright (c) 2023 HashiCorp, Inc. 4 // SPDX-License-Identifier: MPL-2.0 5 6 package tfdiags 7 8 import ( 9 "fmt" 10 "testing" 11 12 "github.com/google/go-cmp/cmp" 13 "github.com/hashicorp/hcl/v2" 14 ) 15 16 func TestConsolidateWarnings(t *testing.T) { 17 var diags Diagnostics 18 19 for i := 0; i < 4; i++ { 20 diags = diags.Append(&hcl.Diagnostic{ 21 Severity: hcl.DiagWarning, 22 Summary: "Warning 1", 23 Detail: fmt.Sprintf("This one has a subject %d", i), 24 Subject: &hcl.Range{ 25 Filename: "foo.tf", 26 Start: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 27 End: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 28 }, 29 }) 30 diags = diags.Append(&hcl.Diagnostic{ 31 Severity: hcl.DiagError, 32 Summary: "Error 1", 33 Detail: fmt.Sprintf("This one has a subject %d", i), 34 Subject: &hcl.Range{ 35 Filename: "foo.tf", 36 Start: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 37 End: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 38 }, 39 }) 40 diags = diags.Append(Sourceless( 41 Warning, 42 "Warning 2", 43 fmt.Sprintf("This one is sourceless %d", i), 44 )) 45 diags = diags.Append(SimpleWarning("Warning 3")) 46 } 47 48 diags = diags.Append(&hcl.Diagnostic{ 49 Severity: hcl.DiagWarning, 50 Summary: "Warning 4", 51 Detail: "Only one of this one", 52 Subject: &hcl.Range{ 53 Filename: "foo.tf", 54 Start: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 55 End: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 56 }, 57 }) 58 59 // Finally, we'll just add a set of diags that should not be consolidated. 60 61 diags = diags.Append(&hcl.Diagnostic{ 62 Severity: hcl.DiagWarning, 63 Summary: "do not consolidate", 64 Detail: "warning 1, I should not have been consolidated", 65 Subject: &hcl.Range{ 66 Filename: "bar.tf", 67 Start: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 68 End: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 69 }, 70 Extra: doNotConsolidate(true), 71 }) 72 73 diags = diags.Append(&hcl.Diagnostic{ 74 Severity: hcl.DiagWarning, 75 Summary: "do not consolidate", 76 Detail: "warning 2, I should not have been consolidated", 77 Subject: &hcl.Range{ 78 Filename: "bar.tf", 79 Start: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 80 End: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 81 }, 82 Extra: doNotConsolidate(true), 83 }) 84 85 diags = diags.Append(&hcl.Diagnostic{ 86 Severity: hcl.DiagWarning, 87 Summary: "do not consolidate", 88 Detail: "warning 3, I should not have been consolidated", 89 Subject: &hcl.Range{ 90 Filename: "bar.tf", 91 Start: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 92 End: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 93 }, 94 Extra: doNotConsolidate(true), 95 }) 96 97 // We're using ForRPC here to force the diagnostics to be of a consistent 98 // type that we can easily assert against below. 99 got := diags.ConsolidateWarnings(2).ForRPC() 100 want := Diagnostics{ 101 // First set 102 &rpcFriendlyDiag{ 103 Severity_: Warning, 104 Summary_: "Warning 1", 105 Detail_: "This one has a subject 0", 106 Subject_: &SourceRange{ 107 Filename: "foo.tf", 108 Start: SourcePos{Line: 1, Column: 1, Byte: 0}, 109 End: SourcePos{Line: 1, Column: 1, Byte: 0}, 110 }, 111 }, 112 &rpcFriendlyDiag{ 113 Severity_: Error, 114 Summary_: "Error 1", 115 Detail_: "This one has a subject 0", 116 Subject_: &SourceRange{ 117 Filename: "foo.tf", 118 Start: SourcePos{Line: 1, Column: 1, Byte: 0}, 119 End: SourcePos{Line: 1, Column: 1, Byte: 0}, 120 }, 121 }, 122 &rpcFriendlyDiag{ 123 Severity_: Warning, 124 Summary_: "Warning 2", 125 Detail_: "This one is sourceless 0", 126 }, 127 &rpcFriendlyDiag{ 128 Severity_: Warning, 129 Summary_: "Warning 3", 130 }, 131 132 // Second set (consolidation begins; note additional paragraph in Warning 1 detail) 133 &rpcFriendlyDiag{ 134 Severity_: Warning, 135 Summary_: "Warning 1", 136 Detail_: "This one has a subject 1\n\n(and 2 more similar warnings elsewhere)", 137 Subject_: &SourceRange{ 138 Filename: "foo.tf", 139 Start: SourcePos{Line: 1, Column: 1, Byte: 0}, 140 End: SourcePos{Line: 1, Column: 1, Byte: 0}, 141 }, 142 }, 143 &rpcFriendlyDiag{ 144 Severity_: Error, 145 Summary_: "Error 1", 146 Detail_: "This one has a subject 1", 147 Subject_: &SourceRange{ 148 Filename: "foo.tf", 149 Start: SourcePos{Line: 1, Column: 1, Byte: 0}, 150 End: SourcePos{Line: 1, Column: 1, Byte: 0}, 151 }, 152 }, 153 &rpcFriendlyDiag{ 154 Severity_: Warning, 155 Summary_: "Warning 2", 156 Detail_: "This one is sourceless 1", 157 }, 158 &rpcFriendlyDiag{ 159 Severity_: Warning, 160 Summary_: "Warning 3", 161 }, 162 163 // Third set (no more Warning 1, because it's consolidated) 164 &rpcFriendlyDiag{ 165 Severity_: Error, 166 Summary_: "Error 1", 167 Detail_: "This one has a subject 2", 168 Subject_: &SourceRange{ 169 Filename: "foo.tf", 170 Start: SourcePos{Line: 1, Column: 1, Byte: 0}, 171 End: SourcePos{Line: 1, Column: 1, Byte: 0}, 172 }, 173 }, 174 &rpcFriendlyDiag{ 175 Severity_: Warning, 176 Summary_: "Warning 2", 177 Detail_: "This one is sourceless 2", 178 }, 179 &rpcFriendlyDiag{ 180 Severity_: Warning, 181 Summary_: "Warning 3", 182 }, 183 184 // Fourth set (still no warning 1) 185 &rpcFriendlyDiag{ 186 Severity_: Error, 187 Summary_: "Error 1", 188 Detail_: "This one has a subject 3", 189 Subject_: &SourceRange{ 190 Filename: "foo.tf", 191 Start: SourcePos{Line: 1, Column: 1, Byte: 0}, 192 End: SourcePos{Line: 1, Column: 1, Byte: 0}, 193 }, 194 }, 195 &rpcFriendlyDiag{ 196 Severity_: Warning, 197 Summary_: "Warning 2", 198 Detail_: "This one is sourceless 3", 199 }, 200 &rpcFriendlyDiag{ 201 Severity_: Warning, 202 Summary_: "Warning 3", 203 }, 204 205 // Special straggler warning gets to show up unconsolidated, because 206 // there is only one of it. 207 &rpcFriendlyDiag{ 208 Severity_: Warning, 209 Summary_: "Warning 4", 210 Detail_: "Only one of this one", 211 Subject_: &SourceRange{ 212 Filename: "foo.tf", 213 Start: SourcePos{Line: 1, Column: 1, Byte: 0}, 214 End: SourcePos{Line: 1, Column: 1, Byte: 0}, 215 }, 216 }, 217 218 // The final set of warnings should not have been consolidated because 219 // of our filter function. 220 &rpcFriendlyDiag{ 221 Severity_: Warning, 222 Summary_: "do not consolidate", 223 Detail_: "warning 1, I should not have been consolidated", 224 Subject_: &SourceRange{ 225 Filename: "bar.tf", 226 Start: SourcePos{Line: 1, Column: 1, Byte: 0}, 227 End: SourcePos{Line: 1, Column: 1, Byte: 0}, 228 }, 229 }, 230 &rpcFriendlyDiag{ 231 Severity_: Warning, 232 Summary_: "do not consolidate", 233 Detail_: "warning 2, I should not have been consolidated", 234 Subject_: &SourceRange{ 235 Filename: "bar.tf", 236 Start: SourcePos{Line: 1, Column: 1, Byte: 0}, 237 End: SourcePos{Line: 1, Column: 1, Byte: 0}, 238 }, 239 }, 240 &rpcFriendlyDiag{ 241 Severity_: Warning, 242 Summary_: "do not consolidate", 243 Detail_: "warning 3, I should not have been consolidated", 244 Subject_: &SourceRange{ 245 Filename: "bar.tf", 246 Start: SourcePos{Line: 1, Column: 1, Byte: 0}, 247 End: SourcePos{Line: 1, Column: 1, Byte: 0}, 248 }, 249 }, 250 } 251 252 if diff := cmp.Diff(want, got); diff != "" { 253 t.Errorf("wrong result\n%s", diff) 254 } 255 } 256 257 type doNotConsolidate bool 258 259 var _ DiagnosticExtraDoNotConsolidate = doNotConsolidate(true) 260 261 func (d doNotConsolidate) DoNotConsolidateDiagnostic() bool { 262 return bool(d) 263 }