github.com/songzhibin97/go-baseutils@v0.0.2-0.20240302024150-487d8ce9c082/structure/queues/arrayqueue/arrayqueue_test.go (about) 1 package arrayqueue 2 3 import ( 4 "encoding/json" 5 "reflect" 6 "strings" 7 "testing" 8 ) 9 10 func TestQueueEnqueue(t *testing.T) { 11 queue := New[int]() 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]() 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 queue := New[int]() 48 queue.Enqueue(1) 49 queue.Enqueue(2) 50 queue.Enqueue(3) 51 queue.Dequeue() 52 if actualValue, ok := queue.Peek(); actualValue != 2 || !ok { 53 t.Errorf("Got %v expected %v", actualValue, 2) 54 } 55 if actualValue, ok := queue.Dequeue(); actualValue != 2 || !ok { 56 t.Errorf("Got %v expected %v", actualValue, 2) 57 } 58 if actualValue, ok := queue.Dequeue(); actualValue != 3 || !ok { 59 t.Errorf("Got %v expected %v", actualValue, 3) 60 } 61 if actualValue, ok := queue.Dequeue(); actualValue != 0 || ok { 62 t.Errorf("Got %v expected %v", actualValue, nil) 63 } 64 if actualValue := queue.Empty(); actualValue != true { 65 t.Errorf("Got %v expected %v", actualValue, true) 66 } 67 if actualValue := queue.Values(); len(actualValue) != 0 { 68 t.Errorf("Got %v expected %v", actualValue, "[]") 69 } 70 } 71 72 func TestQueueIteratorOnEmpty(t *testing.T) { 73 queue := New[int]() 74 it := queue.Iterator() 75 for it.Next() { 76 t.Errorf("Shouldn't iterate on empty queue") 77 } 78 } 79 80 func TestQueueIteratorNext(t *testing.T) { 81 queue := New[string]() 82 queue.Enqueue("a") 83 queue.Enqueue("b") 84 queue.Enqueue("c") 85 86 it := queue.Iterator() 87 count := 0 88 for it.Next() { 89 count++ 90 index := it.Index() 91 value := it.Value() 92 switch index { 93 case 0: 94 if actualValue, expectedValue := value, "a"; actualValue != expectedValue { 95 t.Errorf("Got %v expected %v", actualValue, expectedValue) 96 } 97 case 1: 98 if actualValue, expectedValue := value, "b"; actualValue != expectedValue { 99 t.Errorf("Got %v expected %v", actualValue, expectedValue) 100 } 101 case 2: 102 if actualValue, expectedValue := value, "c"; actualValue != expectedValue { 103 t.Errorf("Got %v expected %v", actualValue, expectedValue) 104 } 105 default: 106 t.Errorf("Too many") 107 } 108 if actualValue, expectedValue := index, count-1; actualValue != expectedValue { 109 t.Errorf("Got %v expected %v", actualValue, expectedValue) 110 } 111 } 112 if actualValue, expectedValue := count, 3; actualValue != expectedValue { 113 t.Errorf("Got %v expected %v", actualValue, expectedValue) 114 } 115 116 queue.Clear() 117 it = queue.Iterator() 118 for it.Next() { 119 t.Errorf("Shouldn't iterate on empty queue") 120 } 121 } 122 123 func TestQueueIteratorPrev(t *testing.T) { 124 queue := New[string]() 125 queue.Enqueue("a") 126 queue.Enqueue("b") 127 queue.Enqueue("c") 128 129 it := queue.Iterator() 130 for it.Next() { 131 } 132 count := 0 133 for it.Prev() { 134 count++ 135 index := it.Index() 136 value := it.Value() 137 switch index { 138 case 0: 139 if actualValue, expectedValue := value, "a"; actualValue != expectedValue { 140 t.Errorf("Got %v expected %v", actualValue, expectedValue) 141 } 142 case 1: 143 if actualValue, expectedValue := value, "b"; actualValue != expectedValue { 144 t.Errorf("Got %v expected %v", actualValue, expectedValue) 145 } 146 case 2: 147 if actualValue, expectedValue := value, "c"; actualValue != expectedValue { 148 t.Errorf("Got %v expected %v", actualValue, expectedValue) 149 } 150 default: 151 t.Errorf("Too many") 152 } 153 if actualValue, expectedValue := index, 3-count; actualValue != expectedValue { 154 t.Errorf("Got %v expected %v", actualValue, expectedValue) 155 } 156 } 157 if actualValue, expectedValue := count, 3; actualValue != expectedValue { 158 t.Errorf("Got %v expected %v", actualValue, expectedValue) 159 } 160 } 161 162 func TestQueueIteratorBegin(t *testing.T) { 163 queue := New[string]() 164 it := queue.Iterator() 165 it.Begin() 166 queue.Enqueue("a") 167 queue.Enqueue("b") 168 queue.Enqueue("c") 169 for it.Next() { 170 } 171 it.Begin() 172 it.Next() 173 if index, value := it.Index(), it.Value(); index != 0 || value != "a" { 174 t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a") 175 } 176 } 177 178 func TestQueueIteratorEnd(t *testing.T) { 179 queue := New[string]() 180 it := queue.Iterator() 181 182 if index := it.Index(); index != -1 { 183 t.Errorf("Got %v expected %v", index, -1) 184 } 185 186 it.End() 187 if index := it.Index(); index != 0 { 188 t.Errorf("Got %v expected %v", index, 0) 189 } 190 191 queue.Enqueue("a") 192 queue.Enqueue("b") 193 queue.Enqueue("c") 194 it.End() 195 if index := it.Index(); index != queue.Size() { 196 t.Errorf("Got %v expected %v", index, queue.Size()) 197 } 198 199 it.Prev() 200 if index, value := it.Index(), it.Value(); index != queue.Size()-1 || value != "c" { 201 t.Errorf("Got %v,%v expected %v,%v", index, value, queue.Size()-1, "c") 202 } 203 } 204 205 func TestQueueIteratorFirst(t *testing.T) { 206 queue := New[string]() 207 it := queue.Iterator() 208 if actualValue, expectedValue := it.First(), false; actualValue != expectedValue { 209 t.Errorf("Got %v expected %v", actualValue, expectedValue) 210 } 211 queue.Enqueue("a") 212 queue.Enqueue("b") 213 queue.Enqueue("c") 214 if actualValue, expectedValue := it.First(), true; actualValue != expectedValue { 215 t.Errorf("Got %v expected %v", actualValue, expectedValue) 216 } 217 if index, value := it.Index(), it.Value(); index != 0 || value != "a" { 218 t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a") 219 } 220 } 221 222 func TestQueueIteratorLast(t *testing.T) { 223 queue := New[string]() 224 it := queue.Iterator() 225 if actualValue, expectedValue := it.Last(), false; actualValue != expectedValue { 226 t.Errorf("Got %v expected %v", actualValue, expectedValue) 227 } 228 queue.Enqueue("a") 229 queue.Enqueue("b") 230 queue.Enqueue("c") 231 if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue { 232 t.Errorf("Got %v expected %v", actualValue, expectedValue) 233 } 234 if index, value := it.Index(), it.Value(); index != 2 || value != "c" { 235 t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "c") 236 } 237 } 238 239 func TestQueueIteratorNextTo(t *testing.T) { 240 // Sample seek function, i.e. string starting with "b" 241 seek := func(index int, value string) bool { 242 return strings.HasSuffix(value, "b") 243 } 244 245 // NextTo (empty) 246 { 247 queue := New[string]() 248 it := queue.Iterator() 249 for it.NextTo(seek) { 250 t.Errorf("Shouldn't iterate on empty queue") 251 } 252 } 253 254 // NextTo (not found) 255 { 256 queue := New[string]() 257 queue.Enqueue("xx") 258 queue.Enqueue("yy") 259 it := queue.Iterator() 260 for it.NextTo(seek) { 261 t.Errorf("Shouldn't iterate on empty queue") 262 } 263 } 264 265 // NextTo (found) 266 { 267 queue := New[string]() 268 queue.Enqueue("aa") 269 queue.Enqueue("bb") 270 queue.Enqueue("cc") 271 it := queue.Iterator() 272 it.Begin() 273 if !it.NextTo(seek) { 274 t.Errorf("Shouldn't iterate on empty queue") 275 } 276 if index, value := it.Index(), it.Value(); index != 1 || value != "bb" { 277 t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb") 278 } 279 if !it.Next() { 280 t.Errorf("Should go to first element") 281 } 282 if index, value := it.Index(), it.Value(); index != 2 || value != "cc" { 283 t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "cc") 284 } 285 if it.Next() { 286 t.Errorf("Should not go past last element") 287 } 288 } 289 } 290 291 func TestQueueIteratorPrevTo(t *testing.T) { 292 // Sample seek function, i.e. string starting with "b" 293 seek := func(index int, value string) bool { 294 return strings.HasSuffix(value, "b") 295 } 296 297 // PrevTo (empty) 298 { 299 queue := New[string]() 300 it := queue.Iterator() 301 it.End() 302 for it.PrevTo(seek) { 303 t.Errorf("Shouldn't iterate on empty queue") 304 } 305 } 306 307 // PrevTo (not found) 308 { 309 queue := New[string]() 310 queue.Enqueue("xx") 311 queue.Enqueue("yy") 312 it := queue.Iterator() 313 it.End() 314 for it.PrevTo(seek) { 315 t.Errorf("Shouldn't iterate on empty queue") 316 } 317 } 318 319 // PrevTo (found) 320 { 321 queue := New[string]() 322 queue.Enqueue("aa") 323 queue.Enqueue("bb") 324 queue.Enqueue("cc") 325 it := queue.Iterator() 326 it.End() 327 if !it.PrevTo(seek) { 328 t.Errorf("Shouldn't iterate on empty queue") 329 } 330 if index, value := it.Index(), it.Value(); index != 1 || value != "bb" { 331 t.Errorf("Got %v,%v expected %v,%v", index, value, 1, "bb") 332 } 333 if !it.Prev() { 334 t.Errorf("Should go to first element") 335 } 336 if index, value := it.Index(), it.Value(); index != 0 || value != "aa" { 337 t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "aa") 338 } 339 if it.Prev() { 340 t.Errorf("Should not go before first element") 341 } 342 } 343 } 344 345 func TestQueueSerialization(t *testing.T) { 346 queue := New[string]() 347 queue.Enqueue("a") 348 queue.Enqueue("b") 349 queue.Enqueue("c") 350 351 var err error 352 assert := func() { 353 if actualValue, expectedValue := queue.Values(), []string{"a", "b", "c"}; !reflect.DeepEqual(actualValue, expectedValue) { 354 t.Errorf("Got %v expected %v", actualValue, expectedValue) 355 } 356 if actualValue, expectedValue := queue.Size(), 3; actualValue != expectedValue { 357 t.Errorf("Got %v expected %v", actualValue, expectedValue) 358 } 359 if err != nil { 360 t.Errorf("Got error %v", err) 361 } 362 } 363 364 assert() 365 366 bytes, err := queue.MarshalJSON() 367 assert() 368 369 err = queue.UnmarshalJSON(bytes) 370 assert() 371 372 bytes, err = json.Marshal([]interface{}{"a", "b", "c", queue}) 373 if err != nil { 374 t.Errorf("Got error %v", err) 375 } 376 377 err = json.Unmarshal([]byte(`["1","2","3"]`), &queue) 378 if err != nil { 379 t.Errorf("Got error %v", err) 380 } 381 } 382 383 func TestQueueString(t *testing.T) { 384 c := New[int]() 385 c.Enqueue(1) 386 if !strings.HasPrefix(c.String(), "ArrayQueue") { 387 t.Errorf("String should start with container name") 388 } 389 } 390 391 func benchmarkEnqueue[E int](b *testing.B, queue *Queue[E], size int) { 392 for i := 0; i < b.N; i++ { 393 for n := 0; n < size; n++ { 394 queue.Enqueue(E(n)) 395 } 396 } 397 } 398 399 func benchmarkDequeue[E int](b *testing.B, queue *Queue[E], size int) { 400 for i := 0; i < b.N; i++ { 401 for n := 0; n < size; n++ { 402 queue.Dequeue() 403 } 404 } 405 } 406 407 func BenchmarkArrayQueueDequeue100(b *testing.B) { 408 b.StopTimer() 409 size := 100 410 queue := New[int]() 411 for n := 0; n < size; n++ { 412 queue.Enqueue(n) 413 } 414 b.StartTimer() 415 benchmarkDequeue(b, queue, size) 416 } 417 418 func BenchmarkArrayQueueDequeue1000(b *testing.B) { 419 b.StopTimer() 420 size := 1000 421 queue := New[int]() 422 for n := 0; n < size; n++ { 423 queue.Enqueue(n) 424 } 425 b.StartTimer() 426 benchmarkDequeue(b, queue, size) 427 } 428 429 func BenchmarkArrayQueueDequeue10000(b *testing.B) { 430 b.StopTimer() 431 size := 10000 432 queue := New[int]() 433 for n := 0; n < size; n++ { 434 queue.Enqueue(n) 435 } 436 b.StartTimer() 437 benchmarkDequeue(b, queue, size) 438 } 439 440 func BenchmarkArrayQueueDequeue100000(b *testing.B) { 441 b.StopTimer() 442 size := 100000 443 queue := New[int]() 444 for n := 0; n < size; n++ { 445 queue.Enqueue(n) 446 } 447 b.StartTimer() 448 benchmarkDequeue(b, queue, size) 449 } 450 451 func BenchmarkArrayQueueEnqueue100(b *testing.B) { 452 b.StopTimer() 453 size := 100 454 queue := New[int]() 455 b.StartTimer() 456 benchmarkEnqueue(b, queue, size) 457 } 458 459 func BenchmarkArrayQueueEnqueue1000(b *testing.B) { 460 b.StopTimer() 461 size := 1000 462 queue := New[int]() 463 for n := 0; n < size; n++ { 464 queue.Enqueue(n) 465 } 466 b.StartTimer() 467 benchmarkEnqueue(b, queue, size) 468 } 469 470 func BenchmarkArrayQueueEnqueue10000(b *testing.B) { 471 b.StopTimer() 472 size := 10000 473 queue := New[int]() 474 for n := 0; n < size; n++ { 475 queue.Enqueue(n) 476 } 477 b.StartTimer() 478 benchmarkEnqueue(b, queue, size) 479 } 480 481 func BenchmarkArrayQueueEnqueue100000(b *testing.B) { 482 b.StopTimer() 483 size := 100000 484 queue := New[int]() 485 for n := 0; n < size; n++ { 486 queue.Enqueue(n) 487 } 488 b.StartTimer() 489 benchmarkEnqueue(b, queue, size) 490 }