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