Use UnitTest-Cpp library for testing

This commit is contained in:
Ilusha 2024-03-15 16:03:33 +03:00
parent ecaa2bbdfb
commit 00d8fa0886
53 changed files with 1046 additions and 1383 deletions

View file

@ -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);
}
}

View file

@ -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); }
}

View file

@ -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));
}
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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;
}

View file

@ -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();
};

View file

@ -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();
}
}