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