diff --git a/docs/test_cases.md b/docs/test_cases.md index 9f87eca0..e4da3ba2 100644 --- a/docs/test_cases.md +++ b/docs/test_cases.md @@ -24,6 +24,7 @@ * [t00023](./test_cases/t00023.md) - Strategy pattern * [t00024](./test_cases/t00024.md) - Proxy pattern * [t00025](./test_cases/t00025.md) - Template proxy pattern + * [t00026](./test_cases/t00026.md) - Template memento pattern ## Sequence diagrams * [t20001](./test_cases/t20001.md) - Basic sequence diagram ## Configuration diagrams diff --git a/docs/test_cases/t00026.md b/docs/test_cases/t00026.md new file mode 100644 index 00000000..fece16cc --- /dev/null +++ b/docs/test_cases/t00026.md @@ -0,0 +1,83 @@ +# t00026 - Template memento pattern +## Config +```yaml +compilation_database_dir: .. +output_directory: puml +diagrams: + t00026_class: + type: class + glob: + - ../../tests/t00026/t00026.cc + using_namespace: + - clanguml::t00026 + include: + namespaces: + - clanguml::t00026 + +``` +## Source code +File t00026.cc +```cpp +#include +#include +#include + +namespace clanguml { +namespace t00026 { + +template class Memento { +public: + Memento(T &&v) + : m_value(std::forward(v)) + { + } + + T value() const { return m_value; } + +private: + T m_value; +}; + +template class Originator { +public: + Originator(T &&v) + : m_value(std::forward(v)) + { + } + + Memento memoize_value() const { return Memento{m_value}; } + + void load(const Memento &m) { m_value = m.value(); } + + void print() const { std::cout << m_value << std::endl; } + + void set(T &&v) { m_value = std::forward(v); } + +private: + T m_value; +}; + +template class Caretaker { +public: + Memento &state(const std::string &n) { return m_mementos.at(n); } + + void set_state(const std::string &s, Memento &&m) + { + m_mementos.try_emplace(s, std::move(m)); + } + +private: + std::unordered_map> m_mementos; +}; + +struct StringMemento { + Caretaker caretaker; + Originator originator; +}; + +} +} + +``` +## Generated UML diagrams +![t00026_class](./t00026_class.png "Template memento pattern") diff --git a/docs/test_cases/t00026_class.png b/docs/test_cases/t00026_class.png new file mode 100644 index 00000000..45dc0e97 Binary files /dev/null and b/docs/test_cases/t00026_class.png differ diff --git a/tests/t00026/.clanguml b/tests/t00026/.clanguml new file mode 100644 index 00000000..33224cee --- /dev/null +++ b/tests/t00026/.clanguml @@ -0,0 +1,12 @@ +compilation_database_dir: .. +output_directory: puml +diagrams: + t00026_class: + type: class + glob: + - ../../tests/t00026/t00026.cc + using_namespace: + - clanguml::t00026 + include: + namespaces: + - clanguml::t00026 diff --git a/tests/t00026/t00026.cc b/tests/t00026/t00026.cc new file mode 100644 index 00000000..747e8f4b --- /dev/null +++ b/tests/t00026/t00026.cc @@ -0,0 +1,58 @@ +#include +#include +#include + +namespace clanguml { +namespace t00026 { + +template class Memento { +public: + Memento(T &&v) + : m_value(std::forward(v)) + { + } + + T value() const { return m_value; } + +private: + T m_value; +}; + +template class Originator { +public: + Originator(T &&v) + : m_value(std::forward(v)) + { + } + + Memento memoize_value() const { return Memento{m_value}; } + + void load(const Memento &m) { m_value = m.value(); } + + void print() const { std::cout << m_value << std::endl; } + + void set(T &&v) { m_value = std::forward(v); } + +private: + T m_value; +}; + +template class Caretaker { +public: + Memento &state(const std::string &n) { return m_mementos.at(n); } + + void set_state(const std::string &s, Memento &&m) + { + m_mementos.try_emplace(s, std::move(m)); + } + +private: + std::unordered_map> m_mementos; +}; + +struct StringMemento { + Caretaker caretaker; + Originator originator; +}; +} +} diff --git a/tests/t00026/test_case.h b/tests/t00026/test_case.h new file mode 100644 index 00000000..4dc8892c --- /dev/null +++ b/tests/t00026/test_case.h @@ -0,0 +1,54 @@ +/** + * tests/t00026/test_case.cc + * + * Copyright (c) 2021 Bartek Kryza + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +TEST_CASE("t00026", "[test-case][class]") +{ + auto [config, db] = load_config("t00026"); + + auto diagram = config.diagrams["t00026_class"]; + + REQUIRE(diagram->name == "t00026_class"); + + REQUIRE(diagram->include.namespaces.size() == 1); + REQUIRE_THAT(diagram->include.namespaces, + VectorContains(std::string{"clanguml::t00026"})); + + REQUIRE(diagram->exclude.namespaces.size() == 0); + + REQUIRE(diagram->should_include("clanguml::t00026::A")); + + auto model = generate_class_diagram(db, diagram); + + REQUIRE(model.name == "t00026_class"); + + auto puml = generate_class_puml(diagram, model); + AliasMatcher _A(puml); + + REQUIRE_THAT(puml, StartsWith("@startuml")); + REQUIRE_THAT(puml, EndsWith("@enduml\n")); + REQUIRE_THAT(puml, IsClassTemplate("Memento", "T")); + REQUIRE_THAT(puml, IsClassTemplate("Originator", "T")); + REQUIRE_THAT(puml, IsClassTemplate("Caretaker", "T")); + REQUIRE_THAT(puml, + IsInstantiation(_A("Originator"), _A("Originator"))); + REQUIRE_THAT(puml, + IsInstantiation(_A("Caretaker"), _A("Caretaker"))); + + save_puml( + "./" + config.output_directory + "/" + diagram->name + ".puml", puml); +} diff --git a/tests/test_cases.cc b/tests/test_cases.cc index 36c830a8..c2140124 100644 --- a/tests/test_cases.cc +++ b/tests/test_cases.cc @@ -129,6 +129,7 @@ using namespace clanguml::test::matchers; #include "t00023/test_case.h" #include "t00024/test_case.h" #include "t00025/test_case.h" +#include "t00026/test_case.h" // // Sequence diagram tests diff --git a/tests/test_cases.yaml b/tests/test_cases.yaml index ab33058f..72ab5a2f 100644 --- a/tests/test_cases.yaml +++ b/tests/test_cases.yaml @@ -72,6 +72,9 @@ test_cases: - name: t00025 title: Template proxy pattern description: + - name: t00026 + title: Template memento pattern + description: Sequence diagrams: - name: t20001 title: Basic sequence diagram