github.com/kjmkznr/terraform@v0.5.2-0.20180216194316-1d0f5fdac99e/tfdiags/diagnostics_test.go (about) 1 package tfdiags 2 3 import ( 4 "errors" 5 "fmt" 6 "reflect" 7 "strings" 8 "testing" 9 10 "github.com/hashicorp/go-multierror" 11 12 "github.com/davecgh/go-spew/spew" 13 "github.com/hashicorp/hcl2/hcl" 14 ) 15 16 func TestBuild(t *testing.T) { 17 type diagFlat struct { 18 Severity Severity 19 Summary string 20 Detail string 21 Subject *SourceRange 22 Context *SourceRange 23 } 24 25 tests := map[string]struct { 26 Cons func(Diagnostics) Diagnostics 27 Want []diagFlat 28 }{ 29 "nil": { 30 func(diags Diagnostics) Diagnostics { 31 return diags 32 }, 33 nil, 34 }, 35 "fmt.Errorf": { 36 func(diags Diagnostics) Diagnostics { 37 diags = diags.Append(fmt.Errorf("oh no bad")) 38 return diags 39 }, 40 []diagFlat{ 41 { 42 Severity: Error, 43 Summary: "oh no bad", 44 }, 45 }, 46 }, 47 "errors.New": { 48 func(diags Diagnostics) Diagnostics { 49 diags = diags.Append(errors.New("oh no bad")) 50 return diags 51 }, 52 []diagFlat{ 53 { 54 Severity: Error, 55 Summary: "oh no bad", 56 }, 57 }, 58 }, 59 "hcl.Diagnostic": { 60 func(diags Diagnostics) Diagnostics { 61 diags = diags.Append(&hcl.Diagnostic{ 62 Severity: hcl.DiagError, 63 Summary: "Something bad happened", 64 Detail: "It was really, really bad.", 65 Subject: &hcl.Range{ 66 Filename: "foo.tf", 67 Start: hcl.Pos{Line: 1, Column: 10, Byte: 9}, 68 End: hcl.Pos{Line: 2, Column: 3, Byte: 25}, 69 }, 70 Context: &hcl.Range{ 71 Filename: "foo.tf", 72 Start: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 73 End: hcl.Pos{Line: 3, Column: 1, Byte: 30}, 74 }, 75 }) 76 return diags 77 }, 78 []diagFlat{ 79 { 80 Severity: Error, 81 Summary: "Something bad happened", 82 Detail: "It was really, really bad.", 83 Subject: &SourceRange{ 84 Filename: "foo.tf", 85 Start: SourcePos{Line: 1, Column: 10, Byte: 9}, 86 End: SourcePos{Line: 2, Column: 3, Byte: 25}, 87 }, 88 Context: &SourceRange{ 89 Filename: "foo.tf", 90 Start: SourcePos{Line: 1, Column: 1, Byte: 0}, 91 End: SourcePos{Line: 3, Column: 1, Byte: 30}, 92 }, 93 }, 94 }, 95 }, 96 "hcl.Diagnostics": { 97 func(diags Diagnostics) Diagnostics { 98 diags = diags.Append(hcl.Diagnostics{ 99 { 100 Severity: hcl.DiagError, 101 Summary: "Something bad happened", 102 Detail: "It was really, really bad.", 103 }, 104 { 105 Severity: hcl.DiagWarning, 106 Summary: "Also, somebody sneezed", 107 Detail: "How rude!", 108 }, 109 }) 110 return diags 111 }, 112 []diagFlat{ 113 { 114 Severity: Error, 115 Summary: "Something bad happened", 116 Detail: "It was really, really bad.", 117 }, 118 { 119 Severity: Warning, 120 Summary: "Also, somebody sneezed", 121 Detail: "How rude!", 122 }, 123 }, 124 }, 125 "multierror.Error": { 126 func(diags Diagnostics) Diagnostics { 127 err := multierror.Append(nil, errors.New("bad thing A")) 128 err = multierror.Append(err, errors.New("bad thing B")) 129 diags = diags.Append(err) 130 return diags 131 }, 132 []diagFlat{ 133 { 134 Severity: Error, 135 Summary: "bad thing A", 136 }, 137 { 138 Severity: Error, 139 Summary: "bad thing B", 140 }, 141 }, 142 }, 143 "concat Diagnostics": { 144 func(diags Diagnostics) Diagnostics { 145 var moreDiags Diagnostics 146 moreDiags = moreDiags.Append(errors.New("bad thing A")) 147 moreDiags = moreDiags.Append(errors.New("bad thing B")) 148 return diags.Append(moreDiags) 149 }, 150 []diagFlat{ 151 { 152 Severity: Error, 153 Summary: "bad thing A", 154 }, 155 { 156 Severity: Error, 157 Summary: "bad thing B", 158 }, 159 }, 160 }, 161 "single Diagnostic": { 162 func(diags Diagnostics) Diagnostics { 163 return diags.Append(SimpleWarning("Don't forget your toothbrush!")) 164 }, 165 []diagFlat{ 166 { 167 Severity: Warning, 168 Summary: "Don't forget your toothbrush!", 169 }, 170 }, 171 }, 172 "multiple appends": { 173 func(diags Diagnostics) Diagnostics { 174 diags = diags.Append(SimpleWarning("Don't forget your toothbrush!")) 175 diags = diags.Append(fmt.Errorf("exploded")) 176 return diags 177 }, 178 []diagFlat{ 179 { 180 Severity: Warning, 181 Summary: "Don't forget your toothbrush!", 182 }, 183 { 184 Severity: Error, 185 Summary: "exploded", 186 }, 187 }, 188 }, 189 } 190 191 for name, test := range tests { 192 t.Run(name, func(t *testing.T) { 193 gotDiags := test.Cons(nil) 194 var got []diagFlat 195 for _, item := range gotDiags { 196 desc := item.Description() 197 source := item.Source() 198 got = append(got, diagFlat{ 199 Severity: item.Severity(), 200 Summary: desc.Summary, 201 Detail: desc.Detail, 202 Subject: source.Subject, 203 Context: source.Context, 204 }) 205 } 206 207 if !reflect.DeepEqual(got, test.Want) { 208 t.Errorf("wrong result\ngot: %swant: %s", spew.Sdump(got), spew.Sdump(test.Want)) 209 } 210 }) 211 } 212 } 213 214 func TestDiagnosticsErr(t *testing.T) { 215 t.Run("empty", func(t *testing.T) { 216 var diags Diagnostics 217 err := diags.Err() 218 if err != nil { 219 t.Errorf("got non-nil error %#v; want nil", err) 220 } 221 }) 222 t.Run("warning only", func(t *testing.T) { 223 var diags Diagnostics 224 diags = diags.Append(SimpleWarning("bad")) 225 err := diags.Err() 226 if err != nil { 227 t.Errorf("got non-nil error %#v; want nil", err) 228 } 229 }) 230 t.Run("one error", func(t *testing.T) { 231 var diags Diagnostics 232 diags = diags.Append(errors.New("didn't work")) 233 err := diags.Err() 234 if err == nil { 235 t.Fatalf("got nil error %#v; want non-nil", err) 236 } 237 if got, want := err.Error(), "didn't work"; got != want { 238 t.Errorf("wrong error message\ngot: %s\nwant: %s", got, want) 239 } 240 }) 241 t.Run("two errors", func(t *testing.T) { 242 var diags Diagnostics 243 diags = diags.Append(errors.New("didn't work")) 244 diags = diags.Append(errors.New("didn't work either")) 245 err := diags.Err() 246 if err == nil { 247 t.Fatalf("got nil error %#v; want non-nil", err) 248 } 249 want := strings.TrimSpace(` 250 2 problems: 251 252 - didn't work 253 - didn't work either 254 `) 255 if got := err.Error(); got != want { 256 t.Errorf("wrong error message\ngot: %s\nwant: %s", got, want) 257 } 258 }) 259 t.Run("error and warning", func(t *testing.T) { 260 var diags Diagnostics 261 diags = diags.Append(errors.New("didn't work")) 262 diags = diags.Append(SimpleWarning("didn't work either")) 263 err := diags.Err() 264 if err == nil { 265 t.Fatalf("got nil error %#v; want non-nil", err) 266 } 267 // Since this "as error" mode is just a fallback for 268 // non-diagnostics-aware situations like tests, we don't actually 269 // distinguish warnings and errors here since the point is to just 270 // get the messages rendered. User-facing code should be printing 271 // each diagnostic separately, so won't enter this codepath, 272 want := strings.TrimSpace(` 273 2 problems: 274 275 - didn't work 276 - didn't work either 277 `) 278 if got := err.Error(); got != want { 279 t.Errorf("wrong error message\ngot: %s\nwant: %s", got, want) 280 } 281 }) 282 }