12 "github.com/hashicorp/hcl/hcl/parser"
15 var update = flag.Bool("update", false, "update golden files")
25 // Use go test -update to create/update the respective golden files.
27 {"complexhcl.input", "complexhcl.golden"},
28 {"list.input", "list.golden"},
29 {"list_comment.input", "list_comment.golden"},
30 {"comment.input", "comment.golden"},
31 {"comment_crlf.input", "comment.golden"},
32 {"comment_aligned.input", "comment_aligned.golden"},
33 {"comment_array.input", "comment_array.golden"},
34 {"comment_end_file.input", "comment_end_file.golden"},
35 {"comment_multiline_indent.input", "comment_multiline_indent.golden"},
36 {"comment_multiline_no_stanza.input", "comment_multiline_no_stanza.golden"},
37 {"comment_multiline_stanza.input", "comment_multiline_stanza.golden"},
38 {"comment_newline.input", "comment_newline.golden"},
39 {"comment_object_multi.input", "comment_object_multi.golden"},
40 {"comment_standalone.input", "comment_standalone.golden"},
41 {"empty_block.input", "empty_block.golden"},
42 {"list_of_objects.input", "list_of_objects.golden"},
43 {"multiline_string.input", "multiline_string.golden"},
44 {"object_singleline.input", "object_singleline.golden"},
45 {"object_with_heredoc.input", "object_with_heredoc.golden"},
48 func TestFiles(t *testing.T) {
49 for _, e := range data {
50 source := filepath.Join(dataDir, e.source)
51 golden := filepath.Join(dataDir, e.golden)
52 t.Run(e.source, func(t *testing.T) {
53 check(t, source, golden)
58 func check(t *testing.T, source, golden string) {
59 src, err := ioutil.ReadFile(source)
65 res, err := format(src)
71 // update golden files if necessary
73 if err := ioutil.WriteFile(golden, res, 0644); err != nil {
80 gld, err := ioutil.ReadFile(golden)
86 // formatted source and golden must be the same
87 if err := diff(source, golden, res, gld); err != nil {
93 // diff compares a and b.
94 func diff(aname, bname string, a, b []byte) error {
95 var buf bytes.Buffer // holding long error message
99 fmt.Fprintf(&buf, "\nlength changed: len(%s) = %d, len(%s) = %d", aname, len(a), bname, len(b))
105 for i := 0; i < len(a) && i < len(b); i++ {
108 fmt.Fprintf(&buf, "\n%s:%d:%d: %q", aname, line, i-offs+1, lineAt(a, offs))
109 fmt.Fprintf(&buf, "\n%s:%d:%d: %q", bname, line, i-offs+1, lineAt(b, offs))
110 fmt.Fprintf(&buf, "\n\n")
120 return errors.New(buf.String())
125 // format parses src, prints the corresponding AST, verifies the resulting
126 // src is syntactically correct, and returns the resulting src or an error
128 func format(src []byte) ([]byte, error) {
129 formatted, err := Format(src)
134 // make sure formatted output is syntactically correct
135 if _, err := parser.Parse(formatted); err != nil {
136 return nil, fmt.Errorf("parse: %s\n%s", err, formatted)
139 return formatted, nil
142 // lineAt returns the line in text starting at offset offs.
143 func lineAt(text []byte, offs int) []byte {
145 for i < len(text) && text[i] != '\n' {