github.com/terraform-linters/tflint-plugin-sdk@v0.22.0/terraform/lang/references_test.go (about) 1 package lang 2 3 import ( 4 "sort" 5 "testing" 6 7 "github.com/go-test/deep" 8 "github.com/hashicorp/hcl/v2" 9 "github.com/hashicorp/hcl/v2/hclsyntax" 10 "github.com/terraform-linters/tflint-plugin-sdk/terraform/addrs" 11 ) 12 13 func TestReferencesInExpr(t *testing.T) { 14 tests := []struct { 15 Name string 16 Input string 17 Want []*addrs.Reference 18 }{ 19 { 20 Name: "input variable", 21 Input: `var.foo`, 22 Want: []*addrs.Reference{ 23 { 24 Subject: addrs.InputVariable{ 25 Name: "foo", 26 }, 27 SourceRange: hcl.Range{ 28 Start: hcl.Pos{Line: 1, Column: 1, Byte: 0}, 29 End: hcl.Pos{Line: 1, Column: 8, Byte: 7}, 30 }, 31 }, 32 }, 33 }, 34 { 35 Name: "multiple input variables", 36 Input: `"${var.foo}-${var.bar}"`, 37 Want: []*addrs.Reference{ 38 { 39 Subject: addrs.InputVariable{ 40 Name: "foo", 41 }, 42 SourceRange: hcl.Range{ 43 Start: hcl.Pos{Line: 1, Column: 4, Byte: 3}, 44 End: hcl.Pos{Line: 1, Column: 11, Byte: 10}, 45 }, 46 }, 47 { 48 Subject: addrs.InputVariable{ 49 Name: "bar", 50 }, 51 SourceRange: hcl.Range{ 52 Start: hcl.Pos{Line: 1, Column: 15, Byte: 14}, 53 End: hcl.Pos{Line: 1, Column: 22, Byte: 21}, 54 }, 55 }, 56 }, 57 }, 58 { 59 Name: "input variable and resource", 60 Input: `"${boop_instance.foo}_${var.foo}"`, 61 Want: []*addrs.Reference{ 62 { 63 Subject: addrs.Resource{ 64 Mode: addrs.ManagedResourceMode, 65 Type: "boop_instance", 66 Name: "foo", 67 }, 68 SourceRange: hcl.Range{ 69 Start: hcl.Pos{Line: 1, Column: 4, Byte: 3}, 70 End: hcl.Pos{Line: 1, Column: 21, Byte: 20}, 71 }, 72 }, 73 { 74 Subject: addrs.InputVariable{ 75 Name: "foo", 76 }, 77 SourceRange: hcl.Range{ 78 Start: hcl.Pos{Line: 1, Column: 25, Byte: 24}, 79 End: hcl.Pos{Line: 1, Column: 32, Byte: 31}, 80 }, 81 }, 82 }, 83 }, 84 { 85 Name: "contains invalid references", 86 Input: `"${boop_instance}_${var.foo}"`, // A reference to a resource type must be followed by at least one attribute access, specifying the resource name. 87 Want: []*addrs.Reference{ 88 { 89 Subject: addrs.InputVariable{ 90 Name: "foo", 91 }, 92 SourceRange: hcl.Range{ 93 Start: hcl.Pos{Line: 1, Column: 21, Byte: 20}, 94 End: hcl.Pos{Line: 1, Column: 28, Byte: 27}, 95 }, 96 }, 97 }, 98 }, 99 } 100 101 for _, test := range tests { 102 t.Run(test.Name, func(t *testing.T) { 103 expr, diags := hclsyntax.ParseExpression([]byte(test.Input), "", hcl.InitialPos) 104 if diags.HasErrors() { 105 t.Fatal(diags) 106 } 107 108 got := ReferencesInExpr(expr) 109 sort.Slice(got, func(i, j int) bool { 110 return got[i].SourceRange.String() > got[j].SourceRange.String() 111 }) 112 113 for _, problem := range deep.Equal(got, test.Want) { 114 t.Errorf(problem) 115 } 116 }) 117 } 118 }