github.com/cycloidio/terraform@v1.1.10-0.20220513142504-76d5c768dc63/command/fmt_test.go (about) 1 package command 2 3 import ( 4 "bytes" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "strings" 10 "testing" 11 12 "github.com/google/go-cmp/cmp" 13 "github.com/mitchellh/cli" 14 ) 15 16 func TestFmt(t *testing.T) { 17 const inSuffix = "_in.tf" 18 const outSuffix = "_out.tf" 19 const gotSuffix = "_got.tf" 20 entries, err := ioutil.ReadDir("testdata/fmt") 21 if err != nil { 22 t.Fatal(err) 23 } 24 25 td, err := ioutil.TempDir("", "terraform-fmt-test") 26 if err != nil { 27 t.Fatal(err) 28 } 29 tmpDir, err := filepath.EvalSymlinks(td) 30 if err != nil { 31 t.Fatal(err) 32 } 33 defer os.RemoveAll(td) 34 35 for _, info := range entries { 36 if info.IsDir() { 37 continue 38 } 39 filename := info.Name() 40 if !strings.HasSuffix(filename, inSuffix) { 41 continue 42 } 43 testName := filename[:len(filename)-len(inSuffix)] 44 t.Run(testName, func(t *testing.T) { 45 inFile := filepath.Join("testdata", "fmt", testName+inSuffix) 46 wantFile := filepath.Join("testdata", "fmt", testName+outSuffix) 47 gotFile := filepath.Join(tmpDir, testName+gotSuffix) 48 input, err := ioutil.ReadFile(inFile) 49 if err != nil { 50 t.Fatal(err) 51 } 52 want, err := ioutil.ReadFile(wantFile) 53 if err != nil { 54 t.Fatal(err) 55 } 56 err = ioutil.WriteFile(gotFile, input, 0700) 57 if err != nil { 58 t.Fatal(err) 59 } 60 61 ui := cli.NewMockUi() 62 c := &FmtCommand{ 63 Meta: Meta{ 64 testingOverrides: metaOverridesForProvider(testProvider()), 65 Ui: ui, 66 }, 67 } 68 args := []string{gotFile} 69 if code := c.Run(args); code != 0 { 70 t.Fatalf("fmt command was unsuccessful:\n%s", ui.ErrorWriter.String()) 71 } 72 73 got, err := ioutil.ReadFile(gotFile) 74 if err != nil { 75 t.Fatal(err) 76 } 77 78 if diff := cmp.Diff(string(want), string(got)); diff != "" { 79 t.Errorf("wrong result\n%s", diff) 80 } 81 }) 82 } 83 } 84 85 func TestFmt_nonexist(t *testing.T) { 86 tempDir := fmtFixtureWriteDir(t) 87 88 ui := new(cli.MockUi) 89 c := &FmtCommand{ 90 Meta: Meta{ 91 testingOverrides: metaOverridesForProvider(testProvider()), 92 Ui: ui, 93 }, 94 } 95 96 missingDir := filepath.Join(tempDir, "doesnotexist") 97 args := []string{missingDir} 98 if code := c.Run(args); code != 2 { 99 t.Fatalf("wrong exit code. errors: \n%s", ui.ErrorWriter.String()) 100 } 101 102 expected := "No file or directory at" 103 if actual := ui.ErrorWriter.String(); !strings.Contains(actual, expected) { 104 t.Fatalf("expected:\n%s\n\nto include: %q", actual, expected) 105 } 106 } 107 108 func TestFmt_syntaxError(t *testing.T) { 109 tempDir := testTempDir(t) 110 111 invalidSrc := ` 112 a = 1 + 113 ` 114 115 err := ioutil.WriteFile(filepath.Join(tempDir, "invalid.tf"), []byte(invalidSrc), 0644) 116 if err != nil { 117 t.Fatal(err) 118 } 119 120 ui := new(cli.MockUi) 121 c := &FmtCommand{ 122 Meta: Meta{ 123 testingOverrides: metaOverridesForProvider(testProvider()), 124 Ui: ui, 125 }, 126 } 127 128 args := []string{tempDir} 129 if code := c.Run(args); code != 2 { 130 t.Fatalf("wrong exit code. errors: \n%s", ui.ErrorWriter.String()) 131 } 132 133 expected := "Invalid expression" 134 if actual := ui.ErrorWriter.String(); !strings.Contains(actual, expected) { 135 t.Fatalf("expected:\n%s\n\nto include: %q", actual, expected) 136 } 137 } 138 139 func TestFmt_snippetInError(t *testing.T) { 140 tempDir := testTempDir(t) 141 142 backendSrc := `terraform {backend "s3" {}}` 143 144 err := ioutil.WriteFile(filepath.Join(tempDir, "backend.tf"), []byte(backendSrc), 0644) 145 if err != nil { 146 t.Fatal(err) 147 } 148 149 ui := new(cli.MockUi) 150 c := &FmtCommand{ 151 Meta: Meta{ 152 testingOverrides: metaOverridesForProvider(testProvider()), 153 Ui: ui, 154 }, 155 } 156 157 args := []string{tempDir} 158 if code := c.Run(args); code != 2 { 159 t.Fatalf("wrong exit code. errors: \n%s", ui.ErrorWriter.String()) 160 } 161 162 substrings := []string{ 163 "Argument definition required", 164 "line 1, in terraform", 165 `1: terraform {backend "s3" {}}`, 166 } 167 for _, substring := range substrings { 168 if actual := ui.ErrorWriter.String(); !strings.Contains(actual, substring) { 169 t.Errorf("expected:\n%s\n\nto include: %q", actual, substring) 170 } 171 } 172 } 173 174 func TestFmt_tooManyArgs(t *testing.T) { 175 ui := new(cli.MockUi) 176 c := &FmtCommand{ 177 Meta: Meta{ 178 testingOverrides: metaOverridesForProvider(testProvider()), 179 Ui: ui, 180 }, 181 } 182 183 args := []string{ 184 "one", 185 "two", 186 } 187 if code := c.Run(args); code != 1 { 188 t.Fatalf("wrong exit code. errors: \n%s", ui.ErrorWriter.String()) 189 } 190 191 expected := "The fmt command expects at most one argument." 192 if actual := ui.ErrorWriter.String(); !strings.Contains(actual, expected) { 193 t.Fatalf("expected:\n%s\n\nto include: %q", actual, expected) 194 } 195 } 196 197 func TestFmt_workingDirectory(t *testing.T) { 198 tempDir := fmtFixtureWriteDir(t) 199 200 cwd, err := os.Getwd() 201 if err != nil { 202 t.Fatalf("err: %s", err) 203 } 204 err = os.Chdir(tempDir) 205 if err != nil { 206 t.Fatalf("err: %s", err) 207 } 208 defer os.Chdir(cwd) 209 210 ui := new(cli.MockUi) 211 c := &FmtCommand{ 212 Meta: Meta{ 213 testingOverrides: metaOverridesForProvider(testProvider()), 214 Ui: ui, 215 }, 216 } 217 218 args := []string{} 219 if code := c.Run(args); code != 0 { 220 t.Fatalf("wrong exit code. errors: \n%s", ui.ErrorWriter.String()) 221 } 222 223 expected := fmt.Sprintf("%s\n", fmtFixture.filename) 224 if actual := ui.OutputWriter.String(); actual != expected { 225 t.Fatalf("got: %q\nexpected: %q", actual, expected) 226 } 227 } 228 229 func TestFmt_directoryArg(t *testing.T) { 230 tempDir := fmtFixtureWriteDir(t) 231 232 ui := new(cli.MockUi) 233 c := &FmtCommand{ 234 Meta: Meta{ 235 testingOverrides: metaOverridesForProvider(testProvider()), 236 Ui: ui, 237 }, 238 } 239 240 args := []string{tempDir} 241 if code := c.Run(args); code != 0 { 242 t.Fatalf("wrong exit code. errors: \n%s", ui.ErrorWriter.String()) 243 } 244 245 got, err := filepath.Abs(strings.TrimSpace(ui.OutputWriter.String())) 246 if err != nil { 247 t.Fatal(err) 248 } 249 want := filepath.Join(tempDir, fmtFixture.filename) 250 251 if got != want { 252 t.Fatalf("wrong output\ngot: %s\nwant: %s", got, want) 253 } 254 } 255 256 func TestFmt_fileArg(t *testing.T) { 257 tempDir := fmtFixtureWriteDir(t) 258 259 ui := new(cli.MockUi) 260 c := &FmtCommand{ 261 Meta: Meta{ 262 testingOverrides: metaOverridesForProvider(testProvider()), 263 Ui: ui, 264 }, 265 } 266 267 args := []string{filepath.Join(tempDir, fmtFixture.filename)} 268 if code := c.Run(args); code != 0 { 269 t.Fatalf("wrong exit code. errors: \n%s", ui.ErrorWriter.String()) 270 } 271 272 got, err := filepath.Abs(strings.TrimSpace(ui.OutputWriter.String())) 273 if err != nil { 274 t.Fatal(err) 275 } 276 want := filepath.Join(tempDir, fmtFixture.filename) 277 278 if got != want { 279 t.Fatalf("wrong output\ngot: %s\nwant: %s", got, want) 280 } 281 } 282 283 func TestFmt_stdinArg(t *testing.T) { 284 input := new(bytes.Buffer) 285 input.Write(fmtFixture.input) 286 287 ui := new(cli.MockUi) 288 c := &FmtCommand{ 289 Meta: Meta{ 290 testingOverrides: metaOverridesForProvider(testProvider()), 291 Ui: ui, 292 }, 293 input: input, 294 } 295 296 args := []string{"-"} 297 if code := c.Run(args); code != 0 { 298 t.Fatalf("wrong exit code. errors: \n%s", ui.ErrorWriter.String()) 299 } 300 301 expected := fmtFixture.golden 302 if actual := ui.OutputWriter.Bytes(); !bytes.Equal(actual, expected) { 303 t.Fatalf("got: %q\nexpected: %q", actual, expected) 304 } 305 } 306 307 func TestFmt_nonDefaultOptions(t *testing.T) { 308 tempDir := fmtFixtureWriteDir(t) 309 310 ui := new(cli.MockUi) 311 c := &FmtCommand{ 312 Meta: Meta{ 313 testingOverrides: metaOverridesForProvider(testProvider()), 314 Ui: ui, 315 }, 316 } 317 318 args := []string{ 319 "-list=false", 320 "-write=false", 321 "-diff", 322 tempDir, 323 } 324 if code := c.Run(args); code != 0 { 325 t.Fatalf("wrong exit code. errors: \n%s", ui.ErrorWriter.String()) 326 } 327 328 expected := fmt.Sprintf("-%s+%s", fmtFixture.input, fmtFixture.golden) 329 if actual := ui.OutputWriter.String(); !strings.Contains(actual, expected) { 330 t.Fatalf("expected:\n%s\n\nto include: %q", actual, expected) 331 } 332 } 333 334 func TestFmt_check(t *testing.T) { 335 tempDir := fmtFixtureWriteDir(t) 336 337 ui := new(cli.MockUi) 338 c := &FmtCommand{ 339 Meta: Meta{ 340 testingOverrides: metaOverridesForProvider(testProvider()), 341 Ui: ui, 342 }, 343 } 344 345 args := []string{ 346 "-check", 347 tempDir, 348 } 349 if code := c.Run(args); code != 3 { 350 t.Fatalf("wrong exit code. expected 3") 351 } 352 353 // Given that we give relative paths back to the user, normalize this temp 354 // dir so that we're comparing against a relative-ized (normalized) path 355 tempDir = c.normalizePath(tempDir) 356 357 if actual := ui.OutputWriter.String(); !strings.Contains(actual, tempDir) { 358 t.Fatalf("expected:\n%s\n\nto include: %q", actual, tempDir) 359 } 360 } 361 362 func TestFmt_checkStdin(t *testing.T) { 363 input := new(bytes.Buffer) 364 input.Write(fmtFixture.input) 365 366 ui := new(cli.MockUi) 367 c := &FmtCommand{ 368 Meta: Meta{ 369 testingOverrides: metaOverridesForProvider(testProvider()), 370 Ui: ui, 371 }, 372 input: input, 373 } 374 375 args := []string{ 376 "-check", 377 "-", 378 } 379 if code := c.Run(args); code != 3 { 380 t.Fatalf("wrong exit code. expected 3, got %d", code) 381 } 382 383 if ui.OutputWriter != nil { 384 t.Fatalf("expected no output, got: %q", ui.OutputWriter.String()) 385 } 386 } 387 388 var fmtFixture = struct { 389 filename string 390 input, golden []byte 391 }{ 392 "main.tf", 393 []byte(` foo = "bar" 394 `), 395 []byte(`foo = "bar" 396 `), 397 } 398 399 func fmtFixtureWriteDir(t *testing.T) string { 400 dir := testTempDir(t) 401 402 err := ioutil.WriteFile(filepath.Join(dir, fmtFixture.filename), fmtFixture.input, 0644) 403 if err != nil { 404 t.Fatal(err) 405 } 406 407 return dir 408 }