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:
VectorArena()
: First(nullptr)
, Last(nullptr)
, Count(0)
, Stride(sizeof(Type))
{
@@ -21,6 +22,27 @@ namespace Juliet
~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)
{
Type* entry = ArenaPushStruct<Type>(Arena);
@@ -46,12 +68,19 @@ namespace Juliet
Swap(Last, elementAdr);
--Last;
--Count;
if (Count == 0)
{
First = Last = nullptr;
}
ArenaPop(Arena, Stride);
}
void Clear()
{
ArenaClear(Arena);
First = Last = nullptr;
Count = 0;
}

View File

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

View File

@@ -2,33 +2,54 @@
#if JULIET_DEBUG
#include <algorithm>
#include <Core/Common/CoreUtils.h>
#include <Core/Container/Vector.h>
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()
{
// Test 1: Integer VectorArena - Basic PushBack and Access
// Test 1: Integer VectorArena
{
VectorArena<int> vec;
Assert(vec.Size() == 0);
Assert(vec.begin() == vec.end());
VerifyVectorState(vec, 0);
vec.PushBack(10);
Assert(vec.Size() == 1);
VerifyVectorState(vec, 1);
Assert(vec[0] == 10);
Assert(*vec.begin() == 10);
Assert(*(vec.end() - 1) == 10);
vec.PushBack(20);
Assert(vec.Size() == 2);
VerifyVectorState(vec, 2);
Assert(vec[0] == 10);
Assert(vec[1] == 20);
Assert(*(vec.end() - 1) == 20);
vec.PushBack(30);
Assert(vec.Size() == 3);
VerifyVectorState(vec, 3);
Assert(vec[2] == 30);
Assert(*(vec.end() - 1) == 30);
// Test Iteration
int sum = 0;
@@ -45,24 +66,24 @@ namespace Juliet
vec.PushBack(10);
vec.PushBack(20);
vec.PushBack(30);
VerifyVectorState(vec, 3);
// Initial: [10, 20, 30]
// Remove index 0 (value 10). Should swap with Last (30) and pop last.
// Expected: [30, 20]
// Remove index 0 (value 10). Should swap with Last (30).
vec.RemoveAtFast(0);
Assert(vec.Size() == 2);
VerifyVectorState(vec, 2);
Assert(vec[0] == 30);
Assert(vec[1] == 20);
Assert(*(vec.end() - 1) == 20);
// Remove index 1 (value 20). Last is 20. Swap 20 with 20.
// Expected: [30]
// Remove index 1 (value 20).
vec.RemoveAtFast(1);
Assert(vec.Size() == 1);
VerifyVectorState(vec, 1);
Assert(vec[0] == 30);
Assert(*(vec.end() - 1) == 30);
// Remove remaining element
vec.RemoveAtFast(0);
Assert(vec.Size() == 0);
VerifyVectorState(vec, 0);
}
// Test 3: Clear and Reuse
@@ -70,19 +91,18 @@ namespace Juliet
VectorArena<int> vec;
vec.PushBack(100);
vec.PushBack(200);
Assert(vec.Size() == 2);
VerifyVectorState(vec, 2);
vec.Clear();
Assert(vec.Size() == 0);
Assert(vec.begin() == vec.end());
VerifyVectorState(vec, 0);
// Should be able to push again
vec.PushBack(300);
Assert(vec.Size() == 1);
VerifyVectorState(vec, 1);
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
{
@@ -97,25 +117,60 @@ namespace Juliet
};
VectorArena<TestItem> vec;
TestItem test{ 1, 1.0f };
vec.PushBack(std::move(test));
VerifyVectorState(vec, 0);
vec.PushBack({ 1, 1.0f });
vec.PushBack({ 2, 2.0f });
vec.PushBack({ 3, 3.0f });
VerifyVectorState(vec, 3);
Assert(vec.Size() == 3);
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}]
// Remove middle element (index 1)
vec.RemoveAtFast(1);
Assert(vec.Size() == 2);
// Use operator== to verify entire struct including float
VerifyVectorState(vec, 2);
Assert(vec[0] == (TestItem{ 1, 1.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
#endif