github.com/opentofu/opentofu@v1.7.1/internal/tofu/evaluate_triggers_test.go (about) 1 // Copyright (c) The OpenTofu Authors 2 // SPDX-License-Identifier: MPL-2.0 3 // Copyright (c) 2023 HashiCorp, Inc. 4 // SPDX-License-Identifier: MPL-2.0 5 6 package tofu 7 8 import ( 9 "testing" 10 11 "github.com/hashicorp/hcl/v2" 12 "github.com/hashicorp/hcl/v2/hclsyntax" 13 "github.com/opentofu/opentofu/internal/addrs" 14 "github.com/opentofu/opentofu/internal/instances" 15 "github.com/zclconf/go-cty/cty" 16 ) 17 18 func TestEvalReplaceTriggeredBy(t *testing.T) { 19 tests := map[string]struct { 20 // Raw config expression from within replace_triggered_by list. 21 // If this does not contains any count or each references, it should 22 // directly parse into the same *addrs.Reference. 23 expr string 24 25 // If the expression contains count or each, then we need to add 26 // repetition data, and the static string to parse into the desired 27 // *addrs.Reference 28 repData instances.RepetitionData 29 reference string 30 }{ 31 "single resource": { 32 expr: "test_resource.a", 33 }, 34 35 "resource instance attr": { 36 expr: "test_resource.a.attr", 37 }, 38 39 "resource instance index attr": { 40 expr: "test_resource.a[0].attr", 41 }, 42 43 "resource instance count": { 44 expr: "test_resource.a[count.index]", 45 repData: instances.RepetitionData{ 46 CountIndex: cty.NumberIntVal(0), 47 }, 48 reference: "test_resource.a[0]", 49 }, 50 "resource instance for_each": { 51 expr: "test_resource.a[each.key].attr", 52 repData: instances.RepetitionData{ 53 EachKey: cty.StringVal("k"), 54 }, 55 reference: `test_resource.a["k"].attr`, 56 }, 57 "resource instance for_each map attr": { 58 expr: "test_resource.a[each.key].attr[each.key]", 59 repData: instances.RepetitionData{ 60 EachKey: cty.StringVal("k"), 61 }, 62 reference: `test_resource.a["k"].attr["k"]`, 63 }, 64 } 65 66 for name, tc := range tests { 67 pos := hcl.Pos{Line: 1, Column: 1} 68 t.Run(name, func(t *testing.T) { 69 expr, hclDiags := hclsyntax.ParseExpression([]byte(tc.expr), "", pos) 70 if hclDiags.HasErrors() { 71 t.Fatal(hclDiags) 72 } 73 74 got, diags := evalReplaceTriggeredByExpr(expr, tc.repData) 75 if diags.HasErrors() { 76 t.Fatal(diags.Err()) 77 } 78 79 want := tc.reference 80 if want == "" { 81 want = tc.expr 82 } 83 84 // create the desired reference 85 traversal, travDiags := hclsyntax.ParseTraversalAbs([]byte(want), "", pos) 86 if travDiags.HasErrors() { 87 t.Fatal(travDiags) 88 } 89 ref, diags := addrs.ParseRef(traversal) 90 if diags.HasErrors() { 91 t.Fatal(diags.Err()) 92 } 93 94 if got.DisplayString() != ref.DisplayString() { 95 t.Fatalf("expected %q: got %q", ref.DisplayString(), got.DisplayString()) 96 } 97 }) 98 } 99 }