hcl/hclsyntax/parse_traversal_test.go
Martin Atkins 6c4344623b Unfold the "hcl" directory up into the root
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.
2019-09-09 16:08:19 -07:00

228 lines
4.7 KiB
Go

package hclsyntax
import (
"testing"
"github.com/go-test/deep"
"github.com/hashicorp/hcl/v2"
"github.com/zclconf/go-cty/cty"
)
func TestParseTraversalAbs(t *testing.T) {
tests := []struct {
src string
want hcl.Traversal
diagCount int
}{
{
"",
nil,
1, // variable name required
},
{
"foo",
hcl.Traversal{
hcl.TraverseRoot{
Name: "foo",
SrcRange: hcl.Range{
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
End: hcl.Pos{Line: 1, Column: 4, Byte: 3},
},
},
},
0,
},
{
"foo.bar.baz",
hcl.Traversal{
hcl.TraverseRoot{
Name: "foo",
SrcRange: hcl.Range{
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
End: hcl.Pos{Line: 1, Column: 4, Byte: 3},
},
},
hcl.TraverseAttr{
Name: "bar",
SrcRange: hcl.Range{
Start: hcl.Pos{Line: 1, Column: 4, Byte: 3},
End: hcl.Pos{Line: 1, Column: 8, Byte: 7},
},
},
hcl.TraverseAttr{
Name: "baz",
SrcRange: hcl.Range{
Start: hcl.Pos{Line: 1, Column: 8, Byte: 7},
End: hcl.Pos{Line: 1, Column: 12, Byte: 11},
},
},
},
0,
},
{
"foo[1]",
hcl.Traversal{
hcl.TraverseRoot{
Name: "foo",
SrcRange: hcl.Range{
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
End: hcl.Pos{Line: 1, Column: 4, Byte: 3},
},
},
hcl.TraverseIndex{
Key: cty.NumberIntVal(1),
SrcRange: hcl.Range{
Start: hcl.Pos{Line: 1, Column: 4, Byte: 3},
End: hcl.Pos{Line: 1, Column: 7, Byte: 6},
},
},
},
0,
},
{
"foo[1][2]",
hcl.Traversal{
hcl.TraverseRoot{
Name: "foo",
SrcRange: hcl.Range{
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
End: hcl.Pos{Line: 1, Column: 4, Byte: 3},
},
},
hcl.TraverseIndex{
Key: cty.NumberIntVal(1),
SrcRange: hcl.Range{
Start: hcl.Pos{Line: 1, Column: 4, Byte: 3},
End: hcl.Pos{Line: 1, Column: 7, Byte: 6},
},
},
hcl.TraverseIndex{
Key: cty.NumberIntVal(2),
SrcRange: hcl.Range{
Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
End: hcl.Pos{Line: 1, Column: 10, Byte: 9},
},
},
},
0,
},
{
"foo[1].bar",
hcl.Traversal{
hcl.TraverseRoot{
Name: "foo",
SrcRange: hcl.Range{
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
End: hcl.Pos{Line: 1, Column: 4, Byte: 3},
},
},
hcl.TraverseIndex{
Key: cty.NumberIntVal(1),
SrcRange: hcl.Range{
Start: hcl.Pos{Line: 1, Column: 4, Byte: 3},
End: hcl.Pos{Line: 1, Column: 7, Byte: 6},
},
},
hcl.TraverseAttr{
Name: "bar",
SrcRange: hcl.Range{
Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
End: hcl.Pos{Line: 1, Column: 11, Byte: 10},
},
},
},
0,
},
{
"foo.",
hcl.Traversal{
hcl.TraverseRoot{
Name: "foo",
SrcRange: hcl.Range{
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
End: hcl.Pos{Line: 1, Column: 4, Byte: 3},
},
},
},
1, // attribute name required
},
{
"foo[",
hcl.Traversal{
hcl.TraverseRoot{
Name: "foo",
SrcRange: hcl.Range{
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
End: hcl.Pos{Line: 1, Column: 4, Byte: 3},
},
},
},
1, // index required
},
{
"foo[index]",
hcl.Traversal{
hcl.TraverseRoot{
Name: "foo",
SrcRange: hcl.Range{
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
End: hcl.Pos{Line: 1, Column: 4, Byte: 3},
},
},
},
1, // index must be literal
},
{
"foo[0",
hcl.Traversal{
hcl.TraverseRoot{
Name: "foo",
SrcRange: hcl.Range{
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
End: hcl.Pos{Line: 1, Column: 4, Byte: 3},
},
},
hcl.TraverseIndex{
Key: cty.NumberIntVal(0),
SrcRange: hcl.Range{
Start: hcl.Pos{Line: 1, Column: 4, Byte: 3},
End: hcl.Pos{Line: 1, Column: 6, Byte: 5},
},
},
},
1, // missing close bracket
},
{
"foo 0",
hcl.Traversal{
hcl.TraverseRoot{
Name: "foo",
SrcRange: hcl.Range{
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
End: hcl.Pos{Line: 1, Column: 4, Byte: 3},
},
},
},
1, // extra junk after traversal
},
}
for _, test := range tests {
t.Run(test.src, func(t *testing.T) {
got, diags := ParseTraversalAbs([]byte(test.src), "", hcl.Pos{Line: 1, Column: 1})
if len(diags) != test.diagCount {
for _, diag := range diags {
t.Logf(" - %s", diag.Error())
}
t.Errorf("wrong number of diagnostics %d; want %d", len(diags), test.diagCount)
}
if diff := deep.Equal(got, test.want); diff != nil {
for _, problem := range diff {
t.Error(problem)
}
}
})
}
}