2 // TODO(jen20): These need fixing on Windows but fmt is not used right now
3 // and red CI is making it harder to process other bugs, so ignore until
4 // we get around to fixing them.
20 "github.com/hashicorp/hcl/testhelper"
23 var fixtureExtensions = []string{"hcl"}
26 sort.Sort(ByFilename(fixtures))
29 func TestIsValidFile(t *testing.T) {
30 const fixtureDir = "./test-fixtures"
37 {".hidden.ignore", false},
38 {"file.ignore", false},
39 {"dir.ignore", false},
42 for _, tc := range cases {
43 file, err := os.Stat(filepath.Join(fixtureDir, tc.Path))
45 t.Errorf("unexpected error: %s", err)
48 if res := isValidFile(file, fixtureExtensions); res != tc.Expected {
49 t.Errorf("want: %b, got: %b", tc.Expected, res)
54 func TestRunMultiplePaths(t *testing.T) {
55 path1, err := renderFixtures("")
57 t.Errorf("unexpected error: %s", err)
59 defer os.RemoveAll(path1)
60 path2, err := renderFixtures("")
62 t.Errorf("unexpected error: %s", err)
64 defer os.RemoveAll(path2)
66 var expectedOut bytes.Buffer
67 for _, path := range []string{path1, path2} {
68 for _, fixture := range fixtures {
69 if !bytes.Equal(fixture.golden, fixture.input) {
70 expectedOut.WriteString(filepath.Join(path, fixture.filename) + "\n")
77 []string{path1, path2},
86 t.Errorf("unexpected error: %s", err)
88 if stdout.String() != expectedOut.String() {
89 t.Errorf("stdout want:\n%s\ngot:\n%s", expectedOut, stdout)
93 func TestRunSubDirectories(t *testing.T) {
94 pathParent, err := ioutil.TempDir("", "")
96 t.Errorf("unexpected error: %s", err)
98 defer os.RemoveAll(pathParent)
100 path1, err := renderFixtures(pathParent)
102 t.Errorf("unexpected error: %s", err)
104 path2, err := renderFixtures(pathParent)
106 t.Errorf("unexpected error: %s", err)
109 paths := []string{path1, path2}
112 var expectedOut bytes.Buffer
113 for _, path := range paths {
114 for _, fixture := range fixtures {
115 if !bytes.Equal(fixture.golden, fixture.input) {
116 expectedOut.WriteString(filepath.Join(path, fixture.filename) + "\n")
121 _, stdout := mockIO()
123 []string{pathParent},
132 t.Errorf("unexpected error: %s", err)
134 if stdout.String() != expectedOut.String() {
135 t.Errorf("stdout want:\n%s\ngot:\n%s", expectedOut, stdout)
139 func TestRunStdin(t *testing.T) {
140 var expectedOut bytes.Buffer
141 for i, fixture := range fixtures {
143 expectedOut.WriteString("\n")
145 expectedOut.Write(fixture.golden)
148 stdin, stdout := mockIO()
149 for _, fixture := range fixtures {
150 stdin.Write(fixture.input)
161 t.Errorf("unexpected error: %s", err)
163 if !bytes.Equal(stdout.Bytes(), expectedOut.Bytes()) {
164 t.Errorf("stdout want:\n%s\ngot:\n%s", expectedOut, stdout)
168 func TestRunStdinAndWrite(t *testing.T) {
169 var expectedOut = []byte{}
171 stdin, stdout := mockIO()
172 stdin.WriteString("")
174 []string{}, []string{},
181 if err != ErrWriteStdin {
182 t.Errorf("error want:\n%s\ngot:\n%s", ErrWriteStdin, err)
184 if !bytes.Equal(stdout.Bytes(), expectedOut) {
185 t.Errorf("stdout want:\n%s\ngot:\n%s", expectedOut, stdout)
189 func TestRunFileError(t *testing.T) {
190 path, err := ioutil.TempDir("", "")
192 t.Errorf("unexpected error: %s", err)
194 defer os.RemoveAll(path)
195 filename := filepath.Join(path, "unreadable.hcl")
197 var expectedError = &os.PathError{
203 err = ioutil.WriteFile(filename, []byte{}, 0000)
205 t.Errorf("unexpected error: %s", err)
208 _, stdout := mockIO()
216 if !reflect.DeepEqual(err, expectedError) {
217 t.Errorf("error want: %#v, got: %#v", expectedError, err)
221 func TestRunNoOptions(t *testing.T) {
222 path, err := renderFixtures("")
224 t.Errorf("unexpected error: %s", err)
226 defer os.RemoveAll(path)
228 var expectedOut bytes.Buffer
229 for _, fixture := range fixtures {
230 expectedOut.Write(fixture.golden)
233 _, stdout := mockIO()
242 t.Errorf("unexpected error: %s", err)
244 if stdout.String() != expectedOut.String() {
245 t.Errorf("stdout want:\n%s\ngot:\n%s", expectedOut, stdout)
249 func TestRunList(t *testing.T) {
250 path, err := renderFixtures("")
252 t.Errorf("unexpected error: %s", err)
254 defer os.RemoveAll(path)
256 var expectedOut bytes.Buffer
257 for _, fixture := range fixtures {
258 if !bytes.Equal(fixture.golden, fixture.input) {
259 expectedOut.WriteString(fmt.Sprintln(filepath.Join(path, fixture.filename)))
263 _, stdout := mockIO()
274 t.Errorf("unexpected error: %s", err)
276 if stdout.String() != expectedOut.String() {
277 t.Errorf("stdout want:\n%s\ngot:\n%s", expectedOut, stdout)
281 func TestRunWrite(t *testing.T) {
282 path, err := renderFixtures("")
284 t.Errorf("unexpected error: %s", err)
286 defer os.RemoveAll(path)
288 _, stdout := mockIO()
299 t.Errorf("unexpected error: %s", err)
301 for _, fixture := range fixtures {
302 res, err := ioutil.ReadFile(filepath.Join(path, fixture.filename))
304 t.Errorf("unexpected error: %s", err)
306 if !bytes.Equal(res, fixture.golden) {
307 t.Errorf("file %q contents want:\n%s\ngot:\n%s", fixture.filename, fixture.golden, res)
312 func TestRunDiff(t *testing.T) {
313 path, err := renderFixtures("")
315 t.Errorf("unexpected error: %s", err)
317 defer os.RemoveAll(path)
319 var expectedOut bytes.Buffer
320 for _, fixture := range fixtures {
321 if len(fixture.diff) > 0 {
322 expectedOut.WriteString(
324 fmt.Sprintf("diff a/%s/%s b/%s/%s\n", path, fixture.filename, path, fixture.filename),
327 // Need to use regex to ignore datetimes in diff.
328 expectedOut.WriteString(`--- .+?\n`)
329 expectedOut.WriteString(`\+\+\+ .+?\n`)
330 expectedOut.WriteString(regexp.QuoteMeta(string(fixture.diff)))
334 expectedOutString := testhelper.Unix2dos(expectedOut.String())
336 _, stdout := mockIO()
347 t.Errorf("unexpected error: %s", err)
349 if !regexp.MustCompile(expectedOutString).Match(stdout.Bytes()) {
350 t.Errorf("stdout want match:\n%s\ngot:\n%q", expectedOutString, stdout)
354 func mockIO() (stdin, stdout *bytes.Buffer) {
355 return new(bytes.Buffer), new(bytes.Buffer)
358 type fixture struct {
360 input, golden, diff []byte
363 type ByFilename []fixture
365 func (s ByFilename) Len() int { return len(s) }
366 func (s ByFilename) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
367 func (s ByFilename) Less(i, j int) bool { return len(s[i].filename) > len(s[j].filename) }
369 var fixtures = []fixture{
372 []byte(`resource "aws_security_group" "firewall" {
376 []byte(`resource "aws_security_group" "firewall" {
383 []byte(`variable "foo" {
388 []byte(`variable "foo" {
393 []byte(`@@ -1,4 +1,4 @@
402 []byte(`provider "aws" {
407 []byte(`provider "aws" {
412 []byte(`@@ -1,4 +1,4 @@
423 // parent can be an empty string, in which case the system's default
424 // temporary directory will be used.
425 func renderFixtures(parent string) (path string, err error) {
426 path, err = ioutil.TempDir(parent, "")
431 for _, fixture := range fixtures {
432 err = ioutil.WriteFile(filepath.Join(path, fixture.filename), []byte(fixture.input), 0644)