Adding more unit tests and fixing the last errors

This commit is contained in:
2026-02-07 23:12:48 -05:00
parent 76f094de4f
commit 16c3a6052f
3 changed files with 121 additions and 35 deletions

View File

@@ -13,6 +13,7 @@ namespace Juliet
public: public:
VectorArena() VectorArena()
: First(nullptr) : First(nullptr)
, Last(nullptr)
, Count(0) , Count(0)
, Stride(sizeof(Type)) , Stride(sizeof(Type))
{ {
@@ -21,6 +22,27 @@ namespace Juliet
~VectorArena() { ArenaRelease(Arena); } ~VectorArena() { ArenaRelease(Arena); }
VectorArena(const VectorArena&)
: Arena(nullptr)
, First(nullptr)
, Last(nullptr)
, Count(0)
, Stride(sizeof(Type))
{
Assert(false, "Copying VectorArena is not allowed");
}
VectorArena(VectorArena&&) noexcept
: Arena(nullptr)
, First(nullptr)
, Last(nullptr)
, Count(0)
, Stride(sizeof(Type))
{
Assert(false, "Moving VectorArena is not allowed");
}
void operator=(const VectorArena&) { Assert(false, "Copying VectorArena is not allowed"); }
void operator=(VectorArena&&) noexcept { Assert(false, "Moving VectorArena is not allowed"); }
void PushBack(Type&& value) void PushBack(Type&& value)
{ {
Type* entry = ArenaPushStruct<Type>(Arena); Type* entry = ArenaPushStruct<Type>(Arena);
@@ -46,13 +68,20 @@ namespace Juliet
Swap(Last, elementAdr); Swap(Last, elementAdr);
--Last; --Last;
--Count; --Count;
if (Count == 0)
{
First = Last = nullptr;
}
ArenaPop(Arena, Stride); ArenaPop(Arena, Stride);
} }
void Clear() void Clear()
{ {
ArenaClear(Arena); ArenaClear(Arena);
Count = 0; First = Last = nullptr;
Count = 0;
} }
// C++ Accessors for loop supports and Index based access // C++ Accessors for loop supports and Index based access

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include <Core/Common/NonNullPtr.h> #include <Core/Common/NonNullPtr.h>
#include <Core/Container/Vector.h>
#include <Core/HAL/Display/Window.h> #include <Core/HAL/Display/Window.h>
namespace Juliet namespace Juliet
@@ -29,7 +30,8 @@ namespace Juliet
void (*PumpEvents)(NonNullPtr<DisplayDevice> self); void (*PumpEvents)(NonNullPtr<DisplayDevice> self);
// TODO : Use vector // TODO : Use vector
Window* MainWindow = nullptr; VectorArena<Window*> Windows;
Window* MainWindow = nullptr;
}; };
struct DisplayDeviceFactory struct DisplayDeviceFactory

View File

