Use UnitTest-Cpp library for testing
This commit is contained in:
parent
79d018ffb4
commit
b8bcf58a29
53 changed files with 1046 additions and 1383 deletions
6
.gitmodules
vendored
6
.gitmodules
vendored
|
|
@ -13,9 +13,9 @@
|
|||
[submodule "Externals/nanovg"]
|
||||
path = Externals/nanovg
|
||||
url = https://github.com/elushaX/nanovg.git
|
||||
[submodule "Externals/asio"]
|
||||
path = Externals/asio
|
||||
url = https://github.com/elushaX/asio.git
|
||||
[submodule "Externals/lalr"]
|
||||
path = Externals/lalr
|
||||
url = https://github.com/elushaX/lalr.git
|
||||
[submodule "Externals/asio"]
|
||||
path = Externals/asio
|
||||
url = https://github.com/elushaX/asio.git
|
||||
|
|
|
|||
|
|
@ -11,5 +11,5 @@ target_link_libraries(${PROJECT_NAME} PUBLIC Utils)
|
|||
enable_testing()
|
||||
file(GLOB TEST_SOURCES "./tests/*.cpp")
|
||||
add_executable(${PROJECT_NAME}Tests ${TEST_SOURCES})
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} Utils)
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} UnitTest++)
|
||||
add_test(NAME ${PROJECT_NAME}Tests COMMAND ${PROJECT_NAME}Tests)
|
||||
|
|
@ -13,7 +13,10 @@ using namespace tp;
|
|||
|
||||
// ----------------------- Release Implementation ---------------------------- //
|
||||
void* HeapAlloc::allocate(ualni aBlockSize) { return malloc(aBlockSize); }
|
||||
void HeapAlloc::deallocate(void* aPtr) { free(aPtr); }
|
||||
void HeapAlloc::deallocate(void* aPtr) {
|
||||
if (!aPtr) return;
|
||||
free(aPtr);
|
||||
}
|
||||
HeapAlloc::~HeapAlloc() {}
|
||||
|
||||
#else
|
||||
|
|
@ -45,6 +48,8 @@ void* HeapAlloc::allocate(ualni aBlockSize) {
|
|||
}
|
||||
|
||||
void HeapAlloc::deallocate(void* aPtr) {
|
||||
if (!aPtr) return;
|
||||
|
||||
auto head = ((MemHeadLocal*) (aPtr)) - 1;
|
||||
|
||||
mNumAllocations--;
|
||||
|
|
@ -60,7 +65,7 @@ void HeapAlloc::deallocate(void* aPtr) {
|
|||
|
||||
HeapAlloc::~HeapAlloc() {
|
||||
if (mNumAllocations) {
|
||||
DEBUG_BREAK("Destruction of not freed Allocator")
|
||||
DEBUG_ASSERT(0 && "Destruction of not freed Allocator")
|
||||
|
||||
#ifdef MEM_STACK_TRACE
|
||||
// TODO : log leaks and free them up
|
||||
|
|
|
|||
|
|
@ -16,7 +16,10 @@ using namespace tp;
|
|||
// ----------------------- Release Implementation ---------------------------- //
|
||||
|
||||
void* HeapAllocGlobal::allocate(ualni aBlockSize) { return malloc(aBlockSize); }
|
||||
void HeapAllocGlobal::deallocate(void* aPtr) { free(aPtr); }
|
||||
void HeapAllocGlobal::deallocate(void* aPtr) {
|
||||
if (!aPtr) return;
|
||||
free(aPtr);
|
||||
}
|
||||
HeapAllocGlobal::~HeapAllocGlobal() = default;
|
||||
bool HeapAllocGlobal::checkLeaks() { return false; }
|
||||
void HeapAllocGlobal::startIgnore() {}
|
||||
|
|
|
|||
|
|
@ -132,6 +132,7 @@ namespace tp {
|
|||
}
|
||||
|
||||
void deallocate(void* aPtr) {
|
||||
if (!aPtr) return;
|
||||
auto chunk = mChunks.find(aPtr);
|
||||
(*chunk)->deallocate(aPtr);
|
||||
if ((*chunk)->isEmpty()) {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
|
||||
#include "Testing.hpp"
|
||||
#include "UnitTest++/UnitTest++.h"
|
||||
|
||||
#include "Allocators.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include "ChunkAllocator.hpp"
|
||||
#include "HeapAllocator.hpp"
|
||||
#include "HeapAllocatorGlobal.hpp"
|
||||
#include "PoolAllocator.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
using namespace tp;
|
||||
|
|
@ -80,7 +77,7 @@ private:
|
|||
if (mIsLoaded[idx]) return;
|
||||
verifyIntegrity();
|
||||
mLoaded[idx] = new (mAlloc.allocate(sizeof(TestStruct))) TestStruct(mData[idx]);
|
||||
TEST(mLoaded[idx]);
|
||||
ASSERT(mLoaded[idx]);
|
||||
mIsLoaded[idx] = true;
|
||||
mLoadedNum++;
|
||||
verifyIntegrity();
|
||||
|
|
@ -181,7 +178,7 @@ private:
|
|||
uint1 val = *address;
|
||||
*address = 5;
|
||||
|
||||
TEST(!mAlloc.checkWrap());
|
||||
ASSERT(!mAlloc.checkWrap());
|
||||
|
||||
*address = val;
|
||||
}
|
||||
|
|
@ -208,38 +205,45 @@ void testAlloc() {
|
|||
TestBenches<size, Alloc> heapTests{};
|
||||
heapTests.runTests();
|
||||
} catch (...) {
|
||||
TEST(false);
|
||||
ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_DEF_STATIC(GlobalHeap) { testAlloc<HeapAllocGlobal>(); }
|
||||
SUITE(Allocators) {
|
||||
TEST(GlobalHeap) { testAlloc<HeapAllocGlobal>(); }
|
||||
|
||||
TEST_DEF_STATIC(Heap) { testAlloc<tp::HeapAlloc>(); }
|
||||
TEST(Heap) { testAlloc<tp::HeapAlloc>(); }
|
||||
|
||||
TEST_DEF_STATIC(Chunk) {
|
||||
testAlloc<ChunkAlloc<TestStruct, size>>();
|
||||
testAlloc<ChunkAlloc<TestStruct, size * 2>>();
|
||||
TEST(Chunk) {
|
||||
testAlloc<ChunkAlloc<TestStruct, size>>();
|
||||
testAlloc<ChunkAlloc<TestStruct, size * 2>>();
|
||||
}
|
||||
|
||||
TEST(Pool) {
|
||||
testAlloc<PoolAlloc<TestStruct, 1>>();
|
||||
testAlloc<PoolAlloc<TestStruct, size / 100>>();
|
||||
testAlloc<PoolAlloc<TestStruct, size>>();
|
||||
}
|
||||
|
||||
TEST(Simple) {
|
||||
auto a = new TestStruct(-1);
|
||||
delete a;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_DEF_STATIC(Pool) {
|
||||
testAlloc<PoolAlloc<TestStruct, 1>>();
|
||||
testAlloc<PoolAlloc<TestStruct, size / 100>>();
|
||||
testAlloc<PoolAlloc<TestStruct, size>>();
|
||||
}
|
||||
|
||||
TEST_DEF_STATIC(Simple) {
|
||||
auto a = new TestStruct(-1);
|
||||
delete a;
|
||||
}
|
||||
int main() {
|
||||
|
||||
TEST_DEF(All) {
|
||||
testSimple();
|
||||
tp::ModuleManifest* deps[] = { &tp::gModuleAllocators, &tp::gModuleUtils, nullptr };
|
||||
tp::ModuleManifest testModule("AllocatorsTest", nullptr, nullptr, deps);
|
||||
|
||||
testGlobalHeap();
|
||||
testHeap();
|
||||
testChunk();
|
||||
testPool();
|
||||
if (!testModule.initialize()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TEST(HeapAllocGlobal::checkLeaks());
|
||||
// TEST(false);
|
||||
bool res = UnitTest::RunAllTests();
|
||||
|
||||
testModule.deinitialize();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
#include "Tests.hpp"
|
||||
|
||||
using namespace tp;
|
||||
|
||||
int main() {
|
||||
|
||||
tp::ModuleManifest* deps[] = { &tp::gModuleAllocators, &tp::gModuleUtils, nullptr };
|
||||
tp::ModuleManifest testModule("AllocatorsTest", nullptr, nullptr, deps);
|
||||
|
||||
if (!testModule.initialize()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
testAll();
|
||||
|
||||
testModule.deinitialize();
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "Testing.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
void testAll();
|
||||
|
|
@ -14,5 +14,5 @@ target_link_libraries(${PROJECT_NAME} PUBLIC Strings)
|
|||
enable_testing()
|
||||
file(GLOB TEST_SOURCES "./tests/*.cpp")
|
||||
add_executable(${PROJECT_NAME}Tests ${TEST_SOURCES})
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} Utils)
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} UnitTest++)
|
||||
add_test(NAME ${PROJECT_NAME}Tests COMMAND ${PROJECT_NAME}Tests)
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "ConnectionCommon.hpp"
|
||||
#include "List.hpp"
|
||||
|
||||
namespace tp {
|
||||
|
||||
class RemoteConnectionContext;
|
||||
|
||||
class RemoteConnection : public Connection {
|
||||
public:
|
||||
class Location {
|
||||
ualni mId = 0;
|
||||
|
||||
public:
|
||||
Location() = default;
|
||||
};
|
||||
|
||||
public:
|
||||
RemoteConnection(){ MODULE_SANITY_CHECK(gModuleConnection) };
|
||||
|
||||
virtual ~RemoteConnection() {
|
||||
if (mStatus.isOpened()) RemoteConnection::disconnect();
|
||||
}
|
||||
|
||||
public:
|
||||
virtual bool connect(const Location& location, const Type& connectionInfo);
|
||||
virtual bool disconnect();
|
||||
|
||||
public:
|
||||
virtual const Location& getLocation() { return mLocation; }
|
||||
|
||||
public:
|
||||
virtual bool readBytes(Byte* bytes, SizeBytes size);
|
||||
virtual bool writeBytes(const Byte* bytes, SizeBytes size);
|
||||
|
||||
private:
|
||||
RemoteConnectionContext* mHandle = nullptr;
|
||||
Location mLocation;
|
||||
};
|
||||
}
|
||||
51
Connection/tests/Test.cpp
Normal file
51
Connection/tests/Test.cpp
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
|
||||
#include "ConnectionCommon.hpp"
|
||||
|
||||
#include "LocalConnection.hpp"
|
||||
|
||||
#include "UnitTest++/UnitTest++.h"
|
||||
|
||||
using namespace tp;
|
||||
|
||||
SUITE(Connection) {
|
||||
TEST(LocalConnection) {
|
||||
const int1* data = "abcde\0";
|
||||
int1 dataRead[6]{};
|
||||
|
||||
{
|
||||
LocalConnection file;
|
||||
file.connect(LocalConnection::Location(String("tmp2.txt")), LocalConnection::Type(false));
|
||||
file.writeBytes(data, 6);
|
||||
file.disconnect();
|
||||
}
|
||||
|
||||
{
|
||||
LocalConnection file;
|
||||
file.connect(LocalConnection::Location(String("tmp2.txt")), LocalConnection::Type(true));
|
||||
file.readBytes(dataRead, 6);
|
||||
file.disconnect();
|
||||
}
|
||||
|
||||
for (auto i = 0; i < 5; i++) {
|
||||
CHECK(data[i] == dataRead[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(NO_TESTS) { CHECK(false); }
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
tp::ModuleManifest* deps[] = { &tp::gModuleConnection, nullptr };
|
||||
tp::ModuleManifest testModule("ConnectionTest", nullptr, nullptr, deps);
|
||||
|
||||
if (!testModule.initialize()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool res = UnitTest::RunAllTests();
|
||||
|
||||
testModule.deinitialize();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
|
||||
#include "LocalConnection.hpp"
|
||||
#include "Testing.hpp"
|
||||
|
||||
using namespace tp;
|
||||
|
||||
TEST_DEF_STATIC(Simple) {
|
||||
|
||||
const int1* data = "abcde\0";
|
||||
int1 dataRead[6]{};
|
||||
|
||||
{
|
||||
LocalConnection file;
|
||||
file.connect(LocalConnection::Location(String("tmp2.txt")), LocalConnection::Type(false));
|
||||
file.writeBytes(data, 6);
|
||||
file.disconnect();
|
||||
}
|
||||
|
||||
{
|
||||
LocalConnection file;
|
||||
file.connect(LocalConnection::Location(String("tmp2.txt")), LocalConnection::Type(true));
|
||||
file.readBytes(dataRead, 6);
|
||||
file.disconnect();
|
||||
}
|
||||
|
||||
for (auto i = 0; i < 5; i++) {
|
||||
TEST(data[i] == dataRead[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_DEF(LocalConnection) { testSimple(); }
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
#include "RemoteConnection.hpp"
|
||||
#include "Testing.hpp"
|
||||
|
||||
using namespace tp;
|
||||
|
||||
TEST_DEF_STATIC(Simple) {
|
||||
TEST(false);
|
||||
}
|
||||
|
||||
TEST_DEF(RemoteConnection) { testSimple(); }
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
|
||||
#include "ConnectionCommon.hpp"
|
||||
#include "Testing.hpp"
|
||||
|
||||
void testLocalConnection();
|
||||
|
||||
int main() {
|
||||
|
||||
tp::ModuleManifest* deps[] = { &tp::gModuleConnection, nullptr };
|
||||
tp::ModuleManifest testModule("ConnectionTest", nullptr, nullptr, deps);
|
||||
|
||||
if (!testModule.initialize()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
testLocalConnection();
|
||||
|
||||
testModule.deinitialize();
|
||||
}
|
||||
|
|
@ -11,5 +11,5 @@ target_link_libraries(${PROJECT_NAME} PUBLIC Modules)
|
|||
enable_testing()
|
||||
file(GLOB TEST_SOURCES "./tests/*.cpp")
|
||||
add_executable(${PROJECT_NAME}Tests ${TEST_SOURCES})
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} Allocators)
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} Allocators UnitTest++)
|
||||
add_test(NAME ${PROJECT_NAME}Tests COMMAND ${PROJECT_NAME}Tests)
|
||||
|
|
@ -245,6 +245,7 @@ namespace tp {
|
|||
}
|
||||
removeAll();
|
||||
mNSlots = in.mNSlots;
|
||||
deleteTable(mTable);
|
||||
mTable = newTable(mNSlots);
|
||||
for (alni i = 0; i < mNSlots; i++) {
|
||||
if (in.mTable[i] && !isDeletedNode(in.mTable[i])) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#include "Buffer2D.hpp"
|
||||
#include "Testing.hpp"
|
||||
#include "Tests.hpp"
|
||||
|
||||
#include "HeapAllocator.hpp"
|
||||
|
|
@ -8,18 +7,15 @@ using namespace tp;
|
|||
|
||||
const ualni size = 1000;
|
||||
|
||||
TEST_DEF_STATIC(Simple1) {
|
||||
Buffer2D<int, tp::HeapAlloc> buff;
|
||||
buff.reserve({ 4, 4 });
|
||||
buff.set({ 2, 2 }, 5);
|
||||
TEST(buff.get({ 2, 2 }) == 5);
|
||||
}
|
||||
SUITE(Buffer2D) {
|
||||
TEST(Simple) {
|
||||
Buffer2D<int, tp::HeapAlloc> buff;
|
||||
buff.reserve({ 4, 4 });
|
||||
buff.set({ 2, 2 }, 5);
|
||||
CHECK(buff.get({ 2, 2 }) == 5);
|
||||
}
|
||||
|
||||
TEST_DEF_STATIC(Simple2) {
|
||||
// TEST(false);
|
||||
}
|
||||
|
||||
TEST_DEF(Buffer2d) {
|
||||
testSimple1();
|
||||
testSimple2();
|
||||
TEST(NO_TESTS) {
|
||||
CHECK(false);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,35 +1,33 @@
|
|||
#include "Buffer.hpp"
|
||||
#include "Testing.hpp"
|
||||
#include "Tests.hpp"
|
||||
|
||||
using namespace tp;
|
||||
|
||||
const ualni size = 1000;
|
||||
|
||||
TEST_DEF_STATIC(Simple1) {
|
||||
Buffer<TestClass, tp::HeapAlloc> buff;
|
||||
TEST(buff.size() == 0);
|
||||
for (auto i : Range(size * 10)) {
|
||||
buff.append(TestClass(i));
|
||||
SUITE(Buffer) {
|
||||
TEST(Simple1) {
|
||||
Buffer<TestClass, tp::HeapAlloc> buff;
|
||||
CHECK(buff.size() == 0);
|
||||
for (auto i : Range(size * 10)) {
|
||||
buff.append(TestClass(i));
|
||||
}
|
||||
CHECK(buff.size() == size * 10);
|
||||
while (buff.size())
|
||||
buff.pop();
|
||||
CHECK(buff.size() == 0);
|
||||
}
|
||||
TEST(buff.size() == size * 10);
|
||||
while (buff.size())
|
||||
buff.pop();
|
||||
TEST(buff.size() == 0);
|
||||
}
|
||||
|
||||
TEST_DEF_STATIC(Simple2) {
|
||||
Buffer<TestClass, tp::HeapAlloc> buff(size);
|
||||
TEST(buff.size() == size);
|
||||
for (auto i : Range(size * 10))
|
||||
buff.append(TestClass(i));
|
||||
TEST(buff.size() == size + size * 10);
|
||||
while (buff.size())
|
||||
buff.pop();
|
||||
TEST(buff.size() == 0);
|
||||
}
|
||||
TEST(Simple2) {
|
||||
Buffer<TestClass, tp::HeapAlloc> buff(size);
|
||||
CHECK(buff.size() == size);
|
||||
for (auto i : Range(size * 10))
|
||||
buff.append(TestClass(i));
|
||||
CHECK(buff.size() == size + size * 10);
|
||||
while (buff.size())
|
||||
buff.pop();
|
||||
CHECK(buff.size() == 0);
|
||||
}
|
||||
|
||||
TEST_DEF(Buffer) {
|
||||
testSimple1();
|
||||
testSimple2();
|
||||
}
|
||||
TEST(NO_TEST) { CHECK(false); }
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
#include "IntervalTree.hpp"
|
||||
#include "Testing.hpp"
|
||||
#include "Tests.hpp"
|
||||
|
||||
#include "Buffer.hpp"
|
||||
|
|
@ -34,246 +33,242 @@ struct Interval {
|
|||
}
|
||||
};
|
||||
|
||||
TEST_DEF_STATIC(FunctionalitySimple) {
|
||||
SUITE(IntervalTree) {
|
||||
TEST(FunctionalitySimple) {
|
||||
|
||||
IntervalTree<ualni, ualni> intervalTree;
|
||||
IntervalTree<ualni, ualni> intervalTree;
|
||||
|
||||
intervalTree.insert({ 0, 10 }, 1);
|
||||
intervalTree.insert({ 3, 6 }, 2);
|
||||
intervalTree.insert({ 8, 12 }, 3);
|
||||
intervalTree.insert({ 0, 10 }, 1);
|
||||
intervalTree.insert({ 3, 6 }, 2);
|
||||
intervalTree.insert({ 8, 12 }, 3);
|
||||
|
||||
intervalTree.forEachIntersection(4, 5, [](alni start, ualni end, ualni data) {
|
||||
printf("%i", int(data));
|
||||
printf("\n");
|
||||
});
|
||||
}
|
||||
|
||||
TEST_DEF_STATIC(FunctionalityScale) {
|
||||
|
||||
const int NUM_TEST_INTERVALS = 1000;
|
||||
const halnf SPAN = 100;
|
||||
|
||||
Buffer<Interval> pool;
|
||||
IntervalTree<halnf, ualni> intervalTree;
|
||||
|
||||
Buffer<Interval> testIntervals;
|
||||
|
||||
auto test = [&]() {
|
||||
for (auto testInterval : testIntervals) {
|
||||
|
||||
Buffer<ualni> correct;
|
||||
Buffer<ualni> result;
|
||||
|
||||
ualni idx = 0;
|
||||
for (auto interval : pool) {
|
||||
if (!interval->ignore && interval->overlaps(testInterval.data())) {
|
||||
correct.append(idx);
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
|
||||
intervalTree.forEachIntersection(testInterval->start, testInterval->end, [&](alni start, ualni end, ualni data) {
|
||||
result.append(data);
|
||||
});
|
||||
|
||||
TEST(correct.size() == result.size());
|
||||
|
||||
if (!(correct.size() == result.size())) {
|
||||
printf("intersections - \n");
|
||||
|
||||
for (auto i : correct) {
|
||||
printf(" %i", (int) i.data());
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
for (auto i : result) {
|
||||
printf(" %i", (int) i.data());
|
||||
}
|
||||
printf("\n\n");
|
||||
}
|
||||
// todo compare containers
|
||||
}
|
||||
};
|
||||
|
||||
// initialize
|
||||
for (auto i : Range<ualni>(NUM_TEST_INTERVALS)) {
|
||||
auto interval = Interval();
|
||||
interval.random(SPAN);
|
||||
|
||||
pool.append(interval);
|
||||
intervalTree.insert({ interval.start, interval.end }, i);
|
||||
|
||||
interval.random(SPAN * 2.f, (halnf) randomFloat());
|
||||
|
||||
testIntervals.append(interval);
|
||||
intervalTree.forEachIntersection(4, 5, [](alni start, ualni end, ualni data) {
|
||||
printf("%i", int(data));
|
||||
printf("\n");
|
||||
});
|
||||
}
|
||||
|
||||
test();
|
||||
TEST(FunctionalityScale) {
|
||||
|
||||
// remove some
|
||||
for (auto i : Range<ualni>(NUM_TEST_INTERVALS / 2)) {
|
||||
auto idx = ualni(randomFloat() * (alnf) pool.size());
|
||||
pool[idx].ignore = true;
|
||||
intervalTree.remove({ pool[idx].start, pool[idx].end });
|
||||
}
|
||||
|
||||
test();
|
||||
}
|
||||
|
||||
TEST_DEF_STATIC(Efficency) {
|
||||
|
||||
struct Stat {
|
||||
halnf numItems = 0;
|
||||
halnf avgFound = 0;
|
||||
halnf avgChecks = 0;
|
||||
};
|
||||
|
||||
auto test = [&](ualni NUM_TEST_INTERVALS, ualni NUM_CHECKS) {
|
||||
const auto SPAN = (halnf) (halnf(NUM_TEST_INTERVALS));
|
||||
const auto SCALE = (halnf) (2.f);
|
||||
const int NUM_TEST_INTERVALS = 1000;
|
||||
const halnf SPAN = 100;
|
||||
|
||||
Buffer<Interval> pool;
|
||||
IntervalTree<halnf, ualni> intervalTree;
|
||||
|
||||
Buffer<Interval> testIntervals;
|
||||
|
||||
auto WOBBLE = SPAN * 0;
|
||||
auto test = [&]() {
|
||||
for (auto testInterval : testIntervals) {
|
||||
|
||||
Buffer<ualni> correct;
|
||||
Buffer<ualni> result;
|
||||
|
||||
ualni idx = 0;
|
||||
for (auto interval : pool) {
|
||||
if (!interval->ignore && interval->overlaps(testInterval.data())) {
|
||||
correct.append(idx);
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
|
||||
intervalTree.forEachIntersection(testInterval->start, testInterval->end, [&](alni start, ualni end, ualni data) {
|
||||
result.append(data);
|
||||
});
|
||||
|
||||
CHECK(correct.size() == result.size());
|
||||
|
||||
if (!(correct.size() == result.size())) {
|
||||
printf("intersections - \n");
|
||||
|
||||
for (auto i : correct) {
|
||||
printf(" %i", (int) i.data());
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
for (auto i : result) {
|
||||
printf(" %i", (int) i.data());
|
||||
}
|
||||
printf("\n\n");
|
||||
}
|
||||
// todo compare containers
|
||||
}
|
||||
};
|
||||
|
||||
// initialize
|
||||
for (auto i : Range<ualni>(NUM_TEST_INTERVALS)) {
|
||||
auto interval = Interval();
|
||||
interval.randomSized(SPAN, SCALE, WOBBLE);
|
||||
interval.random(SPAN);
|
||||
|
||||
pool.append(interval);
|
||||
intervalTree.insert({ interval.start, interval.end }, i);
|
||||
// WOBBLE -= 1.f;
|
||||
}
|
||||
|
||||
for (auto i : Range(0))
|
||||
intervalTree.insert({ (halnf) i * 0.01f, SPAN }, 0);
|
||||
interval.random(SPAN * 2.f, (halnf) randomFloat());
|
||||
|
||||
WOBBLE = 0;
|
||||
for (auto i : Range<ualni>(NUM_CHECKS)) {
|
||||
auto interval = Interval();
|
||||
interval.randomSized(SPAN, SCALE, WOBBLE);
|
||||
testIntervals.append(interval);
|
||||
}
|
||||
|
||||
ualni debugMaxChecks = 0;
|
||||
ualni debugMaxFound = 0;
|
||||
halnf debugAvgChecks = 0;
|
||||
halnf debugAvgFound = 0;
|
||||
test();
|
||||
|
||||
for (auto testInterval : testIntervals) {
|
||||
ualni debugFound = 0;
|
||||
ualni debug = intervalTree.forEachIntersection(
|
||||
testInterval->start,
|
||||
testInterval->end,
|
||||
[&](ualni start, ualni end, ualni data) {
|
||||
debugFound++;
|
||||
//
|
||||
}
|
||||
);
|
||||
|
||||
if (debug > debugMaxChecks) {
|
||||
debugMaxChecks = debug;
|
||||
debugMaxFound = debugFound;
|
||||
}
|
||||
|
||||
debugMaxChecks = max(debug, debugMaxChecks);
|
||||
debugAvgChecks += (halnf) debug;
|
||||
debugAvgFound += (halnf) debugFound;
|
||||
// remove some
|
||||
for (auto i : Range<ualni>(NUM_TEST_INTERVALS / 2)) {
|
||||
auto idx = ualni(randomFloat() * (alnf) pool.size());
|
||||
pool[idx].ignore = true;
|
||||
intervalTree.remove({ pool[idx].start, pool[idx].end });
|
||||
}
|
||||
|
||||
debugAvgChecks /= (halnf) testIntervals.size();
|
||||
debugAvgFound /= (halnf) testIntervals.size();
|
||||
|
||||
printf("\nItems : %llu\n", NUM_TEST_INTERVALS);
|
||||
printf("Avg(checks) : %f\n", debugAvgChecks);
|
||||
printf("Avg(found) : %f\n", debugAvgFound);
|
||||
printf("Max checks : %llu\n", debugMaxChecks);
|
||||
printf("Max checks found : %llu\n", debugMaxFound);
|
||||
printf("N(Avg(checks) / Avg(N(items)) : %f\n", debugAvgChecks / (halnf) intervalTree.size());
|
||||
printf("N(Avg(found)) / Avg(N(items)) : %f\n", debugAvgFound / (halnf) intervalTree.size());
|
||||
printf("Avg(found) / Avg(checks) : %f\n", debugAvgFound / debugAvgChecks);
|
||||
|
||||
return Stat{ (halnf) NUM_TEST_INTERVALS,
|
||||
debugAvgFound / (halnf) intervalTree.size(),
|
||||
debugAvgChecks / (halnf) intervalTree.size() };
|
||||
};
|
||||
|
||||
Buffer<Stat> stats;
|
||||
for (auto i : Range(2, 5)) {
|
||||
Stat stat = test(pow(10, i), 100);
|
||||
stats.append(stat);
|
||||
test();
|
||||
}
|
||||
|
||||
printf("\nChecks: ");
|
||||
for (auto stat : stats)
|
||||
printf("%e ", stat->avgChecks);
|
||||
TEST(Efficency) {
|
||||
|
||||
printf("\nHits: ");
|
||||
for (auto stat : stats)
|
||||
printf("%e ", stat->avgFound);
|
||||
struct Stat {
|
||||
halnf numItems = 0;
|
||||
halnf avgFound = 0;
|
||||
halnf avgChecks = 0;
|
||||
};
|
||||
|
||||
printf("\nItems: ");
|
||||
for (auto stat : stats)
|
||||
printf("%e ", stat->numItems);
|
||||
auto test = [&](ualni NUM_TEST_INTERVALS, ualni NUM_CHECKS) {
|
||||
const auto SPAN = (halnf) (halnf(NUM_TEST_INTERVALS));
|
||||
const auto SCALE = (halnf) (2.f);
|
||||
|
||||
printf("\n\n");
|
||||
}
|
||||
IntervalTree<halnf, ualni> intervalTree;
|
||||
Buffer<Interval> testIntervals;
|
||||
|
||||
TEST_DEF_STATIC(FunctionalityComplex) {
|
||||
IntervalTree<ualni, ualni> intervals;
|
||||
auto WOBBLE = SPAN * 0;
|
||||
for (auto i : Range<ualni>(NUM_TEST_INTERVALS)) {
|
||||
auto interval = Interval();
|
||||
interval.randomSized(SPAN, SCALE, WOBBLE);
|
||||
intervalTree.insert({ interval.start, interval.end }, i);
|
||||
// WOBBLE -= 1.f;
|
||||
}
|
||||
|
||||
struct QueryResult {
|
||||
ualni numFound = 0;
|
||||
ualni lastDataFound = 0;
|
||||
for (auto i : Range(0))
|
||||
intervalTree.insert({ (halnf) i * 0.01f, SPAN }, 0);
|
||||
|
||||
[[nodiscard]] bool isSingleData(ualni aData) const { return numFound == 1 & lastDataFound == aData; }
|
||||
[[nodiscard]] bool notFound() const { return numFound == 0; }
|
||||
[[nodiscard]] bool found(ualni num) const { return numFound == num; }
|
||||
};
|
||||
WOBBLE = 0;
|
||||
for (auto i : Range<ualni>(NUM_CHECKS)) {
|
||||
auto interval = Interval();
|
||||
interval.randomSized(SPAN, SCALE, WOBBLE);
|
||||
testIntervals.append(interval);
|
||||
}
|
||||
|
||||
auto makeQuery = [&](ualni aStart, ualni aEnd) {
|
||||
QueryResult out;
|
||||
intervals.forEachIntersection(aStart, aEnd, [&](alni start, ualni end, ualni data) {
|
||||
out.numFound++;
|
||||
out.lastDataFound = data;
|
||||
});
|
||||
return out;
|
||||
};
|
||||
ualni debugMaxChecks = 0;
|
||||
ualni debugMaxFound = 0;
|
||||
halnf debugAvgChecks = 0;
|
||||
halnf debugAvgFound = 0;
|
||||
|
||||
intervals.insert({ 2, 5 }, 1);
|
||||
intervals.insert({ 12, 15 }, 2);
|
||||
intervals.insert({ 22, 25 }, 3);
|
||||
for (auto testInterval : testIntervals) {
|
||||
ualni debugFound = 0;
|
||||
ualni debug = intervalTree.forEachIntersection(
|
||||
testInterval->start,
|
||||
testInterval->end,
|
||||
[&](ualni start, ualni end, ualni data) {
|
||||
debugFound++;
|
||||
//
|
||||
}
|
||||
);
|
||||
|
||||
TEST(makeQuery(1, 6).isSingleData(1));
|
||||
TEST(makeQuery(1, 3).isSingleData(1));
|
||||
TEST(makeQuery(3, 6).isSingleData(1));
|
||||
if (debug > debugMaxChecks) {
|
||||
debugMaxChecks = debug;
|
||||
debugMaxFound = debugFound;
|
||||
}
|
||||
|
||||
TEST(makeQuery(0, 1).notFound());
|
||||
TEST(makeQuery(7, 8).notFound());
|
||||
debugMaxChecks = max(debug, debugMaxChecks);
|
||||
debugAvgChecks += (halnf) debug;
|
||||
debugAvgFound += (halnf) debugFound;
|
||||
}
|
||||
|
||||
TEST(makeQuery(3, 4).isSingleData(1));
|
||||
debugAvgChecks /= (halnf) testIntervals.size();
|
||||
debugAvgFound /= (halnf) testIntervals.size();
|
||||
|
||||
TEST(makeQuery(13, 14).isSingleData(2));
|
||||
printf("\nItems : %llu\n", NUM_TEST_INTERVALS);
|
||||
printf("Avg(checks) : %f\n", debugAvgChecks);
|
||||
printf("Avg(found) : %f\n", debugAvgFound);
|
||||
printf("Max checks : %llu\n", debugMaxChecks);
|
||||
printf("Max checks found : %llu\n", debugMaxFound);
|
||||
printf("N(Avg(checks) / Avg(N(items)) : %f\n", debugAvgChecks / (halnf) intervalTree.size());
|
||||
printf("N(Avg(found)) / Avg(N(items)) : %f\n", debugAvgFound / (halnf) intervalTree.size());
|
||||
printf("Avg(found) / Avg(checks) : %f\n", debugAvgFound / debugAvgChecks);
|
||||
|
||||
TEST(makeQuery(1, 35).found(3));
|
||||
TEST(makeQuery(11, 35).found(2));
|
||||
return Stat{ (halnf) NUM_TEST_INTERVALS,
|
||||
debugAvgFound / (halnf) intervalTree.size(),
|
||||
debugAvgChecks / (halnf) intervalTree.size() };
|
||||
};
|
||||
|
||||
// check opened
|
||||
TEST(makeQuery(5, 12).found(2));
|
||||
TEST(makeQuery(15, 22).found(2));
|
||||
Buffer<Stat> stats;
|
||||
for (auto i : Range(2, 5)) {
|
||||
Stat stat = test(pow(10, i), 100);
|
||||
stats.append(stat);
|
||||
}
|
||||
|
||||
TEST(makeQuery(1, 2).isSingleData(1));
|
||||
TEST(makeQuery(25, 35).isSingleData(3));
|
||||
printf("\nChecks: ");
|
||||
for (auto stat : stats)
|
||||
printf("%e ", stat->avgChecks);
|
||||
|
||||
intervals.removeAll();
|
||||
printf("\nHits: ");
|
||||
for (auto stat : stats)
|
||||
printf("%e ", stat->avgFound);
|
||||
|
||||
intervals.insert({ 0, 3 }, 1);
|
||||
intervals.insert({ 0, 13 }, 2);
|
||||
printf("\nItems: ");
|
||||
for (auto stat : stats)
|
||||
printf("%e ", stat->numItems);
|
||||
|
||||
TEST(makeQuery(0, 1).found(2));
|
||||
}
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
TEST_DEF(IntervalTree) {
|
||||
testFunctionalitySimple();
|
||||
testFunctionalityScale();
|
||||
testEfficency();
|
||||
testFunctionalityComplex();
|
||||
}
|
||||
TEST(FunctionalityComplex) {
|
||||
IntervalTree<ualni, ualni> intervals;
|
||||
|
||||
struct QueryResult {
|
||||
ualni numFound = 0;
|
||||
ualni lastDataFound = 0;
|
||||
|
||||
[[nodiscard]] bool isSingleData(ualni aData) const { return numFound == 1 & lastDataFound == aData; }
|
||||
[[nodiscard]] bool notFound() const { return numFound == 0; }
|
||||
[[nodiscard]] bool found(ualni num) const { return numFound == num; }
|
||||
};
|
||||
|
||||
auto makeQuery = [&](ualni aStart, ualni aEnd) {
|
||||
QueryResult out;
|
||||
intervals.forEachIntersection(aStart, aEnd, [&](alni start, ualni end, ualni data) {
|
||||
out.numFound++;
|
||||
out.lastDataFound = data;
|
||||
});
|
||||
return out;
|
||||
};
|
||||
|
||||
intervals.insert({ 2, 5 }, 1);
|
||||
intervals.insert({ 12, 15 }, 2);
|
||||
intervals.insert({ 22, 25 }, 3);
|
||||
|
||||
CHECK(makeQuery(1, 6).isSingleData(1));
|
||||
CHECK(makeQuery(1, 3).isSingleData(1));
|
||||
CHECK(makeQuery(3, 6).isSingleData(1));
|
||||
|
||||
CHECK(makeQuery(0, 1).notFound());
|
||||
CHECK(makeQuery(7, 8).notFound());
|
||||
|
||||
CHECK(makeQuery(3, 4).isSingleData(1));
|
||||
|
||||
CHECK(makeQuery(13, 14).isSingleData(2));
|
||||
|
||||
CHECK(makeQuery(1, 35).found(3));
|
||||
CHECK(makeQuery(11, 35).found(2));
|
||||
|
||||
// check opened
|
||||
CHECK(makeQuery(5, 12).found(2));
|
||||
CHECK(makeQuery(15, 22).found(2));
|
||||
|
||||
CHECK(makeQuery(1, 2).isSingleData(1));
|
||||
CHECK(makeQuery(25, 35).isSingleData(3));
|
||||
|
||||
intervals.removeAll();
|
||||
|
||||
intervals.insert({ 0, 3 }, 1);
|
||||
intervals.insert({ 0, 13 }, 2);
|
||||
|
||||
CHECK(makeQuery(0, 1).found(2));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,83 +1,80 @@
|
|||
#include "Archiver.hpp"
|
||||
#include "Testing.hpp"
|
||||
#include "Tests.hpp"
|
||||
#include "List.hpp"
|
||||
|
||||
using namespace tp;
|
||||
|
||||
TEST_DEF_STATIC(SimpleReference) {
|
||||
tp::List<TestClass, tp::HeapAlloc> list = { TestClass(1), TestClass(2), TestClass(3), TestClass(4) };
|
||||
SUITE(DoubleLinkedList) {
|
||||
|
||||
list.pushBack(TestClass(5));
|
||||
list.pushFront(TestClass(0));
|
||||
TEST(SimpleReference) {
|
||||
tp::List<TestClass, tp::HeapAlloc> list = { TestClass(1), TestClass(2), TestClass(3), TestClass(4) };
|
||||
|
||||
ualni i = -1;
|
||||
for (auto iter : list) {
|
||||
i++;
|
||||
TEST_EQUAL(iter->getVal(), i);
|
||||
list.pushBack(TestClass(5));
|
||||
list.pushFront(TestClass(0));
|
||||
|
||||
ualni i = -1;
|
||||
for (auto iter : list) {
|
||||
i++;
|
||||
CHECK_EQUAL(iter->getVal(), i);
|
||||
}
|
||||
|
||||
CHECK(i == 5);
|
||||
|
||||
list.removeAll();
|
||||
}
|
||||
|
||||
TEST(i == 5);
|
||||
TEST(SimplePointer) {
|
||||
tp::List<TestClass*, tp::HeapAlloc> list = { new TestClass(1), new TestClass(2), new TestClass(3), new TestClass(4) };
|
||||
|
||||
list.removeAll();
|
||||
}
|
||||
list.pushBack(new TestClass(5));
|
||||
list.pushFront(new TestClass(0));
|
||||
|
||||
TEST_DEF_STATIC(SimplePointer) {
|
||||
tp::List<TestClass*, tp::HeapAlloc> list = { new TestClass(1), new TestClass(2), new TestClass(3), new TestClass(4) };
|
||||
ualni i = -1;
|
||||
for (auto iter : list) {
|
||||
i++;
|
||||
CHECK_EQUAL(iter->getVal(), i);
|
||||
}
|
||||
|
||||
list.pushBack(new TestClass(5));
|
||||
list.pushFront(new TestClass(0));
|
||||
CHECK(i == 5);
|
||||
|
||||
ualni i = -1;
|
||||
for (auto iter : list) {
|
||||
i++;
|
||||
TEST_EQUAL(iter->getVal(), i);
|
||||
for (auto iter : list) {
|
||||
delete iter.data();
|
||||
}
|
||||
|
||||
list.removeAll();
|
||||
}
|
||||
|
||||
TEST(i == 5);
|
||||
TEST(Copy) {
|
||||
tp::List<TestClass, tp::HeapAlloc> list = { TestClass(1), TestClass(2), TestClass(3), TestClass(4) };
|
||||
tp::List<TestClass, tp::HeapAlloc> list2 = list;
|
||||
|
||||
for (auto iter : list) {
|
||||
delete iter.data();
|
||||
CHECK(list == list2);
|
||||
|
||||
list.removeAll();
|
||||
list2.removeAll();
|
||||
}
|
||||
|
||||
list.removeAll();
|
||||
}
|
||||
TEST(Serialization) {
|
||||
tp::List<TestClass, tp::HeapAlloc> list = { TestClass(1), TestClass(2), TestClass(3), TestClass(4) };
|
||||
|
||||
TEST_DEF_STATIC(Copy) {
|
||||
tp::List<TestClass, tp::HeapAlloc> list = { TestClass(1), TestClass(2), TestClass(3), TestClass(4) };
|
||||
tp::List<TestClass, tp::HeapAlloc> list2 = list;
|
||||
ArchiverExample<1024, false> write;
|
||||
ArchiverExample<1024, true> read;
|
||||
|
||||
TEST_EQUAL(list, list2);
|
||||
write % list;
|
||||
|
||||
list.removeAll();
|
||||
list2.removeAll();
|
||||
}
|
||||
list.removeAll();
|
||||
|
||||
TEST_DEF_STATIC(Serialization) {
|
||||
tp::List<TestClass, tp::HeapAlloc> list = { TestClass(1), TestClass(2), TestClass(3), TestClass(4) };
|
||||
memCopy(read.mBuff, write.mBuff, sizeof(write.mBuff));
|
||||
|
||||
ArchiverExample<1024, false> write;
|
||||
ArchiverExample<1024, true> read;
|
||||
read % list;
|
||||
|
||||
write % list;
|
||||
ualni i = 0;
|
||||
for (auto iter : list) {
|
||||
i++;
|
||||
CHECK(iter->getVal() == i);
|
||||
}
|
||||
CHECK(i == 4);
|
||||
|
||||
list.removeAll();
|
||||
|
||||
memCopy(read.mBuff, write.mBuff, sizeof(write.mBuff));
|
||||
|
||||
read % list;
|
||||
|
||||
ualni i = 0;
|
||||
for (auto iter : list) {
|
||||
i++;
|
||||
TEST_EQUAL(iter->getVal(), i);
|
||||
list.removeAll();
|
||||
}
|
||||
TEST(i == 4);
|
||||
|
||||
list.removeAll();
|
||||
}
|
||||
|
||||
TEST_DEF(List) {
|
||||
testSimplePointer();
|
||||
testSimpleReference();
|
||||
testSerialization();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,129 +1,124 @@
|
|||
#include "Archiver.hpp"
|
||||
#include "Map.hpp"
|
||||
#include "Testing.hpp"
|
||||
#include "Tests.hpp"
|
||||
|
||||
using namespace tp;
|
||||
|
||||
TEST_DEF_STATIC(SimpleReference) {
|
||||
tp::Map<tp::ualni, TestClass, tp::HeapAlloc> map;
|
||||
SUITE(HashTable) {
|
||||
TEST(SimpleReference) {
|
||||
tp::Map<tp::ualni, TestClass, tp::HeapAlloc> map;
|
||||
|
||||
for (auto i : Range(1000, 100000)) {
|
||||
map.put(i, TestClass(i));
|
||||
for (auto i : Range(1000, 100000)) {
|
||||
map.put(i, TestClass(i));
|
||||
}
|
||||
|
||||
for (auto i : Range(1000, 100000)) {
|
||||
CHECK(map.presents(i));
|
||||
CHECK_EQUAL((tp::ualni) map.get(i).getVal(), (tp::ualni) i);
|
||||
}
|
||||
|
||||
for (auto i : Range(1000, 100000)) {
|
||||
map.put(i, TestClass(i));
|
||||
}
|
||||
|
||||
for (auto i : Range(1000, 2000)) {
|
||||
CHECK(map.presents(i));
|
||||
map.remove(i);
|
||||
CHECK(!map.presents(i));
|
||||
}
|
||||
|
||||
for (auto i : Range(2000, 100000)) {
|
||||
CHECK(map.presents(i));
|
||||
CHECK_EQUAL((tp::ualni) map.get(i).getVal(), (tp::ualni) i);
|
||||
}
|
||||
|
||||
for (auto i : map) {
|
||||
i->val.setVal(3);
|
||||
}
|
||||
|
||||
map.removeAll();
|
||||
}
|
||||
|
||||
for (auto i : Range(1000, 100000)) {
|
||||
TEST(map.presents(i));
|
||||
TEST_EQUAL(map.get(i).getVal(), i);
|
||||
TEST(SimplePointer) {
|
||||
tp::Map<tp::ualni, TestClass*, tp::HeapAlloc> map;
|
||||
|
||||
for (auto i : Range(1000)) {
|
||||
map.put(i, new TestClass(i));
|
||||
}
|
||||
|
||||
for (auto i : Range(1000)) {
|
||||
CHECK(map.presents(i));
|
||||
CHECK_EQUAL((tp::ualni) map.get(i)->getVal(), (tp::ualni) i);
|
||||
}
|
||||
|
||||
for (auto i : Range(1000)) {
|
||||
auto del = map.get(i);
|
||||
map.put(i, new TestClass(i));
|
||||
delete del;
|
||||
}
|
||||
|
||||
for (auto i : Range(900, 1000)) {
|
||||
CHECK(map.presents(i));
|
||||
delete map.get(i);
|
||||
map.remove(i);
|
||||
CHECK(!map.presents(i));
|
||||
}
|
||||
|
||||
for (auto i : Range(900)) {
|
||||
CHECK(map.presents(i));
|
||||
CHECK_EQUAL((tp::ualni) map.get(i)->getVal(), (tp::ualni) i);
|
||||
}
|
||||
|
||||
for (auto i : map) {
|
||||
i->val->setVal(3);
|
||||
delete i->val;
|
||||
}
|
||||
|
||||
map.removeAll();
|
||||
}
|
||||
|
||||
for (auto i : Range(1000, 100000)) {
|
||||
map.put(i, TestClass(i));
|
||||
TEST(Copy) {
|
||||
tp::Map<tp::ualni, TestClass, tp::HeapAlloc> map;
|
||||
|
||||
for (auto i : Range(10)) {
|
||||
map.put(i, TestClass(i));
|
||||
}
|
||||
|
||||
tp::Map<tp::ualni, TestClass, tp::HeapAlloc> map2 = map;
|
||||
|
||||
CHECK(map == map2);
|
||||
|
||||
map.removeAll();
|
||||
map2.removeAll();
|
||||
}
|
||||
|
||||
for (auto i : Range(1000, 2000)) {
|
||||
TEST(map.presents(i));
|
||||
map.remove(i);
|
||||
TEST(!map.presents(i));
|
||||
TEST(SaveLoad) {
|
||||
tp::Map<tp::ualni, TestClass, tp::HeapAlloc> map;
|
||||
|
||||
for (auto i : Range(10)) {
|
||||
map.put(i, TestClass(i));
|
||||
}
|
||||
|
||||
ArchiverExample<1024, false> write;
|
||||
ArchiverExample<1024, true> read;
|
||||
|
||||
write % map;
|
||||
|
||||
map.removeAll();
|
||||
|
||||
CHECK(map.size() == 0);
|
||||
|
||||
memCopy(read.mBuff, write.mBuff, sizeof(write.mBuff));
|
||||
|
||||
read % map;
|
||||
|
||||
CHECK(map.size() == 10);
|
||||
|
||||
for (auto i : Range(10)) {
|
||||
CHECK(map.presents(i));
|
||||
CHECK_EQUAL(map.get(i).getVal(), i);
|
||||
}
|
||||
|
||||
map.removeAll();
|
||||
}
|
||||
|
||||
for (auto i : Range(2000, 100000)) {
|
||||
TEST(map.presents(i));
|
||||
TEST_EQUAL(map.get(i).getVal(), i);
|
||||
}
|
||||
|
||||
for (auto i : map) {
|
||||
i->val.setVal(3);
|
||||
}
|
||||
|
||||
map.removeAll();
|
||||
}
|
||||
|
||||
TEST_DEF_STATIC(SimplePointer) {
|
||||
tp::Map<tp::ualni, TestClass*, tp::HeapAlloc> map;
|
||||
|
||||
for (auto i : Range(1000)) {
|
||||
map.put(i, new TestClass(i));
|
||||
}
|
||||
|
||||
for (auto i : Range(1000)) {
|
||||
TEST(map.presents(i));
|
||||
TEST_EQUAL(map.get(i)->getVal(), i);
|
||||
}
|
||||
|
||||
for (auto i : Range(1000)) {
|
||||
auto del = map.get(i);
|
||||
map.put(i, new TestClass(i));
|
||||
delete del;
|
||||
}
|
||||
|
||||
for (auto i : Range(900, 1000)) {
|
||||
TEST(map.presents(i));
|
||||
delete map.get(i);
|
||||
map.remove(i);
|
||||
TEST(!map.presents(i));
|
||||
}
|
||||
|
||||
for (auto i : Range(900)) {
|
||||
TEST(map.presents(i));
|
||||
TEST_EQUAL(map.get(i)->getVal(), i);
|
||||
}
|
||||
|
||||
for (auto i : map) {
|
||||
i->val->setVal(3);
|
||||
delete i->val;
|
||||
}
|
||||
|
||||
map.removeAll();
|
||||
}
|
||||
|
||||
TEST_DEF_STATIC(Copy) {
|
||||
tp::Map<tp::ualni, TestClass, tp::HeapAlloc> map;
|
||||
|
||||
for (auto i : Range(10)) {
|
||||
map.put(i, TestClass(i));
|
||||
}
|
||||
|
||||
tp::Map<tp::ualni, TestClass, tp::HeapAlloc> map2 = map;
|
||||
|
||||
TEST_EQUAL(map, map2);
|
||||
|
||||
map.removeAll();
|
||||
map2.removeAll();
|
||||
}
|
||||
|
||||
TEST_DEF_STATIC(SaveLoad) {
|
||||
tp::Map<tp::ualni, TestClass, tp::HeapAlloc> map;
|
||||
|
||||
for (auto i : Range(10)) {
|
||||
map.put(i, TestClass(i));
|
||||
}
|
||||
|
||||
ArchiverExample<1024, false> write;
|
||||
ArchiverExample<1024, true> read;
|
||||
|
||||
write % map;
|
||||
|
||||
map.removeAll();
|
||||
|
||||
TEST(map.size() == 0);
|
||||
|
||||
memCopy(read.mBuff, write.mBuff, sizeof(write.mBuff));
|
||||
|
||||
read % map;
|
||||
|
||||
TEST(map.size() == 10);
|
||||
|
||||
for (auto i : Range(10)) {
|
||||
TEST(map.presents(i));
|
||||
TEST_EQUAL(map.get(i).getVal(), i);
|
||||
}
|
||||
|
||||
map.removeAll();
|
||||
}
|
||||
|
||||
TEST_DEF(Map) {
|
||||
testSimplePointer();
|
||||
testSimpleReference();
|
||||
testSaveLoad();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +1,19 @@
|
|||
|
||||
#include "Tests.hpp"
|
||||
#include "Testing.hpp"
|
||||
|
||||
static bool init(const tp::ModuleManifest* self) {
|
||||
tp::gTesting.setRootName(self->getName());
|
||||
return true;
|
||||
}
|
||||
#include "UnitTest++/UnitTest++.h"
|
||||
|
||||
int main() {
|
||||
|
||||
tp::ModuleManifest* deps[] = { &tp::gModuleUtils, &tp::gModuleAllocators, nullptr };
|
||||
tp::ModuleManifest testModule("ContainersTest", init, nullptr, deps);
|
||||
tp::ModuleManifest testModule("ContainersTest", nullptr, nullptr, deps);
|
||||
|
||||
if (!testModule.initialize()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
testIntervalTree();
|
||||
testList();
|
||||
testMap();
|
||||
testAvl();
|
||||
testBuffer();
|
||||
testBuffer2d();
|
||||
bool res = UnitTest::RunAllTests();
|
||||
|
||||
testModule.deinitialize();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "UnitTest++/UnitTest++.h"
|
||||
|
||||
#include "Allocators.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
|
|
@ -27,11 +29,4 @@ public:
|
|||
|
||||
[[nodiscard]] tp::ualni getVal() const { return val1; }
|
||||
void setVal(tp::ualni val) { val1 = val; }
|
||||
};
|
||||
|
||||
void testList();
|
||||
void testMap();
|
||||
void testAvl();
|
||||
void testBuffer();
|
||||
void testBuffer2d();
|
||||
void testIntervalTree();
|
||||
};
|
||||
|
|
@ -1,127 +1,124 @@
|
|||
#include "Testing.hpp"
|
||||
#include "Tests.hpp"
|
||||
#include "Tree.hpp"
|
||||
|
||||
using namespace tp;
|
||||
|
||||
TEST_DEF_STATIC(Simple) {
|
||||
AvlTree<AvlNumericKey<alni>, TestClass, tp::HeapAlloc> tree;
|
||||
SUITE(AvlTree) {
|
||||
TEST(Simple) {
|
||||
AvlTree<AvlNumericKey<alni>, TestClass, tp::HeapAlloc> tree;
|
||||
|
||||
TEST(tree.size() == 0);
|
||||
TEST(tree.head() == nullptr);
|
||||
CHECK(tree.size() == 0);
|
||||
CHECK(tree.head() == nullptr);
|
||||
|
||||
tree.insert(6, TestClass(6));
|
||||
TEST(tree.isValid());
|
||||
TEST(tree.size() == 1);
|
||||
TEST(tree.head()->data == TestClass(6));
|
||||
tree.insert(6, TestClass(6));
|
||||
CHECK(tree.isValid());
|
||||
CHECK(tree.size() == 1);
|
||||
CHECK(tree.head()->data == TestClass(6));
|
||||
|
||||
tree.remove(6);
|
||||
TEST(tree.isValid());
|
||||
TEST(tree.size() == 0);
|
||||
TEST(tree.head() == nullptr);
|
||||
}
|
||||
|
||||
TEST_DEF_STATIC(Persistance) {
|
||||
AvlTree<AvlNumericKey<alni>, TestClass, tp::HeapAlloc> tree;
|
||||
|
||||
const auto size = 1000;
|
||||
|
||||
struct Item {
|
||||
Item() :
|
||||
data(0) {}
|
||||
bool presents = false;
|
||||
TestClass data;
|
||||
};
|
||||
|
||||
Item buff[size];
|
||||
|
||||
for (auto i : Range(size)) {
|
||||
buff[i].data.setVal(i);
|
||||
tree.remove(6);
|
||||
CHECK(tree.isValid());
|
||||
CHECK(tree.size() == 0);
|
||||
CHECK(tree.head() == nullptr);
|
||||
}
|
||||
|
||||
// random load
|
||||
ualni loadSize = 0;
|
||||
while (loadSize < size / 2) {
|
||||
auto idx = ualni(randomFloat() * (size - 1));
|
||||
DEBUG_ASSERT(idx < size)
|
||||
if (!buff[idx].presents) {
|
||||
tree.insert((alni) buff[idx].data.getVal(), buff[idx].data);
|
||||
loadSize++;
|
||||
buff[idx].presents = true;
|
||||
TEST(Persistance) {
|
||||
AvlTree<AvlNumericKey<alni>, TestClass, tp::HeapAlloc> tree;
|
||||
|
||||
TEST(tree.isValid());
|
||||
TEST(tree.size() == loadSize);
|
||||
const auto size = 1000;
|
||||
|
||||
struct Item {
|
||||
Item() :
|
||||
data(0) {}
|
||||
bool presents = false;
|
||||
TestClass data;
|
||||
};
|
||||
|
||||
Item buff[size];
|
||||
|
||||
for (auto i : Range(size)) {
|
||||
buff[i].data.setVal(i);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& item : buff) {
|
||||
if (item.presents) continue;
|
||||
tree.insert((alni) item.data.getVal(), item.data);
|
||||
loadSize++;
|
||||
item.presents = true;
|
||||
// random load
|
||||
ualni loadSize = 0;
|
||||
while (loadSize < size / 2) {
|
||||
auto idx = ualni(randomFloat() * (size - 1));
|
||||
DEBUG_ASSERT(idx < size)
|
||||
if (!buff[idx].presents) {
|
||||
tree.insert((alni) buff[idx].data.getVal(), buff[idx].data);
|
||||
loadSize++;
|
||||
buff[idx].presents = true;
|
||||
|
||||
TEST(tree.isValid());
|
||||
TEST(tree.size() == loadSize);
|
||||
}
|
||||
|
||||
TEST(tree.size() == size);
|
||||
TEST(tree.maxNode(tree.head())->data.getVal() == size - 1);
|
||||
TEST(tree.minNode(tree.head())->data.getVal() == 0);
|
||||
|
||||
// find
|
||||
for (auto item : buff) {
|
||||
auto node = tree.find((alni) item.data.getVal());
|
||||
TEST(node);
|
||||
if (!node) continue;
|
||||
TEST(node->data.getVal() == item.data.getVal());
|
||||
}
|
||||
|
||||
TEST(!tree.find(size + 1));
|
||||
TEST(!tree.find(-1));
|
||||
|
||||
// random unload
|
||||
ualni unloadSize = 0;
|
||||
while (unloadSize < size / 2) {
|
||||
auto idx = ualni(randomFloat() * (size - 1));
|
||||
if (buff[idx].presents) {
|
||||
|
||||
tree.remove((alni) buff[idx].data.getVal());
|
||||
|
||||
unloadSize++;
|
||||
buff[idx].presents = false;
|
||||
|
||||
// find
|
||||
for (auto item : buff) {
|
||||
if (!item.presents) continue;
|
||||
auto node = tree.find((alni) item.data.getVal());
|
||||
TEST(node);
|
||||
if (!node) continue;
|
||||
TEST(node->data.getVal() == item.data.getVal());
|
||||
CHECK(tree.isValid());
|
||||
CHECK(tree.size() == loadSize);
|
||||
}
|
||||
|
||||
TEST(tree.isValid());
|
||||
TEST(tree.size() == size - unloadSize);
|
||||
}
|
||||
|
||||
for (auto& item : buff) {
|
||||
if (item.presents) continue;
|
||||
tree.insert((alni) item.data.getVal(), item.data);
|
||||
loadSize++;
|
||||
item.presents = true;
|
||||
|
||||
CHECK(tree.isValid());
|
||||
CHECK(tree.size() == loadSize);
|
||||
}
|
||||
|
||||
CHECK(tree.size() == size);
|
||||
CHECK(tree.maxNode(tree.head())->data.getVal() == size - 1);
|
||||
CHECK(tree.minNode(tree.head())->data.getVal() == 0);
|
||||
|
||||
// find
|
||||
for (auto item : buff) {
|
||||
auto node = tree.find((alni) item.data.getVal());
|
||||
CHECK(node);
|
||||
if (!node) continue;
|
||||
CHECK(node->data.getVal() == item.data.getVal());
|
||||
}
|
||||
|
||||
CHECK(!tree.find(size + 1));
|
||||
CHECK(!tree.find(-1));
|
||||
|
||||
// random unload
|
||||
ualni unloadSize = 0;
|
||||
while (unloadSize < size / 2) {
|
||||
auto idx = ualni(randomFloat() * (size - 1));
|
||||
if (buff[idx].presents) {
|
||||
|
||||
tree.remove((alni) buff[idx].data.getVal());
|
||||
|
||||
unloadSize++;
|
||||
buff[idx].presents = false;
|
||||
|
||||
// find
|
||||
for (auto item : buff) {
|
||||
if (!item.presents) continue;
|
||||
auto node = tree.find((alni) item.data.getVal());
|
||||
CHECK(node);
|
||||
if (!node) continue;
|
||||
CHECK(node->data.getVal() == item.data.getVal());
|
||||
}
|
||||
|
||||
CHECK(tree.isValid());
|
||||
CHECK(tree.size() == size - unloadSize);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& item : buff) {
|
||||
if (item.presents) {
|
||||
tree.remove((alni) item.data.getVal());
|
||||
unloadSize++;
|
||||
item.presents = false;
|
||||
|
||||
CHECK(tree.isValid());
|
||||
CHECK(tree.size() == size - unloadSize);
|
||||
}
|
||||
}
|
||||
|
||||
CHECK(tree.size() == 0);
|
||||
CHECK(tree.head() == nullptr);
|
||||
CHECK(tree.maxNode(tree.head()) == nullptr);
|
||||
CHECK(tree.minNode(tree.head()) == nullptr);
|
||||
}
|
||||
|
||||
for (auto& item : buff) {
|
||||
if (item.presents) {
|
||||
tree.remove((alni) item.data.getVal());
|
||||
unloadSize++;
|
||||
item.presents = false;
|
||||
|
||||
TEST(tree.isValid());
|
||||
TEST(tree.size() == size - unloadSize);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(tree.size() == 0);
|
||||
TEST(tree.head() == nullptr);
|
||||
TEST(tree.maxNode(tree.head()) == nullptr);
|
||||
TEST(tree.minNode(tree.head()) == nullptr);
|
||||
}
|
||||
|
||||
TEST_DEF(Avl) {
|
||||
testSimple();
|
||||
testPersistance();
|
||||
}
|
||||
}
|
||||
|
|
@ -28,5 +28,5 @@ add_executable(${PROJECT_NAME}Tests ${TEST_SOURCES})
|
|||
|
||||
target_include_directories(${PROJECT_NAME}Tests PUBLIC ./applications/)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} Utils)
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} UnitTest++)
|
||||
add_test(NAME ${PROJECT_NAME}Tests COMMAND ${PROJECT_NAME}Tests)
|
||||
|
|
|
|||
|
|
@ -1,39 +1,40 @@
|
|||
|
||||
#include "NewPlacement.hpp"
|
||||
#include "UnitTest++/UnitTest++.h"
|
||||
|
||||
#include "FCNN.hpp"
|
||||
#include "Testing.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
using namespace tp;
|
||||
|
||||
void test() {
|
||||
Buffer<halni> layers = { 100, 70, 50, 30, 20 };
|
||||
Buffer<halnf> input(layers.first());
|
||||
Buffer<halnf> outputExpected(layers.last());
|
||||
Buffer<halnf> output(layers.last());
|
||||
SUITE(FCNN) {
|
||||
TEST(Basic) {
|
||||
Buffer<halni> layers = { 100, 70, 50, 30, 20 };
|
||||
Buffer<halnf> input(layers.first());
|
||||
Buffer<halnf> outputExpected(layers.last());
|
||||
Buffer<halnf> output(layers.last());
|
||||
|
||||
for (auto inputVal : Range(layers.first())) {
|
||||
input[inputVal] = (halnf) randomFloat() * 100;
|
||||
}
|
||||
for (auto inputVal : Range(layers.first())) {
|
||||
input[inputVal] = (halnf) randomFloat() * 100;
|
||||
}
|
||||
|
||||
for (auto outIdx : Range(layers.last())) {
|
||||
outputExpected[outIdx] = (halnf) randomFloat();
|
||||
}
|
||||
for (auto outIdx : Range(layers.last())) {
|
||||
outputExpected[outIdx] = (halnf) randomFloat();
|
||||
}
|
||||
|
||||
FCNN nn(layers);
|
||||
halnf steppingValue = 100;
|
||||
FCNN nn(layers);
|
||||
halnf steppingValue = 100;
|
||||
|
||||
for (auto i : Range(50)) {
|
||||
for (auto i : Range(50)) {
|
||||
|
||||
nn.evaluate(input, output);
|
||||
nn.evaluate(input, output);
|
||||
|
||||
nn.calcGrad(outputExpected);
|
||||
nn.applyGrad(steppingValue);
|
||||
nn.calcGrad(outputExpected);
|
||||
nn.applyGrad(steppingValue);
|
||||
|
||||
printf("Loss %f \n", nn.calcCost(outputExpected));
|
||||
printf("Loss %f \n", nn.calcCost(outputExpected));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -45,9 +46,9 @@ int main() {
|
|||
return 1;
|
||||
}
|
||||
|
||||
test();
|
||||
bool res = UnitTest::RunAllTests();
|
||||
|
||||
testModule.deinitialize();
|
||||
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
2
Externals/asio
vendored
2
Externals/asio
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit d6b95c0188e0359a8cdbdb6571f0cbacf11a538c
|
||||
Subproject commit 3a7078a2002c670d98ee3044802a5086f3e49634
|
||||
|
|
@ -18,9 +18,3 @@ add_executable(${PROJECT_NAME}Example ./examples/Example.cpp)
|
|||
target_link_libraries(${PROJECT_NAME}Example ${PROJECT_NAME} ${BINDINGS_LIBS})
|
||||
target_include_directories(${PROJECT_NAME}Example PRIVATE ${BINDINGS_INCLUDE})
|
||||
|
||||
### -------------------------- Tests -------------------------- ###
|
||||
enable_testing()
|
||||
file(GLOB TEST_SOURCES "./tests/*.cpp")
|
||||
add_executable(${PROJECT_NAME}Tests ${TEST_SOURCES})
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} Utils)
|
||||
add_test(NAME ${PROJECT_NAME}Tests COMMAND ${PROJECT_NAME}Tests)
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
int main() {}
|
||||
|
|
@ -16,7 +16,5 @@ target_link_libraries(${PROJECT_NAME} PUBLIC Strings)
|
|||
enable_testing()
|
||||
file(GLOB TEST_SOURCES "./tests/*.cpp")
|
||||
add_executable(${PROJECT_NAME}Tests ${TEST_SOURCES})
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} Utils)
|
||||
add_test(NAME ${PROJECT_NAME}Tests COMMAND ${PROJECT_NAME}Tests)
|
||||
|
||||
install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}/lib)
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} UnitTest++)
|
||||
add_test(NAME ${PROJECT_NAME}Tests COMMAND ${PROJECT_NAME}Tests)
|
||||
|
|
@ -11,5 +11,5 @@ target_link_libraries(${PROJECT_NAME} PUBLIC Allocators)
|
|||
enable_testing()
|
||||
file(GLOB TEST_SOURCES "./tests/*.cpp")
|
||||
add_executable(${PROJECT_NAME}Tests ${TEST_SOURCES})
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} Utils)
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} UnitTest++)
|
||||
add_test(NAME ${PROJECT_NAME}Tests COMMAND ${PROJECT_NAME}Tests)
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
|
||||
#include "ComplexNumbers.hpp"
|
||||
#include "Testing.hpp"
|
||||
|
||||
using namespace tp;
|
||||
|
||||
TEST_DEF(ComplexNumber) {
|
||||
TEST((ComplexCart{ 3, 4 }.mod() == 5));
|
||||
TEST((abs(ComplexCart{ 1, 1 }.arg() - 0.7853981633974483) < 0.001));
|
||||
TEST((ComplexCart{ 3, 4 }.norm2() == 25));
|
||||
|
||||
{
|
||||
ComplexCart cn{ 3, 4 };
|
||||
ComplexCart expected{ 0.12, -0.16 };
|
||||
auto val = cn.reciprocal();
|
||||
TEST((val == expected));
|
||||
}
|
||||
|
||||
{
|
||||
ComplexCart cn{ 3, 4 };
|
||||
ComplexCart expected{ 3, -4 };
|
||||
TEST((cn.conjugate() == expected));
|
||||
}
|
||||
|
||||
{
|
||||
ComplexCart cn1{ 3, 4 };
|
||||
ComplexCart cn2{ 1, 2 };
|
||||
ComplexCart expected{ -5, 10 };
|
||||
TEST((cn1 * cn2 == expected));
|
||||
}
|
||||
|
||||
{
|
||||
ComplexRad c1{ 5, 7 };
|
||||
ComplexRad c2{ 10, 3 };
|
||||
ComplexCart tmp1 = (c1 * c2).cart();
|
||||
ComplexCart tmp2 = (c1.cart() * c2.cart());
|
||||
TEST((tmp1 - tmp2).mod() < 0.001);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_DEF(Math) { testComplexNumber(); }
|
||||
|
|
@ -1,23 +1,59 @@
|
|||
|
||||
#include "MathCommon.hpp"
|
||||
#include "Testing.hpp"
|
||||
#include "ComplexNumbers.hpp"
|
||||
|
||||
static bool init(const tp::ModuleManifest* self) {
|
||||
tp::gTesting.setRootName(self->getName());
|
||||
return true;
|
||||
#include "UnitTest++/UnitTest++.h"
|
||||
|
||||
using namespace tp;
|
||||
|
||||
SUITE(Math) {
|
||||
TEST(ComplexNumber) {
|
||||
CHECK((ComplexCart{ 3, 4 }.mod() == 5));
|
||||
CHECK((abs(ComplexCart{ 1, 1 }.arg() - 0.7853981633974483) < 0.001));
|
||||
CHECK((ComplexCart{ 3, 4 }.norm2() == 25));
|
||||
|
||||
{
|
||||
ComplexCart cn{ 3, 4 };
|
||||
ComplexCart expected{ 0.12, -0.16 };
|
||||
auto val = cn.reciprocal();
|
||||
CHECK((val == expected));
|
||||
}
|
||||
|
||||
{
|
||||
ComplexCart cn{ 3, 4 };
|
||||
ComplexCart expected{ 3, -4 };
|
||||
CHECK((cn.conjugate() == expected));
|
||||
}
|
||||
|
||||
{
|
||||
ComplexCart cn1{ 3, 4 };
|
||||
ComplexCart cn2{ 1, 2 };
|
||||
ComplexCart expected{ -5, 10 };
|
||||
CHECK((cn1 * cn2 == expected));
|
||||
}
|
||||
|
||||
{
|
||||
ComplexRad c1{ 5, 7 };
|
||||
ComplexRad c2{ 10, 3 };
|
||||
ComplexCart tmp1 = (c1 * c2).cart();
|
||||
ComplexCart tmp2 = (c1.cart() * c2.cart());
|
||||
CHECK((tmp1 - tmp2).mod() < 0.001);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(NO_TESTS) { CHECK(false); }
|
||||
}
|
||||
|
||||
void testMath();
|
||||
|
||||
int main() {
|
||||
tp::ModuleManifest* deps[] = { &tp::gModuleMath, &tp::gModuleUtils, nullptr };
|
||||
tp::ModuleManifest testModule("MathTest", init, nullptr, deps);
|
||||
tp::ModuleManifest testModule("MathTest", nullptr, nullptr, deps);
|
||||
|
||||
if (!testModule.initialize()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
testMath();
|
||||
bool res = UnitTest::RunAllTests();
|
||||
|
||||
testModule.deinitialize();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,5 +9,5 @@ target_include_directories(${PROJECT_NAME} PUBLIC ./public/)
|
|||
enable_testing()
|
||||
file(GLOB SOURCES_TEST "./tests/*.cpp")
|
||||
add_executable(${PROJECT_NAME}Tests ${SOURCES_TEST})
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME})
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} UnitTest++)
|
||||
add_test(NAME ${PROJECT_NAME}Tests COMMAND ${PROJECT_NAME}Tests)
|
||||
|
|
@ -1,12 +1,14 @@
|
|||
|
||||
#include "Module.hpp"
|
||||
|
||||
#include "UnitTest++/UnitTest++.h"
|
||||
|
||||
#include "Archiver.hpp"
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace tp;
|
||||
|
||||
bool sFailed = false;
|
||||
|
||||
struct Undef {
|
||||
char character1 = 'a';
|
||||
bool boolean = true;
|
||||
|
|
@ -202,10 +204,7 @@ void test() {
|
|||
|
||||
read % res;
|
||||
|
||||
if (val != res) {
|
||||
printf("Test %s Failed\n", typeid(tType).name());
|
||||
sFailed = true;
|
||||
}
|
||||
CHECK(!(val != res));
|
||||
}
|
||||
|
||||
template <typename T, typename A, typename = void>
|
||||
|
|
@ -214,17 +213,32 @@ struct HasArchive : FalseType {};
|
|||
template <typename T, typename A>
|
||||
struct HasArchive<T, A, VoidType<decltype(DeclareValue<T>()().archive(DeclareValue<A&>()()))>> : TrueType {};
|
||||
|
||||
void testArchiver() {
|
||||
printf("has archive method - %i\n", HasArchive<SimpleArchive, ArchiverExample<10, false>>::value);
|
||||
printf("has archive method - %i\n", ArchiverExample<10, false>::HasFunc::Archive<SimpleArchive>::value);
|
||||
printf("has archive method - %i\n", ArchiverExample<10, false>::HasFunc::Archive<Simple>::value);
|
||||
|
||||
test<SimpleArchive>();
|
||||
test<Simple>();
|
||||
test<Set<Simple>>();
|
||||
test<ComplexCart<Simple>>();
|
||||
SUITE(BaseModule) {
|
||||
TEST(Basic) {
|
||||
tp::ModuleManifest* ModuleDependencies[] = { &tp::gModuleBase, nullptr };
|
||||
tp::ModuleManifest TestModule("Test", nullptr, nullptr, ModuleDependencies);
|
||||
|
||||
if (sFailed) {
|
||||
exit(1);
|
||||
REQUIRE CHECK(TestModule.initialize());
|
||||
|
||||
REQUIRE CHECK(tp::gEnvironment.mWidth == tp::Environment::ArchWidth::X64);
|
||||
|
||||
CHECK(tp::max(2, 1) == 2);
|
||||
CHECK(tp::max(-1, 0) == 0);
|
||||
CHECK(tp::max(0, -1) == 0);
|
||||
CHECK(tp::min(0, -1) == -1);
|
||||
|
||||
printf("has archive method - %i\n", HasArchive<SimpleArchive, ArchiverExample<10, false>>::value);
|
||||
printf("has archive method - %i\n", ArchiverExample<10, false>::HasFunc::Archive<SimpleArchive>::value);
|
||||
printf("has archive method - %i\n", ArchiverExample<10, false>::HasFunc::Archive<Simple>::value);
|
||||
|
||||
test<SimpleArchive>();
|
||||
test<Simple>();
|
||||
test<Set<Simple>>();
|
||||
test<ComplexCart<Simple>>();
|
||||
|
||||
TestModule.deinitialize();
|
||||
}
|
||||
}
|
||||
|
||||
int main() { return UnitTest::RunAllTests(); }
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
|
||||
#include "Module.hpp"
|
||||
|
||||
void testArchiver();
|
||||
|
||||
int main() {
|
||||
tp::ModuleManifest* ModuleDependencies[] = { &tp::gModuleBase, nullptr };
|
||||
tp::ModuleManifest TestModule("Test", nullptr, nullptr, ModuleDependencies);
|
||||
|
||||
if (!TestModule.initialize()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
ASSERT(tp::gEnvironment.mWidth == tp::Environment::ArchWidth::X64);
|
||||
|
||||
ASSERT(tp::max(2, 1) == 2)
|
||||
ASSERT(tp::max(-1, 0) == 0)
|
||||
ASSERT(tp::max(0, -1) == 0)
|
||||
ASSERT(tp::min(0, -1) == -1)
|
||||
|
||||
testArchiver();
|
||||
|
||||
TestModule.deinitialize();
|
||||
}
|
||||
|
|
@ -24,5 +24,5 @@ add_executable(${PROJECT_NAME}Tests ${TEST_SOURCES})
|
|||
|
||||
target_include_directories(${PROJECT_NAME}Tests PUBLIC ./applications/)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} Utils ImageIO)
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} UnitTest++ ImageIO)
|
||||
add_test(NAME ${PROJECT_NAME}Tests COMMAND ${PROJECT_NAME}Tests)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// #include "NewPlacement.hpp"
|
||||
|
||||
#include "RayTracer.hpp"
|
||||
#include "Testing.hpp"
|
||||
#include "UnitTest++/UnitTest++.h"
|
||||
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include "stb_image_write.h"
|
||||
|
|
@ -47,63 +47,67 @@ bool compareCols(const RGBA& l, const RGBA& r) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void testRT() {
|
||||
using namespace tp;
|
||||
SUITE(RayTracer) {
|
||||
TEST(Basic) {
|
||||
using namespace tp;
|
||||
|
||||
Scene scene;
|
||||
Scene scene;
|
||||
|
||||
scene.mCamera.lookAtPoint({ 0, 0, 0 }, { 2, 2, 2 }, { 0, 0, 1 });
|
||||
scene.mCamera.setFOV(3.14 / 4);
|
||||
scene.mCamera.lookAtPoint({ 0, 0, 0 }, { 2, 2, 2 }, { 0, 0, 1 });
|
||||
scene.mCamera.setFOV(3.14 / 4);
|
||||
|
||||
scene.mLights.append({ { 0, 0, 1.1f }, 1.f, 0.3f });
|
||||
scene.mLights.append({ { 0, 0, 1.1f }, 1.f, 0.3f });
|
||||
|
||||
scene.mObjects.append(Object());
|
||||
auto& object = scene.mObjects.last();
|
||||
scene.mObjects.append(Object());
|
||||
auto& object = scene.mObjects.last();
|
||||
|
||||
object.mTopology.Points = {
|
||||
{ 1.000000, 0.000000, 0.000000 },
|
||||
{ 0.000000, 1.000000, 0.000000 },
|
||||
{ 0.000000, 0.000000, 1.000000 },
|
||||
};
|
||||
object.mTopology.Points = {
|
||||
{ 1.000000, 0.000000, 0.000000 },
|
||||
{ 0.000000, 1.000000, 0.000000 },
|
||||
{ 0.000000, 0.000000, 1.000000 },
|
||||
};
|
||||
|
||||
object.mTopology.Normals = {
|
||||
{ 1.000000, 1.000000, 1.000000 },
|
||||
{ 1.000000, 1.000000, 1.000000 },
|
||||
{ 1.000000, 1.000000, 1.000000 },
|
||||
};
|
||||
object.mTopology.Normals = {
|
||||
{ 1.000000, 1.000000, 1.000000 },
|
||||
{ 1.000000, 1.000000, 1.000000 },
|
||||
{ 1.000000, 1.000000, 1.000000 },
|
||||
};
|
||||
|
||||
object.mTopology.Indexes = {
|
||||
{ 0, 1, 2 },
|
||||
};
|
||||
object.mTopology.Indexes = {
|
||||
{ 0, 1, 2 },
|
||||
};
|
||||
|
||||
object.mCache.Source = &object.mTopology;
|
||||
object.mCache.updateCache();
|
||||
object.mCache.Source = &object.mTopology;
|
||||
object.mCache.updateCache();
|
||||
|
||||
RayTracer::RenderSettings settings = {
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
{ 10, 10 },
|
||||
};
|
||||
RayTracer::RenderSettings settings = {
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
{ 10, 10 },
|
||||
};
|
||||
|
||||
RayTracer::OutputBuffers output;
|
||||
// output.reserve(RayTracer::RenderBuffer::Index2D(settings.size.x, settings.size.y));
|
||||
RayTracer::OutputBuffers output;
|
||||
// output.reserve(RayTracer::RenderBuffer::Index2D(settings.size.x, settings.size.y));
|
||||
|
||||
RayTracer rt;
|
||||
rt.render(scene, output, settings);
|
||||
RayTracer rt;
|
||||
rt.render(scene, output, settings);
|
||||
|
||||
TEST(compareCols(output.color.get({ 6, 4 }), RGBA{ 0.560100f, 0.560100f, 0.560100f, 1.000000f }));
|
||||
TEST(compareCols(output.color.get({ 6, 5 }), RGBA{ 0.353739f, 0.353739f, 0.353739f, 1.000000f }));
|
||||
TEST(compareCols(output.color.get({ 6, 6 }), RGBA{ 0.242577f, 0.242577f, 0.242577f, 1.000000f }));
|
||||
TEST(compareCols(output.color.get({ 6, 7 }), RGBA{ 0.176313f, 0.176313f, 0.176313f, 1.000000f }));
|
||||
TEST(compareCols(output.color.get({ 6, 8 }), RGBA{ 0.000000f, 0.000000f, 0.000000f, 0.000000f }));
|
||||
CHECK(compareCols(output.color.get({ 6, 4 }), RGBA{ 0.560100f, 0.560100f, 0.560100f, 1.000000f }));
|
||||
CHECK(compareCols(output.color.get({ 6, 5 }), RGBA{ 0.353739f, 0.353739f, 0.353739f, 1.000000f }));
|
||||
CHECK(compareCols(output.color.get({ 6, 6 }), RGBA{ 0.242577f, 0.242577f, 0.242577f, 1.000000f }));
|
||||
CHECK(compareCols(output.color.get({ 6, 7 }), RGBA{ 0.176313f, 0.176313f, 0.176313f, 1.000000f }));
|
||||
CHECK(compareCols(output.color.get({ 6, 8 }), RGBA{ 0.000000f, 0.000000f, 0.000000f, 0.000000f }));
|
||||
|
||||
if (0) {
|
||||
writeImage(output.color);
|
||||
for (auto i = 0; i < output.color.size().x; i++) {
|
||||
for (auto j = 0; j < output.color.size().y; j++) {
|
||||
auto tmp = output.color.get({ i, j });
|
||||
printf("TEST(compareCols(output.get({%i, %i}), RGBA{ %ff, %ff, %ff, %ff }));\n", i, j, tmp.r, tmp.g, tmp.b, tmp.a);
|
||||
if (0) {
|
||||
writeImage(output.color);
|
||||
for (auto i = 0; i < output.color.size().x; i++) {
|
||||
for (auto j = 0; j < output.color.size().y; j++) {
|
||||
auto tmp = output.color.get({ i, j });
|
||||
printf(
|
||||
"TEST(compareCols(output.get({%i, %i}), RGBA{ %ff, %ff, %ff, %ff }));\n", i, j, tmp.r, tmp.g, tmp.b, tmp.a
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -117,7 +121,9 @@ int main(int argc, char* argv[]) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
testRT();
|
||||
bool res = UnitTest::RunAllTests();
|
||||
|
||||
TestModule.deinitialize();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,5 +11,5 @@ target_link_libraries(${PROJECT_NAME} PUBLIC Allocators Containers)
|
|||
enable_testing()
|
||||
file(GLOB TEST_SOURCES "./tests/*.cpp")
|
||||
add_executable(${PROJECT_NAME}Tests ${TEST_SOURCES})
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} Utils)
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} UnitTest++)
|
||||
add_test(NAME ${PROJECT_NAME}Tests COMMAND ${PROJECT_NAME}Tests)
|
||||
244
Strings/tests/Test.cpp
Normal file
244
Strings/tests/Test.cpp
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
|
||||
#include "UnitTest++/UnitTest++.h"
|
||||
|
||||
#include "Strings.hpp"
|
||||
#include "StringLogic.hpp"
|
||||
|
||||
SUITE(Strings) {
|
||||
using namespace tp;
|
||||
|
||||
typedef StringLogic<char> Logic;
|
||||
|
||||
struct TestStruct {
|
||||
String str = "test data";
|
||||
};
|
||||
|
||||
TEST(CoreLogic) {
|
||||
String str;
|
||||
CHECK(str.getIsConstFlag());
|
||||
CHECK(str.getReferenceCount() == 2);
|
||||
|
||||
String str2;
|
||||
CHECK(str.getIsConstFlag());
|
||||
CHECK(str.getReferenceCount() == 3);
|
||||
|
||||
auto tmp = new TestStruct();
|
||||
CHECK(tmp->str.getIsConstFlag());
|
||||
CHECK(tmp->str.getReferenceCount() == 1);
|
||||
|
||||
str = tmp->str;
|
||||
|
||||
CHECK(str.getIsConstFlag());
|
||||
CHECK(str.getReferenceCount() == 2);
|
||||
|
||||
delete tmp;
|
||||
|
||||
CHECK(str.getIsConstFlag());
|
||||
CHECK(str.getReferenceCount() == 1);
|
||||
}
|
||||
|
||||
TEST(Addition) {
|
||||
String str1 = "abc";
|
||||
String str2 = "def";
|
||||
{ str1 + str2; }
|
||||
{
|
||||
CHECK(str1 + str2 == "abcdef");
|
||||
CHECK(str1 + "aaaccc" == "abcaaaccc");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(isNewLineChar) {
|
||||
CHECK(Logic::isNewLineChar('\n'));
|
||||
CHECK(Logic::isNewLineChar('\r'));
|
||||
CHECK(!Logic::isNewLineChar('a'));
|
||||
}
|
||||
|
||||
TEST(isEndChar) {
|
||||
CHECK(Logic::isEndChar('\0'));
|
||||
CHECK(!Logic::isEndChar('a'));
|
||||
}
|
||||
|
||||
TEST(calcLength) {
|
||||
const char* str1 = "Hello";
|
||||
const char* str2 = "Wor\nld2";
|
||||
CHECK(Logic::calcLength(str1) == 5);
|
||||
CHECK(Logic::calcLength(str2) == 7);
|
||||
}
|
||||
|
||||
TEST(insertLogic_emptyTarget) {
|
||||
char inserted[40] = { "" };
|
||||
const char* cur = "Hello";
|
||||
const char* tar = "";
|
||||
const char* result = "Hello";
|
||||
Logic::insertLogic(inserted, 40, cur, tar, 5, 0);
|
||||
CHECK(Logic::isEqualLogic(inserted, result));
|
||||
}
|
||||
|
||||
TEST(insertLogic_emptyCurrent) {
|
||||
char inserted[40] = { "" };
|
||||
const char* cur = "";
|
||||
const char* tar = "World";
|
||||
const char* result = "World";
|
||||
Logic::insertLogic(inserted, 40, cur, tar, 0, 5);
|
||||
CHECK(Logic::isEqualLogic(inserted, result));
|
||||
}
|
||||
|
||||
TEST(insertLogic_curLengthLessThanPos) {
|
||||
char inserted[40] = { "" };
|
||||
const char* cur = "Hello";
|
||||
const char* tar = "World";
|
||||
const char* result = "HelloWorld";
|
||||
Logic::insertLogic(inserted, 40, cur, tar, 5, 5);
|
||||
CHECK(Logic::isEqualLogic(inserted, result));
|
||||
}
|
||||
|
||||
TEST(removeLogic_emptyCurrent) {
|
||||
char removed[40] = { "" };
|
||||
const char* cur = "";
|
||||
const char* result = "";
|
||||
Logic::removeLogic(removed, 40, cur, 0, 0);
|
||||
CHECK(Logic::isEqualLogic(removed, result));
|
||||
}
|
||||
|
||||
TEST(removeLogic_removeUntilEnd) {
|
||||
char removed[40] = { "" };
|
||||
const char* cur = "HelloWorld";
|
||||
const char* result = "World";
|
||||
Logic::removeLogic(removed, 40, cur, 0, 5);
|
||||
CHECK(Logic::isEqualLogic(removed, result));
|
||||
}
|
||||
|
||||
TEST(removeLogic_removeMiddleCharacters) {
|
||||
char removed[40] = { "" };
|
||||
const char* cur = "HelloWorld";
|
||||
const char* result = "Helrld";
|
||||
Logic::removeLogic(removed, 40, cur, 3, 7);
|
||||
CHECK(Logic::isEqualLogic(removed, result));
|
||||
}
|
||||
|
||||
TEST(insertLogicGood) {
|
||||
char inserted[40] = { "" };
|
||||
const char* cur = "Hello";
|
||||
const char* tar = "World";
|
||||
const char* result = "HelloWorld";
|
||||
Logic::insertLogic(inserted, 40, cur, tar, 5, 5);
|
||||
CHECK(Logic::isEqualLogic(inserted, result));
|
||||
}
|
||||
|
||||
TEST(removeLogicGood) {
|
||||
char removed[40] = { "" };
|
||||
const char* cur = "HelloWorld";
|
||||
const char* result = "Helld";
|
||||
Logic::removeLogic(removed, 40, cur, 3, 8);
|
||||
CHECK(Logic::isEqualLogic(removed, result));
|
||||
}
|
||||
|
||||
TEST(convertStringToValue_alni) {
|
||||
const char* str1 = "123";
|
||||
const char* str2 = "456xyz";
|
||||
const char* str3 = "789";
|
||||
alni output;
|
||||
CHECK(Logic::convertStringToValue(str1, output) && output == 123);
|
||||
CHECK(!Logic::convertStringToValue(str2, output));
|
||||
CHECK(Logic::convertStringToValue(str3, output) && output == 789);
|
||||
}
|
||||
|
||||
TEST(convertStringToValue_alnf) {
|
||||
const char* str1 = "12.34";
|
||||
const char* str2 = "56.78xyz";
|
||||
const char* str3 = "90.12";
|
||||
alnf output;
|
||||
CHECK(Logic::convertStringToValue(str1, output) && output == 12.34);
|
||||
CHECK(!Logic::convertStringToValue(str2, output));
|
||||
CHECK(Logic::convertStringToValue(str3, output) && output == 90.12);
|
||||
}
|
||||
|
||||
TEST(convertStringToValue_bool) {
|
||||
const char* str1 = "true";
|
||||
const char* str2 = "false";
|
||||
const char* str3 = "1";
|
||||
const char* str4 = "0";
|
||||
bool output;
|
||||
CHECK(Logic::convertStringToValue(str1, output) && output == true);
|
||||
CHECK(Logic::convertStringToValue(str2, output) && output == false);
|
||||
CHECK(Logic::convertStringToValue(str3, output) && output == true);
|
||||
CHECK(Logic::convertStringToValue(str4, output) && output == false);
|
||||
}
|
||||
|
||||
TEST(convertValueToString_alni) {
|
||||
alni input1 = 123;
|
||||
alni input2 = -456;
|
||||
char output[10];
|
||||
CHECK(Logic::convertValueToString(input1, output, 10));
|
||||
CHECK(Logic::isEqualLogic(output, "123"));
|
||||
|
||||
CHECK(Logic::convertValueToString(input2, output, 10));
|
||||
CHECK(Logic::isEqualLogic(output, "-456"));
|
||||
}
|
||||
|
||||
TEST(convertValueToString_alnf) {
|
||||
alnf input1 = 12.34;
|
||||
alnf input2 = -56.78;
|
||||
char output[10];
|
||||
|
||||
CHECK(Logic::convertValueToString(input1, output, 10));
|
||||
CHECK(Logic::isEqualLogic(output, "12.340000"));
|
||||
|
||||
CHECK(Logic::convertValueToString(input2, output, 10));
|
||||
CHECK(Logic::isEqualLogic(output, "-56.78000"));
|
||||
}
|
||||
|
||||
TEST(convertValueToString_bool) {
|
||||
bool input1 = true;
|
||||
bool input2 = false;
|
||||
char output[10];
|
||||
|
||||
CHECK(Logic::convertValueToString(input1, output, 10));
|
||||
CHECK(Logic::isEqualLogic(output, "true"));
|
||||
|
||||
CHECK(Logic::convertValueToString(input2, output, 10));
|
||||
CHECK(Logic::isEqualLogic(output, "false"));
|
||||
}
|
||||
|
||||
TEST(isEqualLogic) {
|
||||
const char* str1 = "Hello";
|
||||
const char* str2 = "Hello";
|
||||
const char* str3 = "World";
|
||||
const char* str4 = "Hello2";
|
||||
CHECK(Logic::isEqualLogic(str1, str2));
|
||||
CHECK(!Logic::isEqualLogic(str1, str4));
|
||||
CHECK(!Logic::isEqualLogic(str1, str3));
|
||||
}
|
||||
|
||||
TEST(calcLineOffsets) {
|
||||
const char* str = "\n\nHello\nWorld\n\n ";
|
||||
Buffer<Logic::Index> offsets;
|
||||
Logic::calcLineOffsets(str, Logic::calcLength(str), offsets);
|
||||
|
||||
CHECK(offsets.size() == 7);
|
||||
|
||||
CHECK(offsets[0] == 0);
|
||||
CHECK(offsets[1] == 1);
|
||||
CHECK(offsets[2] == 2);
|
||||
CHECK(offsets[3] == 8);
|
||||
CHECK(offsets[4] == 14);
|
||||
CHECK(offsets[5] == 15);
|
||||
CHECK(offsets[6] == 16);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
tp::ModuleManifest* deps[] = { &tp::gModuleStrings, &tp::gModuleUtils, nullptr };
|
||||
tp::ModuleManifest testModule("StringsTest", nullptr, nullptr, deps);
|
||||
|
||||
if (!testModule.initialize()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto res = UnitTest::RunAllTests();
|
||||
|
||||
testModule.deinitialize();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
|
||||
#include "Tests.hpp"
|
||||
|
||||
#include "Strings.hpp"
|
||||
|
||||
void testStringLogic();
|
||||
void testStrings();
|
||||
void testLogging();
|
||||
|
||||
int main() {
|
||||
|
||||
tp::ModuleManifest* deps[] = { &tp::gModuleStrings, &tp::gModuleUtils, nullptr };
|
||||
tp::ModuleManifest testModule("StringsTest", nullptr, nullptr, deps);
|
||||
|
||||
if (!testModule.initialize()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
testStringLogic();
|
||||
testStrings();
|
||||
testLogging();
|
||||
|
||||
testModule.deinitialize();
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "Allocators.hpp"
|
||||
#include "Testing.hpp"
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
|
||||
#include "Logging.hpp"
|
||||
#include "Tests.hpp"
|
||||
|
||||
using namespace tp;
|
||||
|
||||
TEST_DEF(Logging) {}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
#include "Strings.hpp"
|
||||
#include "Tests.hpp"
|
||||
|
||||
using namespace tp;
|
||||
|
||||
struct TestStruct {
|
||||
String str = "test data";
|
||||
};
|
||||
|
||||
TEST_DEF_STATIC(Addition) {
|
||||
String str1 = "abc";
|
||||
String str2 = "def";
|
||||
{ str1 + str2; }
|
||||
{
|
||||
TEST(str1 + str2 == "abcdef");
|
||||
TEST(str1 + "aaaccc" == "abcaaaccc");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_DEF_STATIC(Simple) {
|
||||
String str;
|
||||
TEST(str.getIsConstFlag());
|
||||
TEST(str.getReferenceCount() == 2);
|
||||
|
||||
String str2;
|
||||
TEST(str.getIsConstFlag());
|
||||
TEST(str.getReferenceCount() == 3);
|
||||
|
||||
auto tmp = new TestStruct();
|
||||
TEST(tmp->str.getIsConstFlag());
|
||||
TEST(tmp->str.getReferenceCount() == 1);
|
||||
|
||||
str = tmp->str;
|
||||
|
||||
TEST(str.getIsConstFlag());
|
||||
TEST(str.getReferenceCount() == 2);
|
||||
|
||||
delete tmp;
|
||||
|
||||
TEST(str.getIsConstFlag());
|
||||
TEST(str.getReferenceCount() == 1);
|
||||
}
|
||||
|
||||
TEST_DEF(Strings) {
|
||||
testSimple();
|
||||
testAddition();
|
||||
}
|
||||
|
|
@ -1,243 +0,0 @@
|
|||
#include "StringLogic.hpp"
|
||||
#include "Tests.hpp"
|
||||
|
||||
using namespace tp;
|
||||
|
||||
typedef StringLogic<char> Logic;
|
||||
|
||||
TEST_DEF(isNewLineChar) {
|
||||
// Test isNewLineChar function
|
||||
TEST(Logic::isNewLineChar('\n'));
|
||||
TEST(Logic::isNewLineChar('\r'));
|
||||
TEST(!Logic::isNewLineChar('a'));
|
||||
}
|
||||
|
||||
TEST_DEF(isEndChar) {
|
||||
// Test isEndChar function
|
||||
TEST(Logic::isEndChar('\0'));
|
||||
TEST(!Logic::isEndChar('a'));
|
||||
}
|
||||
|
||||
TEST_DEF(calcLength) {
|
||||
// Test calcLength function
|
||||
const char* str1 = "Hello";
|
||||
const char* str2 = "Wor\nld2";
|
||||
TEST(Logic::calcLength(str1) == 5);
|
||||
TEST(Logic::calcLength(str2) == 7);
|
||||
}
|
||||
|
||||
// ------------------------------- Inserting / Removing ----------------------------------------- //
|
||||
|
||||
TEST_DEF(insertLogic_emptyTarget) {
|
||||
// Test insertLogic function with an empty target string
|
||||
char inserted[40] = { "" };
|
||||
const char* cur = "Hello";
|
||||
const char* tar = "";
|
||||
const char* result = "Hello";
|
||||
Logic::insertLogic(inserted, 40, cur, tar, 5, 0);
|
||||
TEST(Logic::isEqualLogic(inserted, result));
|
||||
}
|
||||
|
||||
TEST_DEF(insertLogic_emptyCurrent) {
|
||||
// Test insertLogic function with an empty current string
|
||||
char inserted[40] = { "" };
|
||||
const char* cur = "";
|
||||
const char* tar = "World";
|
||||
const char* result = "World";
|
||||
Logic::insertLogic(inserted, 40, cur, tar, 0, 5);
|
||||
TEST(Logic::isEqualLogic(inserted, result));
|
||||
}
|
||||
|
||||
TEST_DEF(insertLogic_curLengthLessThanPos) {
|
||||
// Test insertLogic function with current length less than the insert position
|
||||
char inserted[40] = { "" };
|
||||
const char* cur = "Hello";
|
||||
const char* tar = "World";
|
||||
const char* result = "HelloWorld";
|
||||
Logic::insertLogic(inserted, 40, cur, tar, 10, 5);
|
||||
TEST(Logic::isEqualLogic(inserted, result));
|
||||
}
|
||||
|
||||
TEST_DEF(removeLogic_emptyCurrent) {
|
||||
// Test removeLogic function with an empty current string
|
||||
char removed[40] = { "" };
|
||||
const char* cur = "";
|
||||
const char* result = "";
|
||||
Logic::removeLogic(removed, 40, cur, 0, 0);
|
||||
TEST(Logic::isEqualLogic(removed, result));
|
||||
}
|
||||
|
||||
TEST_DEF(removeLogic_removeUntilEnd) {
|
||||
// Test removeLogic function by removing until the end of the current string
|
||||
char removed[40] = { "" };
|
||||
const char* cur = "HelloWorld";
|
||||
const char* result = "World";
|
||||
Logic::removeLogic(removed, 40, cur, 0, 5);
|
||||
TEST(Logic::isEqualLogic(removed, result));
|
||||
}
|
||||
|
||||
TEST_DEF(removeLogic_removeMiddleCharacters) {
|
||||
// Test removeLogic function by removing characters in the middle of the current string
|
||||
char removed[40] = { "" };
|
||||
const char* cur = "HelloWorld";
|
||||
const char* result = "Helrld";
|
||||
Logic::removeLogic(removed, 40, cur, 3, 7);
|
||||
TEST(Logic::isEqualLogic(removed, result));
|
||||
}
|
||||
|
||||
TEST_DEF(insertLogicGood) {
|
||||
// Test insertLogic function
|
||||
char inserted[40] = { "" };
|
||||
const char* cur = "Hello";
|
||||
const char* tar = "World";
|
||||
const char* result = "HelloWorld";
|
||||
Logic::insertLogic(inserted, 40, cur, tar, 5, 5);
|
||||
TEST(Logic::isEqualLogic(inserted, result));
|
||||
}
|
||||
|
||||
TEST_DEF(removeLogicGood) {
|
||||
// Test removeLogic function
|
||||
char removed[40] = { "" };
|
||||
const char* cur = "HelloWorld";
|
||||
const char* result = "Helo";
|
||||
Logic::removeLogic(removed, 40, cur, 3, 8);
|
||||
TEST(Logic::isEqualLogic(removed, result));
|
||||
}
|
||||
|
||||
TEST_DEF(insertLogic) {
|
||||
// Test insertLogic function
|
||||
testinsertLogicGood();
|
||||
testinsertLogic_emptyTarget();
|
||||
testinsertLogic_emptyCurrent();
|
||||
// testinsertLogic_curLengthLessThanPos();
|
||||
}
|
||||
|
||||
TEST_DEF(removeLogic) {
|
||||
// Test removeLogic function
|
||||
// testremoveLogicGood();
|
||||
testremoveLogic_emptyCurrent();
|
||||
testremoveLogic_removeUntilEnd();
|
||||
testremoveLogic_removeMiddleCharacters();
|
||||
}
|
||||
|
||||
// -------------------------------- Conversions --------------------------------------- //
|
||||
|
||||
TEST_DEF(convertStringToValue_alni) {
|
||||
const char* str1 = "123";
|
||||
const char* str2 = "456xyz";
|
||||
const char* str3 = "789";
|
||||
alni output;
|
||||
TEST(Logic::convertStringToValue(str1, output) && output == 123);
|
||||
TEST(!Logic::convertStringToValue(str2, output));
|
||||
TEST(Logic::convertStringToValue(str3, output) && output == 789);
|
||||
}
|
||||
|
||||
TEST_DEF(convertStringToValue_alnf) {
|
||||
const char* str1 = "12.34";
|
||||
const char* str2 = "56.78xyz";
|
||||
const char* str3 = "90.12";
|
||||
alnf output;
|
||||
TEST(Logic::convertStringToValue(str1, output) && output == 12.34);
|
||||
TEST(!Logic::convertStringToValue(str2, output));
|
||||
TEST(Logic::convertStringToValue(str3, output) && output == 90.12);
|
||||
}
|
||||
|
||||
TEST_DEF(convertStringToValue_bool) {
|
||||
const char* str1 = "true";
|
||||
const char* str2 = "false";
|
||||
const char* str3 = "1";
|
||||
const char* str4 = "0";
|
||||
bool output;
|
||||
TEST(Logic::convertStringToValue(str1, output) && output == true);
|
||||
TEST(Logic::convertStringToValue(str2, output) && output == false);
|
||||
TEST(Logic::convertStringToValue(str3, output) && output == true);
|
||||
TEST(Logic::convertStringToValue(str4, output) && output == false);
|
||||
}
|
||||
|
||||
TEST_DEF(convertValueToString_alni) {
|
||||
alni input1 = 123;
|
||||
alni input2 = -456;
|
||||
char output[10];
|
||||
TEST(Logic::convertValueToString(input1, output, 10));
|
||||
TEST(Logic::isEqualLogic(output, "123"));
|
||||
|
||||
TEST(Logic::convertValueToString(input2, output, 10));
|
||||
TEST(Logic::isEqualLogic(output, "-456"));
|
||||
}
|
||||
|
||||
TEST_DEF(convertValueToString_alnf) {
|
||||
alnf input1 = 12.34;
|
||||
alnf input2 = -56.78;
|
||||
char output[10];
|
||||
|
||||
TEST(Logic::convertValueToString(input1, output, 10));
|
||||
TEST(Logic::isEqualLogic(output, "12.340000"));
|
||||
|
||||
TEST(Logic::convertValueToString(input2, output, 10));
|
||||
TEST(Logic::isEqualLogic(output, "-56.78000"));
|
||||
}
|
||||
|
||||
TEST_DEF(convertValueToString_bool) {
|
||||
bool input1 = true;
|
||||
bool input2 = false;
|
||||
char output[10];
|
||||
|
||||
TEST(Logic::convertValueToString(input1, output, 10));
|
||||
TEST(Logic::isEqualLogic(output, "true"));
|
||||
|
||||
TEST(Logic::convertValueToString(input2, output, 10));
|
||||
TEST(Logic::isEqualLogic(output, "false"));
|
||||
}
|
||||
|
||||
TEST_DEF(Conversions) {
|
||||
testconvertValueToString_bool();
|
||||
testconvertValueToString_alnf();
|
||||
testconvertValueToString_alni();
|
||||
testconvertStringToValue_bool();
|
||||
testconvertStringToValue_alnf();
|
||||
testconvertStringToValue_alni();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------ //
|
||||
|
||||
TEST_DEF(isEqualLogic) {
|
||||
// Test isEqualLogic function
|
||||
const char* str1 = "Hello";
|
||||
const char* str2 = "Hello";
|
||||
const char* str3 = "World";
|
||||
const char* str4 = "Hello2";
|
||||
TEST(Logic::isEqualLogic(str1, str2));
|
||||
TEST(!Logic::isEqualLogic(str1, str4));
|
||||
TEST(!Logic::isEqualLogic(str1, str3));
|
||||
}
|
||||
|
||||
TEST_DEF(calcLineOffsets) {
|
||||
// Test calcLineOffsets function
|
||||
const char* str = "\n\nHello\nWorld\n\n ";
|
||||
Buffer<Logic::Index> offsets;
|
||||
Logic::calcLineOffsets(str, Logic::calcLength(str), offsets);
|
||||
|
||||
TEST(offsets.size() == 7);
|
||||
|
||||
TEST(offsets[0] == 0);
|
||||
TEST(offsets[1] == 1);
|
||||
TEST(offsets[2] == 2);
|
||||
TEST(offsets[3] == 8);
|
||||
TEST(offsets[4] == 14);
|
||||
TEST(offsets[5] == 15);
|
||||
TEST(offsets[6] == 16);
|
||||
}
|
||||
|
||||
TEST_DEF(StringLogic) {
|
||||
testisNewLineChar();
|
||||
testisEndChar();
|
||||
testcalcLength();
|
||||
|
||||
testisEqualLogic();
|
||||
testcalcLineOffsets();
|
||||
|
||||
testinsertLogic();
|
||||
testremoveLogic();
|
||||
|
||||
testConversions();
|
||||
}
|
||||
8
TODO
8
TODO
|
|
@ -1,5 +1,13 @@
|
|||
|
||||
ALL:
|
||||
|
||||
Remove utils module
|
||||
add scoped api for module manifest
|
||||
Add windows old beautifull window to graphics
|
||||
add windows callstack support
|
||||
remove loki library
|
||||
remove archiver and add boost serialization
|
||||
|
||||
Check Warnings
|
||||
Gradually introduce STL into the project (replace own classes or add seamless interface and conversions into STL)
|
||||
Make all modules stable with tests
|
||||
|
|
|
|||
|
|
@ -12,5 +12,5 @@ target_link_libraries(${PROJECT_NAME} PUBLIC Containers)
|
|||
enable_testing()
|
||||
file(GLOB TEST_SOURCES "./tests/*.cpp")
|
||||
add_executable(${PROJECT_NAME}Tests ${TEST_SOURCES})
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME})
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} UnitTest++)
|
||||
add_test(NAME ${PROJECT_NAME}Tests COMMAND ${PROJECT_NAME}Tests)
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
|
||||
#include "Testing.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
using namespace tp;
|
||||
|
||||
Testing tp::gTesting;
|
||||
|
||||
void Testing::startTest(const char* name) {
|
||||
auto newNode = new (malloc(sizeof(TestingNode))) TestingNode{ {}, {}, name, mCurrent };
|
||||
mCurrent->mSubTests.pushBack(newNode);
|
||||
mCurrent = mCurrent->mSubTests.last()->data;
|
||||
}
|
||||
|
||||
void Testing::endTest() {
|
||||
if (mCurrent->mParent) {
|
||||
mCurrent = mCurrent->mParent;
|
||||
}
|
||||
}
|
||||
|
||||
void Testing::addFailedCheck(const FailedCheck& info) {
|
||||
auto lastRecord = &mCurrent->mFailedChecks.last()->data;
|
||||
if (lastRecord && lastRecord->failedCheck.file == info.file && lastRecord->failedCheck.line == info.line) {
|
||||
lastRecord->times++;
|
||||
return;
|
||||
}
|
||||
mCurrent->mFailedChecks.pushBack({ info, 1 });
|
||||
}
|
||||
|
||||
void Testing::reportState() {
|
||||
mRootTest.updateState();
|
||||
|
||||
printf("\n");
|
||||
mRootTest.report();
|
||||
}
|
||||
|
||||
bool Testing::hasFailed() {
|
||||
mRootTest.updateState();
|
||||
return mRootTest.mHasFailed;
|
||||
}
|
||||
|
||||
void Testing::setRootName(const char* name) { mRootTest.mName = name; }
|
||||
|
||||
void Testing::TestingNode::updateState() {
|
||||
for (auto child : mSubTests) {
|
||||
child->updateState();
|
||||
mHasFailed = child->mHasFailed;
|
||||
if (mHasFailed) return;
|
||||
}
|
||||
mHasFailed = mFailedChecks.length();
|
||||
}
|
||||
|
||||
void Testing::TestingNode::report(const char* path) const {
|
||||
if (!mHasFailed) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto newPath = path ? std::string(path) + "/" + mName : std::string(mName);
|
||||
|
||||
for (auto check : mFailedChecks) {
|
||||
auto failedCheck = &check.data().failedCheck;
|
||||
auto times = check.data().times;
|
||||
printf("%s Failed - (%s) %s:%llu x%i\n", newPath.c_str(), failedCheck->expression, failedCheck->file, failedCheck->line, (halni) times);
|
||||
}
|
||||
|
||||
for (const auto& child : mSubTests) {
|
||||
child->report(newPath.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
Testing::TestingNode::~TestingNode() {
|
||||
for (const auto& child : mSubTests) {
|
||||
child.data()->~TestingNode();
|
||||
free(child.data());
|
||||
}
|
||||
}
|
||||
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
#include "ContainersCommon.hpp"
|
||||
|
||||
#include "Testing.hpp"
|
||||
|
||||
#include <ctime>
|
||||
#include <random>
|
||||
|
||||
|
|
@ -19,10 +17,6 @@ static bool initialize(const tp::ModuleManifest*) {
|
|||
|
||||
static void deinitialize(const tp::ModuleManifest*) {
|
||||
deinitializeCallStackCapture();
|
||||
tp::gTesting.reportState();
|
||||
if (tp::gTesting.hasFailed()) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
namespace tp {
|
||||
|
|
|
|||
|
|
@ -1,71 +0,0 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "List.hpp"
|
||||
|
||||
namespace tp {
|
||||
class Testing {
|
||||
public:
|
||||
struct FailedCheck {
|
||||
const char* expression = nullptr;
|
||||
const char* file = nullptr;
|
||||
ualni line = 0;
|
||||
};
|
||||
|
||||
Testing() = default;
|
||||
void startTest(const char* name);
|
||||
void endTest();
|
||||
void addFailedCheck(const FailedCheck& info);
|
||||
void reportState();
|
||||
void setRootName(const char* name);
|
||||
[[nodiscard]] bool hasFailed();
|
||||
|
||||
private:
|
||||
struct TestingNode {
|
||||
struct FailedCheckRecord {
|
||||
FailedCheck failedCheck;
|
||||
ualni times;
|
||||
};
|
||||
List<FailedCheckRecord> mFailedChecks;
|
||||
List<TestingNode*> mSubTests;
|
||||
const char* mName = "Unnamed";
|
||||
TestingNode* mParent = nullptr;
|
||||
bool mHasFailed = false;
|
||||
|
||||
void report(const char* path = nullptr) const;
|
||||
void updateState();
|
||||
~TestingNode();
|
||||
};
|
||||
|
||||
TestingNode mRootTest;
|
||||
TestingNode* mCurrent = &mRootTest;
|
||||
};
|
||||
|
||||
extern Testing gTesting;
|
||||
}
|
||||
|
||||
#define TEST_DEF(Name) \
|
||||
static void Name##FunctorBody(); \
|
||||
void test##Name() { \
|
||||
tp::gTesting.startTest(#Name); \
|
||||
Name##FunctorBody(); \
|
||||
tp::gTesting.endTest(); \
|
||||
} \
|
||||
void Name##FunctorBody()
|
||||
|
||||
#define TEST_DEF_STATIC(Name) \
|
||||
static void Name##FunctorBody(); \
|
||||
static void test##Name() { \
|
||||
tp::gTesting.startTest(#Name); \
|
||||
Name##FunctorBody(); \
|
||||
tp::gTesting.endTest(); \
|
||||
} \
|
||||
void Name##FunctorBody()
|
||||
|
||||
#define TEST(expr) \
|
||||
if (!(expr)) tp::gTesting.addFailedCheck({ #expr, __FILE__, __LINE__ })
|
||||
#define TEST_ASSERT(expr) \
|
||||
TEST(expr); \
|
||||
if (!(expr)) return
|
||||
#define TEST_EQUAL(l, r) \
|
||||
if (!((l) == (r))) tp::gTesting.addFailedCheck({ #l " == " #r, __FILE__, __LINE__ })
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
#include "UnitTest++/UnitTest++.h"
|
||||
|
||||
#include "Debugging.hpp"
|
||||
#include "Testing.hpp"
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
|
|
@ -42,22 +43,23 @@ void root() {
|
|||
third();
|
||||
}
|
||||
|
||||
TEST_DEF(Debugging) {
|
||||
root();
|
||||
SUITE(Utils) {
|
||||
TEST(CallStackCapture) {
|
||||
tp::ModuleManifest* deps[] = { &tp::gModuleUtils, nullptr };
|
||||
tp::ModuleManifest testModule("UtilsTest", nullptr, nullptr, deps);
|
||||
|
||||
gCSCapture->logAll();
|
||||
}
|
||||
REQUIRE CHECK(testModule.initialize());
|
||||
|
||||
int main() {
|
||||
root();
|
||||
|
||||
tp::ModuleManifest* deps[] = { &tp::gModuleUtils, nullptr };
|
||||
tp::ModuleManifest testModule("UtilsTest", nullptr, nullptr, deps);
|
||||
gCSCapture->logAll();
|
||||
|
||||
if (!testModule.initialize()) {
|
||||
return 1;
|
||||
testModule.deinitialize();
|
||||
}
|
||||
|
||||
testDebugging();
|
||||
TEST(CAllStackCaptureContent) {
|
||||
CHECK(false);
|
||||
}
|
||||
}
|
||||
|
||||
testModule.deinitialize();
|
||||
}
|
||||
int main() { return UnitTest::RunAllTests(); }
|
||||
|
|
@ -12,7 +12,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC Math Strings)
|
|||
enable_testing()
|
||||
file(GLOB TEST_SOURCES "./tests/*.cpp")
|
||||
add_executable(${PROJECT_NAME}Tests ${TEST_SOURCES})
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} Utils)
|
||||
target_link_libraries(${PROJECT_NAME}Tests ${PROJECT_NAME} UnitTest++)
|
||||
add_test(NAME ${PROJECT_NAME}Tests COMMAND ${PROJECT_NAME}Tests)
|
||||
|
||||
### -------------------------- Applications -------------------------- ###
|
||||
|
|
|
|||
|
|
@ -1 +1,6 @@
|
|||
int main() {}
|
||||
|
||||
#include "UnitTest++/UnitTest++.h"
|
||||
|
||||
TEST(NO_TESTS) { CHECK(false); }
|
||||
|
||||
int main() { return UnitTest::RunAllTests(); }
|
||||
Loading…
Add table
Add a link
Reference in a new issue