github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/structure/sets/linkedhashset/linkedhashset_test.go (about) 1 package linkedhashset 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "strings" 7 "testing" 8 ) 9 10 func TestSetNew(t *testing.T) { 11 set := New[int](2, 1) 12 if actualValue := set.Size(); actualValue != 2 { 13 t.Errorf("Got %v expected %v", actualValue, 2) 14 } 15 values := set.Values() 16 if actualValue := values[0]; actualValue != 2 { 17 t.Errorf("Got %v expected %v", actualValue, 2) 18 } 19 if actualValue := values[1]; actualValue != 1 { 20 t.Errorf("Got %v expected %v", actualValue, 1) 21 } 22 } 23 24 func TestSetAdd(t *testing.T) { 25 set := New[int]() 26 set.Add() 27 set.Add(1) 28 set.Add(2) 29 set.Add(2, 3) 30 set.Add() 31 if actualValue := set.Empty(); actualValue != false { 32 t.Errorf("Got %v expected %v", actualValue, false) 33 } 34 if actualValue := set.Size(); actualValue != 3 { 35 t.Errorf("Got %v expected %v", actualValue, 3) 36 } 37 } 38 39 func TestSetContains(t *testing.T) { 40 set := New[int]() 41 set.Add(3, 1, 2) 42 set.Add(2, 3) 43 set.Add() 44 if actualValue := set.Contains(); actualValue != true { 45 t.Errorf("Got %v expected %v", actualValue, true) 46 } 47 if actualValue := set.Contains(1); actualValue != true { 48 t.Errorf("Got %v expected %v", actualValue, true) 49 } 50 if actualValue := set.Contains(1, 2, 3); actualValue != true { 51 t.Errorf("Got %v expected %v", actualValue, true) 52 } 53 if actualValue := set.Contains(1, 2, 3, 4); actualValue != false { 54 t.Errorf("Got %v expected %v", actualValue, false) 55 } 56 } 57 58 func TestSetRemove(t *testing.T) { 59 set := New[int]() 60 set.Add(3, 1, 2) 61 set.Remove() 62 if actualValue := set.Size(); actualValue != 3 { 63 t.Errorf("Got %v expected %v", actualValue, 3) 64 } 65 set.Remove(1) 66 if actualValue := set.Size(); actualValue != 2 { 67 t.Errorf("Got %v expected %v", actualValue, 2) 68 } 69 set.Remove(3) 70 set.Remove(3) 71 set.Remove() 72 set.Remove(2) 73 if actualValue := set.Size(); actualValue != 0 { 74 t.Errorf("Got %v expected %v", actualValue, 0) 75 } 76 } 77 78 func TestSetEach(t *testing.T) { 79 set := New[string]() 80 set.Add("c", "a", "b") 81 set.Each(func(index int, value string) { 82 switch index { 83 case 0: 84 if actualValue, expectedValue := value, "c"; actualValue != expectedValue { 85 t.Errorf("Got %v expected %v", actualValue, expectedValue) 86 } 87 case 1: 88 if actualValue, expectedValue := value, "a"; actualValue != expectedValue { 89 t.Errorf("Got %v expected %v", actualValue, expectedValue) 90 } 91 case 2: 92 if actualValue, expectedValue := value, "b"; actualValue != expectedValue { 93 t.Errorf("Got %v expected %v", actualValue, expectedValue) 94 } 95 default: 96 t.Errorf("Too many") 97 } 98 }) 99 } 100 101 func TestSetMap(t *testing.T) { 102 set := New[string]() 103 set.Add("c", "a", "b") 104 mappedSet := set.Map(func(index int, value string) string { 105 return "mapped: " + value 106 }) 107 if actualValue, expectedValue := mappedSet.Contains("mapped: c", "mapped: b", "mapped: a"), true; actualValue != expectedValue { 108 t.Errorf("Got %v expected %v", actualValue, expectedValue) 109 } 110 if actualValue, expectedValue := mappedSet.Contains("mapped: c", "mapped: b", "mapped: x"), false; actualValue != expectedValue { 111 t.Errorf("Got %v expected %v", actualValue, expectedValue) 112 } 113 if mappedSet.Size() != 3 { 114 t.Errorf("Got %v expected %v", mappedSet.Size(), 3) 115 } 116 } 117 118 func TestSetSelect(t *testing.T) { 119 set := New[string]() 120 set.Add("c", "a", "b") 121 selectedSet := set.Select(func(index int, value string) bool { 122 return value >= "a" && value <= "b" 123 }) 124 if actualValue, expectedValue := selectedSet.Contains("a", "b"), true; actualValue != expectedValue { 125 fmt.Println("A: ", selectedSet.Contains("b")) 126 t.Errorf("Got %v (%v) expected %v (%v)", actualValue, selectedSet.Values(), expectedValue, "[a b]") 127 } 128 if actualValue, expectedValue := selectedSet.Contains("a", "b", "c"), false; actualValue != expectedValue { 129 t.Errorf("Got %v (%v) expected %v (%v)", actualValue, selectedSet.Values(), expectedValue, "[a b]") 130 } 131 if selectedSet.Size() != 2 { 132 t.Errorf("Got %v expected %v", selectedSet.Size(), 3) 133 } 134 } 135 136 func TestSetAny(t *testing.T) { 137 set := New[string]() 138 set.Add("c", "a", "b") 139 any := set.Any(func(index int, value string) bool { 140 return value == "c" 141 }) 142 if any != true { 143 t.Errorf("Got %v expected %v", any, true) 144 } 145 any = set.Any(func(index int, value string) bool { 146 return value == "x" 147 }) 148 if any != false { 149 t.Errorf("Got %v expected %v", any, false) 150 } 151 } 152 153 func TestSetAll(t *testing.T) { 154 set := New[string]() 155 set.Add("c", "a", "b") 156 all := set.All(func(index int, value string) bool { 157 return value >= "a" && value <= "c" 158 }) 159 if all != true { 160 t.Errorf("Got %v expected %v", all, true) 161 } 162 all = set.All(func(index int, value string) bool { 163 return value >= "a" && value <= "b" 164 }) 165 if all != false { 166 t.Errorf("Got %v expected %v", all, false) 167 } 168 } 169 170 func TestSetFind(t *testing.T) { 171 set := New[string]() 172 set.Add("c", "a", "b") 173 foundIndex, foundValue := set.Find(func(index int, value string) bool { 174 return value == "c" 175 }) 176 if foundValue != "c" || foundIndex != 0 { 177 t.Errorf("Got %v at %v expected %v at %v", foundValue, foundIndex, "c", 0) 178 } 179 foundIndex, foundValue = set.Find(func(index int, value string) bool { 180 return value == "x" 181 }) 182 if foundValue != "" || foundIndex != -1 { 183 t.Errorf("Got %v at %v expected %v at %v", foundValue, foundIndex, nil, nil) 184 } 185 } 186 187 func TestSetChaining(t *testing.T) { 188 set := New[string]() 189 set.Add("c", "a", "b") 190 } 191 192 func TestSetIteratorPrevOnEmpty(t *testing.T) { 193 set := New[int]() 194 it := set.Iterator() 195 for it.Prev() { 196 t.Errorf("Shouldn't iterate on empty set") 197 } 198 } 199 200 func TestSetIteratorNext(t *testing.T) { 201 set := New[string]() 202 set.Add("c", "a", "b") 203 it := set.Iterator() 204 count := 0 205 for it.Next() { 206 count++ 207 index := it.Index() 208 value := it.Value() 209 switch index { 210 case 0: 211 if actualValue, expectedValue := value, "c"; actualValue != expectedValue { 212 t.Errorf("Got %v expected %v", actualValue, expectedValue) 213 } 214 case 1: 215 if actualValue, expectedValue := value, "a"; actualValue != expectedValue { 216 t.Errorf("Got %v expected %v", actualValue, expectedValue) 217 } 218 case 2: 219 if actualValue, expectedValue := value, "b"; actualValue != expectedValue { 220 t.Errorf("Got %v expected %v", actualValue, expectedValue) 221 } 222 default: 223 t.Errorf("Too many") 224 } 225 if actualValue, expectedValue := index, count-1; actualValue != expectedValue { 226 t.Errorf("Got %v expected %v", actualValue, expectedValue) 227 } 228 } 229 if actualValue, expectedValue := count, 3; actualValue != expectedValue { 230 t.Errorf("Got %v expected %v", actualValue, expectedValue) 231 } 232 } 233 234 func TestSetIteratorPrev(t *testing.T) { 235 set := New[string]() 236 set.Add("c", "a", "b") 237 it := set.Iterator() 238 for it.Prev() { 239 } 240 count := 0 241 for it.Next() { 242 count++ 243 index := it.Index() 244 value := it.Value() 245 switch index { 246 case 0: 247 if actualValue, expectedValue := value, "c"; actualValue != expectedValue { 248 t.Errorf("Got %v expected %v", actualValue, expectedValue) 249 } 250 case 1: 251 if actualValue, expectedValue := value, "a"; actualValue != expectedValue { 252 t.Errorf("Got %v expected %v", actualValue, expectedValue) 253 } 254 case 2: 255 if actualValue, expectedValue := value, "b"; actualValue != expectedValue { 256 t.Errorf("Got %v expected %v", actualValue, expectedValue) 257 } 258 default: 259 t.Errorf("Too many") 260 } 261 if actualValue, expectedValue := index, count-1; actualValue != expectedValue { 262 t.Errorf("Got %v expected %v", actualValue, expectedValue) 263 } 264 } 265 if actualValue, expectedValue := count, 3; actualValue != expectedValue { 266 t.Errorf("Got %v expected %v", actualValue, expectedValue) 267 } 268 } 269 270 func TestSetIteratorBegin(t *testing.T) { 271 set := New[string]() 272 it := set.Iterator() 273 it.Begin() 274 set.Add("a", "b", "c") 275 for it.Next() { 276 } 277 it.Begin() 278 it.Next() 279 if index, value := it.Index(), it.Value(); index != 0 || value != "a" { 280 t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a") 281 } 282 } 283 284 func TestSetIteratorEnd(t *testing.T) { 285 set := New[string]() 286 it := set.Iterator() 287 288 if index := it.Index(); index != -1 { 289 t.Errorf("Got %v expected %v", index, -1) 290 } 291 292 it.End() 293 if index := it.Index(); index != 0 { 294 t.Errorf("Got %v expected %v", index, 0) 295 } 296 297 set.Add("a", "b", "c") 298 it.End() 299 if index := it.Index(); index != set.Size() { 300 t.Errorf("Got %v expected %v", index, set.Size()) 301 } 302 303 it.Prev() 304 if index, value := it.Index(), it.Value(); index != set.Size()-1 || value != "c" { 305 t.Errorf("Got %v,%v expected %v,%v", index, value, set.Size()-1, "c") 306 } 307 } 308 309 func TestSetIteratorFirst(t *testing.T) { 310 set := New[string]() 311 set.Add("a", "b", "c") 312 it := set.Iterator() 313 if actualValue, expectedValue := it.First(), true; actualValue != expectedValue { 314 t.Errorf("Got %v expected %v", actualValue, expectedValue) 315 } 316 if index, value := it.Index(), it.Value(); index != 0 || value != "a" { 317 t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a") 318 } 319 } 320 321 func TestSetIteratorLast(t *testing.T) { 322 set := New[string]() 323 set.Add("a", "b", "c") 324 it := set.Iterator() 325 if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue { 326 t.Errorf("Got %v expected %v", actualValue, expectedValue) 327 } 328 if index, value := it.Index(), it.Value(); index != 2 || value != "c" { 329 t.Errorf("Got %v,%v expected %v,%v", index, value, 3, "c") 330 } 331 } 332 333 func TestSetIteratorNextTo(t *testing.T) { 334 // Sample seek function, i.e. string starting with "b" 335 seek := func(index int, value string) bool { 336 return strings.HasSuffix(value, "b") 337 } 338 339 // NextTo (empty) 340 { 341 set := New[string]() 342 it := set.Iterator() 343 for it.NextTo(seek) { 344 t.Errorf("Shouldn't iterate on empty set") 345 } 346 } 347 348 // NextTo (not found) 349 { 350 set := New[string]() 351 set.Add("xx", "yy") 352 it := set.Iterator() 353 for it.NextTo(seek) { 354 t.Errorf("Shouldn't iterate on empty set") 355 } 356 } 357 358 // NextTo (found) 359 { 360 set := New[string]() 361 set.Add("aa", "bb", "cc") 362 it := set.Iterator() 363 it.Begin() 364 if !it.NextTo(seek) { 365 t.Errorf("Shouldn't iterate on empty set") 366 } 367 if index, value := it.Index(), it.Value(); index != 1 || value != "bb" { 368 t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb") 369 } 370 if !it.Next() { 371 t.Errorf("Should go to first element") 372 } 373 if index, value := it.Index(), it.Value(); index != 2 || value != "cc" { 374 t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "cc") 375 } 376 if it.Next() { 377 t.Errorf("Should not go past last element") 378 } 379 } 380 } 381 382 func TestSetIteratorPrevTo(t *testing.T) { 383 // Sample seek function, i.e. string starting with "b" 384 seek := func(index int, value string) bool { 385 return strings.HasSuffix(value, "b") 386 } 387 388 // PrevTo (empty) 389 { 390 set := New[string]() 391 it := set.Iterator() 392 it.End() 393 for it.PrevTo(seek) { 394 t.Errorf("Shouldn't iterate on empty set") 395 } 396 } 397 398 // PrevTo (not found) 399 { 400 set := New[string]() 401 set.Add("xx", "yy") 402 it := set.Iterator() 403 it.End() 404 for it.PrevTo(seek) { 405 t.Errorf("Shouldn't iterate on empty set") 406 } 407 } 408 409 // PrevTo (found) 410 { 411 set := New[string]() 412 set.Add("aa", "bb", "cc") 413 it := set.Iterator() 414 it.End() 415 if !it.PrevTo(seek) { 416 t.Errorf("Shouldn't iterate on empty set") 417 } 418 if index, value := it.Index(), it.Value(); index != 1 || value != "bb" { 419 t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb") 420 } 421 if !it.Prev() { 422 t.Errorf("Should go to first element") 423 } 424 if index, value := it.Index(), it.Value(); index != 0 || value != "aa" { 425 t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "aa") 426 } 427 if it.Prev() { 428 t.Errorf("Should not go before first element") 429 } 430 } 431 } 432 433 func TestSetSerialization(t *testing.T) { 434 set := New[string]() 435 set.Add("a", "b", "c") 436 437 var err error 438 assert := func() { 439 if actualValue, expectedValue := set.Size(), 3; actualValue != expectedValue { 440 t.Errorf("Got %v expected %v", actualValue, expectedValue) 441 } 442 if actualValue := set.Contains("a", "b", "c"); actualValue != true { 443 t.Errorf("Got %v expected %v", actualValue, true) 444 } 445 if err != nil { 446 t.Errorf("Got error %v", err) 447 } 448 } 449 450 assert() 451 452 bytes, err := set.MarshalJSON() 453 assert() 454 455 err = set.UnmarshalJSON(bytes) 456 assert() 457 458 bytes, err = json.Marshal([]interface{}{"a", "b", "c", set}) 459 if err != nil { 460 t.Errorf("Got error %v", err) 461 } 462 463 err = json.Unmarshal([]byte(`["1","2","3"]`), &set) 464 if err != nil { 465 t.Errorf("Got error %v", err) 466 } 467 } 468 469 func TestSetString(t *testing.T) { 470 c := New[int]() 471 c.Add(1) 472 if !strings.HasPrefix(c.String(), "LinkedHashSet") { 473 t.Errorf("String should start with container name") 474 } 475 } 476 477 func TestSetIntersection(t *testing.T) { 478 set := New[string]() 479 another := New[string]() 480 481 intersection := set.Intersection(another) 482 if actualValue, expectedValue := intersection.Size(), 0; actualValue != expectedValue { 483 t.Errorf("Got %v expected %v", actualValue, expectedValue) 484 } 485 486 set.Add("a", "b", "c", "d") 487 another.Add("c", "d", "e", "f") 488 489 intersection = set.Intersection(another) 490 491 if actualValue, expectedValue := intersection.Size(), 2; actualValue != expectedValue { 492 t.Errorf("Got %v expected %v", actualValue, expectedValue) 493 } 494 if actualValue := intersection.Contains("c", "d"); actualValue != true { 495 t.Errorf("Got %v expected %v", actualValue, true) 496 } 497 } 498 499 func TestSetUnion(t *testing.T) { 500 set := New[string]() 501 another := New[string]() 502 503 union := set.Union(another) 504 if actualValue, expectedValue := union.Size(), 0; actualValue != expectedValue { 505 t.Errorf("Got %v expected %v", actualValue, expectedValue) 506 } 507 508 set.Add("a", "b", "c", "d") 509 another.Add("c", "d", "e", "f") 510 511 union = set.Union(another) 512 513 if actualValue, expectedValue := union.Size(), 6; actualValue != expectedValue { 514 t.Errorf("Got %v expected %v", actualValue, expectedValue) 515 } 516 if actualValue := union.Contains("a", "b", "c", "d", "e", "f"); actualValue != true { 517 t.Errorf("Got %v expected %v", actualValue, true) 518 } 519 } 520 521 func TestSetDifference(t *testing.T) { 522 set := New[string]() 523 another := New[string]() 524 525 difference := set.Difference(another) 526 if actualValue, expectedValue := difference.Size(), 0; actualValue != expectedValue { 527 t.Errorf("Got %v expected %v", actualValue, expectedValue) 528 } 529 530 set.Add("a", "b", "c", "d") 531 another.Add("c", "d", "e", "f") 532 533 difference = set.Difference(another) 534 535 if actualValue, expectedValue := difference.Size(), 2; actualValue != expectedValue { 536 t.Errorf("Got %v expected %v", actualValue, expectedValue) 537 } 538 if actualValue := difference.Contains("a", "b"); actualValue != true { 539 t.Errorf("Got %v expected %v", actualValue, true) 540 } 541 } 542 543 func benchmarkContains[E int](b *testing.B, set *Set[E], size int) { 544 for i := 0; i < b.N; i++ { 545 for n := 0; n < size; n++ { 546 set.Contains(E(n)) 547 } 548 } 549 } 550 551 func benchmarkAdd[E int](b *testing.B, set *Set[E], size int) { 552 for i := 0; i < b.N; i++ { 553 for n := 0; n < size; n++ { 554 set.Add(E(n)) 555 } 556 } 557 } 558 559 func benchmarkRemove[E int](b *testing.B, set *Set[E], size int) { 560 for i := 0; i < b.N; i++ { 561 for n := 0; n < size; n++ { 562 set.Remove(E(n)) 563 } 564 } 565 } 566 567 func BenchmarkHashSetContains100(b *testing.B) { 568 b.StopTimer() 569 size := 100 570 set := New[int]() 571 for n := 0; n < size; n++ { 572 set.Add(n) 573 } 574 b.StartTimer() 575 benchmarkContains(b, set, size) 576 } 577 578 func BenchmarkHashSetContains1000(b *testing.B) { 579 b.StopTimer() 580 size := 1000 581 set := New[int]() 582 for n := 0; n < size; n++ { 583 set.Add(n) 584 } 585 b.StartTimer() 586 benchmarkContains(b, set, size) 587 } 588 589 func BenchmarkHashSetContains10000(b *testing.B) { 590 b.StopTimer() 591 size := 10000 592 set := New[int]() 593 for n := 0; n < size; n++ { 594 set.Add(n) 595 } 596 b.StartTimer() 597 benchmarkContains(b, set, size) 598 } 599 600 func BenchmarkHashSetContains100000(b *testing.B) { 601 b.StopTimer() 602 size := 100000 603 set := New[int]() 604 for n := 0; n < size; n++ { 605 set.Add(n) 606 } 607 b.StartTimer() 608 benchmarkContains(b, set, size) 609 } 610 611 func BenchmarkHashSetAdd100(b *testing.B) { 612 b.StopTimer() 613 size := 100 614 set := New[int]() 615 b.StartTimer() 616 benchmarkAdd(b, set, size) 617 } 618 619 func BenchmarkHashSetAdd1000(b *testing.B) { 620 b.StopTimer() 621 size := 1000 622 set := New[int]() 623 for n := 0; n < size; n++ { 624 set.Add(n) 625 } 626 b.StartTimer() 627 benchmarkAdd(b, set, size) 628 } 629 630 func BenchmarkHashSetAdd10000(b *testing.B) { 631 b.StopTimer() 632 size := 10000 633 set := New[int]() 634 for n := 0; n < size; n++ { 635 set.Add(n) 636 } 637 b.StartTimer() 638 benchmarkAdd(b, set, size) 639 } 640 641 func BenchmarkHashSetAdd100000(b *testing.B) { 642 b.StopTimer() 643 size := 100000 644 set := New[int]() 645 for n := 0; n < size; n++ { 646 set.Add(n) 647 } 648 b.StartTimer() 649 benchmarkAdd(b, set, size) 650 } 651 652 func BenchmarkHashSetRemove100(b *testing.B) { 653 b.StopTimer() 654 size := 100 655 set := New[int]() 656 for n := 0; n < size; n++ { 657 set.Add(n) 658 } 659 b.StartTimer() 660 benchmarkRemove(b, set, size) 661 } 662 663 func BenchmarkHashSetRemove1000(b *testing.B) { 664 b.StopTimer() 665 size := 1000 666 set := New[int]() 667 for n := 0; n < size; n++ { 668 set.Add(n) 669 } 670 b.StartTimer() 671 benchmarkRemove(b, set, size) 672 } 673 674 func BenchmarkHashSetRemove10000(b *testing.B) { 675 b.StopTimer() 676 size := 10000 677 set := New[int]() 678 for n := 0; n < size; n++ { 679 set.Add(n) 680 } 681 b.StartTimer() 682 benchmarkRemove(b, set, size) 683 } 684 685 func BenchmarkHashSetRemove100000(b *testing.B) { 686 b.StopTimer() 687 size := 100000 688 set := New[int]() 689 for n := 0; n < size; n++ { 690 set.Add(n) 691 } 692 b.StartTimer() 693 benchmarkRemove(b, set, size) 694 }