@@ -2,33 +2,54 @@
#if JULIET_DEBUG #if JULIET_DEBUG
#include <algorithm> #include <algorithm>
#include <Core/Common/CoreUtils.h> #include <Core/Common/CoreUtils.h>
#include <Core/Container/Vector.h> #include <Core/Container/Vector.h>
namespace Juliet namespace Juliet
{ {
namespace
{
template <typename T>
inline void VerifyVectorState(const VectorArena<T>& vec, size_t expectedCount)
{
Assert(vec.Size() == expectedCount);
if (expectedCount == 0)
{
Assert(vec.begin() == nullptr);
Assert(vec.end() == nullptr);
}
else
{
Assert(vec.begin() != nullptr);
Assert(vec.end() == vec.begin() + expectedCount);
}
}
} // namespace
void VectorUnitTest() void VectorUnitTest()
{ {
// Test 1: Integer VectorArena - Basic PushBack and Access // Test 1: Integer VectorArena
{ {
VectorArena<int> vec; VectorArena<int> vec;
Assert(vec.Size() == 0); VerifyVectorState(vec, 0);
Assert(vec.begin() == vec.end());
vec.PushBack(10); vec.PushBack(10);
Assert(vec.Size() == 1); VerifyVectorState(vec, 1);
Assert(vec[0] == 10); Assert(vec[0] == 10);
Assert(*vec.begin() == 10); Assert(*vec.begin() == 10);
Assert(*(vec.end() - 1) == 10);
vec.PushBack(20); vec.PushBack(20);
Assert(vec.Size() == 2); VerifyVectorState(vec, 2);
Assert(vec[0] == 10); Assert(vec[0] == 10);
Assert(vec[1] == 20); Assert(vec[1] == 20);
Assert(*(vec.end() - 1) == 20);
vec.PushBack(30); vec.PushBack(30);
Assert(vec.Size() == 3); VerifyVectorState(vec, 3);
Assert(vec[2] == 30); Assert(vec[2] == 30);
Assert(*(vec.end() - 1) == 30);
// Test Iteration // Test Iteration
int sum = 0; int sum = 0;
@@ -45,24 +66,24 @@ namespace Juliet
vec.PushBack(10); vec.PushBack(10);
vec.PushBack(20); vec.PushBack(20);
vec.PushBack(30); vec.PushBack(30);
VerifyVectorState(vec, 3);
// Initial: [10, 20, 30] // Remove index 0 (value 10). Should swap with Last (30).
// Remove index 0 (value 10). Should swap with Last (30) and pop last.
// Expected: [30, 20]
vec.RemoveAtFast(0); vec.RemoveAtFast(0);
Assert(vec.Size() == 2); VerifyVectorState(vec, 2);
Assert(vec[0] == 30); Assert(vec[0] == 30);
Assert(vec[1] == 20); Assert(vec[1] == 20);
Assert(*(vec.end() - 1) == 20);
// Remove index 1 (value 20). Last is 20. Swap 20 with 20. // Remove index 1 (value 20).
// Expected: [30]
vec.RemoveAtFast(1); vec.RemoveAtFast(1);
Assert(vec.Size() == 1); VerifyVectorState(vec, 1);
Assert(vec[0] == 30); Assert(vec[0] == 30);
Assert(*(vec.end() - 1) == 30);
// Remove remaining element // Remove remaining element
vec.RemoveAtFast(0); vec.RemoveAtFast(0);
Assert(vec.Size() == 0); VerifyVectorState(vec, 0);
} }
// Test 3: Clear and Reuse // Test 3: Clear and Reuse
@@ -70,19 +91,18 @@ namespace Juliet
VectorArena<int> vec; VectorArena<int> vec;
vec.PushBack(100); vec.PushBack(100);
vec.PushBack(200); vec.PushBack(200);
Assert(vec.Size() == 2); VerifyVectorState(vec, 2);
vec.Clear(); vec.Clear();
Assert(vec.Size() == 0); VerifyVectorState(vec, 0);
Assert(vec.begin() == vec.end());
// Should be able to push again
vec.PushBack(300); vec.PushBack(300);
Assert(vec.Size() == 1); VerifyVectorState(vec, 1);
Assert(vec[0] == 300); Assert(vec[0] == 300);
Assert(*(vec.end() - 1) == 300);
} }
// Test 4: Struct VectorArena (Testing Move Semantics and Complex Types) // Test 4: Struct VectorArena
{ {
struct TestItem struct TestItem
{ {
@@ -97,25 +117,60 @@ namespace Juliet
}; };
VectorArena<TestItem> vec; VectorArena<TestItem> vec;
TestItem test{ 1, 1.0f }; VerifyVectorState(vec, 0);
vec.PushBack(std::move(test));
vec.PushBack({ 1, 1.0f });
vec.PushBack({ 2, 2.0f }); vec.PushBack({ 2, 2.0f });
vec.PushBack({ 3, 3.0f }); vec.PushBack({ 3, 3.0f });
VerifyVectorState(vec, 3);
Assert(vec.Size() == 3); // Remove middle element (index 1)
Assert(vec[0].A == 1);
Assert(vec[1].A == 2);
// Remove middle element (index 1, value {2, 2.0f})
// Should swap with last ({3, 3.0f})
// Result: [{1, 1.0f}, {3, 3.0f}]
vec.RemoveAtFast(1); vec.RemoveAtFast(1);
Assert(vec.Size() == 2); VerifyVectorState(vec, 2);
// Use operator== to verify entire struct including float
Assert(vec[0] == (TestItem{ 1, 1.0f })); Assert(vec[0] == (TestItem{ 1, 1.0f }));
Assert(vec[1] == (TestItem{ 3, 3.0f })); Assert(vec[1] == (TestItem{ 3, 3.0f }));
} }
// Test 5: Add 2, Remove 2 -> Expect nullptr
{
VectorArena<int> vec;
vec.PushBack(1);
vec.PushBack(2);
VerifyVectorState(vec, 2);
vec.RemoveAtFast(0);
vec.RemoveAtFast(0);
VerifyVectorState(vec, 0);
}
// Test 6: Volume Test (100 items)
{
VectorArena<int> vec;
VerifyVectorState(vec, 0);
// Push 100 items
for (int i = 0; i < 100; ++i)
{
vec.PushBack(static_cast<int>(i));
}
VerifyVectorState(vec, 100);
// Verify content
for (int i = 0; i < 100; ++i)
{
Assert(vec[static_cast<size_t>(i)] == i);
}
// Remove 50 items from front (causing swaps)
for (int i = 0; i < 50; ++i)
{
vec.RemoveAtFast(0);
}
VerifyVectorState(vec, 50);
vec.Clear();
VerifyVectorState(vec, 0);
}
} }
} // namespace Juliet } // namespace Juliet
#endif #endif