github.com/opentofu/opentofu@v1.7.1/internal/legacy/helper/schema/set_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 "reflect" 10 "testing" 11 ) 12 13 func TestSetAdd(t *testing.T) { 14 s := &Set{F: testSetInt} 15 s.Add(1) 16 s.Add(5) 17 s.Add(25) 18 19 expected := []interface{}{1, 25, 5} 20 actual := s.List() 21 if !reflect.DeepEqual(actual, expected) { 22 t.Fatalf("bad: %#v", actual) 23 } 24 } 25 26 func TestSetAdd_negative(t *testing.T) { 27 // Since we don't allow negative hashes, this should just hash to the 28 // same thing... 29 s := &Set{F: testSetInt} 30 s.Add(-1) 31 s.Add(1) 32 33 expected := []interface{}{-1} 34 actual := s.List() 35 if !reflect.DeepEqual(actual, expected) { 36 t.Fatalf("bad: %#v", actual) 37 } 38 } 39 40 func TestSetContains(t *testing.T) { 41 s := &Set{F: testSetInt} 42 s.Add(5) 43 s.Add(-5) 44 45 if s.Contains(2) { 46 t.Fatal("should not contain") 47 } 48 if !s.Contains(5) { 49 t.Fatal("should contain") 50 } 51 if !s.Contains(-5) { 52 t.Fatal("should contain") 53 } 54 } 55 56 func TestSetDifference(t *testing.T) { 57 s1 := &Set{F: testSetInt} 58 s2 := &Set{F: testSetInt} 59 60 s1.Add(1) 61 s1.Add(5) 62 63 s2.Add(5) 64 s2.Add(25) 65 66 difference := s1.Difference(s2) 67 difference.Add(2) 68 69 expected := []interface{}{1, 2} 70 actual := difference.List() 71 if !reflect.DeepEqual(actual, expected) { 72 t.Fatalf("bad: %#v", actual) 73 } 74 } 75 76 func TestSetIntersection(t *testing.T) { 77 s1 := &Set{F: testSetInt} 78 s2 := &Set{F: testSetInt} 79 80 s1.Add(1) 81 s1.Add(5) 82 83 s2.Add(5) 84 s2.Add(25) 85 86 intersection := s1.Intersection(s2) 87 intersection.Add(2) 88 89 expected := []interface{}{2, 5} 90 actual := intersection.List() 91 if !reflect.DeepEqual(actual, expected) { 92 t.Fatalf("bad: %#v", actual) 93 } 94 } 95 96 func TestSetUnion(t *testing.T) { 97 s1 := &Set{F: testSetInt} 98 s2 := &Set{F: testSetInt} 99 100 s1.Add(1) 101 s1.Add(5) 102 103 s2.Add(5) 104 s2.Add(25) 105 106 union := s1.Union(s2) 107 union.Add(2) 108 109 expected := []interface{}{1, 2, 25, 5} 110 actual := union.List() 111 if !reflect.DeepEqual(actual, expected) { 112 t.Fatalf("bad: %#v", actual) 113 } 114 } 115 116 func testSetInt(v interface{}) int { 117 return v.(int) 118 } 119 120 func TestHashResource_nil(t *testing.T) { 121 resource := &Resource{ 122 Schema: map[string]*Schema{ 123 "name": { 124 Type: TypeString, 125 Optional: true, 126 }, 127 }, 128 } 129 f := HashResource(resource) 130 131 idx := f(nil) 132 if idx != 0 { 133 t.Fatalf("Expected 0 when hashing nil, given: %d", idx) 134 } 135 } 136 137 func TestHashEqual(t *testing.T) { 138 nested := &Resource{ 139 Schema: map[string]*Schema{ 140 "foo": { 141 Type: TypeString, 142 Optional: true, 143 }, 144 }, 145 } 146 root := &Resource{ 147 Schema: map[string]*Schema{ 148 "bar": { 149 Type: TypeString, 150 Optional: true, 151 }, 152 "nested": { 153 Type: TypeSet, 154 Optional: true, 155 Elem: nested, 156 }, 157 }, 158 } 159 n1 := map[string]interface{}{"foo": "bar"} 160 n2 := map[string]interface{}{"foo": "baz"} 161 162 r1 := map[string]interface{}{ 163 "bar": "baz", 164 "nested": NewSet(HashResource(nested), []interface{}{n1}), 165 } 166 r2 := map[string]interface{}{ 167 "bar": "qux", 168 "nested": NewSet(HashResource(nested), []interface{}{n2}), 169 } 170 r3 := map[string]interface{}{ 171 "bar": "baz", 172 "nested": NewSet(HashResource(nested), []interface{}{n2}), 173 } 174 r4 := map[string]interface{}{ 175 "bar": "qux", 176 "nested": NewSet(HashResource(nested), []interface{}{n1}), 177 } 178 s1 := NewSet(HashResource(root), []interface{}{r1}) 179 s2 := NewSet(HashResource(root), []interface{}{r2}) 180 s3 := NewSet(HashResource(root), []interface{}{r3}) 181 s4 := NewSet(HashResource(root), []interface{}{r4}) 182 183 cases := []struct { 184 name string 185 set *Set 186 compare *Set 187 expected bool 188 }{ 189 { 190 name: "equal", 191 set: s1, 192 compare: s1, 193 expected: true, 194 }, 195 { 196 name: "not equal", 197 set: s1, 198 compare: s2, 199 expected: false, 200 }, 201 { 202 name: "outer equal, should still not be equal", 203 set: s1, 204 compare: s3, 205 expected: false, 206 }, 207 { 208 name: "inner equal, should still not be equal", 209 set: s1, 210 compare: s4, 211 expected: false, 212 }, 213 } 214 for _, tc := range cases { 215 t.Run(tc.name, func(t *testing.T) { 216 actual := tc.set.HashEqual(tc.compare) 217 if tc.expected != actual { 218 t.Fatalf("expected %t, got %t", tc.expected, actual) 219 } 220 }) 221 } 222 }