From 757dd3eed962befc13cbf80b33173019257c372a Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Fri, 9 Dec 2022 23:34:52 +0100 Subject: [PATCH] Added recursive template sequence diagram test case --- .../plantuml/sequence_diagram_generator.cc | 7 +-- src/sequence_diagram/model/participant.cc | 8 +-- src/sequence_diagram/model/participant.h | 10 ++-- tests/t20018/.clang-uml | 14 +++++ tests/t20018/t20018.cc | 20 +++++++ tests/t20018/test_case.h | 57 +++++++++++++++++++ tests/test_cases.cc | 1 + tests/test_cases.yaml | 3 + 8 files changed, 107 insertions(+), 13 deletions(-) create mode 100644 tests/t20018/.clang-uml create mode 100644 tests/t20018/t20018.cc create mode 100644 tests/t20018/test_case.h diff --git a/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc b/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc index aeb9e1e4..6598d751 100644 --- a/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc +++ b/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc @@ -90,10 +90,9 @@ void generator::generate_return(const message &m, std::ostream &ostr) const { // Add return activity only for messages between different actors and // only if the return type is different than void - if ((m.from != m.to) && (m.return_type != "void")) { - const auto &from = m_model.get_participant(m.from); - const auto &to = m_model.get_participant(m.to); - + const auto &from = m_model.get_participant(m.from); + const auto &to = m_model.get_participant(m.to); + if ((m.from != m.to) && !to.value().is_void()) { const std::string from_alias = generate_alias(from.value()); const std::string to_alias = generate_alias(to.value()); diff --git a/src/sequence_diagram/model/participant.cc b/src/sequence_diagram/model/participant.cc index f9f15098..fdf61a28 100644 --- a/src/sequence_diagram/model/participant.cc +++ b/src/sequence_diagram/model/participant.cc @@ -209,6 +209,10 @@ bool function::is_void() const { return is_void_; } void function::is_void(bool v) { is_void_ = v; } +bool function::is_static() const { return is_static_; } + +void function::is_static(bool s) { is_static_ = s; } + void function::add_parameter(const std::string &a) { parameters_.push_back(a); } const std::vector &function::parameters() const @@ -268,10 +272,6 @@ std::string method::to_string() const type_name(), id(), full_name(false), class_id()); } -bool method::is_static() const { return is_static_; } - -void method::is_static(bool s) { is_static_ = s; } - function_template::function_template( const common::model::namespace_ &using_namespace) : function{using_namespace} diff --git a/src/sequence_diagram/model/participant.h b/src/sequence_diagram/model/participant.h index 3b41fb62..dce84dec 100644 --- a/src/sequence_diagram/model/participant.h +++ b/src/sequence_diagram/model/participant.h @@ -160,6 +160,10 @@ struct function : public participant { void is_void(bool v); + bool is_static() const; + + void is_static(bool s); + void add_parameter(const std::string &a); const std::vector ¶meters() const; @@ -167,6 +171,7 @@ struct function : public participant { private: bool is_const_{false}; bool is_void_{false}; + bool is_static_{false}; std::vector parameters_; }; @@ -200,15 +205,10 @@ struct method : public function { std::string to_string() const override; - bool is_static() const; - - void is_static(bool s); - private: diagram_element::id_t class_id_; std::string method_name_; std::string class_full_name_; - bool is_static_{false}; }; struct function_template : public function, public template_trait { diff --git a/tests/t20018/.clang-uml b/tests/t20018/.clang-uml new file mode 100644 index 00000000..a3f634da --- /dev/null +++ b/tests/t20018/.clang-uml @@ -0,0 +1,14 @@ +compilation_database_dir: .. +output_directory: puml +diagrams: + t20018_sequence: + type: sequence + glob: + - ../../tests/t20018/t20018.cc + include: + namespaces: + - clanguml::t20018 + using_namespace: + - clanguml::t20018 + start_from: + - function: "clanguml::t20018::tmain()" \ No newline at end of file diff --git a/tests/t20018/t20018.cc b/tests/t20018/t20018.cc new file mode 100644 index 00000000..6d36524c --- /dev/null +++ b/tests/t20018/t20018.cc @@ -0,0 +1,20 @@ +#include + +namespace clanguml { +namespace t20018 { + +template struct Factorial { + static const int value = N * Factorial::value; + + static void print() { Factorial::print(); } +}; + +template <> struct Factorial<0> { + static const int value = 1; + + static void print() { std::cout << "Hello world\n"; } +}; + +void tmain() { Factorial<5>::print(); } +} +} \ No newline at end of file diff --git a/tests/t20018/test_case.h b/tests/t20018/test_case.h new file mode 100644 index 00000000..18734c5d --- /dev/null +++ b/tests/t20018/test_case.h @@ -0,0 +1,57 @@ +/** + * tests/t20018/test_case.h + * + * Copyright (c) 2021-2022 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("t20018", "[test-case][sequence]") +{ + auto [config, db] = load_config("t20018"); + + auto diagram = config.diagrams["t20018_sequence"]; + + REQUIRE(diagram->name == "t20018_sequence"); + + auto model = generate_sequence_diagram(*db, diagram); + + REQUIRE(model->name() == "t20018_sequence"); + + auto puml = generate_sequence_puml(diagram, *model); + AliasMatcher _A(puml); + + REQUIRE_THAT(puml, StartsWith("@startuml")); + REQUIRE_THAT(puml, EndsWith("@enduml\n")); + + // Check if all calls exist + REQUIRE_THAT( + puml, HasCall(_A("Factorial<5>"), _A("Factorial<4>"), "__print()__")); + REQUIRE_THAT(puml, + !HasCallWithResponse( + _A("Factorial<5>"), _A("Factorial<4>"), "__print()__")); + REQUIRE_THAT( + puml, HasCall(_A("Factorial<4>"), _A("Factorial<3>"), "__print()__")); + REQUIRE_THAT( + puml, HasCall(_A("Factorial<3>"), _A("Factorial<2>"), "__print()__")); + REQUIRE_THAT( + puml, HasCall(_A("Factorial<2>"), _A("Factorial<1>"), "__print()__")); + REQUIRE_THAT( + puml, HasCall(_A("Factorial<1>"), _A("Factorial<0>"), "__print()__")); + + // REQUIRE_THAT(puml, HasCall("A", "log_result")); + // REQUIRE_THAT(puml, HasCallWithResponse("B", "A", "add3")); + + save_puml( + "./" + config.output_directory() + "/" + diagram->name + ".puml", puml); +} \ No newline at end of file diff --git a/tests/test_cases.cc b/tests/test_cases.cc index 8846bfbe..5a875638 100644 --- a/tests/test_cases.cc +++ b/tests/test_cases.cc @@ -264,6 +264,7 @@ using namespace clanguml::test::matchers; #include "t20015/test_case.h" #include "t20016/test_case.h" #include "t20017/test_case.h" +#include "t20018/test_case.h" /// /// Package diagram tests diff --git a/tests/test_cases.yaml b/tests/test_cases.yaml index 4651bcda..ccaf8d29 100644 --- a/tests/test_cases.yaml +++ b/tests/test_cases.yaml @@ -199,6 +199,9 @@ test_cases: - name: t20017 title: Test case for combine_free_functions_into_file_participants option description: + - name: t20018 + title: Recursive template sequence diagram test case + description: Package diagrams: - name: t30001 title: Basic package diagram test case