kubeform.dev/terraform-backend-sdk@v0.0.0-20220310143633-45f07fe731c5/configs/moved_test.go (about)

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