// // Created by erki on 13.03.21. // #include #include "utility_ringbuffer.hpp" template using Ringbuffer = Utility::Ringbuffer; TEST_CASE("Ringbuffer iterator", "[utility],[ringbuffer]") { using iterator = Ringbuffer<10>::iterator; const auto begin = iterator::pointer(10); const auto end = iterator::pointer(21); iterator it = iterator(iterator::pointer(15), begin, end); SECTION("Incrementing postfix increases its pointer and returns initial.") { iterator it_second = it++; REQUIRE(it - it_second == iterator::difference_type(1)); } SECTION("Incrementing prefix increases its pointer and returns new.") { const iterator original = it; iterator it_second = ++it; REQUIRE(it_second == it); REQUIRE(it - original == iterator::difference_type(1)); } SECTION("Subtracting 1 decreases its pointer.") { iterator it_second = it - 1; REQUIRE(it - it_second == iterator::difference_type(1)); } SECTION("Adding 1 increases its pointer.") { iterator it_second = it + 1; REQUIRE(it_second - it == iterator::difference_type(1)); } } TEST_CASE("Ringbuffer iterator at the end", "[utility],[ringbuffer]") { using iterator = Ringbuffer<10>::iterator; const auto begin = iterator::pointer(10); const auto end = iterator::pointer(21); iterator it = iterator(end - 1, begin, end); const auto it_begin = iterator(begin, begin, end); SECTION("Incrementing postfix sets the pointer to begin().") { it++; REQUIRE(it == it_begin); } SECTION("Incrementing prefix sets the pointer to begin().") { ++it; REQUIRE(it == it_begin); } SECTION("Adding 1 sets the pointer to begin().") { const iterator it_second = it + 1; REQUIRE(it_second == it_begin); } } TEST_CASE("Ringbuffer iterator at the beginning", "[utility],[ringbuffer]") { using iterator = Ringbuffer<10>::iterator; const auto begin = iterator::pointer(10); const auto end = iterator::pointer(21); iterator it = iterator(begin, begin, end); const auto it_last = iterator(end - 1, begin, end); SECTION("Subtracting 1 sets the pointer to last element.") { const iterator it_second = it - 1; REQUIRE(it_last == it_second); } } TEST_CASE("Ringbuffer constructed buffer is empty.", "[utility],[ringbuffer]") { Ringbuffer<10> buffer; REQUIRE(buffer.begin() == buffer.end()); REQUIRE(buffer.size() == 0); REQUIRE(buffer.empty()); REQUIRE(&buffer.front() == &buffer.back()); } TEST_CASE("Ringbuffer reports size properly.", "[utility],[ringbuffer]") { Ringbuffer<3> buffer; buffer.push_back(1); buffer.push_back(2); SECTION("max_size() reports maximum size properly.") { REQUIRE(buffer.max_size() == 3); } SECTION("After pushing 2 elements, size is reported properly.") { REQUIRE(buffer.size() == 2); } SECTION("A full buffer reports size as max_size.") { buffer.push_back(3); REQUIRE(buffer.size() == 3); REQUIRE(buffer.size() == buffer.max_size()); } SECTION("Removing an element updates size properly.") { buffer.pop_front(); REQUIRE(buffer.size() == 1); } SECTION("Removing and adding an element updates size properly.") { buffer.pop_front(); buffer.push_back(4); REQUIRE(buffer.size() == 2); buffer.push_back(5); REQUIRE(buffer.size() == 3); } } TEST_CASE("Ringbuffer adding single element.", "[utility],[ringbuffer]") { Ringbuffer<10> buffer; const auto old_end = buffer.end(); const auto old_begin = buffer.begin(); buffer.push_back(1); SECTION("Increases size and empty appropriately.") { REQUIRE(buffer.size() == 1); REQUIRE(!buffer.empty()); } SECTION("Updates end() appropriately.") { REQUIRE(old_end != buffer.end()); } SECTION("begin() remains the same.") { REQUIRE(old_begin == buffer.begin()); } SECTION("Makes begin() refer to the inserted member.") { REQUIRE(*old_begin == 1); REQUIRE(*buffer.begin() == 1); } SECTION("Distance between begin and end is 1.") { REQUIRE(buffer.end() - buffer.begin() == 1); } SECTION("Makes back() refer to the first element.") { REQUIRE(buffer.back() == 1); } SECTION("Makes front() refer to the first element.") { REQUIRE(buffer.front() == 1); } SECTION("Makes front() and back() refer to the same memory address.") { REQUIRE(&buffer.front() == &buffer.back()); } } TEST_CASE("Ringbuffer adding multiple elements.", "[utility],[ringbuffer]") { Ringbuffer<10> buffer; const auto old_begin = buffer.begin(); buffer.push_back(1); buffer.push_back(2); buffer.push_back(3); SECTION("Increases size and empty appropriately.") { REQUIRE(buffer.size() == 3); REQUIRE(!buffer.empty()); } SECTION("Makes front() refer to the first element.") { REQUIRE(buffer.front() == 1); } SECTION("Makes back() refer to the last element.") { REQUIRE(buffer.back() == 3); } SECTION("Updates begin() and end() appropriately.") { REQUIRE(old_begin == buffer.begin()); REQUIRE(buffer.end() - buffer.begin() == 3); } } TEST_CASE("Ringbuffer removing elements from the ringbuffer.", "[utility],[ringbuffer]") { Ringbuffer<10> buffer; const auto old_begin = buffer.begin(); buffer.push_back(1); buffer.push_back(2); buffer.push_back(3); buffer.pop_front(); SECTION("Updates the front() appropriately.") { REQUIRE(buffer.front() == 2); } SECTION("Updates begin() appropriately.") { REQUIRE(buffer.begin() - old_begin == 1); } SECTION("Updates size() appropriately.") { REQUIRE(buffer.size() == 2); } SECTION("Erasing remaining elements") { buffer.pop_front(); buffer.pop_front(); SECTION("Updates empty() appropriately.") { REQUIRE(buffer.empty()); } SECTION("Updates begin() and end() appropriately.") { REQUIRE(buffer.begin() == buffer.end()); } SECTION("Updates size() appropriately.") { REQUIRE(buffer.size() == 0); } } } TEST_CASE("Ringbuffer clearing a ringbuffer works.", "[utility],[ringbuffer]") { Ringbuffer<10> buffer; buffer.push_back(1); buffer.push_back(2); buffer.push_back(3); buffer.clear(); SECTION("Updates size() and empty() appropriately.") { REQUIRE(buffer.empty()); REQUIRE(buffer.size() == 0); } SECTION("Sets begin() and end() pointers appropriately.") { REQUIRE(buffer.begin() == buffer.end()); REQUIRE(&buffer.front() == &buffer.back()); } } TEST_CASE("Ringbuffer manually incrementing tail works.", "[utility],[ringbuffer]") { Ringbuffer<10> buffer; buffer.push_back(1); auto old_end = buffer.end(); *old_end = 2; buffer.increment_tail(); SECTION("New end is set forward by 1.") { const auto new_end = buffer.end(); REQUIRE(old_end != new_end); REQUIRE(new_end - old_end == 1); } } TEST_CASE("Ringbuffer manually incrementing tail from empty state works.", "[utility],[ringbuffer]") { Ringbuffer<10> buffer; const auto old_end = buffer.end(); const auto old_begin = buffer.begin(); auto* old_tail_item_ptr = &(*old_end); buffer.increment_tail(); SECTION("Head remains in place.") { const auto new_end = buffer.end(); const auto new_begin = buffer.begin(); REQUIRE(old_begin == new_begin); REQUIRE(new_end != new_begin); REQUIRE(new_end - new_begin == 1); } SECTION("Tail has been incremented.") { const auto new_end = buffer.end(); REQUIRE(new_end != old_end); REQUIRE(new_end - old_end == 1); REQUIRE(buffer.size() == 1); } SECTION("Item pointer for end is increased appropriately.") { auto* new_tail_item_ptr = &(*buffer.end()); REQUIRE(new_tail_item_ptr != old_tail_item_ptr); REQUIRE(new_tail_item_ptr - old_tail_item_ptr == 1); } SECTION("Second incrementation works as expected.") { buffer.increment_tail(); const auto new_end = buffer.end(); const auto new_begin = buffer.begin(); auto* new_tail_item_ptr = &(*buffer.end()); REQUIRE(new_begin == old_begin); REQUIRE(new_end - old_end == 2); REQUIRE(new_tail_item_ptr - old_tail_item_ptr == 2); REQUIRE(buffer.size() == 2); } } TEST_CASE("Ringbuffer manually incrementing tail when full deletes data.", "[utility],[ringbuffer]") { Ringbuffer<2> buffer; buffer.push_back(1); buffer.push_back(2); const auto old_start = buffer.begin(); const auto old_end = buffer.end(); REQUIRE(buffer.size() == buffer.max_size()); buffer.increment_tail(); REQUIRE(buffer.size() == buffer.max_size()); SECTION("End is incremented properly.") { const auto new_end = buffer.end(); REQUIRE(old_end != new_end); REQUIRE(new_end - old_end == 1); } SECTION("Begin is incremented properly.") { const auto new_start = buffer.begin(); REQUIRE(old_start != new_start); REQUIRE(new_start - old_start == 1); } }