add tree tests
This commit is contained in:
parent
75722822f6
commit
1e926dc3e4
6 changed files with 161 additions and 9 deletions
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "ext/testing"]
|
||||||
|
path = ext/testing
|
||||||
|
url = https://github.com/unittest-cpp/unittest-cpp.git
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
cmake_minimum_required(VERSION 3.5)
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
project(FileSystemEmulator)
|
project(FileSystemEmulator)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
|
||||||
|
add_subdirectory(ext/testing)
|
||||||
|
target_compile_options(UnitTest++ PUBLIC -Wno-error)
|
||||||
|
|
||||||
file(GLOB SOURCES "src/*.cpp")
|
file(GLOB SOURCES "src/*.cpp")
|
||||||
file(GLOB HEADERS "inc/*.hpp")
|
file(GLOB HEADERS "inc/*.hpp")
|
||||||
|
|
||||||
|
|
@ -15,5 +17,5 @@ target_link_libraries(fse ${PROJECT_NAME})
|
||||||
|
|
||||||
file(GLOB TEST_SOURCES "./test/*.cpp")
|
file(GLOB TEST_SOURCES "./test/*.cpp")
|
||||||
add_executable(Test${PROJECT_NAME} ${TEST_SOURCES})
|
add_executable(Test${PROJECT_NAME} ${TEST_SOURCES})
|
||||||
target_link_libraries(Test${PROJECT_NAME} ${PROJECT_NAME})
|
target_link_libraries(Test${PROJECT_NAME} ${PROJECT_NAME} UnitTest++)
|
||||||
add_test(NAME Test${PROJECT_NAME} COMMAND Test${PROJECT_NAME})
|
add_test(NAME Test${PROJECT_NAME} COMMAND Test${PROJECT_NAME})
|
||||||
1
ext/testing
Submodule
1
ext/testing
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 10e50ad70c696002b1d5bbefd0ea04b3ea92a03b
|
||||||
15
inc/Tree.hpp
15
inc/Tree.hpp
|
|
@ -8,6 +8,11 @@ typedef unsigned long ui32;
|
||||||
typedef long long i64;
|
typedef long long i64;
|
||||||
typedef long i32;
|
typedef long i32;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct SelectValueOrReference {
|
||||||
|
using type = typename std::conditional<std::is_scalar<T>::value, T, const T&>::type;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename NumericType>
|
template <typename NumericType>
|
||||||
struct AvlNumericKey {
|
struct AvlNumericKey {
|
||||||
|
|
||||||
|
|
@ -21,9 +26,9 @@ struct AvlNumericKey {
|
||||||
inline bool descentLeft(AvlNumericKey in) const { return in.val < val; }
|
inline bool descentLeft(AvlNumericKey in) const { return in.val < val; }
|
||||||
inline bool exactNode(AvlNumericKey in) const { return in.val == val; }
|
inline bool exactNode(AvlNumericKey in) const { return in.val == val; }
|
||||||
|
|
||||||
inline AvlNumericKey getFindKey(/**/) const { return *this; }
|
inline const AvlNumericKey& getFindKey(/**/) const { return *this; }
|
||||||
inline AvlNumericKey keyInRightSubtree(AvlNumericKey in) const { return in; }
|
inline const AvlNumericKey& keyInRightSubtree(const AvlNumericKey& in) const { return in; }
|
||||||
inline AvlNumericKey keyInLeftSubtree(AvlNumericKey in) const { return in; }
|
inline const AvlNumericKey& keyInLeftSubtree(const AvlNumericKey& in) const { return in; }
|
||||||
|
|
||||||
template <typename NodeType>
|
template <typename NodeType>
|
||||||
inline void updateTreeCacheCallBack(const NodeType&) {}
|
inline void updateTreeCacheCallBack(const NodeType&) {}
|
||||||
|
|
@ -31,8 +36,8 @@ struct AvlNumericKey {
|
||||||
|
|
||||||
template <typename Key, typename Data>
|
template <typename Key, typename Data>
|
||||||
class AvlTree {
|
class AvlTree {
|
||||||
typedef const Key& KeyArg;
|
typedef SelectValueOrReference<Key>::type KeyArg;
|
||||||
typedef Data DataArg;
|
typedef SelectValueOrReference<Data>::type DataArg;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class Node {
|
class Node {
|
||||||
|
|
|
||||||
137
test/TestTree.cpp
Normal file
137
test/TestTree.cpp
Normal file
|
|
@ -0,0 +1,137 @@
|
||||||
|
#include "Tree.hpp"
|
||||||
|
|
||||||
|
#include "UnitTest++/UnitTest++.h"
|
||||||
|
|
||||||
|
static double randomFloat() {
|
||||||
|
return static_cast<double>(std::rand()) / static_cast<double>(RAND_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto size = 10000;
|
||||||
|
|
||||||
|
class TestClass {
|
||||||
|
ui64 val1 = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TestClass() = default;
|
||||||
|
explicit TestClass(ui64 val) : val1(val) {}
|
||||||
|
[[nodiscard]] bool operator==(const TestClass& in) const { return in.val1 == val1; }
|
||||||
|
[[nodiscard]] ui64 getVal() const { return val1; }
|
||||||
|
void setVal(ui64 val) { val1 = val; }
|
||||||
|
};
|
||||||
|
|
||||||
|
SUITE(AvlTree) {
|
||||||
|
TEST(Simple) {
|
||||||
|
AvlTree<AvlNumericKey<i64>, TestClass> tree;
|
||||||
|
|
||||||
|
CHECK(tree.size() == 0);
|
||||||
|
CHECK(tree.getRoot() == nullptr);
|
||||||
|
|
||||||
|
tree.insert(6, TestClass(6));
|
||||||
|
CHECK(tree.isValid());
|
||||||
|
CHECK(tree.size() == 1);
|
||||||
|
CHECK(tree.getRoot()->data == TestClass(6));
|
||||||
|
|
||||||
|
tree.remove(6);
|
||||||
|
CHECK(tree.isValid());
|
||||||
|
CHECK(tree.size() == 0);
|
||||||
|
CHECK(tree.getRoot() == nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Persistance) {
|
||||||
|
AvlTree<AvlNumericKey<i64>, TestClass> tree;
|
||||||
|
|
||||||
|
struct Item {
|
||||||
|
Item() :
|
||||||
|
data(0) {}
|
||||||
|
bool presents = false;
|
||||||
|
TestClass data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Item buff[size];
|
||||||
|
|
||||||
|
for (auto i = 0; i < size; i++) {
|
||||||
|
buff[i].data.setVal(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// random load
|
||||||
|
ui64 loadSize = 0;
|
||||||
|
while (loadSize < size / 2) {
|
||||||
|
auto idx = ui64(randomFloat() * (size - 1));
|
||||||
|
assert(idx < size);
|
||||||
|
if (!buff[idx].presents) {
|
||||||
|
tree.insert((i64) buff[idx].data.getVal(), buff[idx].data);
|
||||||
|
loadSize++;
|
||||||
|
buff[idx].presents = true;
|
||||||
|
|
||||||
|
CHECK(tree.isValid());
|
||||||
|
CHECK(tree.size() == loadSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& item : buff) {
|
||||||
|
if (item.presents) continue;
|
||||||
|
tree.insert((i64) item.data.getVal(), item.data);
|
||||||
|
loadSize++;
|
||||||
|
item.presents = true;
|
||||||
|
|
||||||
|
CHECK(tree.isValid());
|
||||||
|
CHECK(tree.size() == loadSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(tree.size() == size);
|
||||||
|
CHECK(tree.maxNode(tree.getRoot())->data.getVal() == size - 1);
|
||||||
|
CHECK(tree.minNode(tree.getRoot())->data.getVal() == 0);
|
||||||
|
|
||||||
|
// find
|
||||||
|
for (auto item : buff) {
|
||||||
|
auto node = tree.find((i64) 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
|
||||||
|
ui64 unloadSize = 0;
|
||||||
|
while (unloadSize < size / 2) {
|
||||||
|
auto idx = ui64(randomFloat() * (size - 1));
|
||||||
|
if (buff[idx].presents) {
|
||||||
|
|
||||||
|
tree.remove((i64) buff[idx].data.getVal());
|
||||||
|
|
||||||
|
unloadSize++;
|
||||||
|
buff[idx].presents = false;
|
||||||
|
|
||||||
|
// find
|
||||||
|
for (auto item : buff) {
|
||||||
|
if (!item.presents) continue;
|
||||||
|
auto node = tree.find((i64) 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((i64) item.data.getVal());
|
||||||
|
unloadSize++;
|
||||||
|
item.presents = false;
|
||||||
|
|
||||||
|
CHECK(tree.isValid());
|
||||||
|
CHECK(tree.size() == size - unloadSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(tree.size() == 0);
|
||||||
|
CHECK(tree.getRoot() == nullptr);
|
||||||
|
CHECK(tree.maxNode(tree.getRoot()) == nullptr);
|
||||||
|
CHECK(tree.minNode(tree.getRoot()) == nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
#include "Interpreter.hpp"
|
#include "Interpreter.hpp"
|
||||||
|
#include "UnitTest++/UnitTest++.h"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
Interpreter interpreter;
|
Interpreter interpreter;
|
||||||
|
|
@ -11,7 +12,10 @@ int main() {
|
||||||
interpreter.interpret("MD /A123");
|
interpreter.interpret("MD /A123");
|
||||||
interpreter.interpret("cd /A123");
|
interpreter.interpret("cd /A123");
|
||||||
interpreter.interpret("md asd");
|
interpreter.interpret("md asd");
|
||||||
|
interpreter.interpret("md asd/asd");
|
||||||
|
interpreter.interpret("md asd/asd/asd");
|
||||||
|
interpreter.interpret("md asd/asd/asd/asd");
|
||||||
|
interpreter.interpret("rd asd");
|
||||||
|
|
||||||
|
return UnitTest::RunAllTests();
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue