github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/configs/moved_test.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package configs 5 6 import ( 7 "testing" 8 9 "github.com/google/go-cmp/cmp" 10 "github.com/hashicorp/hcl/v2" 11 "github.com/hashicorp/hcl/v2/hcltest" 12 "github.com/terramate-io/tf/addrs" 13 ) 14 15 func TestMovedBlock_decode(t *testing.T) { 16 blockRange := hcl.Range{ 17 Filename: "mock.tf", 18 Start: hcl.Pos{Line: 3, Column: 12, Byte: 27}, 19 End: hcl.Pos{Line: 3, Column: 19, Byte: 34}, 20 } 21 22 foo_expr := hcltest.MockExprTraversalSrc("test_instance.foo") 23 bar_expr := hcltest.MockExprTraversalSrc("test_instance.bar") 24 25 foo_index_expr := hcltest.MockExprTraversalSrc("test_instance.foo[1]") 26 bar_index_expr := hcltest.MockExprTraversalSrc("test_instance.bar[\"one\"]") 27 28 mod_foo_expr := hcltest.MockExprTraversalSrc("module.foo") 29 mod_bar_expr := hcltest.MockExprTraversalSrc("module.bar") 30 31 tests := map[string]struct { 32 input *hcl.Block 33 want *Moved 34 err string 35 }{ 36 "success": { 37 &hcl.Block{ 38 Type: "moved", 39 Body: hcltest.MockBody(&hcl.BodyContent{ 40 Attributes: hcl.Attributes{ 41 "from": { 42 Name: "from", 43 Expr: foo_expr, 44 }, 45 "to": { 46 Name: "to", 47 Expr: bar_expr, 48 }, 49 }, 50 }), 51 DefRange: blockRange, 52 }, 53 &Moved{ 54 From: mustMoveEndpointFromExpr(foo_expr), 55 To: mustMoveEndpointFromExpr(bar_expr), 56 DeclRange: blockRange, 57 }, 58 ``, 59 }, 60 "indexed resources": { 61 &hcl.Block{ 62 Type: "moved", 63 Body: hcltest.MockBody(&hcl.BodyContent{ 64 Attributes: hcl.Attributes{ 65 "from": { 66 Name: "from", 67 Expr: foo_index_expr, 68 }, 69 "to": { 70 Name: "to", 71 Expr: bar_index_expr, 72 }, 73 }, 74 }), 75 DefRange: blockRange, 76 }, 77 &Moved{ 78 From: mustMoveEndpointFromExpr(foo_index_expr), 79 To: mustMoveEndpointFromExpr(bar_index_expr), 80 DeclRange: blockRange, 81 }, 82 ``, 83 }, 84 "modules": { 85 &hcl.Block{ 86 Type: "moved", 87 Body: hcltest.MockBody(&hcl.BodyContent{ 88 Attributes: hcl.Attributes{ 89 "from": { 90 Name: "from", 91 Expr: mod_foo_expr, 92 }, 93 "to": { 94 Name: "to", 95 Expr: mod_bar_expr, 96 }, 97 }, 98 }), 99 DefRange: blockRange, 100 }, 101 &Moved{ 102 From: mustMoveEndpointFromExpr(mod_foo_expr), 103 To: mustMoveEndpointFromExpr(mod_bar_expr), 104 DeclRange: blockRange, 105 }, 106 ``, 107 }, 108 "error: missing argument": { 109 &hcl.Block{ 110 Type: "moved", 111 Body: hcltest.MockBody(&hcl.BodyContent{ 112 Attributes: hcl.Attributes{ 113 "from": { 114 Name: "from", 115 Expr: foo_expr, 116 }, 117 }, 118 }), 119 DefRange: blockRange, 120 }, 121 &Moved{ 122 From: mustMoveEndpointFromExpr(foo_expr), 123 DeclRange: blockRange, 124 }, 125 "Missing required argument", 126 }, 127 "error: type mismatch": { 128 &hcl.Block{ 129 Type: "moved", 130 Body: hcltest.MockBody(&hcl.BodyContent{ 131 Attributes: hcl.Attributes{ 132 "to": { 133 Name: "to", 134 Expr: foo_expr, 135 }, 136 "from": { 137 Name: "from", 138 Expr: mod_foo_expr, 139 }, 140 }, 141 }), 142 DefRange: blockRange, 143 }, 144 &Moved{ 145 To: mustMoveEndpointFromExpr(foo_expr), 146 From: mustMoveEndpointFromExpr(mod_foo_expr), 147 DeclRange: blockRange, 148 }, 149 "Invalid \"moved\" addresses", 150 }, 151 } 152 153 for name, test := range tests { 154 t.Run(name, func(t *testing.T) { 155 got, diags := decodeMovedBlock(test.input) 156 157 if diags.HasErrors() { 158 if test.err == "" { 159 t.Fatalf("unexpected error: %s", diags.Errs()) 160 } 161 if gotErr := diags[0].Summary; gotErr != test.err { 162 t.Errorf("wrong error, got %q, want %q", gotErr, test.err) 163 } 164 } else if test.err != "" { 165 t.Fatal("expected error") 166 } 167 168 if !cmp.Equal(got, test.want, cmp.AllowUnexported(addrs.MoveEndpoint{})) { 169 t.Fatalf("wrong result: %s", cmp.Diff(got, test.want)) 170 } 171 }) 172 } 173 } 174 175 func TestMovedBlock_inModule(t *testing.T) { 176 parser := NewParser(nil) 177 mod, diags := parser.LoadConfigDir("testdata/valid-modules/moved-blocks") 178 if diags.HasErrors() { 179 t.Errorf("unexpected error: %s", diags.Error()) 180 } 181 182 var gotPairs [][2]string 183 for _, mc := range mod.Moved { 184 gotPairs = append(gotPairs, [2]string{mc.From.String(), mc.To.String()}) 185 } 186 wantPairs := [][2]string{ 187 {`test.foo`, `test.bar`}, 188 {`test.foo`, `test.bar["bloop"]`}, 189 {`module.a`, `module.b`}, 190 {`module.a`, `module.a["foo"]`}, 191 {`test.foo`, `module.a.test.foo`}, 192 {`data.test.foo`, `data.test.bar`}, 193 } 194 if diff := cmp.Diff(wantPairs, gotPairs); diff != "" { 195 t.Errorf("wrong addresses\n%s", diff) 196 } 197 } 198 199 func mustMoveEndpointFromExpr(expr hcl.Expression) *addrs.MoveEndpoint { 200 traversal, hcldiags := hcl.AbsTraversalForExpr(expr) 201 if hcldiags.HasErrors() { 202 panic(hcldiags.Errs()) 203 } 204 205 ep, diags := addrs.ParseMoveEndpoint(traversal) 206 if diags.HasErrors() { 207 panic(diags.Err()) 208 } 209 210 return ep 211 }