github.com/hashicorp/hcl/v2@v2.20.0/hclsyntax/parse_traversal_test.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package hclsyntax 5 6 import ( 7 "testing" 8 9 "github.com/go-test/deep" 10 "github.com/hashicorp/hcl/v2" 11 "github.com/zclconf/go-cty/cty" 12 ) 13 14 func TestParseTraversalAbs(t *testing.T) { 15 tests := []struct { 16 src string 17 want hcl.Traversal 18 diagCount int 19 }{ 20 { 21 "", 22 nil, 23 1, // variable name required 24 }, 25 { 26 "foo", 27 hcl.Traversal{ 28 hcl.TraverseRoot{ 29 Name: "foo", 30 SrcRange: hcl.Range{ 31 Start: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 32 End: hcl.Pos{Line: 1, Column: 4, Byte: 3}, 33 }, 34 }, 35 }, 36 0, 37 }, 38 { 39 "foo.bar.baz", 40 hcl.Traversal{ 41 hcl.TraverseRoot{ 42 Name: "foo", 43 SrcRange: hcl.Range{ 44 Start: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 45 End: hcl.Pos{Line: 1, Column: 4, Byte: 3}, 46 }, 47 }, 48 hcl.TraverseAttr{ 49 Name: "bar", 50 SrcRange: hcl.Range{ 51 Start: hcl.Pos{Line: 1, Column: 4, Byte: 3}, 52 End: hcl.Pos{Line: 1, Column: 8, Byte: 7}, 53 }, 54 }, 55 hcl.TraverseAttr{ 56 Name: "baz", 57 SrcRange: hcl.Range{ 58 Start: hcl.Pos{Line: 1, Column: 8, Byte: 7}, 59 End: hcl.Pos{Line: 1, Column: 12, Byte: 11}, 60 }, 61 }, 62 }, 63 0, 64 }, 65 { 66 "foo[1]", 67 hcl.Traversal{ 68 hcl.TraverseRoot{ 69 Name: "foo", 70 SrcRange: hcl.Range{ 71 Start: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 72 End: hcl.Pos{Line: 1, Column: 4, Byte: 3}, 73 }, 74 }, 75 hcl.TraverseIndex{ 76 Key: cty.NumberIntVal(1), 77 SrcRange: hcl.Range{ 78 Start: hcl.Pos{Line: 1, Column: 4, Byte: 3}, 79 End: hcl.Pos{Line: 1, Column: 7, Byte: 6}, 80 }, 81 }, 82 }, 83 0, 84 }, 85 { 86 "foo[1][2]", 87 hcl.Traversal{ 88 hcl.TraverseRoot{ 89 Name: "foo", 90 SrcRange: hcl.Range{ 91 Start: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 92 End: hcl.Pos{Line: 1, Column: 4, Byte: 3}, 93 }, 94 }, 95 hcl.TraverseIndex{ 96 Key: cty.NumberIntVal(1), 97 SrcRange: hcl.Range{ 98 Start: hcl.Pos{Line: 1, Column: 4, Byte: 3}, 99 End: hcl.Pos{Line: 1, Column: 7, Byte: 6}, 100 }, 101 }, 102 hcl.TraverseIndex{ 103 Key: cty.NumberIntVal(2), 104 SrcRange: hcl.Range{ 105 Start: hcl.Pos{Line: 1, Column: 7, Byte: 6}, 106 End: hcl.Pos{Line: 1, Column: 10, Byte: 9}, 107 }, 108 }, 109 }, 110 0, 111 }, 112 { 113 "foo[1].bar", 114 hcl.Traversal{ 115 hcl.TraverseRoot{ 116 Name: "foo", 117 SrcRange: hcl.Range{ 118 Start: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 119 End: hcl.Pos{Line: 1, Column: 4, Byte: 3}, 120 }, 121 }, 122 hcl.TraverseIndex{ 123 Key: cty.NumberIntVal(1), 124 SrcRange: hcl.Range{ 125 Start: hcl.Pos{Line: 1, Column: 4, Byte: 3}, 126 End: hcl.Pos{Line: 1, Column: 7, Byte: 6}, 127 }, 128 }, 129 hcl.TraverseAttr{ 130 Name: "bar", 131 SrcRange: hcl.Range{ 132 Start: hcl.Pos{Line: 1, Column: 7, Byte: 6}, 133 End: hcl.Pos{Line: 1, Column: 11, Byte: 10}, 134 }, 135 }, 136 }, 137 0, 138 }, 139 { 140 "foo.", 141 hcl.Traversal{ 142 hcl.TraverseRoot{ 143 Name: "foo", 144 SrcRange: hcl.Range{ 145 Start: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 146 End: hcl.Pos{Line: 1, Column: 4, Byte: 3}, 147 }, 148 }, 149 }, 150 1, // attribute name required 151 }, 152 { 153 "foo[", 154 hcl.Traversal{ 155 hcl.TraverseRoot{ 156 Name: "foo", 157 SrcRange: hcl.Range{ 158 Start: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 159 End: hcl.Pos{Line: 1, Column: 4, Byte: 3}, 160 }, 161 }, 162 }, 163 1, // index required 164 }, 165 { 166 "foo[index]", 167 hcl.Traversal{ 168 hcl.TraverseRoot{ 169 Name: "foo", 170 SrcRange: hcl.Range{ 171 Start: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 172 End: hcl.Pos{Line: 1, Column: 4, Byte: 3}, 173 }, 174 }, 175 }, 176 1, // index must be literal 177 }, 178 { 179 "foo[0", 180 hcl.Traversal{ 181 hcl.TraverseRoot{ 182 Name: "foo", 183 SrcRange: hcl.Range{ 184 Start: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 185 End: hcl.Pos{Line: 1, Column: 4, Byte: 3}, 186 }, 187 }, 188 hcl.TraverseIndex{ 189 Key: cty.NumberIntVal(0), 190 SrcRange: hcl.Range{ 191 Start: hcl.Pos{Line: 1, Column: 4, Byte: 3}, 192 End: hcl.Pos{Line: 1, Column: 6, Byte: 5}, 193 }, 194 }, 195 }, 196 1, // missing close bracket 197 }, 198 { 199 "foo 0", 200 hcl.Traversal{ 201 hcl.TraverseRoot{ 202 Name: "foo", 203 SrcRange: hcl.Range{ 204 Start: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 205 End: hcl.Pos{Line: 1, Column: 4, Byte: 3}, 206 }, 207 }, 208 }, 209 1, // extra junk after traversal 210 }, 211 } 212 213 for _, test := range tests { 214 t.Run(test.src, func(t *testing.T) { 215 got, diags := ParseTraversalAbs([]byte(test.src), "", hcl.Pos{Line: 1, Column: 1}) 216 if len(diags) != test.diagCount { 217 for _, diag := range diags { 218 t.Logf(" - %s", diag.Error()) 219 } 220 t.Errorf("wrong number of diagnostics %d; want %d", len(diags), test.diagCount) 221 } 222 223 if diff := deep.Equal(got, test.want); diff != nil { 224 for _, problem := range diff { 225 t.Error(problem) 226 } 227 } 228 }) 229 } 230 }