diff --git a/include/TimedPetriNetEditor/PetriNet.hpp b/include/TimedPetriNetEditor/PetriNet.hpp index 9a350f1..b10d83a 100644 --- a/include/TimedPetriNetEditor/PetriNet.hpp +++ b/include/TimedPetriNetEditor/PetriNet.hpp @@ -191,6 +191,16 @@ class Place : public Node return std::string("P" + std::to_string(id_)); } + //-------------------------------------------------------------------------- + //! \brief Increment the number of token constrained by the type of net. + //-------------------------------------------------------------------------- + size_t increment(size_t const count = 1u); + + //-------------------------------------------------------------------------- + //! \brief Decrement the number of token constrained by the type of net. + //-------------------------------------------------------------------------- + size_t decrement(size_t const count = 1u); + //-------------------------------------------------------------------------- //! \brief For debug purpose only. //-------------------------------------------------------------------------- @@ -534,7 +544,7 @@ class Net //! timed graph even, etc. //! \return false if the net cannot be changed (i.e. to graph event). //-------------------------------------------------------------------------- - bool convertTo(TypeOfNet const type, std::vector& erroneous_arcs); + bool convertTo(TypeOfNet const type, std::string& error, std::vector& erroneous_arcs); //-------------------------------------------------------------------------- //! \brief Load the Petri net from a JSON file. The current net is cleared diff --git a/src/Net/SparseMatrix.hpp b/include/TimedPetriNetEditor/SparseMatrix.hpp similarity index 99% rename from src/Net/SparseMatrix.hpp rename to include/TimedPetriNetEditor/SparseMatrix.hpp index 6500e4c..11aa0ce 100644 --- a/src/Net/SparseMatrix.hpp +++ b/include/TimedPetriNetEditor/SparseMatrix.hpp @@ -21,7 +21,7 @@ #ifndef SPARSE_MATRIX_HPP # define SPARSE_MATRIX_HPP -# include "Net/TropicalAlgebra.hpp" +# include "TimedPetriNetEditor/TropicalAlgebra.hpp" // FIXME Add template and manage (max,+) types //# include diff --git a/src/Net/TropicalAlgebra.hpp b/include/TimedPetriNetEditor/TropicalAlgebra.hpp similarity index 100% rename from src/Net/TropicalAlgebra.hpp rename to include/TimedPetriNetEditor/TropicalAlgebra.hpp diff --git a/src/Editor/DearImGui/Drawable.cpp b/src/Editor/DearImGui/Drawable.cpp index 06d518d..b52d8cf 100644 --- a/src/Editor/DearImGui/Drawable.cpp +++ b/src/Editor/DearImGui/Drawable.cpp @@ -123,7 +123,7 @@ void drawArc(ImDrawList* draw_list, Arc const& arc, TypeOfNet const type, ImVec2 float x = origin.x + arc.from.x + (arc.to.x - arc.from.x) / 2.0f; float y = origin.y + arc.from.y + (arc.to.y - arc.from.y) / 2.0f - 15.0f; std::stringstream stream; - stream << std::fixed << std::setprecision(2) << arc.duration; + stream << std::fixed << std::setprecision(1) << arc.duration; draw_list->AddText(ImVec2(x, y), DURATION_COLOR, stream.str().c_str()); } } @@ -193,6 +193,7 @@ void drawPlace(ImDrawList* draw_list, Place const& place, TypeOfNet const type, } else { + drawToken(draw_list, p.x, p.y); std::string tokens = std::to_string(place.tokens); draw_list->AddText(ImVec2(p.x, p.y), CAPTION_COLOR, tokens.c_str()); } @@ -207,18 +208,22 @@ void drawTransition(ImDrawList* draw_list, Transition const& transition, TypeOfN // Color of the transition: green if validated else yellow if enabled // else color is fadding value. ImU32 color; - //if (type == TypeOfNet::PetriNet) - //{ - if (transition.canFire()) - { - color = FIREABLE_COLOR; - } - else if (transition.isValidated() || transition.isEnabled()) + if (transition.key == "T0") + { + color = IM_COL32(255, 165, 10, 255); + } + + if (transition.canFire()) + { + color = FIREABLE_COLOR; + } + else if (type == TypeOfNet::GRAFCET) + { + if (transition.isValidated() || transition.isEnabled()) { color = IM_COL32(255, 165, 0, 255); } - //} - //else if + } else { color = FILL_COLOR(alpha); diff --git a/src/Editor/DearImGui/KeyBindings.hpp b/src/Editor/DearImGui/KeyBindings.hpp index 3514462..488f0d8 100644 --- a/src/Editor/DearImGui/KeyBindings.hpp +++ b/src/Editor/DearImGui/KeyBindings.hpp @@ -22,11 +22,13 @@ # define KEY_BINDINGS_HPP // ----------------------------------------------------------------------------- -# define KEY_BINDING_QUIT_APPLICATION ImGuiKey_Escape -# define KEY_BINDING_RUN_SIMULATION ImGuiKey_Space -# define KEY_BINDING_RUN_SIMULATION_ALT ImGuiKey_R -# define KEY_BINDING_ROTATE_CW ImGuiKey_PageUp -# define KEY_BINDING_ROTATE_CCW ImGuiKey_PageDown -# define KEY_BINDING_MOVE_PETRI_NODE ImGuiKey_Semicolon +# define KEY_QUIT_APPLICATION ImGuiKey_Escape +# define KEY_RUN_SIMULATION ImGuiKey_Space +# define KEY_RUN_SIMULATION_ALT ImGuiKey_R +# define KEY_ROTATE_CW ImGuiKey_PageUp +# define KEY_ROTATE_CCW ImGuiKey_PageDown +# define KEY_MOVE_PETRI_NODE ImGuiKey_Semicolon +# define KEY_INCREMENT_TOKENS ImGuiKey_KeypadAdd +# define KEY_DECREMENT_TOKENS ImGuiKey_KeypadSubtract #endif \ No newline at end of file diff --git a/src/Editor/PetriEditor.cpp b/src/Editor/PetriEditor.cpp index a901600..41255d8 100644 --- a/src/Editor/PetriEditor.cpp +++ b/src/Editor/PetriEditor.cpp @@ -18,13 +18,14 @@ // along with GNU Emacs. If not, see . //============================================================================= +#include "TimedPetriNetEditor/PetriNet.hpp" +#include "TimedPetriNetEditor/Algorithms.hpp" +#include "TimedPetriNetEditor/SparseMatrix.hpp" #include "Editor/PetriEditor.hpp" #include "Editor/DearImGui/Drawable.hpp" #include "Editor/DearImGui/DearUtils.hpp" #include "Editor/DearImGui/KeyBindings.hpp" -#include "Net/SparseMatrix.hpp" #include "Utils/Utils.hpp" -#include "TimedPetriNetEditor/Algorithms.hpp" namespace tpne { @@ -763,7 +764,8 @@ bool Editor::switchOfNet(TypeOfNet const type) return false; std::vector arcs; - if (m_net.convertTo(type, arcs)) + std::string error; + if (m_net.convertTo(type, error, arcs)) return true; m_messages.setError(m_net.error()); @@ -1332,16 +1334,36 @@ void Editor::PetriView::onHandleInput() if (ImGui::IsItemHovered()) { - if (ImGui::IsKeyPressed(KEY_BINDING_MOVE_PETRI_NODE, false)) + if (ImGui::IsKeyPressed(KEY_MOVE_PETRI_NODE, false)) { handleMoveNode(); } // Run the animation of the Petri net - else if (ImGui::IsKeyPressed(KEY_BINDING_RUN_SIMULATION) || - ImGui::IsKeyPressed(KEY_BINDING_RUN_SIMULATION_ALT)) + else if (ImGui::IsKeyPressed(KEY_RUN_SIMULATION) || + ImGui::IsKeyPressed(KEY_RUN_SIMULATION_ALT)) { m_editor.toogleStartSimulation(); } + // Increment the number of tokens in the place. + else if (ImGui::IsKeyPressed(KEY_INCREMENT_TOKENS)) + { + Node* node = m_editor.getNode(m_mouse.position); + if ((node != nullptr) && (node->type == Node::Type::Place)) + { + reinterpret_cast(node)->increment(1u); + m_editor.m_net.modified = true; + } + } + // Decrement the number of tokens in the place. + else if (ImGui::IsKeyPressed(KEY_DECREMENT_TOKENS)) + { + Node* node = m_editor.getNode(m_mouse.position); + if ((node != nullptr) && (node->type == Node::Type::Place)) + { + reinterpret_cast(node)->decrement(1u); + m_editor.m_net.modified = true; + } + } } } diff --git a/src/Net/Algorithms.cpp b/src/Net/Algorithms.cpp index b4e3689..0aef623 100644 --- a/src/Net/Algorithms.cpp +++ b/src/Net/Algorithms.cpp @@ -20,7 +20,7 @@ #include "TimedPetriNetEditor/PetriNet.hpp" #include "TimedPetriNetEditor/Algorithms.hpp" -#include "Net/SparseMatrix.hpp" +#include "TimedPetriNetEditor/SparseMatrix.hpp" #include "Net/Howard.h" namespace tpne { @@ -35,6 +35,7 @@ template<> bool SparseMatrix::display_as_dense = false; bool isEventGraph(Net const& net, std::string& error, std::vector& erroneous_arcs) { erroneous_arcs.clear(); + error.clear(); if (net.isEmpty()) { error = "Empty Petri net is not an event graph"; diff --git a/src/Net/Exports/ExportJulia.cpp b/src/Net/Exports/ExportJulia.cpp index ecedb21..28c2bad 100644 --- a/src/Net/Exports/ExportJulia.cpp +++ b/src/Net/Exports/ExportJulia.cpp @@ -18,10 +18,10 @@ // along with GNU Emacs. If not, see . //============================================================================= -#include "Net/Exports/Exports.hpp" #include "TimedPetriNetEditor/PetriNet.hpp" #include "TimedPetriNetEditor/Algorithms.hpp" -#include "Net/SparseMatrix.hpp" +#include "TimedPetriNetEditor/SparseMatrix.hpp" +#include "Net/Exports/Exports.hpp" #include #include diff --git a/src/Net/Imports/ImportJSON.cpp b/src/Net/Imports/ImportJSON.cpp index fb915e2..c4ad1f3 100644 --- a/src/Net/Imports/ImportJSON.cpp +++ b/src/Net/Imports/ImportJSON.cpp @@ -54,22 +54,44 @@ std::string importFromJSON(Net& net, std::string const& filename) return error.str(); } - std::string type = std::string(json["type"]); - if (type == "GRAFCET") { - net.clear(TypeOfNet::GRAFCET); - } else if (type == "Petri net") { - net.clear(TypeOfNet::PetriNet); - } else if (type == "Timed Petri net") { - net.clear(TypeOfNet::TimedPetriNet); - } else if (type == "Timed event graph") { - net.clear(TypeOfNet::TimedEventGraph); - } else { + if (json.contains("type")) + { + std::string type = std::string(json["type"]); + if (type == "GRAFCET") { + net.clear(TypeOfNet::GRAFCET); + } else if (type == "Petri net") { + net.clear(TypeOfNet::PetriNet); + } else if (type == "Timed Petri net") { + net.clear(TypeOfNet::TimedPetriNet); + } else if (type == "Timed event graph") { + net.clear(TypeOfNet::TimedEventGraph); + } else { + error << "Failed parsing '" << filename << "'. Reason was '" + << "Unknown type of net: " << type << "'" << std::endl; + return error.str(); + } + } + else + { error << "Failed parsing '" << filename << "'. Reason was '" - << "Unknown type of net: " << type << "'" << std::endl; + << "Missing type of Net'" << std::endl; return error.str(); } + if (!json.contains("nets")) + { + error << "Failed parsing '" << filename << "'. Reason was '" + << "Missing JSON nets field'" << std::endl; + return error.str(); + } nlohmann::json const& jnet = json["nets"][0]; + + if (!jnet.contains("name")) + { + error << "Failed parsing '" << filename << "'. Reason was '" + << "Missing JSON net name'" << std::endl; + return error.str(); + } net.name = std::string(jnet["name"]); // Places diff --git a/src/Net/PetriNet.cpp b/src/Net/PetriNet.cpp index 2f0b464..b65be3f 100644 --- a/src/Net/PetriNet.cpp +++ b/src/Net/PetriNet.cpp @@ -64,6 +64,20 @@ Place::Place(size_t const id_, std::string const& caption_, float const x_, tokens = std::min(Net::Settings::maxTokens, tokens_); } +//------------------------------------------------------------------------------ +size_t Place::increment(size_t const count) +{ + tokens = std::min(Net::Settings::maxTokens, tokens + count); + return tokens; +} + +//------------------------------------------------------------------------------ +size_t Place::decrement(size_t const count) +{ + tokens = std::max(tokens, count) - count; + return tokens; +} + //------------------------------------------------------------------------------ bool Transition::isEnabled() const { @@ -152,7 +166,7 @@ void Net::clear(TypeOfNet const type) } //------------------------------------------------------------------------------ -bool Net::convertTo(TypeOfNet const type, std::vector& erroneous_arcs) +bool Net::convertTo(TypeOfNet const type, std::string& error, std::vector& erroneous_arcs) { if (m_type == type) return true; @@ -162,6 +176,13 @@ bool Net::convertTo(TypeOfNet const type, std::vector& erroneous_arcs) case TypeOfNet::GRAFCET: Net::Settings::maxTokens = 1u; Net::Settings::firing = Net::Settings::Fire::OneByOne; + // Constrain the number of tokens. + // TBD: not constraining the number of tokens allow us to save the + // net (json format) without loosing number of tokens for other nets. + for (auto& place: m_places) + { + place.tokens = std::min(Net::Settings::maxTokens, place.tokens); + } // FIXME //m_sensors.clear(); //for (auto& transition: m_transitions) @@ -179,7 +200,7 @@ bool Net::convertTo(TypeOfNet const type, std::vector& erroneous_arcs) break; case TypeOfNet::TimedEventGraph: // Check conditions of a well formed event graph - if ((!isEmpty()) && (!isEventGraph(*this))) + if ((!isEmpty()) && (!isEventGraph(*this, error, erroneous_arcs))) return false; Net::Settings::maxTokens = std::numeric_limits::max(); Net::Settings::firing = Net::Settings::Fire::OneByOne; @@ -189,8 +210,10 @@ bool Net::convertTo(TypeOfNet const type, std::vector& erroneous_arcs) break; } - // Place this at the end because of possible return false. + // Set the new type of net at the end of this method because of possible + // previous "return false" preventing to change of type. m_type = type; + return true; } @@ -209,10 +232,10 @@ std::vector Net::tokens() const //------------------------------------------------------------------------------ bool Net::tokens(std::vector const& tokens_) { + m_message.str(""); if (m_places.size() != tokens_.size()) { - m_message.str(""); - m_message << "the container dimension holding tokens does not match the number of places" + m_message << "The container dimension holding tokens does not match the number of places" << std::endl; return false; } @@ -220,7 +243,7 @@ bool Net::tokens(std::vector const& tokens_) size_t i = tokens_.size(); while (i--) { - m_places[i].tokens = tokens_[i]; + m_places[i].tokens = std::min(Net::Settings::maxTokens, tokens_[i]); } return true; @@ -471,8 +494,7 @@ Node const* Net::findNode(std::string const& key) const } return nullptr; } - - if (key[0] == 'T') + else if (key[0] == 'T') { for (auto& t: m_transitions) { @@ -646,9 +668,9 @@ bool Net::load(std::string const& filepath) // Get the name from path size_t lastindex = filepath.find_last_of("."); - std::string name = filepath.substr(0, lastindex); - lastindex = name.find_last_of("/"); - name = name.substr(lastindex + 1u); + std::string _name = filepath.substr(0, lastindex); + lastindex = _name.find_last_of("/"); + _name = _name.substr(lastindex + 1u); m_message.str(""); m_message << error; diff --git a/src/Net/Simulation.cpp b/src/Net/Simulation.cpp index ff2c02c..f6c7cd7 100644 --- a/src/Net/Simulation.cpp +++ b/src/Net/Simulation.cpp @@ -109,6 +109,7 @@ void Simulation::stateStarting() #endif // Reset states of the simulator + m_net.generateArcsInArcsOut(); m_initial_tokens = m_net.tokens(); shuffle_transitions(true); m_timed_tokens.clear(); diff --git a/tests/EventGraphTests.cpp b/tests/EventGraphTests.cpp index 713539f..2759a74 100644 --- a/tests/EventGraphTests.cpp +++ b/tests/EventGraphTests.cpp @@ -21,31 +21,34 @@ #include "main.hpp" #define protected public #define private public -# include "src/PetriNet.hpp" -# include "src/utils/Utils.hpp" +# include "TimedPetriNetEditor/PetriNet.hpp" +# include "TimedPetriNetEditor/Algorithms.hpp" +# include "TimedPetriNetEditor/SparseMatrix.hpp" #undef protected #undef private +using namespace ::tpne; + //------------------------------------------------------------------------------ TEST(TestEventGraph, TestHoward2) { + std::string error; std::vector erroneous_arcs; - PetriNet net(PetriNet::Type::TimedPetri); - PetriNet canonic(PetriNet::Type::TimedPetri); + Net net(TypeOfNet::TimedPetriNet); + Net canonic(TypeOfNet::TimedPetriNet); ASSERT_EQ(net.load("data/Howard2.json"), true); ASSERT_EQ(net.isEmpty(), false); - ASSERT_EQ(net.isEventGraph(erroneous_arcs), true); + ASSERT_EQ(isEventGraph(net), true); ASSERT_EQ(erroneous_arcs.empty(), true); - net.toCanonicalForm(canonic); // FIXME shall return bool isEventGraph() ? - canonic.generateArcsInArcsOut(); // FIXME - + toCanonicalForm(net, canonic); ASSERT_EQ(canonic.isEmpty(), false); - ASSERT_EQ(canonic.isEventGraph(erroneous_arcs), true); + ASSERT_EQ(isEventGraph(canonic, error, erroneous_arcs), true); + ASSERT_STREQ(error.c_str(), ""); ASSERT_EQ(erroneous_arcs.empty(), true); - ASSERT_EQ(canonic.save("/tmp/canonic.json"), true); + ASSERT_EQ(canonic.saveAs("/tmp/canonic.json"), true); ASSERT_EQ(canonic.m_next_place_id, 6u); ASSERT_EQ(canonic.m_next_transition_id, 5u); ASSERT_EQ(canonic.m_places.size(), 6u); @@ -64,20 +67,20 @@ TEST(TestEventGraph, TestHoward2) TEST(TestEventGraph, TestToSysLinNoInputNoOutput) { std::vector erroneous_arcs; - PetriNet net(PetriNet::Type::TimedPetri); + Net net(TypeOfNet::TimedPetriNet); ASSERT_EQ(net.load("data/Howard2.json"), true); // FIXME shall call generateArcsInArcsOut ? net.generateArcsInArcsOut(); // FIXME - ASSERT_EQ(net.isEventGraph(erroneous_arcs), true); + ASSERT_EQ(isEventGraph(net), true); ASSERT_EQ(erroneous_arcs.empty(), true); - SparseMatrix D; - SparseMatrix A; - SparseMatrix B; - SparseMatrix C; + SparseMatrix D; + SparseMatrix A; + SparseMatrix B; + SparseMatrix C; - ASSERT_EQ(net.toSysLin(D, A, B, C), true); + ASSERT_EQ(toSysLin(net, D, A, B, C), true); // // j // i | . . . . . | | . . . . 5 | @@ -121,20 +124,19 @@ TEST(TestEventGraph, TestToSysLinNoInputNoOutput) TEST(TestEventGraph, TestToSysLinInputOutput) { std::vector erroneous_arcs; - PetriNet net(PetriNet::Type::TimedPetri); + Net net(TypeOfNet::TimedPetriNet); ASSERT_EQ(net.load("data/JPQ.json"), true); // FIXME shall call generateArcsInArcsOut ? net.generateArcsInArcsOut(); // FIXME - ASSERT_EQ(net.isEventGraph(erroneous_arcs), true); - ASSERT_EQ(erroneous_arcs.empty(), true); + ASSERT_EQ(isEventGraph(net), true); - SparseMatrix D; - SparseMatrix A; - SparseMatrix B; - SparseMatrix C; + SparseMatrix D; + SparseMatrix A; + SparseMatrix B; + SparseMatrix C; - ASSERT_EQ(net.toSysLin(D, A, B, C), true); + ASSERT_EQ(toSysLin(net, D, A, B, C), true); // | . . | | 3 7 | | . | // D = | . . |, A = | 2 4 |, B = | 1 |, C = | 3 . | @@ -177,12 +179,11 @@ TEST(TestEventGraph, TestToSysLinInputOutput) // Chapter 5.2 A Comparison Between Counter and Dater Descriptions TEST(TestEventGraph, TestToDaterEquation) { - std::vector erroneous_arcs; - PetriNet net(PetriNet::Type::TimedPetri); + Net net(TypeOfNet::TimedPetriNet); ASSERT_EQ(net.load("data/EventGraph.json"), true); net.generateArcsInArcsOut(); // FIXME - ASSERT_EQ(net.isEventGraph(erroneous_arcs), true); + ASSERT_EQ(isEventGraph(net), true); std::stringstream expected, obtained; @@ -192,7 +193,7 @@ TEST(TestEventGraph, TestToDaterEquation) "# T1(n) = max(1 + T0(n), 1 + T2(n - 1), 1 + T1(n - 2))\n" "# T2(n) = max(1 + T1(n - 1), 2 + T0(n))\n" "# T3(n) = max(T1(n), T2(n))\n"); - obtained = net.showDaterEquation("# ", false, false); + obtained = showDaterEquation(net, "# ", false, false); ASSERT_STREQ(obtained.str().c_str(), expected.str().c_str()); // -- @@ -201,7 +202,7 @@ TEST(TestEventGraph, TestToDaterEquation) "# x1(n) = max(1 + u(n), 1 + x2(n - 1), 1 + x1(n - 2))\n" "# x2(n) = max(1 + x1(n - 1), 2 + u(n))\n" "# y(n) = max(x1(n), x2(n))\n"); - obtained = net.showDaterEquation("# ", true, false); + obtained = showDaterEquation(net, "# ", true, false); ASSERT_STREQ(obtained.str().c_str(), expected.str().c_str()); // -- @@ -210,7 +211,7 @@ TEST(TestEventGraph, TestToDaterEquation) "# T1(n) = 1 T0(n) ⨁ 1 T2(n - 1) ⨁ 1 T1(n - 2)\n" "# T2(n) = 1 T1(n - 1) ⨁ 2 T0(n)\n" "# T3(n) = T1(n) ⨁ T2(n)\n"); - obtained = net.showDaterEquation("# ", false, true); + obtained = showDaterEquation(net, "# ", false, true); ASSERT_STREQ(obtained.str().c_str(), expected.str().c_str()); // -- @@ -219,7 +220,7 @@ TEST(TestEventGraph, TestToDaterEquation) "# x1(n) = 1 u(n) ⨁ 1 x2(n - 1) ⨁ 1 x1(n - 2)\n" "# x2(n) = 1 x1(n - 1) ⨁ 2 u(n)\n" "# y(n) = x1(n) ⨁ x2(n)\n"); - obtained = net.showDaterEquation("# ", true, true); + obtained = showDaterEquation(net, "# ", true, true); ASSERT_STREQ(obtained.str().c_str(), expected.str().c_str()); } @@ -228,12 +229,11 @@ TEST(TestEventGraph, TestToDaterEquation) // Chapter 5.2 A Comparison Between Counter and Dater Descriptions TEST(TestEventGraph, TestToCounterEquation) { - std::vector erroneous_arcs; - PetriNet net(PetriNet::Type::TimedPetri); + Net net(TypeOfNet::TimedPetriNet); ASSERT_EQ(net.load("data/EventGraph.json"), true); net.generateArcsInArcsOut(); // FIXME - ASSERT_EQ(net.isEventGraph(erroneous_arcs), true); + ASSERT_EQ(isEventGraph(net), true); std::stringstream expected, obtained; @@ -243,7 +243,7 @@ TEST(TestEventGraph, TestToCounterEquation) "# T1(t) = min(T0(t - 1), 1 + T2(t - 1), 2 + T1(t - 1))\n" "# T2(t) = min(1 + T1(t - 1), T0(t - 2))\n" "# T3(t) = min(T1(t), T2(t))\n"); - obtained = net.showCounterEquation("# ", false, false); + obtained = showCounterEquation(net, "# ", false, false); ASSERT_STREQ(obtained.str().c_str(), expected.str().c_str()); // -- @@ -252,7 +252,7 @@ TEST(TestEventGraph, TestToCounterEquation) "# x1(t) = min(u(t - 1), 1 + x2(t - 1), 2 + x1(t - 1))\n" "# x2(t) = min(1 + x1(t - 1), u(t - 2))\n" "# y(t) = min(x1(t), x2(t))\n"); - obtained = net.showCounterEquation("# ", true, false); + obtained = showCounterEquation(net, "# ", true, false); ASSERT_STREQ(obtained.str().c_str(), expected.str().c_str()); // -- @@ -261,7 +261,7 @@ TEST(TestEventGraph, TestToCounterEquation) "# T1(t) = T0(t - 1) ⨁ 1 T2(t - 1) ⨁ 2 T1(t - 1)\n" "# T2(t) = 1 T1(t - 1) ⨁ T0(t - 2)\n" "# T3(t) = T1(t) ⨁ T2(t)\n"); - obtained = net.showCounterEquation("# ", false, true); + obtained = showCounterEquation(net, "# ", false, true); ASSERT_STREQ(obtained.str().c_str(), expected.str().c_str()); // -- @@ -270,6 +270,6 @@ TEST(TestEventGraph, TestToCounterEquation) "# x1(t) = u(t - 1) ⨁ 1 x2(t - 1) ⨁ 2 x1(t - 1)\n" "# x2(t) = 1 x1(t - 1) ⨁ u(t - 2)\n" "# y(t) = x1(t) ⨁ x2(t)\n"); - obtained = net.showCounterEquation("# ", true, true); + obtained = showCounterEquation(net, "# ", true, true); ASSERT_STREQ(obtained.str().c_str(), expected.str().c_str()); } diff --git a/tests/HowardTests.cpp b/tests/HowardTests.cpp index c913754..15c8a4e 100644 --- a/tests/HowardTests.cpp +++ b/tests/HowardTests.cpp @@ -21,11 +21,14 @@ #include "main.hpp" #define protected public #define private public -# include "src/utils/Howard.h" -# include "src/PetriNet.hpp" +# include "TimedPetriNetEditor/PetriNet.hpp" +# include "TimedPetriNetEditor/Algorithms.hpp" +# include "Net/Howard.h" #undef protected #undef private +using namespace ::tpne; + //------------------------------------------------------------------------------ TEST(TestHoward, TestSemiSimple) { @@ -124,10 +127,10 @@ TEST(TestHoward, TestSemiNetherlands) //------------------------------------------------------------------------------ TEST(TestHoward, TestPetriNetSemiSimple) { - PetriNet net(PetriNet::Type::TimedPetri); + Net net(TypeOfNet::TimedPetriNet); // Check dummy result is set to "invalid". - PetriNet::CriticalCycleResult res; + CriticalCycleResult res; ASSERT_EQ(res.success, false); ASSERT_EQ(res.eigenvector.size(), 0u); ASSERT_EQ(res.cycle_time.size(), 0u); @@ -137,21 +140,21 @@ TEST(TestHoward, TestPetriNetSemiSimple) // Load a net that is not event graph ASSERT_EQ(net.load("data/AppelsDurgence.json"), true); - ASSERT_EQ(net.type(), PetriNet::Type::TimedPetri); + ASSERT_EQ(net.type(), TypeOfNet::TimedPetriNet); ASSERT_EQ(net.isEmpty(), false); - res = net.findCriticalCycle(); + res = findCriticalCycle(net); ASSERT_EQ(res.success, false); ASSERT_EQ(res.eigenvector.size(), 0u); ASSERT_EQ(res.cycle_time.size(), 0u); ASSERT_EQ(res.optimal_policy.size(), 0u); ASSERT_NE(res.arcs.size(), 0u); - ASSERT_STREQ(res.message.str().c_str(), "Not an event graph"); + ASSERT_STREQ(res.message.str().c_str(), "The Petri net is not an event graph. Because:\n P0 has more than one output arc: T0 T4 T8\n"); // Load a net that is an event graph but that Howard does find policy (FIXME while it should) ASSERT_EQ(net.load("data/EventGraph.json"), true); - ASSERT_EQ(net.type(), PetriNet::Type::TimedEventGraph); + ASSERT_EQ(net.type(), TypeOfNet::TimedEventGraph); ASSERT_EQ(net.isEmpty(), false); - res = net.findCriticalCycle(); + res = findCriticalCycle(net); ASSERT_EQ(res.success, false); ASSERT_EQ(res.eigenvector.size(), 0u); ASSERT_EQ(res.cycle_time.size(), 0u); @@ -161,9 +164,9 @@ TEST(TestHoward, TestPetriNetSemiSimple) // Load a net that is an event graph ASSERT_EQ(net.load("data/Howard2.json"), true); - ASSERT_EQ(net.type(), PetriNet::Type::TimedPetri); + ASSERT_EQ(net.type(), TypeOfNet::TimedEventGraph); ASSERT_EQ(net.isEmpty(), false); - res = net.findCriticalCycle(); + res = findCriticalCycle(net); ASSERT_EQ(res.success, true); ASSERT_EQ(res.eigenvector.size(), 4u); ASSERT_EQ(res.eigenvector[0], 0.0f); diff --git a/tests/LoadJSONTests.cpp b/tests/LoadJSONTests.cpp index fd5863c..5e7ea23 100644 --- a/tests/LoadJSONTests.cpp +++ b/tests/LoadJSONTests.cpp @@ -21,43 +21,65 @@ #include "main.hpp" #define protected public #define private public -# include "src/PetriNet.hpp" +# include "TimedPetriNetEditor/PetriNet.hpp" #undef protected #undef private +using namespace ::tpne; + //------------------------------------------------------------------------------ // New JSON format TEST(TestJSONLoader, DummyTransitions) { - PetriNet net(PetriNet::Type::TimedPetri); + Net net(TypeOfNet::TimedPetriNet); ASSERT_EQ(net.load("data/DummyTransitions.json"), true); - ASSERT_EQ(net.type(), PetriNet::Type::TimedPetri); + ASSERT_EQ(net.type(), TypeOfNet::TimedPetriNet); ASSERT_EQ(net.m_places.size(), 1u); ASSERT_EQ(net.m_transitions.size(), 0u); ASSERT_EQ(net.m_arcs.size(), 0u); } +//------------------------------------------------------------------------------ +TEST(TestJSONLoader, TestLoadedInvalidNetTimedPetri) +{ + Net net(TypeOfNet::TimedPetriNet); + + ASSERT_EQ(net.load("doesnotexist"), false); + ASSERT_STREQ(net.error().c_str(), "Failed opening 'doesnotexist'." + " Reason was 'No such file or directory'\n"); + ASSERT_EQ(net.isEmpty(), true); + + ASSERT_EQ(net.load("data/BadJSON/BadType.json"), false); + ASSERT_STREQ(net.error().c_str(), "Failed parsing 'data/BadJSON/BadType.json'." + " Reason was 'Unknown type of net: Timed event graphe'\n"); + ASSERT_EQ(net.isEmpty(), true); + + ASSERT_EQ(net.load("data/BadJSON/NoName.json"), false); + ASSERT_STREQ(net.error().c_str(), "Failed parsing 'data/BadJSON/NoName.json'." + " Reason was 'Missing JSON net name'\n"); + ASSERT_EQ(net.isEmpty(), true); +} + //------------------------------------------------------------------------------ TEST(TestJSONLoader, LoadJSONfile) { - PetriNet net(PetriNet::Type::TimedPetri); + Net net(TypeOfNet::TimedPetriNet); ASSERT_EQ(net.load("data/GRAFCET.json"), true); - ASSERT_EQ(net.type(), PetriNet::Type::GRAFCET); + ASSERT_EQ(net.type(), TypeOfNet::GRAFCET); ASSERT_EQ(net.m_places.size(), 13u); ASSERT_EQ(net.m_transitions.size(), 11u); ASSERT_EQ(net.m_arcs.size(), 29u); } //------------------------------------------------------------------------------ -// Compared to TEST(TestJSONLoader, WithCarriageReturn) places have max 1 token. TEST(TestJSONLoader, LoadAsGrafcet) { - PetriNet net(PetriNet::Type::GRAFCET); + Net net(TypeOfNet::GRAFCET); ASSERT_EQ(net.load("data/TrafficLights.json"), true); - ASSERT_EQ(net.type(), PetriNet::Type::TimedPetri); + ASSERT_EQ(net.type(), TypeOfNet::TimedPetriNet); ASSERT_EQ(net.m_places.size(), 7u); ASSERT_EQ(net.m_transitions.size(), 6u); ASSERT_EQ(net.m_arcs.size(), 16u); @@ -72,16 +94,65 @@ TEST(TestJSONLoader, LoadAsGrafcet) ASSERT_EQ(net.findPlace(5u)->tokens, 0u); } +//------------------------------------------------------------------------------ +TEST(TestJSONLoader, CheckMarks) +{ + Net net(TypeOfNet::GRAFCET); + ASSERT_EQ(net.load("data/TrafficLights.json"), true); + ASSERT_EQ(net.type(), TypeOfNet::TimedPetriNet); + + std::vector tokens; + tokens = net.tokens(); + ASSERT_EQ(tokens.size(), 7u); + ASSERT_EQ(tokens[0], 1u); + ASSERT_EQ(tokens[1], 0u); + ASSERT_EQ(tokens[2], 0u); + ASSERT_EQ(tokens[3], 1u); + ASSERT_EQ(tokens[4], 0u); + ASSERT_EQ(tokens[5], 0u); + ASSERT_EQ(tokens[6], 1u); + + tokens[1] = 2u; tokens[2] = 3u; tokens[4] = 4u; tokens[5] = 5u; + ASSERT_EQ(net.tokens(tokens), true); + ASSERT_STREQ(net.error().c_str(), ""); + tokens = net.tokens(); + ASSERT_EQ(tokens.size(), 7u); + ASSERT_EQ(tokens[0], 1u); + ASSERT_EQ(tokens[1], 2u); + ASSERT_EQ(tokens[2], 3u); + ASSERT_EQ(tokens[3], 1u); + ASSERT_EQ(tokens[4], 4u); + ASSERT_EQ(tokens[5], 5u); + ASSERT_EQ(tokens[6], 1u); + + tokens.clear(); + ASSERT_EQ(net.tokens(tokens), false); + ASSERT_STREQ(net.error().c_str(), "The container dimension holding tokens does not match the number of places\n"); + tokens = net.tokens(); + ASSERT_EQ(tokens.size(), 7u); + ASSERT_EQ(tokens[0], 1u); + ASSERT_EQ(tokens[1], 2u); + ASSERT_EQ(tokens[2], 3u); + ASSERT_EQ(tokens[3], 1u); + ASSERT_EQ(tokens[4], 4u); + ASSERT_EQ(tokens[5], 5u); + ASSERT_EQ(tokens[6], 1u); +} + //------------------------------------------------------------------------------ TEST(TestJSONLoader, SaveAndLoadFile) { - PetriNet net(PetriNet::Type::TimedPetri); + std::string error; + std::vector erroneous_arcs; + Net net(TypeOfNet::TimedPetriNet); ASSERT_EQ(net.load("data/AppelsDurgence.json"), true); - net.type(PetriNet::Type::Petri); - ASSERT_EQ(net.save("/tmp/foo.json"), true); + net.convertTo(TypeOfNet::PetriNet, error, erroneous_arcs); + ASSERT_STREQ(error.c_str(), ""); + ASSERT_EQ(erroneous_arcs.size(), 0u); + ASSERT_EQ(net.saveAs("/tmp/foo.json"), true); ASSERT_EQ(net.load("/tmp/foo.json"), true); - ASSERT_EQ(net.type(), PetriNet::Type::Petri); + ASSERT_EQ(net.type(), TypeOfNet::PetriNet); ASSERT_EQ(net.m_places.size(), 13u); ASSERT_EQ(net.m_transitions.size(), 11u); ASSERT_EQ(net.m_arcs.size(), 29u); @@ -93,14 +164,14 @@ TEST(TestJSONLoader, SaveAndLoadFile) //------------------------------------------------------------------------------ TEST(TestJSONLoader, SaveAndLoadDummyNet) { - PetriNet net(PetriNet::Type::TimedPetri); + Net net(TypeOfNet::TimedPetriNet); - ASSERT_EQ(net.save("/tmp/foo.json"), true); + ASSERT_EQ(net.saveAs("/tmp/foo.json"), true); net.addPlace(1.0, 1.0, 2u); ASSERT_EQ(net.m_places.size(), 1u); ASSERT_EQ(net.load("/tmp/foo.json"), true); - ASSERT_EQ(net.type(), PetriNet::Type::TimedPetri); + ASSERT_EQ(net.type(), TypeOfNet::TimedPetriNet); ASSERT_EQ(net.m_places.size(), 0u); ASSERT_EQ(net.m_transitions.size(), 0u); ASSERT_EQ(net.m_arcs.size(), 0u); @@ -109,6 +180,6 @@ TEST(TestJSONLoader, SaveAndLoadDummyNet) //------------------------------------------------------------------------------ TEST(TestJSONLoader, LoadUnexistingFile) { - PetriNet net(PetriNet::Type::TimedPetri); + Net net(TypeOfNet::TimedPetriNet); ASSERT_EQ(net.load("foooobar.json"), false); } diff --git a/tests/Makefile b/tests/Makefile index a51586a..5576639 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -37,42 +37,30 @@ include $(M)/Makefile.header ################################################### # Inform Makefile where to find header files # -INCLUDES += -I$(P) -I$(P)/src -I$(P)/src/utils -INCLUDES += -I$(P)/src/Renderer -INCLUDES += -I$(P)/external/imgui -I$(P)/external/imgui-sfml -INCLUDES += -I$(P)/external/MQTT/include -I$(P)/external -INCLUDES += -I$(P)/external/portable-file-dialogs -INCLUDES += -I$(P)/external/json/include +INCLUDES += -I$(P)/include -I$(P)/src ################################################### # Inform Makefile where to find *.cpp and *.o files # -VPATH += $(P)/src $(P)/src/utils $(P)/src/julia -VPATH += $(P)/src/Renderer $(P)/external/MQTT/src -VPATH += $(P)/external/imgui $(P)/external/imgui-sfml +VPATH += $(P)/include $(P)/src $(P)/src/Utils $(P)/src/Net +VPATH += $(P)/src/Net/Imports VPATH += $(P)/src/Net/Exports +VPATH += $(P)/src/Application $(P)/src/Editor $(P)/src/Editor/DearImGui ################################################### -# Reduce warnings +# Set json Library. # -#DEFINES += -Wno-undef -Wno-switch-enum -Wno-sign-conversion -Wno-float-equal -Wno-shadow -#DEFINES += -Wno-keyword-macro -Wno-defaulted-function-deleted - -################################################### -# Reduce warnings -# -DEFINES += -Wno-undef -Wno-switch-enum -Wno-sign-conversion -Wno-float-equal -DEFINES += -Wno-deprecated-copy-dtor -Wno-defaulted-function-deleted -# Aaaargf needed because of imgui warnings -DEFINES += -Wno-old-style-cast -Wno-unused-parameter -DEFINES += -Wno-conversion -Wno-cast-qual +INCLUDES += -I$(THIRDPART)/json/include ################################################### # Make the list of compiled files for tests # -OBJS += Receptivities.o PetriNet.o Howard.o -OBJS += PetriNetTests.o AnimationTests.o EventGraphTests.o -OBJS += LoadJSONTests.o HowardTests.o SparseMatrixTests.o -OBJS += main.o +OBJS += Path.o Howard.o Utils.o TimedTokens.o Receptivities.o +OBJS += PetriNet.o Algorithms.o Simulation.o +OBJS += ImportJSON.o ExportJSON.o ExportSymfony.o ExportPnEditor.o +OBJS += ExportPetriLaTeX.o ExportJulia.o ExportGraphviz.o ExportDrawIO.o +OBJS += ExportGrafcetCpp.o + +OBJS += PetriNetTests.o LoadJSONTests.o HowardTests.o EventGraphTests.o main.o ################################################### # Set Libraries. For knowing which libraries diff --git a/tests/PetriNetTests.cpp b/tests/PetriNetTests.cpp index ee97b19..69a2f0e 100644 --- a/tests/PetriNetTests.cpp +++ b/tests/PetriNetTests.cpp @@ -21,10 +21,14 @@ #include "main.hpp" #define protected public #define private public -# include "src/PetriNet.hpp" +# include "TimedPetriNetEditor/PetriNet.hpp" #undef protected #undef private +#include "TimedPetriNetEditor/Algorithms.hpp" + +using namespace ::tpne; + //------------------------------------------------------------------------------ TEST(TestPetriNet, TestNodeCreation) { @@ -51,10 +55,11 @@ TEST(TestPetriNet, TestNodeCreation) ASSERT_EQ(n2.arcsOut.size(), 0u); // Check the operator!=() - Node n3(Node::Place, 42u, "", 4.0f, 3.5f); - ASSERT_EQ(n1 != n2, true); // Transition vs Place + different id - ASSERT_EQ(n3 != n2, true); // Transition vs Place + same id - ASSERT_EQ(n1 != n2, true); // different id + //Node n3(Node::Place, 42u, "", 4.0f, 3.5f); + //No more in the API + //ASSERT_EQ(n1 != n2, true); // Transition vs Place + different id + //ASSERT_EQ(n3 != n2, true); // Transition vs Place + same id + //ASSERT_EQ(n1 != n2, true); // different id // Check the copy operator (FIXME is it really needed ?) n1 = n2; @@ -79,9 +84,9 @@ TEST(TestPetriNet, TestNodeCreation) ASSERT_EQ(n4.arcsOut.size(), 0u); // Check the operator==() - n4.x = 5.0f; n4.caption = "foo"; - ASSERT_EQ(n1 == n4, true); - ASSERT_EQ(n1 == n2, true); + //n4.x = 5.0f; n4.caption = "foo"; + //ASSERT_EQ(n1 == n4, true); + //ASSERT_EQ(n1 == n2, true); } //------------------------------------------------------------------------------ @@ -112,13 +117,14 @@ TEST(TestPetriNet, TestPlaceCreation) ASSERT_EQ(p2.arcsOut.size(), 0u); // Check the operator!=() and operator==() - ASSERT_EQ(p1 == p2, true); - ASSERT_EQ(p1 != p2, false); + //ASSERT_EQ(p1 == p2, true); + //ASSERT_EQ(p1 != p2, false); // Check the copy operator Place p3(0u, "world", 0.0f, 0.0f, 0u); - ASSERT_EQ(p1 == p3, false); - ASSERT_EQ(p1 != p3, true); + //ASSERT_EQ(p1 == p3, false); + //ASSERT_EQ(p1 != p3, true); + p3 = p1; ASSERT_EQ(p3.id, 42u); ASSERT_EQ(p3.type, Node::Place); @@ -131,8 +137,8 @@ TEST(TestPetriNet, TestPlaceCreation) ASSERT_EQ(p3.arcsOut.size(), 0u); // Check the operator!=() and operator==() - ASSERT_EQ(p1 == p3, true); - ASSERT_EQ(p1 != p3, false); + //ASSERT_EQ(p1 == p3, true); + //ASSERT_EQ(p1 != p3, false); } //------------------------------------------------------------------------------ @@ -173,13 +179,13 @@ TEST(TestPetriNet, TestTransitionCreation) ASSERT_EQ(t2.isState(), false); // Check the operator!=() and operator==() - ASSERT_EQ(t1 == t2, true); - ASSERT_EQ(t1 != t2, false); + //ASSERT_EQ(t1 == t2, true); + //ASSERT_EQ(t1 != t2, false); // Check the copy operator Transition t3(0u, "world", 0.0f, 0.0f, 0u, false); - ASSERT_EQ(t1 == t3, false); - ASSERT_EQ(t1 != t3, true); + //ASSERT_EQ(t1 == t3, false); + //ASSERT_EQ(t1 != t3, true); t3 = t1; ASSERT_EQ(t3.id, 42u); ASSERT_EQ(t3.type, Node::Transition); @@ -197,8 +203,8 @@ TEST(TestPetriNet, TestTransitionCreation) ASSERT_EQ(t3.isState(), false); // Check the operator!=() and operator==() - ASSERT_EQ(t1 == t3, true); - ASSERT_EQ(t1 != t3, false); + //ASSERT_EQ(t1 == t3, true); + //ASSERT_EQ(t1 != t3, false); } //------------------------------------------------------------------------------ @@ -254,8 +260,8 @@ TEST(TestPetriNet, TestArcCreation) ASSERT_EQ(a2.tokensIn(), 13u); // Check the operator!=() and operator==() - ASSERT_EQ(a1 == a2, false); - ASSERT_EQ(a1 != a2, true); + //ASSERT_EQ(a1 == a2, false); + //ASSERT_EQ(a1 != a2, true); // Check the copy constructor Arc a3(a1); @@ -305,8 +311,8 @@ TEST(TestPetriNet, TestArcCreation) ASSERT_EQ(a4.tokensOut(), 13u); // Check the operator!=() and operator==() - ASSERT_EQ(a1 == a4, true); - ASSERT_EQ(a1 != a4, false); + //ASSERT_EQ(a1 == a4, true); + //ASSERT_EQ(a1 != a4, false); } //------------------------------------------------------------------------------ @@ -319,27 +325,27 @@ TEST(TestPetriNet, TestToKey) //------------------------------------------------------------------------------ TEST(TestPetriNet, TestToMode) { - ASSERT_STREQ(PetriNet::to_str(PetriNet::Type::GRAFCET).c_str(), "GRAFCET"); - ASSERT_STREQ(PetriNet::to_str(PetriNet::Type::Petri).c_str(), "Petri net"); - ASSERT_STREQ(PetriNet::to_str(PetriNet::Type::TimedPetri).c_str(), "Timed Petri net"); - ASSERT_STREQ(PetriNet::to_str(PetriNet::Type::TimedEventGraph).c_str(), "Timed event graph"); - ASSERT_STREQ(PetriNet::to_str(PetriNet::Type(42)).c_str(), "Undefined type of net"); + ASSERT_STREQ(to_str(TypeOfNet::GRAFCET).c_str(), "GRAFCET"); + ASSERT_STREQ(to_str(TypeOfNet::PetriNet).c_str(), "Petri net"); + ASSERT_STREQ(to_str(TypeOfNet::TimedPetriNet).c_str(), "Timed Petri net"); + ASSERT_STREQ(to_str(TypeOfNet::TimedEventGraph).c_str(), "Timed event graph"); + ASSERT_STREQ(to_str(TypeOfNet(42)).c_str(), "Undefined type of net"); } //------------------------------------------------------------------------------ TEST(TestPetriNet, PetriNetConstructor) { - PetriNet timed_net(PetriNet::Type::TimedPetri); - ASSERT_EQ(timed_net.type(), PetriNet::Type::TimedPetri); - ASSERT_EQ(timed_net.m_type, PetriNet::Type::TimedPetri); + Net timed_net(TypeOfNet::TimedPetriNet); + ASSERT_EQ(timed_net.type(), TypeOfNet::TimedPetriNet); + ASSERT_EQ(timed_net.m_type, TypeOfNet::TimedPetriNet); - PetriNet net(PetriNet::Type::Petri); - ASSERT_EQ(net.type(), PetriNet::Type::Petri); - ASSERT_EQ(net.m_type, PetriNet::Type::Petri); + Net net(TypeOfNet::PetriNet); + ASSERT_EQ(net.type(), TypeOfNet::PetriNet); + ASSERT_EQ(net.m_type, TypeOfNet::PetriNet); - PetriNet grafcet(PetriNet::Type::GRAFCET); - ASSERT_EQ(grafcet.type(), PetriNet::Type::GRAFCET); - ASSERT_EQ(grafcet.m_type, PetriNet::Type::GRAFCET); + Net grafcet(TypeOfNet::GRAFCET); + ASSERT_EQ(grafcet.type(), TypeOfNet::GRAFCET); + ASSERT_EQ(grafcet.m_type, TypeOfNet::GRAFCET); } //------------------------------------------------------------------------------ @@ -348,9 +354,9 @@ TEST(TestPetriNet, PetriNetDummy) std::vector erroneous_arcs; // Check the default constructor: dummy net - PetriNet net(PetriNet::Type::TimedPetri); - ASSERT_EQ(net.type(), PetriNet::Type::TimedPetri); - ASSERT_EQ(net.m_type, PetriNet::Type::TimedPetri); + Net net(TypeOfNet::TimedPetriNet); + ASSERT_EQ(net.type(), TypeOfNet::TimedPetriNet); + ASSERT_EQ(net.m_type, TypeOfNet::TimedPetriNet); ASSERT_EQ(net.m_places.size(), 0u); ASSERT_EQ(&net.places(), &net.m_places); @@ -360,8 +366,6 @@ TEST(TestPetriNet, PetriNetDummy) ASSERT_EQ(&net.transitions(), &net.m_transitions); ASSERT_EQ(net.transitions().size(), 0u); - ASSERT_EQ(net.m_shuffled_transitions.size(), 0u); - ASSERT_EQ(net.m_arcs.size(), 0u); ASSERT_EQ(&net.arcs(), &net.m_arcs); ASSERT_EQ(net.arcs().size(), 0u); @@ -370,27 +374,44 @@ TEST(TestPetriNet, PetriNetDummy) ASSERT_EQ(net.m_next_transition_id, 0u); ASSERT_EQ(net.modified, false); + ASSERT_STREQ(net.m_filename.c_str(), ""); + ASSERT_STREQ(net.name.c_str(), to_str(net.type()).c_str()); ASSERT_EQ(net.isEmpty(), true); - ASSERT_EQ(net.isEventGraph(erroneous_arcs), false); - ASSERT_EQ(erroneous_arcs.empty(), true); + ASSERT_EQ(net.tokens().empty(), true); +} - ASSERT_EQ(net.findNode("P0"), nullptr); - ASSERT_EQ(net.findNode("T0"), nullptr); - ASSERT_EQ(net.findNode("pouet"), nullptr); - ASSERT_EQ(net.findNode(""), nullptr); +//------------------------------------------------------------------------------ +TEST(TestPetriNet, TestIncrementId) +{ + Net net(TypeOfNet::TimedPetriNet); + + net.addPlace(42u, "", 3.5f, 4.0f, 45u); + ASSERT_EQ(net.m_next_place_id, 43u); + + net.addPlace(42u, "", 3.5f, 4.0f, 45u); + ASSERT_EQ(net.m_next_place_id, 43u); + + net.addPlace(25u, "", 3.5f, 4.0f, 45u); + ASSERT_EQ(net.m_next_place_id, 43u); + + net.addPlace(3.5f, 4.0f, 45u); + ASSERT_EQ(net.m_next_place_id, 44u); } //------------------------------------------------------------------------------ TEST(TestPetriNet, TestAddRemoveOperations) { std::vector erroneous_arcs; + std::string error; // Check the default constructor: dummy net - PetriNet net(PetriNet::Type::TimedPetri); + Net net(TypeOfNet::TimedPetriNet); ASSERT_EQ(net.isEmpty(), true); ASSERT_EQ(net.m_next_place_id, 0u); ASSERT_EQ(net.m_next_transition_id, 0u); + ASSERT_EQ(isEventGraph(net, error, erroneous_arcs), false); + ASSERT_STREQ(error.c_str(), "Empty Petri net is not an event graph"); // Add Place 0: net = P0 Place& p0 = net.addPlace(3.14f, 2.16f, 10u); @@ -399,7 +420,8 @@ TEST(TestPetriNet, TestAddRemoveOperations) ASSERT_STREQ(p0.key.c_str(), "P0"); ASSERT_STREQ(p0.caption.c_str(), "P0"); ASSERT_EQ(net.isEmpty(), false); - ASSERT_EQ(net.isEventGraph(erroneous_arcs), false); + ASSERT_EQ(isEventGraph(net, error, erroneous_arcs), false); + ASSERT_STREQ(error.c_str(), "The Petri net is not an event graph. Because:\n P0 has no output arc\n P0 has no input arc\n"); ASSERT_EQ(erroneous_arcs.empty(), true); ASSERT_EQ(net.findNode("P0"), &p0); ASSERT_EQ(net.m_places.size(), 1u); @@ -412,7 +434,8 @@ TEST(TestPetriNet, TestAddRemoveOperations) ASSERT_STREQ(t0->key.c_str(), "T0"); ASSERT_STREQ(t0->caption.c_str(), "T0"); ASSERT_EQ(net.isEmpty(), false); - ASSERT_EQ(net.isEventGraph(erroneous_arcs), false); + ASSERT_EQ(isEventGraph(net, error, erroneous_arcs), false); + ASSERT_STREQ(error.c_str(), "The Petri net is not an event graph. Because:\n P0 has no output arc\n P0 has no input arc\n"); ASSERT_EQ(erroneous_arcs.empty(), true); ASSERT_EQ(net.findNode("T0"), t0); ASSERT_EQ(net.m_transitions.size(), 1u); @@ -458,7 +481,8 @@ TEST(TestPetriNet, TestAddRemoveOperations) ASSERT_STREQ(t0->key.c_str(), "T0"); ASSERT_STREQ(t0->caption.c_str(), "T0"); ASSERT_EQ(net.isEmpty(), false); - ASSERT_EQ(net.isEventGraph(erroneous_arcs), false); + ASSERT_EQ(isEventGraph(net, error, erroneous_arcs), false); + ASSERT_STREQ(error.c_str(), "The Petri net is not an event graph. Because:\n P0 has no output arc\n P0 has no input arc\n"); ASSERT_EQ(erroneous_arcs.empty(), true); ASSERT_EQ(net.findNode("T0"), t0); ASSERT_EQ(net.m_transitions.size(), 1u); @@ -521,14 +545,59 @@ TEST(TestPetriNet, TestAddRemoveOperations) ASSERT_EQ(net.isEmpty(), true); // Try removing non existing arc + ASSERT_EQ(net.findArc(p0, *t0), nullptr); ASSERT_EQ(net.removeArc(p0, *t0), false); } +//------------------------------------------------------------------------------ +TEST(TestPetriNet, TestDecrTokens) +{ + Net net(TypeOfNet::TimedPetriNet); + Place& p0 = net.addPlace(0u, "Hello", 3.14f, 2.16f, 10u); + ASSERT_EQ(p0.tokens, 10u); + p0.decrement(2u); + ASSERT_EQ(p0.tokens, 8u); + p0.decrement(); + ASSERT_EQ(p0.tokens, 7u); + p0.decrement(8u); + ASSERT_EQ(p0.tokens, 0u); + p0.decrement(1u); + ASSERT_EQ(p0.tokens, 0u); +} + +//------------------------------------------------------------------------------ +TEST(TestPetriNet, TestIncrTokens) +{ + Net net(TypeOfNet::TimedPetriNet); + Place& p0 = net.addPlace(0u, "Hello", 3.14f, 2.16f, 0u); + ASSERT_EQ(p0.tokens, 0u); + p0.increment(2u); + ASSERT_EQ(p0.tokens, 2u); + p0.increment(); + ASSERT_EQ(p0.tokens, 3u); + + std::vector erroneous_arcs; + std::string error; + ASSERT_EQ(net.convertTo(TypeOfNet::GRAFCET, error, erroneous_arcs), true); + ASSERT_EQ(error.empty(), true); + ASSERT_EQ(erroneous_arcs.empty(), true); + ASSERT_EQ(p0.tokens, 1u); + p0.increment(); + ASSERT_EQ(p0.tokens, 1u); + + ASSERT_EQ(net.convertTo(TypeOfNet::PetriNet, error, erroneous_arcs), true); + ASSERT_EQ(error.empty(), true); + ASSERT_EQ(erroneous_arcs.empty(), true); + ASSERT_EQ(p0.tokens, 1u); + p0.increment(); + ASSERT_EQ(p0.tokens, 2u); +} + //------------------------------------------------------------------------------ TEST(TestPetriNet, TestCaptionAfterRemove) { // Add P0 and P1 - PetriNet net(PetriNet::Type::TimedPetri); + Net net(TypeOfNet::TimedPetriNet); Place& p0 = net.addPlace(0u, "Hello", 3.14f, 2.16f, 10u); net.addPlace(1u, "World", 1.0f, 1.5f, 42u); @@ -565,28 +634,10 @@ TEST(TestPetriNet, TestCaptionAfterRemove) ASSERT_EQ(net.m_places[0].tokens, 24u); } -//------------------------------------------------------------------------------ -TEST(TestPetriNet, TestIncrementId) -{ - PetriNet net(PetriNet::Type::TimedPetri); - - net.addPlace(42u, "", 3.5f, 4.0f, 45u); - ASSERT_EQ(net.m_next_place_id, 43u); - - net.addPlace(42u, "", 3.5f, 4.0f, 45u); - ASSERT_EQ(net.m_next_place_id, 43u); - - net.addPlace(25u, "", 3.5f, 4.0f, 45u); - ASSERT_EQ(net.m_next_place_id, 43u); - - net.addPlace(3.5f, 4.0f, 45u); - ASSERT_EQ(net.m_next_place_id, 44u); -} - //------------------------------------------------------------------------------ TEST(TestPetriNet, TestDoubleAdd) { - PetriNet net(PetriNet::Type::TimedPetri); + Net net(TypeOfNet::TimedPetriNet); Place& p1 = net.addPlace(42u, "", 3.5f, 4.0f, 45u); ASSERT_EQ(net.m_next_place_id, 43u); @@ -628,7 +679,7 @@ TEST(TestPetriNet, TestDoubleAdd) //------------------------------------------------------------------------------ TEST(TestPetriNet, TestInvalidAddArc) { - PetriNet net(PetriNet::Type::TimedPetri); + Net net(TypeOfNet::TimedPetriNet); Transition t1(42u, "", 3.5f, 4.0f, 45u, true); Transition t2(43u, "", 3.5f, 4.0f, 45u, false); @@ -671,16 +722,16 @@ TEST(TestPetriNet, TestInvalidAddArc) Transition& t3 = net.addTransition(43u, "", 3.5f, 4.0f, 45u); ASSERT_EQ(net.addArc(t3, p2), false); ASSERT_EQ(net.m_arcs.size(), 0u); - } //------------------------------------------------------------------------------ TEST(TestPetriNet, TestLoadedNetTimedPetri) { - PetriNet net(PetriNet::Type::TimedPetri); + Net net(TypeOfNet::TimedPetriNet); ASSERT_EQ(net.load("data/Howard2.json"), true); - ASSERT_EQ(net.type(), PetriNet::Type::TimedPetri); + ASSERT_STREQ(net.error().c_str(), ""); + ASSERT_EQ(net.type(), TypeOfNet::TimedEventGraph); ASSERT_EQ(net.isEmpty(), false); ASSERT_EQ(net.m_next_place_id, 5u); ASSERT_EQ(net.m_next_transition_id, 4u); @@ -902,7 +953,9 @@ TEST(TestPetriNet, TestLoadedNetTimedPetri) ASSERT_EQ(net.findTransition(2u), &net.m_transitions[2]); ASSERT_EQ(net.findTransition(3u), &net.m_transitions[3]); ASSERT_EQ(net.findTransition(4u), nullptr); - ASSERT_EQ(net.findNode("pouet"), nullptr); + ASSERT_EQ(net.findNode("foo"), nullptr); + ASSERT_EQ(net.findNode("T2o"), nullptr); + ASSERT_EQ(net.findNode("P0uet"), nullptr); ASSERT_EQ(net.findNode(""), nullptr); // Can we access to arcs ? @@ -964,6 +1017,7 @@ TEST(TestPetriNet, TestLoadedNetTimedPetri) ASSERT_EQ(net.m_transitions[2].isEnabled(), false); ASSERT_EQ(net.m_transitions[3].isEnabled(), false); +#if 0 // FIXMEEEEEEEEEE A FINALISER // Receptivity ASSERT_EQ(net.m_transitions[0].isValidated(), true); ASSERT_EQ(net.m_transitions[1].isValidated(), true); @@ -975,15 +1029,17 @@ TEST(TestPetriNet, TestLoadedNetTimedPetri) ASSERT_EQ(net.m_transitions[1].canFire(), false); ASSERT_EQ(net.m_transitions[2].canFire(), false); ASSERT_EQ(net.m_transitions[3].canFire(), false); +#endif } //------------------------------------------------------------------------------ TEST(TestPetriNet, TestLoadedNetGraphEvent) { - PetriNet net(PetriNet::Type::TimedPetri); + Net net(TypeOfNet::TimedPetriNet); ASSERT_EQ(net.load("data/EventGraph2.json"), true); - ASSERT_EQ(net.type(), PetriNet::Type::TimedEventGraph); + ASSERT_STREQ(net.error().c_str(), ""); + ASSERT_EQ(net.type(), TypeOfNet::TimedEventGraph); ASSERT_EQ(net.isEmpty(), false); ASSERT_EQ(net.m_next_place_id, 5u); ASSERT_EQ(net.m_next_transition_id, 4u); @@ -1267,6 +1323,7 @@ TEST(TestPetriNet, TestLoadedNetGraphEvent) ASSERT_EQ(net.m_transitions[2].isEnabled(), false); ASSERT_EQ(net.m_transitions[3].isEnabled(), false); +#if 0 // FIXMEEEEEEEEEEEEEEE // Receptivity ASSERT_EQ(net.m_transitions[0].isValidated(), true); ASSERT_EQ(net.m_transitions[1].isValidated(), true); @@ -1278,15 +1335,17 @@ TEST(TestPetriNet, TestLoadedNetGraphEvent) ASSERT_EQ(net.m_transitions[1].canFire(), false); ASSERT_EQ(net.m_transitions[2].canFire(), false); ASSERT_EQ(net.m_transitions[3].canFire(), false); +#endif } //------------------------------------------------------------------------------ TEST(TestPetriNet, TestRemoveNode) { - PetriNet net(PetriNet::Type::TimedPetri); + Net net(TypeOfNet::TimedPetriNet); ASSERT_EQ(net.load("data/Howard2.json"), true); - ASSERT_EQ(net.type(), PetriNet::Type::TimedPetri); + ASSERT_STREQ(net.error().c_str(), ""); + ASSERT_EQ(net.type(), TypeOfNet::TimedEventGraph); ASSERT_EQ(net.m_next_place_id, 5u); ASSERT_EQ(net.m_next_transition_id, 4u); ASSERT_EQ(net.m_places.size(), 5u); @@ -1594,13 +1653,17 @@ TEST(TestPetriNet, TestRemoveNode) //------------------------------------------------------------------------------ TEST(TestPetriNet, TestHowManyTokensCanBurnt) { - PetriNet net(PetriNet::Type::TimedPetri); + std::vector erroneous_arcs; + std::string error; + + Net net(TypeOfNet::TimedPetriNet); ASSERT_EQ(net.load("data/EventGraph.json"), true); - net.type(PetriNet::Type::Petri); + ASSERT_STREQ(net.error().c_str(), ""); + ASSERT_EQ(net.convertTo(TypeOfNet::PetriNet, error, erroneous_arcs), true); ASSERT_EQ(net.m_transitions.size(), 4u); - ASSERT_EQ(net.m_transitions[0].howManyTokensCanBurnt(), 1u); // u + //ASSERT_EQ(net.m_transitions[0].howManyTokensCanBurnt(), 1u); // u ASSERT_EQ(net.m_transitions[1].howManyTokensCanBurnt(), 0u); // x1 ASSERT_EQ(net.m_transitions[2].howManyTokensCanBurnt(), 0u); // x2 ASSERT_EQ(net.m_transitions[3].howManyTokensCanBurnt(), 0u); // y @@ -1610,4 +1673,4 @@ TEST(TestPetriNet, TestHowManyTokensCanBurnt) //ASSERT_EQ(net.m_transitions[1].howManyTokensCanBurnt(), 2u); // x1 //ASSERT_EQ(net.m_transitions[2].howManyTokensCanBurnt(), 2u); // x2 //ASSERT_EQ(net.m_transitions[3].howManyTokensCanBurnt(), 0u); // y -} +} \ No newline at end of file diff --git a/tests/data/AppelsDurgence.json b/tests/data/AppelsDurgence.json index 0c1db18..a311acf 100644 --- a/tests/data/AppelsDurgence.json +++ b/tests/data/AppelsDurgence.json @@ -1,9 +1,9 @@ { - "revision": 2, + "revision": 3, + "type": "Timed Petri net", "nets": [ { "name": "AppelsDurgence", - "type": "Timed Petri net", "places": [ { "id": 0, "caption": "P0", "tokens": 0, "x": 403, "y": 136 }, { "id": 1, "caption": "P1", "tokens": 0, "x": 269, "y": 217 }, diff --git a/tests/data/BadJSON/BadType.json b/tests/data/BadJSON/BadType.json new file mode 100644 index 0000000..cdbc086 --- /dev/null +++ b/tests/data/BadJSON/BadType.json @@ -0,0 +1,34 @@ +{ + "revision": 3, + "type": "Timed event graphe", + "nets": [ + { + "name": "Howard2", + "places": [ + { "id": 0, "caption": "P0", "tokens": 2, "x": 208, "y": 250 }, + { "id": 1, "caption": "P1", "tokens": 0, "x": 562, "y": 276 }, + { "id": 2, "caption": "P2", "tokens": 0, "x": 304, "y": 398 }, + { "id": 3, "caption": "P3", "tokens": 0, "x": 650, "y": 200 }, + { "id": 4, "caption": "P4", "tokens": 0, "x": 428, "y": 550 } + ], + "transitions": [ + { "id": 0, "caption": "T0", "x": 320, "y": 128, "angle": 0 }, + { "id": 1, "caption": "T1", "x": 458, "y": 398, "angle": 0 }, + { "id": 2, "caption": "T2", "x": 120, "y": 388, "angle": 0 }, + { "id": 3, "caption": "T3", "x": 734, "y": 406, "angle": 0 } + ], + "arcs": [ + { "from": "P0", "to": "T0" }, + { "from": "T0", "to": "P1", "duration": 5 }, + { "from": "P1", "to": "T1" }, + { "from": "T1", "to": "P2", "duration": 3 }, + { "from": "P2", "to": "T2" }, + { "from": "T2", "to": "P0", "duration": 5 }, + { "from": "T0", "to": "P3", "duration": 1 }, + { "from": "P3", "to": "T3" }, + { "from": "T3", "to": "P4", "duration": 1 }, + { "from": "P4", "to": "T2" } + ] + } + ] +} diff --git a/tests/data/BadJSON/NoName.json b/tests/data/BadJSON/NoName.json new file mode 100644 index 0000000..413a75b --- /dev/null +++ b/tests/data/BadJSON/NoName.json @@ -0,0 +1,33 @@ +{ + "revision": 3, + "type": "Timed event graph", + "nets": [ + { + "places": [ + { "id": 0, "caption": "P0", "tokens": 2, "x": 208, "y": 250 }, + { "id": 1, "caption": "P1", "tokens": 0, "x": 562, "y": 276 }, + { "id": 2, "caption": "P2", "tokens": 0, "x": 304, "y": 398 }, + { "id": 3, "caption": "P3", "tokens": 0, "x": 650, "y": 200 }, + { "id": 4, "caption": "P4", "tokens": 0, "x": 428, "y": 550 } + ], + "transitions": [ + { "id": 0, "caption": "T0", "x": 320, "y": 128, "angle": 0 }, + { "id": 1, "caption": "T1", "x": 458, "y": 398, "angle": 0 }, + { "id": 2, "caption": "T2", "x": 120, "y": 388, "angle": 0 }, + { "id": 3, "caption": "T3", "x": 734, "y": 406, "angle": 0 } + ], + "arcs": [ + { "from": "P0", "to": "T0" }, + { "from": "T0", "to": "P1", "duration": 5 }, + { "from": "P1", "to": "T1" }, + { "from": "T1", "to": "P2", "duration": 3 }, + { "from": "P2", "to": "T2" }, + { "from": "T2", "to": "P0", "duration": 5 }, + { "from": "T0", "to": "P3", "duration": 1 }, + { "from": "P3", "to": "T3" }, + { "from": "T3", "to": "P4", "duration": 1 }, + { "from": "P4", "to": "T2" } + ] + } + ] +} diff --git a/tests/data/DummyTransitions.json b/tests/data/DummyTransitions.json index 2122fd0..ca33f25 100644 --- a/tests/data/DummyTransitions.json +++ b/tests/data/DummyTransitions.json @@ -1,9 +1,9 @@ { - "revision": 2, + "revision": 3, + "type": "Timed Petri net", "nets": [ { "name": "DummyTransitions", - "type": "Timed Petri net", "places": [ { "id": 0, "caption": "P0", "tokens": 0, "x": 213, "y": 183 } ], diff --git a/tests/data/EventGraph.json b/tests/data/EventGraph.json index 0847b11..0dabe2c 100644 --- a/tests/data/EventGraph.json +++ b/tests/data/EventGraph.json @@ -1,9 +1,9 @@ { - "revision": 2, + "revision": 3, + "type": "Timed event graph", "nets": [ { "name": "EventGraph", - "type": "Timed event graph", "places": [ { "id": 0, "caption": "P0", "tokens": 0, "x": 219, "y": 128 }, { "id": 1, "caption": "P1", "tokens": 0, "x": 484, "y": 121 }, diff --git a/tests/data/EventGraph2.json b/tests/data/EventGraph2.json index 56ea0c4..8f7da23 100644 --- a/tests/data/EventGraph2.json +++ b/tests/data/EventGraph2.json @@ -1,9 +1,9 @@ { - "revision": 2, + "revision": 3, + "type": "Timed event graph", "nets": [ { "name": "Howard2", - "type": "Timed event graph", "places": [ { "id": 0, "caption": "P0", "tokens": 2, "x": 208, "y": 250 }, { "id": 1, "caption": "P1", "tokens": 0, "x": 562, "y": 276 }, diff --git a/tests/data/GRAFCET.json b/tests/data/GRAFCET.json index 914abda..d3329e7 100644 --- a/tests/data/GRAFCET.json +++ b/tests/data/GRAFCET.json @@ -1,9 +1,9 @@ { - "revision": 2, + "revision": 3, + "type": "GRAFCET", "nets": [ { "name": "AppelsDurgence", - "type": "GRAFCET", "places": [ { "id": 0, "caption": "P0", "tokens": 0, "x": 403, "y": 136 }, { "id": 1, "caption": "P1", "tokens": 0, "x": 269, "y": 217 }, diff --git a/tests/data/Howard2.json b/tests/data/Howard2.json index d01e355..8f7da23 100644 --- a/tests/data/Howard2.json +++ b/tests/data/Howard2.json @@ -1,9 +1,9 @@ { - "revision": 2, + "revision": 3, + "type": "Timed event graph", "nets": [ { "name": "Howard2", - "type": "Timed Petri net", "places": [ { "id": 0, "caption": "P0", "tokens": 2, "x": 208, "y": 250 }, { "id": 1, "caption": "P1", "tokens": 0, "x": 562, "y": 276 }, diff --git a/tests/data/JPQ.json b/tests/data/JPQ.json index 6e1825f..db6ca19 100644 --- a/tests/data/JPQ.json +++ b/tests/data/JPQ.json @@ -1,22 +1,22 @@ { - "revision": 2, + "revision": 3, + "type": "Timed Petri net", "nets": [ { "name": "JPQ", - "type": "Timed event graph", "places": [ - { "id": 0, "caption": "P0", "tokens": 1, "x": 375, "y": 288 }, - { "id": 1, "caption": "P1", "tokens": 1, "x": 372, "y": 173 }, - { "id": 2, "caption": "P2", "tokens": 1, "x": 138, "y": 211 }, - { "id": 3, "caption": "P3", "tokens": 0, "x": 201, "y": 304 }, - { "id": 4, "caption": "P4", "tokens": 1, "x": 621, "y": 211 }, - { "id": 5, "caption": "P5", "tokens": 0, "x": 613, "y": 114 } + { "id": 0, "caption": "P0", "tokens": 1, "x": 291, "y": 171 }, + { "id": 1, "caption": "P1", "tokens": 1, "x": 295, "y": 77 }, + { "id": 2, "caption": "P2", "tokens": 1, "x": 85, "y": 82 }, + { "id": 3, "caption": "P3", "tokens": 0, "x": 144, "y": 159 }, + { "id": 4, "caption": "P4", "tokens": 1, "x": 546, "y": 164 }, + { "id": 5, "caption": "P5", "tokens": 0, "x": 459, "y": 90 } ], "transitions": [ - { "id": 0, "caption": "T0", "x": 216, "y": 111, "angle": 0 }, - { "id": 1, "caption": "T1", "x": 380, "y": 111, "angle": 0 }, - { "id": 2, "caption": "T2", "x": 102, "y": 111, "angle": 0 }, - { "id": 3, "caption": "T3", "x": 516, "y": 111, "angle": 0 } + { "id": 0, "caption": "Node 0", "x": 216, "y": 111, "angle": 0 }, + { "id": 1, "caption": "Node 1", "x": 380, "y": 111, "angle": 0 }, + { "id": 2, "caption": "y(k)", "x": 86, "y": 159, "angle": 0 }, + { "id": 3, "caption": "u(k)", "x": 546, "y": 76, "angle": 0 } ], "arcs": [ { "from": "T0", "to": "P0", "duration": 2 }, diff --git a/tests/data/TrafficLights.json b/tests/data/TrafficLights.json index 9bdecb7..294712e 100644 --- a/tests/data/TrafficLights.json +++ b/tests/data/TrafficLights.json @@ -1,9 +1,9 @@ { - "revision": 2, + "revision": 3, + "type": "Timed Petri net", "nets": [ { - "name": "TrafficLight", - "type": "Timed Petri net", + "name": "TrafficLights", "places": [ { "id": 0, "caption": "Red1", "tokens": 1, "x": 146, "y": 250 }, { "id": 1, "caption": "Green1", "tokens": 0, "x": 389, "y": 173 }, diff --git a/tests/AnimationTests.cpp b/tests/old/AnimationTests.cpp similarity index 100% rename from tests/AnimationTests.cpp rename to tests/old/AnimationTests.cpp diff --git a/tests/SparseMatrixTests.cpp b/tests/old/SparseMatrixTests.cpp similarity index 100% rename from tests/SparseMatrixTests.cpp rename to tests/old/SparseMatrixTests.cpp