6c4344623b
The main HCL package is more visible this way, and so it's easier than having to pick it out from dozens of other package directories.
213 lines
3.6 KiB
Go
213 lines
3.6 KiB
Go
package hcldec
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/hcl/v2"
|
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
|
"github.com/zclconf/go-cty/cty"
|
|
)
|
|
|
|
func TestVariables(t *testing.T) {
|
|
tests := []struct {
|
|
config string
|
|
spec Spec
|
|
want []hcl.Traversal
|
|
}{
|
|
{
|
|
``,
|
|
&ObjectSpec{},
|
|
nil,
|
|
},
|
|
{
|
|
"a = foo\n",
|
|
&ObjectSpec{},
|
|
nil, // "a" is not actually used, so "foo" is not required
|
|
},
|
|
{
|
|
"a = foo\n",
|
|
&AttrSpec{
|
|
Name: "a",
|
|
},
|
|
[]hcl.Traversal{
|
|
{
|
|
hcl.TraverseRoot{
|
|
Name: "foo",
|
|
SrcRange: hcl.Range{
|
|
Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
|
|
End: hcl.Pos{Line: 1, Column: 8, Byte: 7},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
"a = foo\nb = bar\n",
|
|
&DefaultSpec{
|
|
Primary: &AttrSpec{
|
|
Name: "a",
|
|
},
|
|
Default: &AttrSpec{
|
|
Name: "b",
|
|
},
|
|
},
|
|
[]hcl.Traversal{
|
|
{
|
|
hcl.TraverseRoot{
|
|
Name: "foo",
|
|
SrcRange: hcl.Range{
|
|
Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
|
|
End: hcl.Pos{Line: 1, Column: 8, Byte: 7},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
hcl.TraverseRoot{
|
|
Name: "bar",
|
|
SrcRange: hcl.Range{
|
|
Start: hcl.Pos{Line: 2, Column: 5, Byte: 12},
|
|
End: hcl.Pos{Line: 2, Column: 8, Byte: 15},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
"a = foo\n",
|
|
&ObjectSpec{
|
|
"a": &AttrSpec{
|
|
Name: "a",
|
|
},
|
|
},
|
|
[]hcl.Traversal{
|
|
{
|
|
hcl.TraverseRoot{
|
|
Name: "foo",
|
|
SrcRange: hcl.Range{
|
|
Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
|
|
End: hcl.Pos{Line: 1, Column: 8, Byte: 7},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
`
|
|
b {
|
|
a = foo
|
|
}
|
|
`,
|
|
&BlockSpec{
|
|
TypeName: "b",
|
|
Nested: &AttrSpec{
|
|
Name: "a",
|
|
},
|
|
},
|
|
[]hcl.Traversal{
|
|
{
|
|
hcl.TraverseRoot{
|
|
Name: "foo",
|
|
SrcRange: hcl.Range{
|
|
Start: hcl.Pos{Line: 3, Column: 7, Byte: 11},
|
|
End: hcl.Pos{Line: 3, Column: 10, Byte: 14},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
`
|
|
b {
|
|
a = foo
|
|
b = bar
|
|
}
|
|
`,
|
|
&BlockAttrsSpec{
|
|
TypeName: "b",
|
|
ElementType: cty.String,
|
|
},
|
|
[]hcl.Traversal{
|
|
{
|
|
hcl.TraverseRoot{
|
|
Name: "foo",
|
|
SrcRange: hcl.Range{
|
|
Start: hcl.Pos{Line: 3, Column: 7, Byte: 11},
|
|
End: hcl.Pos{Line: 3, Column: 10, Byte: 14},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
hcl.TraverseRoot{
|
|
Name: "bar",
|
|
SrcRange: hcl.Range{
|
|
Start: hcl.Pos{Line: 4, Column: 7, Byte: 21},
|
|
End: hcl.Pos{Line: 4, Column: 10, Byte: 24},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
`
|
|
b {
|
|
a = foo
|
|
}
|
|
b {
|
|
a = bar
|
|
}
|
|
c {
|
|
a = baz
|
|
}
|
|
`,
|
|
&BlockListSpec{
|
|
TypeName: "b",
|
|
Nested: &AttrSpec{
|
|
Name: "a",
|
|
},
|
|
},
|
|
[]hcl.Traversal{
|
|
{
|
|
hcl.TraverseRoot{
|
|
Name: "foo",
|
|
SrcRange: hcl.Range{
|
|
Start: hcl.Pos{Line: 3, Column: 7, Byte: 11},
|
|
End: hcl.Pos{Line: 3, Column: 10, Byte: 14},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
hcl.TraverseRoot{
|
|
Name: "bar",
|
|
SrcRange: hcl.Range{
|
|
Start: hcl.Pos{Line: 6, Column: 7, Byte: 27},
|
|
End: hcl.Pos{Line: 6, Column: 10, Byte: 30},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for i, test := range tests {
|
|
t.Run(fmt.Sprintf("%02d-%s", i, test.config), func(t *testing.T) {
|
|
file, diags := hclsyntax.ParseConfig([]byte(test.config), "", hcl.Pos{Line: 1, Column: 1, Byte: 0})
|
|
if len(diags) != 0 {
|
|
t.Errorf("wrong number of diagnostics from ParseConfig %d; want %d", len(diags), 0)
|
|
for _, diag := range diags {
|
|
t.Logf(" - %s", diag.Error())
|
|
}
|
|
}
|
|
body := file.Body
|
|
|
|
got := Variables(body, test.spec)
|
|
|
|
if !reflect.DeepEqual(got, test.want) {
|
|
t.Errorf("wrong result\ngot: %#v\nwant: %#v", got, test.want)
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|