| 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) |
| } |
| } |
| }) |
| } |
| } |