|
3 | 3 | // Distributed under the MIT License. See accompanying file LICENSE |
4 | 4 | // or copy at https://opensource.org/licenses/MIT |
5 | 5 |
|
6 | | -#include <market/book.hpp> |
| 6 | +struct assert_error {}; |
| 7 | +#define ASSERT(...) do { if((__VA_ARGS__) == 0) throw assert_error{}; } while(0) |
| 8 | + |
| 9 | +#include "market/book.hpp" |
7 | 10 |
|
8 | 11 | #include <catch2/catch.hpp> |
9 | 12 |
|
@@ -427,6 +430,25 @@ namespace { |
427 | 430 | : book(levels, sides, freel, i, 0, 0, std::forward<Args>(t)...) { |
428 | 431 | this->accept(); |
429 | 432 | } |
| 433 | + |
| 434 | + template <market::side Side, size_t Size> |
| 435 | + size_type populate(Level const (&input)[Size], size_type offset) { |
| 436 | + size_type i = 0; |
| 437 | + for (auto const &l : input) { |
| 438 | + sides[(size_t)Side * capacity + i] = offset + i; |
| 439 | + levels[offset + i++] = l; // Note: must post-increment |
| 440 | + } |
| 441 | + side_i[(size_t)Side] = i; |
| 442 | + return i; |
| 443 | + } |
| 444 | + |
| 445 | + using market::book<Level>::reset; |
| 446 | + using market::book<Level>::accept; |
| 447 | + |
| 448 | + size_type *&base_freel() { return market::book<Level>::freel; } |
| 449 | + size_type &base_tail() { return market::book<Level>::tail_i; } |
| 450 | + size_type &base_size_bid() { return market::book<Level>::side_i[0]; } |
| 451 | + size_type &base_size_ask() { return market::book<Level>::side_i[1]; } |
430 | 452 | }; |
431 | 453 | } |
432 | 454 |
|
@@ -549,6 +571,81 @@ TEST_CASE("AnySizeBook_construction", "[book][capacity][construction][bad_capaci |
549 | 571 | REQUIRE(ptr->emplace_back<side::bid>() == npos); |
550 | 572 | REQUIRE(ptr->emplace_back<side::ask>() == npos); |
551 | 573 | } |
| 574 | + |
| 575 | + SECTION("call accept() on populated book") { |
| 576 | + Level bids[2] = {Level{130130, 100}, Level{130140, 10}}; |
| 577 | + Level offers[3] = {Level{130190, 50}, Level{130180, 40}, Level{130170, 20}}; |
| 578 | + |
| 579 | + CHECK_NOTHROW(ptr.reset(new AnySizeBook(10, std::nothrow))); |
| 580 | + REQUIRE(ptr->capacity == 10); |
| 581 | + auto const offset = ptr->populate<side::bid>(bids, 0); |
| 582 | + ptr->accept(); |
| 583 | + for (std::size_t i = 0; i < 20; ++i) { |
| 584 | + CHECK((i >= 18 ? true : ptr->freel[i] == i + 2)); |
| 585 | + } |
| 586 | + CHECK(ptr->size<side::bid>() == 2); |
| 587 | + CHECK(ptr->size<side::ask>() == 0); |
| 588 | + ptr->populate<side::ask>(offers, offset); |
| 589 | + ptr->accept(); |
| 590 | + for (std::size_t i = 0; i < 20; ++i) { |
| 591 | + CHECK((i >= 15 ? true : ptr->freel[i] == i + 5)); |
| 592 | + } |
| 593 | + CHECK(ptr->size<side::bid>() == 2); |
| 594 | + CHECK(ptr->size<side::ask>() == 3); |
| 595 | + } |
| 596 | + |
| 597 | + SECTION("ASSERT check") { |
| 598 | + CHECK_NOTHROW(ptr.reset(new AnySizeBook(10, std::nothrow))); |
| 599 | + SECTION("null freel") { |
| 600 | + ptr->base_freel() = nullptr; |
| 601 | + CHECK_THROWS_AS(ptr->reset(), assert_error); |
| 602 | + CHECK_THROWS_AS(ptr->accept(), assert_error); |
| 603 | + CHECK_THROWS_AS(ptr->push_back<side::bid>(Level{1, 1}), assert_error); |
| 604 | + CHECK_THROWS_AS(ptr->push_back<side::ask>(Level{1, 1}), assert_error); |
| 605 | + CHECK_THROWS_AS(ptr->emplace_back<side::bid>(1, 1), assert_error); |
| 606 | + CHECK_THROWS_AS(ptr->emplace_back<side::ask>(1, 1), assert_error); |
| 607 | + CHECK_THROWS_AS(ptr->remove<side::bid>(0), assert_error); |
| 608 | + CHECK_THROWS_AS(ptr->remove<side::ask>(0), assert_error); |
| 609 | + } |
| 610 | + SECTION("bad bid size") { |
| 611 | + ptr->base_size_bid() = 1; |
| 612 | + CHECK_THROWS_AS(ptr->push_back<side::bid>(Level{1, 1}), assert_error); |
| 613 | + CHECK_THROWS_AS(ptr->push_back<side::ask>(Level{1, 1}), assert_error); |
| 614 | + CHECK_THROWS_AS(ptr->emplace_back<side::bid>(1, 1), assert_error); |
| 615 | + CHECK_THROWS_AS(ptr->emplace_back<side::ask>(1, 1), assert_error); |
| 616 | + CHECK_THROWS_AS(ptr->remove<side::bid>(0), assert_error); |
| 617 | + CHECK_THROWS_AS(ptr->remove<side::ask>(0), assert_error); |
| 618 | + } |
| 619 | + |
| 620 | + SECTION("bad ask size") { |
| 621 | + ptr->base_size_ask() = 1; |
| 622 | + CHECK_THROWS_AS(ptr->push_back<side::bid>(Level{1, 1}), assert_error); |
| 623 | + CHECK_THROWS_AS(ptr->push_back<side::ask>(Level{1, 1}), assert_error); |
| 624 | + CHECK_THROWS_AS(ptr->emplace_back<side::bid>(1, 1), assert_error); |
| 625 | + CHECK_THROWS_AS(ptr->emplace_back<side::ask>(1, 1), assert_error); |
| 626 | + CHECK_THROWS_AS(ptr->remove<side::bid>(0), assert_error); |
| 627 | + CHECK_THROWS_AS(ptr->remove<side::ask>(0), assert_error); |
| 628 | + } |
| 629 | + |
| 630 | + SECTION("bad tail") { |
| 631 | + ptr->base_tail() = 1; |
| 632 | + CHECK_THROWS_AS(ptr->push_back<side::bid>(Level{1, 1}), assert_error); |
| 633 | + CHECK_THROWS_AS(ptr->push_back<side::ask>(Level{1, 1}), assert_error); |
| 634 | + CHECK_THROWS_AS(ptr->emplace_back<side::bid>(1, 1), assert_error); |
| 635 | + CHECK_THROWS_AS(ptr->emplace_back<side::ask>(1, 1), assert_error); |
| 636 | + CHECK_THROWS_AS(ptr->remove<side::bid>(0), assert_error); |
| 637 | + CHECK_THROWS_AS(ptr->remove<side::ask>(0), assert_error); |
| 638 | + } |
| 639 | + |
| 640 | + SECTION("bad index") { |
| 641 | + CHECK_THROWS_AS(std::as_const(*ptr).at<side::bid>(0), assert_error); |
| 642 | + CHECK_THROWS_AS(std::as_const(*ptr).at<side::ask>(0), assert_error); |
| 643 | + CHECK_THROWS_AS(ptr->at<side::bid>(0), assert_error); |
| 644 | + CHECK_THROWS_AS(ptr->at<side::ask>(0), assert_error); |
| 645 | + CHECK_THROWS_AS(ptr->remove<side::bid>(0), assert_error); |
| 646 | + CHECK_THROWS_AS(ptr->remove<side::ask>(0), assert_error); |
| 647 | + } |
| 648 | + } |
552 | 649 | } |
553 | 650 |
|
554 | 651 | TEST_CASE("AnySizeBook_binary_search", "[book][binary_search]") { |
|
0 commit comments