#include "tests/LinkedListTests.h" #include "data/LinkedList.h" #include "test/Test.h" struct LinkedListTester { int a; LinkedListTester(int a_) : a(a_) { } LinkedListTester(const LinkedListTester&) = delete; LinkedListTester(LinkedListTester&&) = delete; LinkedListTester& operator=(const LinkedListTester&) = delete; LinkedListTester& operator=(LinkedListTester&&) = delete; }; using IntList = Core::LinkedList; using String = Core::ArrayString<128>; template static String build(Core::Test& test, const T& t) { String s; test.checkFalse(s.append(t), "append works"); return s; } static void testWithoutCopyOrMove(Core::Test& test) { Core::LinkedList list; test.checkFalse(list.add(3) == nullptr, "without copy or move"); } static void testAdd(Core::Test& test) { IntList list; test.checkFalse(list.add(5) == nullptr, "add works 1"); auto iter = list.begin(); test.checkEqual(5, *iter, "contains added value"); test.checkEqual(1, list.getLength(), "sizes is increased by add"); } static void testMultipleAdd(Core::Test& test) { IntList list; test.checkFalse(list.add(4) == nullptr, "add works 2"); test.checkFalse(list.add(3) == nullptr, "add works 3"); test.checkFalse(list.add(2) == nullptr, "add works 4"); auto iter = list.begin(); test.checkEqual(4, *iter, "contains added value 1"); test.checkEqual(3, *(++iter), "contains added value 2"); test.checkEqual(2, *(++iter), "contains added value 3"); test.checkEqual(3, list.getLength(), "sizes is increased by add"); } static void testClear(Core::Test& test) { IntList list; test.checkFalse(list.add(5) == nullptr, "add works 6"); test.checkFalse(list.add(4) == nullptr, "add works 7"); list.clear(); test.checkEqual(0, list.getLength(), "length is 0 after clear"); test.checkFalse(list.begin() != list.end(), "iterator is at end after clear"); } static void testBigAdd(Core::Test& test) { IntList list; for(int i = 0; i < 1000000; i++) { test.checkFalse(list.add(i) == nullptr, "add works in big add"); } auto iter = list.begin(); for(int i = 0; i < list.getLength(); i++) { test.checkEqual(i, *iter, "big add"); ++iter; } test.checkEqual(1000000, list.getLength(), "big add length"); } static void testCopy(Core::Test& test) { IntList list; test.checkFalse(list.add(1) == nullptr, "add works 11"); test.checkFalse(list.add(2) == nullptr, "add works 12"); test.checkFalse(list.add(3) == nullptr, "add works 13"); IntList copy; test.checkFalse(copy.copyFrom(list), "copy works 1"); test.checkEqual(list.getLength(), copy.getLength(), "copy has same length"); auto iterA = list.begin(); auto iterB = copy.begin(); for(int i = 0; i < copy.getLength() && i < list.getLength(); i++) { test.checkEqual(*iterA, *iterB, "copy has same values"); ++iterA; ++iterB; } } static void testMove(Core::Test& test) { IntList list; test.checkFalse(list.add(1) == nullptr, "add works 14"); test.checkFalse(list.add(2) == nullptr, "add works 15"); test.checkFalse(list.add(3) == nullptr, "add works 16"); const IntList move(Core::move(list)); test.checkEqual(0, list.getLength(), "moved has length 0"); test.checkEqual(3, move.getLength(), "moved passes length"); auto iter = move.begin(); test.checkEqual(1, *iter, "moved passes values"); test.checkEqual(2, *(++iter), "moved passes values"); test.checkEqual(3, *(++iter), "moved passes values"); } static void testMoveAssignment(Core::Test& test) { IntList list; test.checkFalse(list.add(1) == nullptr, "add works 17"); test.checkFalse(list.add(2) == nullptr, "add works 18"); test.checkFalse(list.add(3) == nullptr, "add works 19"); IntList move; move = Core::move(list); test.checkEqual(0, list.getLength(), "assignment moved has length 0"); test.checkEqual(3, move.getLength(), "assignment moved passes length"); auto iter = move.begin(); test.checkEqual(1, *iter, "assignment moved passes values"); test.checkEqual(2, *(++iter), "assignment moved passes values"); test.checkEqual(3, *(++iter), "assignment moved passes values"); } static void testToString1(Core::Test& test) { IntList list; test.checkFalse(list.add(1) == nullptr, "add works 20"); test.checkFalse(list.add(243) == nullptr, "add works 21"); test.checkFalse(list.add(-423) == nullptr, "add works 22"); test.checkEqual(build(test, "[1, 243, -423]"), build(test, list), "to string 1"); } static void testToString2(Core::Test& test) { IntList list; test.checkFalse(list.add(1) == nullptr, "add works 23"); test.checkEqual(build(test, "[1]"), build(test, list), "to string 2"); } static void testToString3(Core::Test& test) { IntList list; test.checkEqual(build(test, "[]"), build(test, list), "to string 3"); } static void testRemove(Core::Test& test) { IntList list; IntList::Node* a = list.add(4); IntList::Node* b = list.add(3); IntList::Node* c = list.add(2); IntList::Node* d = list.add(1); test.checkFalse(a == nullptr, "add works 24"); test.checkFalse(b == nullptr, "add works 25"); test.checkFalse(c == nullptr, "add works 26"); test.checkFalse(c == nullptr, "add works 27"); list.remove(b); auto iter = list.begin(); test.checkEqual(4, *iter, "value after remove 1"); test.checkEqual(2, *(++iter), "value after remove 2"); test.checkEqual(1, *(++iter), "value after remove 3"); test.checkEqual(3, list.getLength(), "size after remove 1"); list.remove(a); iter = list.begin(); test.checkEqual(2, *iter, "value after remove 4"); test.checkEqual(1, *(++iter), "value after remove 5"); test.checkEqual(2, list.getLength(), "size after remove 2"); list.remove(d); iter = list.begin(); test.checkEqual(2, *iter, "value after remove 6"); test.checkEqual(1, list.getLength(), "size after remove 3"); list.remove(c); test.checkFalse(list.begin() != list.end(), "empty iterator after remove"); test.checkEqual(0, list.getLength(), "size after remove 4"); test.checkTrue(a == nullptr, "nodes are null after remove 1"); test.checkTrue(b == nullptr, "nodes are null after remove 2"); test.checkTrue(c == nullptr, "nodes are null after remove 3"); test.checkTrue(c == nullptr, "nodes are null after remove 4"); } static void testRemoveFirst(Core::Test& test) { IntList list; test.checkFalse(list.add(4) == nullptr, "add works 28"); test.checkFalse(list.add(3) == nullptr, "add works 29"); test.checkFalse(list.add(2) == nullptr, "add works 30"); test.checkFalse(list.add(1) == nullptr, "add works 31"); list.removeFirst(); auto iter = list.begin(); test.checkEqual(3, *iter, "value after remove first 1"); test.checkEqual(2, *(++iter), "value after remove first 2"); test.checkEqual(1, *(++iter), "value after remove first 3"); test.checkEqual(3, list.getLength(), "size after remove first 1"); list.removeFirst(); iter = list.begin(); test.checkEqual(2, *iter, "value after remove first 4"); test.checkEqual(1, *(++iter), "value after remove first 5"); test.checkEqual(2, list.getLength(), "size after remove first 2"); list.removeFirst(); iter = list.begin(); test.checkEqual(1, *iter, "value after remove first 6"); test.checkEqual(1, list.getLength(), "size after remove first 3"); list.removeFirst(); test.checkFalse(list.begin() != list.end(), "empty iterator after remove first"); test.checkEqual(0, list.getLength(), "size after remove first 4"); list.removeFirst(); test.checkFalse(list.begin() != list.end(), "empty iterator after remove first"); test.checkEqual(0, list.getLength(), "size after remove first 5"); } static void testRemoveLast(Core::Test& test) { IntList list; test.checkFalse(list.add(4) == nullptr, "add works 32"); test.checkFalse(list.add(3) == nullptr, "add works 33"); test.checkFalse(list.add(2) == nullptr, "add works 34"); test.checkFalse(list.add(1) == nullptr, "add works 35"); list.removeLast(); auto iter = list.begin(); test.checkEqual(4, *iter, "value after remove last 1"); test.checkEqual(3, *(++iter), "value after remove last 2"); test.checkEqual(2, *(++iter), "value after remove last 3"); test.checkEqual(3, list.getLength(), "size after remove last 1"); list.removeLast(); iter = list.begin(); test.checkEqual(4, *iter, "value after remove last 4"); test.checkEqual(3, *(++iter), "value after remove last 5"); test.checkEqual(2, list.getLength(), "size after remove last 2"); list.removeLast(); iter = list.begin(); test.checkEqual(4, *iter, "value after remove last 6"); test.checkEqual(1, list.getLength(), "size after remove last 3"); list.removeLast(); test.checkFalse(list.begin() != list.end(), "empty iterator after remove last"); test.checkEqual(0, list.getLength(), "size after remove last 4"); list.removeLast(); test.checkFalse(list.begin() != list.end(), "empty iterator after remove last"); test.checkEqual(0, list.getLength(), "size after remove 5"); } void Core::LinkedListTests::test() { Core::Test test("LinkedList"); testWithoutCopyOrMove(test); testAdd(test); testMultipleAdd(test); testClear(test); testBigAdd(test); testCopy(test); testMove(test); testMoveAssignment(test); testToString1(test); testToString2(test); testToString3(test); testRemove(test); testRemoveFirst(test); testRemoveLast(test); test.finalize(); }