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

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package schema
     5  
     6  import (
     7  	"bytes"
     8  	"testing"
     9  )
    10  
    11  func TestSerializeForHash(t *testing.T) {
    12  	type testCase struct {
    13  		Schema   interface{}
    14  		Value    interface{}
    15  		Expected string
    16  	}
    17  
    18  	tests := []testCase{
    19  		testCase{
    20  			Schema: &Schema{
    21  				Type: TypeInt,
    22  			},
    23  			Value:    0,
    24  			Expected: "0;",
    25  		},
    26  
    27  		testCase{
    28  			Schema: &Schema{
    29  				Type: TypeInt,
    30  			},
    31  			Value:    200,
    32  			Expected: "200;",
    33  		},
    34  
    35  		testCase{
    36  			Schema: &Schema{
    37  				Type: TypeBool,
    38  			},
    39  			Value:    true,
    40  			Expected: "1;",
    41  		},
    42  
    43  		testCase{
    44  			Schema: &Schema{
    45  				Type: TypeBool,
    46  			},
    47  			Value:    false,
    48  			Expected: "0;",
    49  		},
    50  
    51  		testCase{
    52  			Schema: &Schema{
    53  				Type: TypeFloat,
    54  			},
    55  			Value:    1.0,
    56  			Expected: "1;",
    57  		},
    58  
    59  		testCase{
    60  			Schema: &Schema{
    61  				Type: TypeFloat,
    62  			},
    63  			Value:    1.54,
    64  			Expected: "1.54;",
    65  		},
    66  
    67  		testCase{
    68  			Schema: &Schema{
    69  				Type: TypeFloat,
    70  			},
    71  			Value:    0.1,
    72  			Expected: "0.1;",
    73  		},
    74  
    75  		testCase{
    76  			Schema: &Schema{
    77  				Type: TypeString,
    78  			},
    79  			Value:    "hello",
    80  			Expected: "hello;",
    81  		},
    82  
    83  		testCase{
    84  			Schema: &Schema{
    85  				Type: TypeString,
    86  			},
    87  			Value:    "1",
    88  			Expected: "1;",
    89  		},
    90  
    91  		testCase{
    92  			Schema: &Schema{
    93  				Type: TypeList,
    94  				Elem: &Schema{
    95  					Type: TypeString,
    96  				},
    97  			},
    98  			Value:    []interface{}{},
    99  			Expected: "();",
   100  		},
   101  
   102  		testCase{
   103  			Schema: &Schema{
   104  				Type: TypeList,
   105  				Elem: &Schema{
   106  					Type: TypeString,
   107  				},
   108  			},
   109  			Value:    []interface{}{"hello", "world"},
   110  			Expected: "(hello;world;);",
   111  		},
   112  
   113  		testCase{
   114  			Schema: &Schema{
   115  				Type: TypeList,
   116  				Elem: &Resource{
   117  					Schema: map[string]*Schema{
   118  						"fo": &Schema{
   119  							Type:     TypeString,
   120  							Required: true,
   121  						},
   122  						"fum": &Schema{
   123  							Type:     TypeString,
   124  							Required: true,
   125  						},
   126  					},
   127  				},
   128  			},
   129  			Value: []interface{}{
   130  				map[string]interface{}{
   131  					"fo": "bar",
   132  				},
   133  				map[string]interface{}{
   134  					"fo":  "baz",
   135  					"fum": "boz",
   136  				},
   137  			},
   138  			Expected: "(<fo:bar;fum:;>;<fo:baz;fum:boz;>;);",
   139  		},
   140  
   141  		testCase{
   142  			Schema: &Schema{
   143  				Type: TypeSet,
   144  				Elem: &Schema{
   145  					Type: TypeString,
   146  				},
   147  			},
   148  			Value: NewSet(func(i interface{}) int { return len(i.(string)) }, []interface{}{
   149  				"hello",
   150  				"woo",
   151  			}),
   152  			Expected: "{woo;hello;};",
   153  		},
   154  
   155  		testCase{
   156  			Schema: &Schema{
   157  				Type: TypeMap,
   158  				Elem: &Schema{
   159  					Type: TypeString,
   160  				},
   161  			},
   162  			Value: map[string]interface{}{
   163  				"foo": "bar",
   164  				"baz": "foo",
   165  			},
   166  			Expected: "[baz:foo;foo:bar;];",
   167  		},
   168  
   169  		testCase{
   170  			Schema: &Resource{
   171  				Schema: map[string]*Schema{
   172  					"name": &Schema{
   173  						Type:     TypeString,
   174  						Required: true,
   175  					},
   176  					"size": &Schema{
   177  						Type:     TypeInt,
   178  						Optional: true,
   179  					},
   180  					"green": &Schema{
   181  						Type:     TypeBool,
   182  						Optional: true,
   183  						Computed: true,
   184  					},
   185  					"upside_down": &Schema{
   186  						Type:     TypeBool,
   187  						Computed: true,
   188  					},
   189  				},
   190  			},
   191  			Value: map[string]interface{}{
   192  				"name":  "my-fun-database",
   193  				"size":  12,
   194  				"green": true,
   195  			},
   196  			Expected: "green:1;name:my-fun-database;size:12;",
   197  		},
   198  
   199  		// test TypeMap nested in Schema: GH-7091
   200  		testCase{
   201  			Schema: &Resource{
   202  				Schema: map[string]*Schema{
   203  					"outer": &Schema{
   204  						Type:     TypeSet,
   205  						Required: true,
   206  						Elem: &Schema{
   207  							Type:     TypeMap,
   208  							Optional: true,
   209  						},
   210  					},
   211  				},
   212  			},
   213  			Value: map[string]interface{}{
   214  				"outer": NewSet(func(i interface{}) int { return 42 }, []interface{}{
   215  					map[string]interface{}{
   216  						"foo": "bar",
   217  						"baz": "foo",
   218  					},
   219  				}),
   220  			},
   221  			Expected: "outer:{[baz:foo;foo:bar;];};",
   222  		},
   223  	}
   224  
   225  	for _, test := range tests {
   226  		var gotBuf bytes.Buffer
   227  		schema := test.Schema
   228  
   229  		switch s := schema.(type) {
   230  		case *Schema:
   231  			SerializeValueForHash(&gotBuf, test.Value, s)
   232  		case *Resource:
   233  			SerializeResourceForHash(&gotBuf, test.Value, s)
   234  		}
   235  
   236  		got := gotBuf.String()
   237  		if got != test.Expected {
   238  			t.Errorf("hash(%#v) got %#v, but want %#v", test.Value, got, test.Expected)
   239  		}
   240  	}
   241  }