github.com/MetalBlockchain/metalgo@v1.11.9/utils/setmap/setmap_test.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package setmap 5 6 import ( 7 "testing" 8 9 "github.com/stretchr/testify/require" 10 11 "github.com/MetalBlockchain/metalgo/utils/set" 12 ) 13 14 func TestSetMapPut(t *testing.T) { 15 tests := []struct { 16 name string 17 state *SetMap[int, int] 18 key int 19 value set.Set[int] 20 expectedRemoved []Entry[int, int] 21 expectedState *SetMap[int, int] 22 }{ 23 { 24 name: "none removed", 25 state: New[int, int](), 26 key: 1, 27 value: set.Of(2), 28 expectedRemoved: nil, 29 expectedState: &SetMap[int, int]{ 30 keyToSet: map[int]set.Set[int]{ 31 1: set.Of(2), 32 }, 33 valueToKey: map[int]int{ 34 2: 1, 35 }, 36 }, 37 }, 38 { 39 name: "key removed", 40 state: &SetMap[int, int]{ 41 keyToSet: map[int]set.Set[int]{ 42 1: set.Of(2), 43 }, 44 valueToKey: map[int]int{ 45 2: 1, 46 }, 47 }, 48 key: 1, 49 value: set.Of(3), 50 expectedRemoved: []Entry[int, int]{ 51 { 52 Key: 1, 53 Set: set.Of(2), 54 }, 55 }, 56 expectedState: &SetMap[int, int]{ 57 keyToSet: map[int]set.Set[int]{ 58 1: set.Of(3), 59 }, 60 valueToKey: map[int]int{ 61 3: 1, 62 }, 63 }, 64 }, 65 { 66 name: "value removed", 67 state: &SetMap[int, int]{ 68 keyToSet: map[int]set.Set[int]{ 69 1: set.Of(2), 70 }, 71 valueToKey: map[int]int{ 72 2: 1, 73 }, 74 }, 75 key: 3, 76 value: set.Of(2), 77 expectedRemoved: []Entry[int, int]{ 78 { 79 Key: 1, 80 Set: set.Of(2), 81 }, 82 }, 83 expectedState: &SetMap[int, int]{ 84 keyToSet: map[int]set.Set[int]{ 85 3: set.Of(2), 86 }, 87 valueToKey: map[int]int{ 88 2: 3, 89 }, 90 }, 91 }, 92 { 93 name: "key and value removed", 94 state: &SetMap[int, int]{ 95 keyToSet: map[int]set.Set[int]{ 96 1: set.Of(2), 97 3: set.Of(4), 98 }, 99 valueToKey: map[int]int{ 100 2: 1, 101 4: 3, 102 }, 103 }, 104 key: 1, 105 value: set.Of(4), 106 expectedRemoved: []Entry[int, int]{ 107 { 108 Key: 1, 109 Set: set.Of(2), 110 }, 111 { 112 Key: 3, 113 Set: set.Of(4), 114 }, 115 }, 116 expectedState: &SetMap[int, int]{ 117 keyToSet: map[int]set.Set[int]{ 118 1: set.Of(4), 119 }, 120 valueToKey: map[int]int{ 121 4: 1, 122 }, 123 }, 124 }, 125 } 126 for _, test := range tests { 127 t.Run(test.name, func(t *testing.T) { 128 require := require.New(t) 129 130 removed := test.state.Put(test.key, test.value) 131 require.ElementsMatch(test.expectedRemoved, removed) 132 require.Equal(test.expectedState, test.state) 133 }) 134 } 135 } 136 137 func TestSetMapHasValueAndGetKeyAndSetOverlaps(t *testing.T) { 138 m := New[int, int]() 139 require.Empty(t, m.Put(1, set.Of(2))) 140 141 tests := []struct { 142 name string 143 value int 144 expectedKey int 145 expectedExists bool 146 }{ 147 { 148 name: "fetch unknown", 149 value: 3, 150 expectedKey: 0, 151 expectedExists: false, 152 }, 153 { 154 name: "fetch known value", 155 value: 2, 156 expectedKey: 1, 157 expectedExists: true, 158 }, 159 { 160 name: "fetch known key", 161 value: 1, 162 expectedKey: 0, 163 expectedExists: false, 164 }, 165 } 166 for _, test := range tests { 167 t.Run(test.name, func(t *testing.T) { 168 require := require.New(t) 169 170 exists := m.HasValue(test.value) 171 require.Equal(test.expectedExists, exists) 172 173 key, exists := m.GetKey(test.value) 174 require.Equal(test.expectedKey, key) 175 require.Equal(test.expectedExists, exists) 176 }) 177 } 178 } 179 180 func TestSetMapHasOverlap(t *testing.T) { 181 m := New[int, int]() 182 require.Empty(t, m.Put(1, set.Of(2))) 183 require.Empty(t, m.Put(2, set.Of(3, 4))) 184 185 tests := []struct { 186 name string 187 set set.Set[int] 188 expectedOverlaps bool 189 }{ 190 { 191 name: "small fetch unknown", 192 set: set.Of(5), 193 expectedOverlaps: false, 194 }, 195 { 196 name: "large fetch unknown", 197 set: set.Of(5, 6, 7, 8), 198 expectedOverlaps: false, 199 }, 200 { 201 name: "small fetch known", 202 set: set.Of(3), 203 expectedOverlaps: true, 204 }, 205 { 206 name: "large fetch known", 207 set: set.Of(3, 5, 6, 7, 8), 208 expectedOverlaps: true, 209 }, 210 } 211 for _, test := range tests { 212 t.Run(test.name, func(t *testing.T) { 213 overlaps := m.HasOverlap(test.set) 214 require.Equal(t, test.expectedOverlaps, overlaps) 215 }) 216 } 217 } 218 219 func TestSetMapHasKeyAndGetSet(t *testing.T) { 220 m := New[int, int]() 221 require.Empty(t, m.Put(1, set.Of(2))) 222 223 tests := []struct { 224 name string 225 key int 226 expectedValue set.Set[int] 227 expectedExists bool 228 }{ 229 { 230 name: "fetch unknown", 231 key: 3, 232 expectedValue: nil, 233 expectedExists: false, 234 }, 235 { 236 name: "fetch known key", 237 key: 1, 238 expectedValue: set.Of(2), 239 expectedExists: true, 240 }, 241 { 242 name: "fetch known value", 243 key: 2, 244 expectedValue: nil, 245 expectedExists: false, 246 }, 247 } 248 for _, test := range tests { 249 t.Run(test.name, func(t *testing.T) { 250 require := require.New(t) 251 252 exists := m.HasKey(test.key) 253 require.Equal(test.expectedExists, exists) 254 255 value, exists := m.GetSet(test.key) 256 require.Equal(test.expectedValue, value) 257 require.Equal(test.expectedExists, exists) 258 }) 259 } 260 } 261 262 func TestSetMapDeleteKey(t *testing.T) { 263 tests := []struct { 264 name string 265 state *SetMap[int, int] 266 key int 267 expectedValue set.Set[int] 268 expectedRemoved bool 269 expectedState *SetMap[int, int] 270 }{ 271 { 272 name: "none removed", 273 state: New[int, int](), 274 key: 1, 275 expectedValue: nil, 276 expectedRemoved: false, 277 expectedState: New[int, int](), 278 }, 279 { 280 name: "key removed", 281 state: &SetMap[int, int]{ 282 keyToSet: map[int]set.Set[int]{ 283 1: set.Of(2), 284 }, 285 valueToKey: map[int]int{ 286 2: 1, 287 }, 288 }, 289 key: 1, 290 expectedValue: set.Of(2), 291 expectedRemoved: true, 292 expectedState: New[int, int](), 293 }, 294 } 295 for _, test := range tests { 296 t.Run(test.name, func(t *testing.T) { 297 require := require.New(t) 298 299 value, removed := test.state.DeleteKey(test.key) 300 require.Equal(test.expectedValue, value) 301 require.Equal(test.expectedRemoved, removed) 302 require.Equal(test.expectedState, test.state) 303 }) 304 } 305 } 306 307 func TestSetMapDeleteValue(t *testing.T) { 308 tests := []struct { 309 name string 310 state *SetMap[int, int] 311 value int 312 expectedKey int 313 expectedSet set.Set[int] 314 expectedRemoved bool 315 expectedState *SetMap[int, int] 316 }{ 317 { 318 name: "none removed", 319 state: New[int, int](), 320 value: 1, 321 expectedKey: 0, 322 expectedSet: nil, 323 expectedRemoved: false, 324 expectedState: New[int, int](), 325 }, 326 { 327 name: "key removed", 328 state: &SetMap[int, int]{ 329 keyToSet: map[int]set.Set[int]{ 330 1: set.Of(2), 331 }, 332 valueToKey: map[int]int{ 333 2: 1, 334 }, 335 }, 336 value: 2, 337 expectedKey: 1, 338 expectedSet: set.Of(2), 339 expectedRemoved: true, 340 expectedState: New[int, int](), 341 }, 342 } 343 for _, test := range tests { 344 t.Run(test.name, func(t *testing.T) { 345 require := require.New(t) 346 347 key, set, removed := test.state.DeleteValue(test.value) 348 require.Equal(test.expectedKey, key) 349 require.Equal(test.expectedSet, set) 350 require.Equal(test.expectedRemoved, removed) 351 require.Equal(test.expectedState, test.state) 352 }) 353 } 354 } 355 356 func TestSetMapDeleteOverlapping(t *testing.T) { 357 tests := []struct { 358 name string 359 state *SetMap[int, int] 360 set set.Set[int] 361 expectedRemoved []Entry[int, int] 362 expectedState *SetMap[int, int] 363 }{ 364 { 365 name: "none removed", 366 state: New[int, int](), 367 set: set.Of(1), 368 expectedRemoved: nil, 369 expectedState: New[int, int](), 370 }, 371 { 372 name: "key removed", 373 state: &SetMap[int, int]{ 374 keyToSet: map[int]set.Set[int]{ 375 1: set.Of(2), 376 }, 377 valueToKey: map[int]int{ 378 2: 1, 379 }, 380 }, 381 set: set.Of(2), 382 expectedRemoved: []Entry[int, int]{ 383 { 384 Key: 1, 385 Set: set.Of(2), 386 }, 387 }, 388 expectedState: New[int, int](), 389 }, 390 { 391 name: "multiple keys removed", 392 state: &SetMap[int, int]{ 393 keyToSet: map[int]set.Set[int]{ 394 1: set.Of(2, 3), 395 2: set.Of(4), 396 }, 397 valueToKey: map[int]int{ 398 2: 1, 399 3: 1, 400 4: 2, 401 }, 402 }, 403 set: set.Of(2, 4), 404 expectedRemoved: []Entry[int, int]{ 405 { 406 Key: 1, 407 Set: set.Of(2, 3), 408 }, 409 { 410 Key: 2, 411 Set: set.Of(4), 412 }, 413 }, 414 expectedState: New[int, int](), 415 }, 416 } 417 for _, test := range tests { 418 t.Run(test.name, func(t *testing.T) { 419 require := require.New(t) 420 421 removed := test.state.DeleteOverlapping(test.set) 422 require.ElementsMatch(test.expectedRemoved, removed) 423 require.Equal(test.expectedState, test.state) 424 }) 425 } 426 } 427 428 func TestSetMapLen(t *testing.T) { 429 require := require.New(t) 430 431 m := New[int, int]() 432 require.Zero(m.Len()) 433 require.Zero(m.LenValues()) 434 435 m.Put(1, set.Of(2)) 436 require.Equal(1, m.Len()) 437 require.Equal(1, m.LenValues()) 438 439 m.Put(2, set.Of(3, 4)) 440 require.Equal(2, m.Len()) 441 require.Equal(3, m.LenValues()) 442 443 m.Put(1, set.Of(4, 5)) 444 require.Equal(1, m.Len()) 445 require.Equal(2, m.LenValues()) 446 447 m.DeleteKey(1) 448 require.Zero(m.Len()) 449 require.Zero(m.LenValues()) 450 }