From 64ffac3a774f2d357aac97cf9f7160a15c687790 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Tue, 15 Feb 2022 20:36:03 +0100 Subject: [PATCH] Added class diagram layout hints --- .../plantuml/class_diagram_generator.cc | 27 ++++++++++ .../plantuml/class_diagram_generator.h | 2 + tests/t00035/.clang-uml | 18 +++++++ tests/t00035/t00035.cc | 15 ++++++ tests/t00035/test_case.h | 52 +++++++++++++++++++ tests/test_cases.cc | 1 + 6 files changed, 115 insertions(+) create mode 100644 tests/t00035/.clang-uml create mode 100644 tests/t00035/t00035.cc create mode 100644 tests/t00035/test_case.h diff --git a/src/class_diagram/generators/plantuml/class_diagram_generator.cc b/src/class_diagram/generators/plantuml/class_diagram_generator.cc index 69e911ae..965939a5 100644 --- a/src/class_diagram/generators/plantuml/class_diagram_generator.cc +++ b/src/class_diagram/generators/plantuml/class_diagram_generator.cc @@ -348,6 +348,31 @@ void generator::generate(const enum_ &e, std::ostream &ostr) const } } +void generator::generate_config_layout_hints(std::ostream &ostr) const +{ + const auto &uns = m_config.using_namespace(); + + // Generate layout hints + for (const auto &[entity, hints] : m_config.layout()) { + for (const auto &hint : hints) { + std::stringstream hint_str; + try { + hint_str << m_model.to_alias(ns_relative(uns, entity)) + << " -[hidden]" + << clanguml::config::to_string(hint.hint) << "- " + << m_model.to_alias(ns_relative(uns, hint.entity)) + << '\n'; + ostr << hint_str.str(); + } + catch (error::uml_alias_missing &e) { + LOG_ERROR("=== Skipping layout hint from {} to {} due " + "to: {}", + entity, hint.entity, e.what()); + } + } + } +} + void generator::generate(std::ostream &ostr) const { ostr << "@startuml" << '\n'; @@ -393,6 +418,8 @@ void generator::generate(std::ostream &ostr) const ostr << '\n'; } + generate_config_layout_hints(ostr); + // Process aliases in any of the puml directives for (const auto &b : m_config.puml().after) { std::string note{b}; diff --git a/src/class_diagram/generators/plantuml/class_diagram_generator.h b/src/class_diagram/generators/plantuml/class_diagram_generator.h index 2f8388c0..eb48897c 100644 --- a/src/class_diagram/generators/plantuml/class_diagram_generator.h +++ b/src/class_diagram/generators/plantuml/class_diagram_generator.h @@ -64,6 +64,8 @@ public: void generate_alias(const enum_ &e, std::ostream &ostr) const; + void generate_config_layout_hints(std::ostream &ostr) const; + void generate(const class_ &c, std::ostream &ostr) const; void generate(const enum_ &e, std::ostream &ostr) const; diff --git a/tests/t00035/.clang-uml b/tests/t00035/.clang-uml new file mode 100644 index 00000000..e2ab858d --- /dev/null +++ b/tests/t00035/.clang-uml @@ -0,0 +1,18 @@ +compilation_database_dir: .. +output_directory: puml +diagrams: + t00035_class: + type: class + glob: + - ../../tests/t00035/t00035.cc + using_namespace: + - clanguml::t00035 + include: + namespaces: + - clanguml::t00035 + layout: + Center: + - up: Top + - down: Bottom + - left: Left + - right: Right diff --git a/tests/t00035/t00035.cc b/tests/t00035/t00035.cc new file mode 100644 index 00000000..12bb4ca6 --- /dev/null +++ b/tests/t00035/t00035.cc @@ -0,0 +1,15 @@ +namespace clanguml { +namespace t00035 { + +struct Top {}; + +struct Left {}; + +struct Center {}; + +struct Bottom {}; + +struct Right {}; + +} // namespace t00035 +} // namespace clanguml diff --git a/tests/t00035/test_case.h b/tests/t00035/test_case.h new file mode 100644 index 00000000..7cbf4163 --- /dev/null +++ b/tests/t00035/test_case.h @@ -0,0 +1,52 @@ +/** + * tests/t00035/test_case.cc + * + * 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("t00035", "[test-case][class]") +{ + auto [config, db] = load_config("t00035"); + + auto diagram = config.diagrams["t00035_class"]; + + REQUIRE(diagram->name == "t00035_class"); + + REQUIRE(diagram->should_include("clanguml::t00035::A")); + + auto model = generate_class_diagram(db, diagram); + + REQUIRE(model.name() == "t00035_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, IsClass(_A("Top"))); + REQUIRE_THAT(puml, IsClass(_A("Bottom"))); + REQUIRE_THAT(puml, IsClass(_A("Center"))); + REQUIRE_THAT(puml, IsClass(_A("Left"))); + REQUIRE_THAT(puml, IsClass(_A("Right"))); + + REQUIRE_THAT(puml, IsLayoutHint(_A("Center"), "up", _A("Top"))); + REQUIRE_THAT(puml, IsLayoutHint(_A("Center"), "left", _A("Left"))); + REQUIRE_THAT(puml, IsLayoutHint(_A("Center"), "right", _A("Right"))); + REQUIRE_THAT(puml, IsLayoutHint(_A("Center"), "down", _A("Bottom"))); + + save_puml( + "./" + config.output_directory() + "/" + diagram->name + ".puml", puml); +} diff --git a/tests/test_cases.cc b/tests/test_cases.cc index e721378d..8e42aff2 100644 --- a/tests/test_cases.cc +++ b/tests/test_cases.cc @@ -166,6 +166,7 @@ using namespace clanguml::test::matchers; #include "t00032/test_case.h" #include "t00033/test_case.h" #include "t00034/test_case.h" +#include "t00035/test_case.h" // // Sequence diagram tests