github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/legacy/helper/schema/field_reader_multi_test.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package schema
     5  
     6  import (
     7  	"reflect"
     8  	"strconv"
     9  	"testing"
    10  
    11  	"github.com/terramate-io/tf/legacy/terraform"
    12  )
    13  
    14  func TestMultiLevelFieldReaderReadFieldExact(t *testing.T) {
    15  	cases := map[string]struct {
    16  		Addr    []string
    17  		Readers []FieldReader
    18  		Level   string
    19  		Result  FieldReadResult
    20  	}{
    21  		"specific": {
    22  			Addr: []string{"foo"},
    23  
    24  			Readers: []FieldReader{
    25  				&MapFieldReader{
    26  					Schema: map[string]*Schema{
    27  						"foo": &Schema{Type: TypeString},
    28  					},
    29  					Map: BasicMapReader(map[string]string{
    30  						"foo": "bar",
    31  					}),
    32  				},
    33  				&MapFieldReader{
    34  					Schema: map[string]*Schema{
    35  						"foo": &Schema{Type: TypeString},
    36  					},
    37  					Map: BasicMapReader(map[string]string{
    38  						"foo": "baz",
    39  					}),
    40  				},
    41  				&MapFieldReader{
    42  					Schema: map[string]*Schema{
    43  						"foo": &Schema{Type: TypeString},
    44  					},
    45  					Map: BasicMapReader(map[string]string{}),
    46  				},
    47  			},
    48  
    49  			Level: "1",
    50  			Result: FieldReadResult{
    51  				Value:  "baz",
    52  				Exists: true,
    53  			},
    54  		},
    55  	}
    56  
    57  	for name, tc := range cases {
    58  		readers := make(map[string]FieldReader)
    59  		levels := make([]string, len(tc.Readers))
    60  		for i, r := range tc.Readers {
    61  			is := strconv.FormatInt(int64(i), 10)
    62  			readers[is] = r
    63  			levels[i] = is
    64  		}
    65  
    66  		r := &MultiLevelFieldReader{
    67  			Readers: readers,
    68  			Levels:  levels,
    69  		}
    70  
    71  		out, err := r.ReadFieldExact(tc.Addr, tc.Level)
    72  		if err != nil {
    73  			t.Fatalf("%s: err: %s", name, err)
    74  		}
    75  
    76  		if !reflect.DeepEqual(tc.Result, out) {
    77  			t.Fatalf("%s: bad: %#v", name, out)
    78  		}
    79  	}
    80  }
    81  
    82  func TestMultiLevelFieldReaderReadFieldMerge(t *testing.T) {
    83  	cases := map[string]struct {
    84  		Addr    []string
    85  		Readers []FieldReader
    86  		Result  FieldReadResult
    87  	}{
    88  		"stringInDiff": {
    89  			Addr: []string{"availability_zone"},
    90  
    91  			Readers: []FieldReader{
    92  				&DiffFieldReader{
    93  					Schema: map[string]*Schema{
    94  						"availability_zone": &Schema{Type: TypeString},
    95  					},
    96  
    97  					Source: &MapFieldReader{
    98  						Schema: map[string]*Schema{
    99  							"availability_zone": &Schema{Type: TypeString},
   100  						},
   101  						Map: BasicMapReader(map[string]string{
   102  							"availability_zone": "foo",
   103  						}),
   104  					},
   105  
   106  					Diff: &terraform.InstanceDiff{
   107  						Attributes: map[string]*terraform.ResourceAttrDiff{
   108  							"availability_zone": &terraform.ResourceAttrDiff{
   109  								Old:         "foo",
   110  								New:         "bar",
   111  								RequiresNew: true,
   112  							},
   113  						},
   114  					},
   115  				},
   116  			},
   117  
   118  			Result: FieldReadResult{
   119  				Value:  "bar",
   120  				Exists: true,
   121  			},
   122  		},
   123  
   124  		"lastLevelComputed": {
   125  			Addr: []string{"availability_zone"},
   126  
   127  			Readers: []FieldReader{
   128  				&MapFieldReader{
   129  					Schema: map[string]*Schema{
   130  						"availability_zone": &Schema{Type: TypeString},
   131  					},
   132  
   133  					Map: BasicMapReader(map[string]string{
   134  						"availability_zone": "foo",
   135  					}),
   136  				},
   137  
   138  				&DiffFieldReader{
   139  					Schema: map[string]*Schema{
   140  						"availability_zone": &Schema{Type: TypeString},
   141  					},
   142  
   143  					Source: &MapFieldReader{
   144  						Schema: map[string]*Schema{
   145  							"availability_zone": &Schema{Type: TypeString},
   146  						},
   147  
   148  						Map: BasicMapReader(map[string]string{
   149  							"availability_zone": "foo",
   150  						}),
   151  					},
   152  
   153  					Diff: &terraform.InstanceDiff{
   154  						Attributes: map[string]*terraform.ResourceAttrDiff{
   155  							"availability_zone": &terraform.ResourceAttrDiff{
   156  								Old:         "foo",
   157  								New:         "bar",
   158  								NewComputed: true,
   159  							},
   160  						},
   161  					},
   162  				},
   163  			},
   164  
   165  			Result: FieldReadResult{
   166  				Value:    "",
   167  				Exists:   true,
   168  				Computed: true,
   169  			},
   170  		},
   171  
   172  		"list of maps with removal in diff": {
   173  			Addr: []string{"config_vars"},
   174  
   175  			Readers: []FieldReader{
   176  				&DiffFieldReader{
   177  					Schema: map[string]*Schema{
   178  						"config_vars": &Schema{
   179  							Type: TypeList,
   180  							Elem: &Schema{Type: TypeMap},
   181  						},
   182  					},
   183  
   184  					Source: &MapFieldReader{
   185  						Schema: map[string]*Schema{
   186  							"config_vars": &Schema{
   187  								Type: TypeList,
   188  								Elem: &Schema{Type: TypeMap},
   189  							},
   190  						},
   191  
   192  						Map: BasicMapReader(map[string]string{
   193  							"config_vars.#":     "2",
   194  							"config_vars.0.foo": "bar",
   195  							"config_vars.0.bar": "bar",
   196  							"config_vars.1.bar": "baz",
   197  						}),
   198  					},
   199  
   200  					Diff: &terraform.InstanceDiff{
   201  						Attributes: map[string]*terraform.ResourceAttrDiff{
   202  							"config_vars.0.bar": &terraform.ResourceAttrDiff{
   203  								NewRemoved: true,
   204  							},
   205  						},
   206  					},
   207  				},
   208  			},
   209  
   210  			Result: FieldReadResult{
   211  				Value: []interface{}{
   212  					map[string]interface{}{
   213  						"foo": "bar",
   214  					},
   215  					map[string]interface{}{
   216  						"bar": "baz",
   217  					},
   218  				},
   219  				Exists: true,
   220  			},
   221  		},
   222  
   223  		"first level only": {
   224  			Addr: []string{"foo"},
   225  
   226  			Readers: []FieldReader{
   227  				&MapFieldReader{
   228  					Schema: map[string]*Schema{
   229  						"foo": &Schema{Type: TypeString},
   230  					},
   231  					Map: BasicMapReader(map[string]string{
   232  						"foo": "bar",
   233  					}),
   234  				},
   235  				&MapFieldReader{
   236  					Schema: map[string]*Schema{
   237  						"foo": &Schema{Type: TypeString},
   238  					},
   239  					Map: BasicMapReader(map[string]string{}),
   240  				},
   241  			},
   242  
   243  			Result: FieldReadResult{
   244  				Value:  "bar",
   245  				Exists: true,
   246  			},
   247  		},
   248  	}
   249  
   250  	for name, tc := range cases {
   251  		readers := make(map[string]FieldReader)
   252  		levels := make([]string, len(tc.Readers))
   253  		for i, r := range tc.Readers {
   254  			is := strconv.FormatInt(int64(i), 10)
   255  			readers[is] = r
   256  			levels[i] = is
   257  		}
   258  
   259  		r := &MultiLevelFieldReader{
   260  			Readers: readers,
   261  			Levels:  levels,
   262  		}
   263  
   264  		out, err := r.ReadFieldMerge(tc.Addr, levels[len(levels)-1])
   265  		if err != nil {
   266  			t.Fatalf("%s: err: %s", name, err)
   267  		}
   268  
   269  		if !reflect.DeepEqual(tc.Result, out) {
   270  			t.Fatalf("%s: bad: %#v", name, out)
   271  		}
   272  	}
   273  }