imported from "final" folder
This commit is contained in:
411
.pio/libdeps/esp01_1m/FastLED/tests/test_deque.cpp
Normal file
411
.pio/libdeps/esp01_1m/FastLED/tests/test_deque.cpp
Normal file
@@ -0,0 +1,411 @@
|
||||
#include <random>
|
||||
|
||||
#include "test.h"
|
||||
#include "fl/deque.h"
|
||||
#include "fl/initializer_list.h"
|
||||
|
||||
using namespace fl;
|
||||
|
||||
TEST_CASE("deque construction and basic operations") {
|
||||
fl::deque<int> dq;
|
||||
|
||||
SUBCASE("Initial state") {
|
||||
CHECK(dq.size() == 0);
|
||||
CHECK(dq.empty());
|
||||
}
|
||||
|
||||
SUBCASE("Push back and access") {
|
||||
dq.push_back(10);
|
||||
dq.push_back(20);
|
||||
dq.push_back(30);
|
||||
|
||||
CHECK(dq.size() == 3);
|
||||
CHECK_FALSE(dq.empty());
|
||||
CHECK(dq[0] == 10);
|
||||
CHECK(dq[1] == 20);
|
||||
CHECK(dq[2] == 30);
|
||||
CHECK(dq.front() == 10);
|
||||
CHECK(dq.back() == 30);
|
||||
}
|
||||
|
||||
SUBCASE("Push front and access") {
|
||||
dq.push_front(10);
|
||||
dq.push_front(20);
|
||||
dq.push_front(30);
|
||||
|
||||
CHECK(dq.size() == 3);
|
||||
CHECK_FALSE(dq.empty());
|
||||
CHECK(dq[0] == 30);
|
||||
CHECK(dq[1] == 20);
|
||||
CHECK(dq[2] == 10);
|
||||
CHECK(dq.front() == 30);
|
||||
CHECK(dq.back() == 10);
|
||||
}
|
||||
|
||||
SUBCASE("Mixed push operations") {
|
||||
dq.push_back(20);
|
||||
dq.push_front(10);
|
||||
dq.push_back(30);
|
||||
dq.push_front(5);
|
||||
|
||||
CHECK(dq.size() == 4);
|
||||
CHECK(dq[0] == 5);
|
||||
CHECK(dq[1] == 10);
|
||||
CHECK(dq[2] == 20);
|
||||
CHECK(dq[3] == 30);
|
||||
CHECK(dq.front() == 5);
|
||||
CHECK(dq.back() == 30);
|
||||
}
|
||||
|
||||
SUBCASE("Pop operations") {
|
||||
dq.push_back(10);
|
||||
dq.push_back(20);
|
||||
dq.push_back(30);
|
||||
dq.push_back(40);
|
||||
|
||||
dq.pop_back();
|
||||
CHECK(dq.size() == 3);
|
||||
CHECK(dq.back() == 30);
|
||||
|
||||
dq.pop_front();
|
||||
CHECK(dq.size() == 2);
|
||||
CHECK(dq.front() == 20);
|
||||
CHECK(dq[0] == 20);
|
||||
CHECK(dq[1] == 30);
|
||||
}
|
||||
|
||||
SUBCASE("Clear") {
|
||||
dq.push_back(10);
|
||||
dq.push_front(5);
|
||||
dq.push_back(20);
|
||||
dq.clear();
|
||||
|
||||
CHECK(dq.size() == 0);
|
||||
CHECK(dq.empty());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("deque iterators") {
|
||||
fl::deque<int> dq;
|
||||
|
||||
SUBCASE("Iterator traversal") {
|
||||
dq.push_back(10);
|
||||
dq.push_back(20);
|
||||
dq.push_back(30);
|
||||
|
||||
int sum = 0;
|
||||
for (auto it = dq.begin(); it != dq.end(); ++it) {
|
||||
sum += *it;
|
||||
}
|
||||
CHECK(sum == 60);
|
||||
|
||||
// Range-based for loop
|
||||
sum = 0;
|
||||
for (const auto& value : dq) {
|
||||
sum += value;
|
||||
}
|
||||
CHECK(sum == 60);
|
||||
}
|
||||
|
||||
SUBCASE("Const iterator") {
|
||||
dq.push_back(5);
|
||||
dq.push_back(15);
|
||||
dq.push_back(25);
|
||||
|
||||
const auto& const_dq = dq;
|
||||
int product = 1;
|
||||
for (auto it = const_dq.begin(); it != const_dq.end(); ++it) {
|
||||
product *= *it;
|
||||
}
|
||||
CHECK(product == 1875); // 5 * 15 * 25
|
||||
}
|
||||
|
||||
SUBCASE("Empty deque iterators") {
|
||||
CHECK(dq.begin() == dq.end());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("deque copy and move semantics") {
|
||||
SUBCASE("Copy constructor") {
|
||||
fl::deque<int> dq1;
|
||||
dq1.push_back(10);
|
||||
dq1.push_front(5);
|
||||
dq1.push_back(20);
|
||||
|
||||
fl::deque<int> dq2(dq1);
|
||||
CHECK(dq2.size() == 3);
|
||||
CHECK(dq2[0] == 5);
|
||||
CHECK(dq2[1] == 10);
|
||||
CHECK(dq2[2] == 20);
|
||||
|
||||
// Ensure independence
|
||||
dq1.push_back(30);
|
||||
CHECK(dq2.size() == 3);
|
||||
CHECK(dq1.size() == 4);
|
||||
}
|
||||
|
||||
SUBCASE("Copy assignment") {
|
||||
fl::deque<int> dq1;
|
||||
dq1.push_back(1);
|
||||
dq1.push_back(2);
|
||||
dq1.push_back(3);
|
||||
|
||||
fl::deque<int> dq2;
|
||||
dq2.push_back(99);
|
||||
|
||||
dq2 = dq1;
|
||||
CHECK(dq2.size() == 3);
|
||||
CHECK(dq2[0] == 1);
|
||||
CHECK(dq2[1] == 2);
|
||||
CHECK(dq2[2] == 3);
|
||||
}
|
||||
|
||||
SUBCASE("Move constructor") {
|
||||
fl::deque<int> dq1;
|
||||
dq1.push_back(10);
|
||||
dq1.push_back(20);
|
||||
dq1.push_back(30);
|
||||
|
||||
fl::deque<int> dq2(fl::move(dq1));
|
||||
CHECK(dq2.size() == 3);
|
||||
CHECK(dq2[0] == 10);
|
||||
CHECK(dq2[1] == 20);
|
||||
CHECK(dq2[2] == 30);
|
||||
CHECK(dq1.empty()); // dq1 should be empty after move
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("deque with custom types") {
|
||||
struct Point {
|
||||
int x, y;
|
||||
Point(int x = 0, int y = 0) : x(x), y(y) {}
|
||||
Point(const Point& other) : x(other.x), y(other.y) {}
|
||||
Point& operator=(const Point& other) {
|
||||
x = other.x;
|
||||
y = other.y;
|
||||
return *this;
|
||||
}
|
||||
bool operator==(const Point& other) const {
|
||||
return x == other.x && y == other.y;
|
||||
}
|
||||
};
|
||||
|
||||
fl::deque<Point> dq;
|
||||
|
||||
SUBCASE("Push and access custom type") {
|
||||
dq.push_back(Point(1, 2));
|
||||
dq.push_front(Point(3, 4));
|
||||
dq.push_back(Point(5, 6));
|
||||
|
||||
CHECK(dq.size() == 3);
|
||||
CHECK(dq[0].x == 3);
|
||||
CHECK(dq[0].y == 4);
|
||||
CHECK(dq[1].x == 1);
|
||||
CHECK(dq[1].y == 2);
|
||||
CHECK(dq[2].x == 5);
|
||||
CHECK(dq[2].y == 6);
|
||||
}
|
||||
|
||||
SUBCASE("Object lifecycle management") {
|
||||
static int construct_count = 0;
|
||||
static int destruct_count = 0;
|
||||
|
||||
struct TestObject {
|
||||
int value;
|
||||
TestObject(int v = 0) : value(v) { ++construct_count; }
|
||||
TestObject(const TestObject& other) : value(other.value) { ++construct_count; }
|
||||
~TestObject() { ++destruct_count; }
|
||||
TestObject& operator=(const TestObject& other) {
|
||||
value = other.value;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
construct_count = 0;
|
||||
destruct_count = 0;
|
||||
|
||||
{
|
||||
fl::deque<TestObject> test_dq;
|
||||
test_dq.push_back(TestObject(1));
|
||||
test_dq.push_back(TestObject(2));
|
||||
test_dq.push_front(TestObject(3));
|
||||
|
||||
CHECK(construct_count >= 3); // At least 3 objects constructed
|
||||
|
||||
test_dq.pop_back();
|
||||
test_dq.pop_front();
|
||||
|
||||
CHECK(destruct_count >= 2); // At least 2 objects destroyed
|
||||
}
|
||||
// Deque goes out of scope, remaining objects should be destroyed
|
||||
CHECK(construct_count == destruct_count); // All constructed objects should be destroyed
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("deque initializer list constructor") {
|
||||
SUBCASE("Basic initializer list") {
|
||||
fl::deque<int> dq{1, 2, 3, 4, 5};
|
||||
|
||||
CHECK(dq.size() == 5);
|
||||
CHECK(dq[0] == 1);
|
||||
CHECK(dq[1] == 2);
|
||||
CHECK(dq[2] == 3);
|
||||
CHECK(dq[3] == 4);
|
||||
CHECK(dq[4] == 5);
|
||||
}
|
||||
|
||||
SUBCASE("Empty initializer list") {
|
||||
fl::deque<int> dq{};
|
||||
|
||||
CHECK(dq.size() == 0);
|
||||
CHECK(dq.empty());
|
||||
}
|
||||
|
||||
SUBCASE("Single element initializer list") {
|
||||
fl::deque<int> dq{42};
|
||||
|
||||
CHECK(dq.size() == 1);
|
||||
CHECK(dq[0] == 42);
|
||||
CHECK(dq.front() == 42);
|
||||
CHECK(dq.back() == 42);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("deque resize operations") {
|
||||
fl::deque<int> dq;
|
||||
|
||||
SUBCASE("Resize to larger size") {
|
||||
dq.push_back(1);
|
||||
dq.push_back(2);
|
||||
dq.resize(5);
|
||||
|
||||
CHECK(dq.size() == 5);
|
||||
CHECK(dq[0] == 1);
|
||||
CHECK(dq[1] == 2);
|
||||
CHECK(dq[2] == 0); // Default constructed
|
||||
CHECK(dq[3] == 0);
|
||||
CHECK(dq[4] == 0);
|
||||
}
|
||||
|
||||
SUBCASE("Resize to smaller size") {
|
||||
dq.push_back(1);
|
||||
dq.push_back(2);
|
||||
dq.push_back(3);
|
||||
dq.push_back(4);
|
||||
dq.push_back(5);
|
||||
dq.resize(3);
|
||||
|
||||
CHECK(dq.size() == 3);
|
||||
CHECK(dq[0] == 1);
|
||||
CHECK(dq[1] == 2);
|
||||
CHECK(dq[2] == 3);
|
||||
}
|
||||
|
||||
SUBCASE("Resize with value") {
|
||||
dq.push_back(1);
|
||||
dq.push_back(2);
|
||||
dq.resize(5, 99);
|
||||
|
||||
CHECK(dq.size() == 5);
|
||||
CHECK(dq[0] == 1);
|
||||
CHECK(dq[1] == 2);
|
||||
CHECK(dq[2] == 99);
|
||||
CHECK(dq[3] == 99);
|
||||
CHECK(dq[4] == 99);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("deque edge cases") {
|
||||
fl::deque<int> dq;
|
||||
|
||||
SUBCASE("Multiple push/pop cycles") {
|
||||
// Simulate queue-like usage
|
||||
for (int i = 0; i < 20; ++i) {
|
||||
dq.push_back(i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
dq.pop_front();
|
||||
}
|
||||
|
||||
for (int i = 20; i < 30; ++i) {
|
||||
dq.push_back(i);
|
||||
}
|
||||
|
||||
CHECK(dq.size() == 20);
|
||||
CHECK(dq.front() == 10); // First 10 elements were popped
|
||||
CHECK(dq.back() == 29);
|
||||
}
|
||||
|
||||
SUBCASE("Stack-like usage from both ends") {
|
||||
dq.push_front(1);
|
||||
dq.push_back(2);
|
||||
dq.push_front(3);
|
||||
dq.push_back(4);
|
||||
|
||||
CHECK(dq.size() == 4);
|
||||
CHECK(dq[0] == 3);
|
||||
CHECK(dq[1] == 1);
|
||||
CHECK(dq[2] == 2);
|
||||
CHECK(dq[3] == 4);
|
||||
|
||||
dq.pop_front();
|
||||
dq.pop_back();
|
||||
|
||||
CHECK(dq.size() == 2);
|
||||
CHECK(dq[0] == 1);
|
||||
CHECK(dq[1] == 2);
|
||||
}
|
||||
|
||||
SUBCASE("Empty deque operations") {
|
||||
// These operations should be safe on empty deque
|
||||
CHECK(dq.empty());
|
||||
CHECK(dq.size() == 0);
|
||||
CHECK(dq.begin() == dq.end());
|
||||
|
||||
// Add and remove single element
|
||||
dq.push_back(42);
|
||||
CHECK(dq.size() == 1);
|
||||
dq.pop_back();
|
||||
CHECK(dq.empty());
|
||||
|
||||
dq.push_front(42);
|
||||
CHECK(dq.size() == 1);
|
||||
dq.pop_front();
|
||||
CHECK(dq.empty());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("deque stress test") {
|
||||
fl::deque<int> dq;
|
||||
|
||||
SUBCASE("Large number of operations") {
|
||||
const int num_ops = 1000;
|
||||
|
||||
// Fill with many elements
|
||||
for (int i = 0; i < num_ops; ++i) {
|
||||
if (i % 2 == 0) {
|
||||
dq.push_back(i);
|
||||
} else {
|
||||
dq.push_front(i);
|
||||
}
|
||||
}
|
||||
|
||||
CHECK(dq.size() == num_ops);
|
||||
|
||||
// Remove half the elements
|
||||
for (int i = 0; i < num_ops / 2; ++i) {
|
||||
if (i % 2 == 0) {
|
||||
dq.pop_back();
|
||||
} else {
|
||||
dq.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
CHECK(dq.size() == num_ops / 2);
|
||||
|
||||
// Clear everything
|
||||
dq.clear();
|
||||
CHECK(dq.empty());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user