github.com/opentofu/opentofu@v1.7.1/internal/configs/configschema/filter_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 configschema
     7  
     8  import (
     9  	"testing"
    10  
    11  	"github.com/zclconf/go-cty/cty"
    12  
    13  	"github.com/google/go-cmp/cmp"
    14  	"github.com/google/go-cmp/cmp/cmpopts"
    15  )
    16  
    17  func TestFilter(t *testing.T) {
    18  	testCases := map[string]struct {
    19  		schema          *Block
    20  		filterAttribute FilterT[*Attribute]
    21  		filterBlock     FilterT[*NestedBlock]
    22  		want            *Block
    23  	}{
    24  		"empty": {
    25  			schema:          &Block{},
    26  			filterAttribute: FilterDeprecatedAttribute,
    27  			filterBlock:     FilterDeprecatedBlock,
    28  			want:            &Block{},
    29  		},
    30  		"noop": {
    31  			schema: &Block{
    32  				Attributes: map[string]*Attribute{
    33  					"string": {
    34  						Type:     cty.String,
    35  						Required: true,
    36  					},
    37  				},
    38  				BlockTypes: map[string]*NestedBlock{
    39  					"list": {
    40  						Nesting: NestingList,
    41  						Block: Block{
    42  							Attributes: map[string]*Attribute{
    43  								"string": {
    44  									Type:     cty.String,
    45  									Required: true,
    46  								},
    47  							},
    48  						},
    49  					},
    50  				},
    51  			},
    52  			filterAttribute: nil,
    53  			filterBlock:     nil,
    54  			want: &Block{
    55  				Attributes: map[string]*Attribute{
    56  					"string": {
    57  						Type:     cty.String,
    58  						Required: true,
    59  					},
    60  				},
    61  				BlockTypes: map[string]*NestedBlock{
    62  					"list": {
    63  						Nesting: NestingList,
    64  						Block: Block{
    65  							Attributes: map[string]*Attribute{
    66  								"string": {
    67  									Type:     cty.String,
    68  									Required: true,
    69  								},
    70  							},
    71  						},
    72  					},
    73  				},
    74  			},
    75  		},
    76  		"filter_deprecated": {
    77  			schema: &Block{
    78  				Attributes: map[string]*Attribute{
    79  					"string": {
    80  						Type:     cty.String,
    81  						Optional: true,
    82  					},
    83  					"deprecated_string": {
    84  						Type:       cty.String,
    85  						Deprecated: true,
    86  					},
    87  					"nested": {
    88  						NestedType: &Object{
    89  							Attributes: map[string]*Attribute{
    90  								"string": {
    91  									Type: cty.String,
    92  								},
    93  								"deprecated_string": {
    94  									Type:       cty.String,
    95  									Deprecated: true,
    96  								},
    97  							},
    98  							Nesting: NestingList,
    99  						},
   100  					},
   101  				},
   102  
   103  				BlockTypes: map[string]*NestedBlock{
   104  					"list": {
   105  						Nesting: NestingList,
   106  						Block: Block{
   107  							Attributes: map[string]*Attribute{
   108  								"string": {
   109  									Type:     cty.String,
   110  									Optional: true,
   111  								},
   112  							},
   113  							Deprecated: true,
   114  						},
   115  					},
   116  				},
   117  			},
   118  			filterAttribute: FilterDeprecatedAttribute,
   119  			filterBlock:     FilterDeprecatedBlock,
   120  			want: &Block{
   121  				Attributes: map[string]*Attribute{
   122  					"string": {
   123  						Type:     cty.String,
   124  						Optional: true,
   125  					},
   126  					"nested": {
   127  						NestedType: &Object{
   128  							Attributes: map[string]*Attribute{
   129  								"string": {
   130  									Type: cty.String,
   131  								},
   132  							},
   133  							Nesting: NestingList,
   134  						},
   135  					},
   136  				},
   137  			},
   138  		},
   139  		"filter_read_only": {
   140  			schema: &Block{
   141  				Attributes: map[string]*Attribute{
   142  					"string": {
   143  						Type:     cty.String,
   144  						Optional: true,
   145  					},
   146  					"read_only_string": {
   147  						Type:     cty.String,
   148  						Computed: true,
   149  					},
   150  					"nested": {
   151  						NestedType: &Object{
   152  							Attributes: map[string]*Attribute{
   153  								"string": {
   154  									Type:     cty.String,
   155  									Optional: true,
   156  								},
   157  								"read_only_string": {
   158  									Type:     cty.String,
   159  									Computed: true,
   160  								},
   161  								"deeply_nested": {
   162  									NestedType: &Object{
   163  										Attributes: map[string]*Attribute{
   164  											"number": {
   165  												Type:     cty.Number,
   166  												Required: true,
   167  											},
   168  											"read_only_number": {
   169  												Type:     cty.Number,
   170  												Computed: true,
   171  											},
   172  										},
   173  										Nesting: NestingList,
   174  									},
   175  								},
   176  							},
   177  							Nesting: NestingList,
   178  						},
   179  					},
   180  				},
   181  
   182  				BlockTypes: map[string]*NestedBlock{
   183  					"list": {
   184  						Nesting: NestingList,
   185  						Block: Block{
   186  							Attributes: map[string]*Attribute{
   187  								"string": {
   188  									Type:     cty.String,
   189  									Optional: true,
   190  								},
   191  								"read_only_string": {
   192  									Type:     cty.String,
   193  									Computed: true,
   194  								},
   195  							},
   196  						},
   197  					},
   198  				},
   199  			},
   200  			filterAttribute: FilterReadOnlyAttribute,
   201  			filterBlock:     nil,
   202  			want: &Block{
   203  				Attributes: map[string]*Attribute{
   204  					"string": {
   205  						Type:     cty.String,
   206  						Optional: true,
   207  					},
   208  					"nested": {
   209  						NestedType: &Object{
   210  							Attributes: map[string]*Attribute{
   211  								"string": {
   212  									Type:     cty.String,
   213  									Optional: true,
   214  								},
   215  								"deeply_nested": {
   216  									NestedType: &Object{
   217  										Attributes: map[string]*Attribute{
   218  											"number": {
   219  												Type:     cty.Number,
   220  												Required: true,
   221  											},
   222  										},
   223  										Nesting: NestingList,
   224  									},
   225  								},
   226  							},
   227  							Nesting: NestingList,
   228  						},
   229  					},
   230  				},
   231  				BlockTypes: map[string]*NestedBlock{
   232  					"list": {
   233  						Nesting: NestingList,
   234  						Block: Block{
   235  							Attributes: map[string]*Attribute{
   236  								"string": {
   237  									Type:     cty.String,
   238  									Optional: true,
   239  								},
   240  							},
   241  						},
   242  					},
   243  				},
   244  			},
   245  		},
   246  		"filter_optional_computed_id": {
   247  			schema: &Block{
   248  				Attributes: map[string]*Attribute{
   249  					"id": {
   250  						Type:     cty.String,
   251  						Optional: true,
   252  						Computed: true,
   253  					},
   254  					"string": {
   255  						Type:     cty.String,
   256  						Optional: true,
   257  						Computed: true,
   258  					},
   259  				},
   260  			},
   261  			filterAttribute: FilterHelperSchemaIdAttribute,
   262  			filterBlock:     nil,
   263  			want: &Block{
   264  				Attributes: map[string]*Attribute{
   265  					"string": {
   266  						Type:     cty.String,
   267  						Optional: true,
   268  						Computed: true,
   269  					},
   270  				},
   271  			},
   272  		},
   273  	}
   274  
   275  	for name, tc := range testCases {
   276  		t.Run(name, func(t *testing.T) {
   277  			got := tc.schema.Filter(tc.filterAttribute, tc.filterBlock)
   278  			if !cmp.Equal(got, tc.want, cmp.Comparer(cty.Type.Equals), cmpopts.EquateEmpty()) {
   279  				t.Fatal(cmp.Diff(got, tc.want, cmp.Comparer(cty.Type.Equals), cmpopts.EquateEmpty()))
   280  			}
   281  		})
   282  	}
   283  }