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