From db1731bf07cad8ae88f6aa3d03bef47af562c116 Mon Sep 17 00:00:00 2001 From: Martin Hanzik <martin@hanzik.com> Date: Thu, 10 May 2018 21:57:51 +0200 Subject: [PATCH] Add more tests --- agui2/CMakeLists.txt | 2 +- agui2/src/Models/ModelBox.cpp | 20 +++++-- agui2/tests/TestModelBox.cpp | 99 ++++++++++++++++++++++++++++++++--- agui2/tests/TestRegistry.cpp | 46 ++++++++++++++++ 4 files changed, 157 insertions(+), 10 deletions(-) create mode 100644 agui2/tests/TestRegistry.cpp diff --git a/agui2/CMakeLists.txt b/agui2/CMakeLists.txt index 95bee0eb4a..85ff8d9373 100644 --- a/agui2/CMakeLists.txt +++ b/agui2/CMakeLists.txt @@ -82,7 +82,7 @@ set(SOURCE_FILES src/Utils.hpp) set(TEST_FILES - tests/main.cpp tests/TestModelBox.cpp) + tests/main.cpp tests/TestModelBox.cpp tests/TestRegistry.cpp) link_libraries( ${CMAKE_THREAD_LIBS_INIT} diff --git a/agui2/src/Models/ModelBox.cpp b/agui2/src/Models/ModelBox.cpp index a4d3e23475..29331112e3 100644 --- a/agui2/src/Models/ModelBox.cpp +++ b/agui2/src/Models/ModelBox.cpp @@ -11,7 +11,7 @@ std::vector<ModelBox*> ModelBox::allModelBoxes; ModelBox::ModelBox(ModelType type, size_t maxInputCount) : type(type) , maxInputCount(maxInputCount) - , inputs(maxInputCount, nullptr) + , inputs(maxInputCount) { // Input box cannot have inputs, other boxes must have inputs Q_ASSERT((this->type == ModelType::Input) == (this->maxInputCount == 0)); @@ -24,18 +24,32 @@ ModelBox::~ModelBox() { } void ModelBox::setInput(size_t slot, ModelBox* model) { - Q_ASSERT(slot < this->maxInputCount); + if (slot >= this->maxInputCount) { + throw std::runtime_error { "Cannot connect to an nonexistent slot." }; + } + + if (model != nullptr && this->inputs[slot]) { + throw std::runtime_error { "Cannot connect to an occupied input." }; + } + this->inputs[slot] = model; } void ModelBox::addOutput(ModelBox* target, size_t targetSlot) { Q_ASSERT(this->canHaveOutput()); + if (this->outputs.find({target, targetSlot}) != this->outputs.end()) { + throw std::runtime_error { "This target is already connected to this output." }; + } this->outputs.emplace(target, targetSlot); } void ModelBox::removeOutput(ModelBox* target, size_t targetSlot) { Q_ASSERT(this->canHaveOutput()); - this->outputs.erase({target, targetSlot}); + auto it = this->outputs.find({target, targetSlot}); + if (it == this->outputs.end()) { + throw std::runtime_error { "Cannot remove an output that is not connected.." }; + } + this->outputs.erase(it); } std::shared_ptr<abstraction::OperationAbstraction> ModelBox::getCachedResultOrEvaluate() { diff --git a/agui2/tests/TestModelBox.cpp b/agui2/tests/TestModelBox.cpp index eca4409e4c..37089c952c 100644 --- a/agui2/tests/TestModelBox.cpp +++ b/agui2/tests/TestModelBox.cpp @@ -4,33 +4,120 @@ #include <Models/OutputModelBox.hpp> #include <Models/AlgorithmModelBox.hpp> #include <Algorithm/Registry.hpp> +#include <Utils.hpp> TEST_CASE("Basic properties") { + auto input = std::make_unique<InputModelBox>(); + auto output = std::make_unique<OutputModelBox>(); + auto algo = std::make_unique<AlgorithmModelBox>(Registry::getAlgorithm("automaton::determinize::Determinize")); + SECTION("Input and output counts") { - auto input = std::make_unique<InputModelBox>(); CHECK(input->getMaxInputCount() == 0); CHECK(input->canHaveOutput()); - auto output = std::make_unique<OutputModelBox>(); CHECK(output->getMaxInputCount() == 1); CHECK_FALSE(output->canHaveOutput()); - auto algo = std::make_unique<AlgorithmModelBox>(Registry::getAlgorithm("automaton::determinize::Determinize")); CHECK(algo->getMaxInputCount() == 1); CHECK(algo->canHaveOutput()); } SECTION("Model type and name") { - auto input = std::make_unique<InputModelBox>(); CHECK(input->getType() == ModelType::Input); CHECK(input->getName() == "INPUT"); - auto output = std::make_unique<OutputModelBox>(); CHECK(output->getType() == ModelType::Output); CHECK(output->getName() == "OUTPUT"); - auto algo = std::make_unique<AlgorithmModelBox>(Registry::getAlgorithm("automaton::determinize::Determinize")); CHECK(algo->getType() == ModelType::Algorithm); CHECK(algo->getName() == "Determinize"); } + + CHECK(algo->getAlgorithm() == Registry::getAlgorithm("automaton::determinize::Determinize")); +} + +TEST_CASE("Connect and disconnect") { + + SECTION("Basic") { + auto input = std::make_unique<InputModelBox>(); + auto output = std::make_unique<OutputModelBox>(); + + CHECK(output->evaluate() == nullptr); + + input->setAutomaton(Utils::generateRandomAutomaton()); + + CHECK(output->evaluate() == nullptr); + + ModelBox::connect(input.get(), output.get(), 0); + + CHECK(output->evaluate() == input->getAutomaton()); + + ModelBox::disconnect(input.get(), output.get(), 0); + + CHECK(output->evaluate() == nullptr); + } + + SECTION("Multiple connections from one slot") { + auto input = std::make_unique<InputModelBox>(); + auto output1 = std::make_unique<OutputModelBox>(); + auto output2 = std::make_unique<OutputModelBox>(); + + CHECK(output1->evaluate() == nullptr); + CHECK(output2->evaluate() == nullptr); + + input->setAutomaton(Utils::generateRandomAutomaton()); + + CHECK(output1->evaluate() == nullptr); + CHECK(output2->evaluate() == nullptr); + + ModelBox::connect(input.get(), output1.get(), 0); + + CHECK(output1->evaluate() == input->getAutomaton()); + CHECK(output2->evaluate() == nullptr); + + ModelBox::connect(input.get(), output2.get(), 0); + + CHECK(output1->evaluate() == input->getAutomaton()); + CHECK(output2->evaluate() == input->getAutomaton()); + + ModelBox::disconnect(input.get(), output1.get(), 0); + + CHECK(output1->evaluate() == nullptr); + CHECK(output2->evaluate() == input->getAutomaton()); + } + + SECTION("Multiple connections to one slot") { + auto input1 = std::make_unique<InputModelBox>(); + auto input2 = std::make_unique<InputModelBox>(); + auto output = std::make_unique<OutputModelBox>(); + + CHECK(output->evaluate() == nullptr); + + ModelBox::connect(input1.get(), output.get(), 0); + CHECK_THROWS(ModelBox::connect(input2.get(), output.get(), 0)); + } + + SECTION("Reconnect existing connection") { + auto input1 = std::make_unique<InputModelBox>(); + auto input2 = std::make_unique<InputModelBox>(); + auto output = std::make_unique<OutputModelBox>(); + + ModelBox::connect(input1.get(), output.get(), 0); + ModelBox::disconnect(input1.get(), output.get(), 0); + CHECK_NOTHROW(ModelBox::connect(input2.get(), output.get(), 0)); + } + + SECTION("Connect to an nonexistent slot") { + auto input = std::make_unique<InputModelBox>(); + auto output = std::make_unique<OutputModelBox>(); + + CHECK_THROWS(ModelBox::connect(input.get(), output.get(), 1)); + } + + SECTION("Disconnect an unconnected slot") { + auto input = std::make_unique<InputModelBox>(); + auto output = std::make_unique<OutputModelBox>(); + + CHECK_THROWS(ModelBox::disconnect(input.get(), output.get(), 0)); + } } \ No newline at end of file diff --git a/agui2/tests/TestRegistry.cpp b/agui2/tests/TestRegistry.cpp new file mode 100644 index 0000000000..4832c39243 --- /dev/null +++ b/agui2/tests/TestRegistry.cpp @@ -0,0 +1,46 @@ +#include <catch.hpp> +#include <Algorithm/Registry.hpp> + +TEST_CASE("Registry") { + Registry::deinitialize(); + + CHECK(Registry::getAlgorithm("automaton::determinize::Determinize") == nullptr); + + Registry::initialize(); + + auto* algo = Registry::getAlgorithm("automaton::determinize::Determinize"); + CHECK(algo != nullptr); + + CHECK(Registry::getAlgorithm("nonexistent_algorithm") == nullptr); +} + +TEST_CASE("Algorithm") { + SECTION("Basic") { + auto name = "automaton::determinize::Determinize"; + + auto* algo = Registry::getAlgorithm(name); + + CHECK(algo->getFullName() == name); + CHECK(algo->getPrettyName() == "Determinize"); + + const auto& groups = algo->getGroups(); + CHECK(groups[0] == "automaton"); + CHECK(groups[1] == "determinize"); + + CHECK(algo->getInputCount() == 1); + } + + SECTION("Input count") { + auto* algo = Registry::getAlgorithm("automaton::transform::AutomataConcatenation"); + + CHECK(algo != nullptr); + CHECK(algo->getInputCount() == 2); + } + + SECTION("Pretty name") { + auto* algo = Registry::getAlgorithm("automaton::transform::AutomataConcatenationEpsilonTransition"); + + CHECK(algo != nullptr); + CHECK(algo->getPrettyName() == u8"\u03B5-Concatenate"); + } +} \ No newline at end of file -- GitLab