hcl/hclwrite/format_test.go

780 lines
8.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package hclwrite
import (
"fmt"
"testing"
"reflect"
"github.com/davecgh/go-spew/spew"
"github.com/hashicorp/hcl/v2/hclsyntax"
)
func TestFormat(t *testing.T) {
tests := []struct {
input string
want string
}{
{
``,
``,
},
{
`a=1`,
`a = 1`,
},
{
`a=b.c`,
`a = b.c`,
},
{
`a=b[c]`,
`a = b[c]`,
},
{
`a=b()[c]`,
`a = b()[c]`,
},
{
`a=["hello"][0]`,
`a = ["hello"][0]`,
},
{
`( a+2 )`,
`(a + 2)`,
},
{
`( a*2 )`,
`(a * 2)`,
},
{
`( a+-2 )`,
`(a + -2)`,
},
{
`( a*-2 )`,
`(a * -2)`,
},
{
`(-2+1)`,
`(-2 + 1)`,
},
{
`foo(1, -2,a*b, b,c)`,
`foo(1, -2, a * b, b, c)`,
},
{
`foo(a,b...)`,
`foo(a, b...)`,
},
{
`! true`,
`!true`,
},
{
`a="hello ${ name }"`,
`a = "hello ${name}"`,
},
{
`a="hello ${~ name ~}"`,
`a = "hello ${~name~}"`,
},
{
`a="${b}${c}${ d } ${e}"`,
`a = "${b}${c}${d} ${e}"`,
},
{
`"%{if true}${var.foo}%{endif}"`,
`"%{if true}${var.foo}%{endif}"`,
},
{
`b{}`,
`b {}`,
},
{
`
"${
hello
}"
`,
`
"${
hello
}"
`,
},
{
`
foo(
1,
- 2,
a*b,
b,
c,
)
`,
`
foo(
1,
-2,
a * b,
b,
c,
)
`,
},
{
`a?b:c`,
`a ? b : c`,
},
{
`[ [ ] ]`,
`[[]]`,
},
{
`[for x in y : x]`,
`[for x in y : x]`,
},
{
`[for x in [y] : x]`,
`[for x in [y] : x]`,
},
{
`
[
[
a
]
]
`,
`
[
[
a
]
]
`,
},
{
`
[[
a
]]
`,
`
[[
a
]]
`,
},
{
`
[[
[
a
]
]]
`,
`
[[
[
a
]
]]
`,
},
{
// degenerate case with asymmetrical brackets
`
[[
[
a
]]
]
`,
`
[[
[
a
]]
]
`,
},
{
`
b {
a = 1
}
`,
`
b {
a = 1
}
`,
},
{
`
b {a = 1}
`,
`
b { a = 1 }
`,
},
{
`
a = 1
bungle = 2
`,
`
a = 1
bungle = 2
`,
},
{
`
a = 1
bungle = 2
`,
`
a = 1
bungle = 2
`,
},
{
`
a = 1 # foo
bungle = 2
`,
`
a = 1 # foo
bungle = 2
`,
},
{
`
a = 1 # foo
bungle = "bonce" # baz
`,
`
a = 1 # foo
bungle = "bonce" # baz
`,
},
{
`
# here we go
a = 1 # foo
bungle = "bonce" # baz
`,
`
# here we go
a = 1 # foo
bungle = "bonce" # baz
`,
},
{
`
foo {} # here we go
a = 1 # foo
bungle = "bonce" # baz
`,
`
foo {} # here we go
a = 1 # foo
bungle = "bonce" # baz
`,
},
{
`
a = 1 # foo
bungle = "bonce" # baz
zebra = "striped" # baz
`,
`
a = 1 # foo
bungle = "bonce" # baz
zebra = "striped" # baz
`,
},
{
`
a = 1 # foo
bungle = (
"bonce"
) # baz
zebra = "striped" # baz
`,
`
a = 1 # foo
bungle = (
"bonce"
) # baz
zebra = "striped" # baz
`,
},
{
`
a="apple"# foo
bungle=(# woo parens
"bonce"
)# baz
zebra="striped"# baz
`,
`
a = "apple" # foo
bungle = ( # woo parens
"bonce"
) # baz
zebra = "striped" # baz
`,
},
{
`
𝒜 = 1 # foo
bungle = "🇬🇧" # baz
zebra = "striped" # baz
`,
`
𝒜 = 1 # foo
bungle = "🇬🇧" # baz
zebra = "striped" # baz
`,
},
{
`
foo {
# ...
}
`,
`
foo {
# ...
}
`,
},
{
`
foo = {
# ...
}
`,
`
foo = {
# ...
}
`,
},
{
`
foo = [
# ...
]
`,
`
foo = [
# ...
]
`,
},
{
`
foo = [{
# ...
}]
`,
`
foo = [{
# ...
}]
`,
},
{
`
foo {
bar {
# ...
}
}
`,
`
foo {
bar {
# ...
}
}
`,
},
{
`
foo {
bar = {
# ...
}
}
`,
`
foo {
bar = {
# ...
}
}
`,
},
{
`
foo {
bar = [
# ...
]
}
`,
`
foo {
bar = [
# ...
]
}
`,
},
{
`
foo {
bar = <<EOT
Foo bar baz
EOT
}
`,
`
foo {
bar = <<EOT
Foo bar baz
EOT
}
`,
},
{
`
foo {
bar = <<-EOT
Foo bar baz
EOT
}
`,
`
foo {
bar = <<-EOT
Foo bar baz
EOT
}
`,
},
{
`
foo {
bar = <<-EOT
Foo bar baz
EOT
}
`,
`
foo {
bar = <<-EOT
Foo bar baz
EOT
}
`,
},
{
`
foo {
bar = <<-EOT
blahblahblah = x
EOT
}
`,
`
foo {
bar = <<-EOT
blahblahblah = x
EOT
}
`,
},
{
`
foo {
bar = <<-EOT
${{ blahblahblah = x }}
EOT
}
`,
`
foo {
bar = <<-EOT
${ { blahblahblah = x } }
EOT
}
`,
},
{
`
foo {
bar = <<-EOT
${a}${b}${ c } ${d}
EOT
}
`,
`
foo {
bar = <<-EOT
${a}${b}${c} ${d}
EOT
}
`,
},
{
`
foo {
bar = <<EOT
Foo bar baz
EOT
}
baz {
default="string"
}
`,
`
foo {
bar = <<EOT
Foo bar baz
EOT
}
baz {
default = "string"
}
`,
},
{
`
foo {
bar = <<EOT
Foo bar baz
EOT
baz = <<EOT
Foo bar baz
EOT
}
bar {
foo = "bar"
}
`,
`
foo {
bar = <<EOT
Foo bar baz
EOT
baz = <<EOT
Foo bar baz
EOT
}
bar {
foo = "bar"
}
`,
},
{
`
module "foo" {
foo = <<EOF
5
EOF
}
module "x" {
a = "b"
abcde = "456"
}`,
`
module "foo" {
foo = <<EOF
5
EOF
}
module "x" {
a = "b"
abcde = "456"
}`,
},
}
for i, test := range tests {
t.Run(fmt.Sprintf("%02d", i), func(t *testing.T) {
tokens := lexConfig([]byte(test.input))
format(tokens)
t.Logf("tokens %s\n", spew.Sdump(tokens))
got := string(tokens.Bytes())
if got != test.want {
t.Errorf("wrong result\ninput:\n%s\ngot:\n%s\nwant:\n%s", test.input, got, test.want)
}
})
}
}
func TestLinesForFormat(t *testing.T) {
tests := []struct {
tokens Tokens
want []formatLine
}{
{
Tokens{
&Token{Type: hclsyntax.TokenEOF},
},
[]formatLine{
{
lead: Tokens{},
},
},
},
{
Tokens{
&Token{Type: hclsyntax.TokenIdent},
&Token{Type: hclsyntax.TokenEOF},
},
[]formatLine{
{
lead: Tokens{
&Token{Type: hclsyntax.TokenIdent},
},
},
},
},
{
Tokens{
&Token{Type: hclsyntax.TokenIdent},
&Token{Type: hclsyntax.TokenNewline},
&Token{Type: hclsyntax.TokenNumberLit},
&Token{Type: hclsyntax.TokenEOF},
},
[]formatLine{
{
lead: Tokens{
&Token{Type: hclsyntax.TokenIdent},
&Token{Type: hclsyntax.TokenNewline},
},
},
{
lead: Tokens{
&Token{Type: hclsyntax.TokenNumberLit},
},
},
},
},
{
Tokens{
&Token{Type: hclsyntax.TokenIdent},
&Token{Type: hclsyntax.TokenComment, Bytes: []byte("#foo\n")},
&Token{Type: hclsyntax.TokenNumberLit},
&Token{Type: hclsyntax.TokenEOF},
},
[]formatLine{
{
lead: Tokens{
&Token{Type: hclsyntax.TokenIdent},
},
comment: Tokens{
&Token{Type: hclsyntax.TokenComment, Bytes: []byte("#foo\n")},
},
},
{
lead: Tokens{
&Token{Type: hclsyntax.TokenNumberLit},
},
},
},
},
{
Tokens{
&Token{Type: hclsyntax.TokenIdent},
&Token{Type: hclsyntax.TokenEqual},
&Token{Type: hclsyntax.TokenNumberLit},
&Token{Type: hclsyntax.TokenEOF},
},
[]formatLine{
{
lead: Tokens{
&Token{Type: hclsyntax.TokenIdent},
},
assign: Tokens{
&Token{Type: hclsyntax.TokenEqual},
&Token{Type: hclsyntax.TokenNumberLit},
},
},
},
},
{
Tokens{
&Token{Type: hclsyntax.TokenIdent},
&Token{Type: hclsyntax.TokenEqual},
&Token{Type: hclsyntax.TokenNumberLit},
&Token{Type: hclsyntax.TokenComment, Bytes: []byte("#foo\n")},
&Token{Type: hclsyntax.TokenEOF},
},
[]formatLine{
{
lead: Tokens{
&Token{Type: hclsyntax.TokenIdent},
},
assign: Tokens{
&Token{Type: hclsyntax.TokenEqual},
&Token{Type: hclsyntax.TokenNumberLit},
},
comment: Tokens{
&Token{Type: hclsyntax.TokenComment, Bytes: []byte("#foo\n")},
},
},
{
lead: Tokens{},
},
},
},
{
Tokens{
// A comment goes into a comment cell only if it is after
// some non-comment tokens, since whole-line comments must
// stay flush with the indent level.
&Token{Type: hclsyntax.TokenComment, Bytes: []byte("#foo\n")},
&Token{Type: hclsyntax.TokenEOF},
},
[]formatLine{
{
lead: Tokens{
&Token{Type: hclsyntax.TokenComment, Bytes: []byte("#foo\n")},
},
},
{
lead: Tokens{},
},
},
},
}
for i, test := range tests {
t.Run(fmt.Sprintf("%02d", i), func(t *testing.T) {
got := linesForFormat(test.tokens)
if !reflect.DeepEqual(got, test.want) {
t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, test.want)
}
})
}
}