Fixed friend relationship generation in mermaid class diagram generator

This commit is contained in:
Bartek Kryza
2023-09-12 20:18:11 +02:00
parent 7c70ab69ad
commit 59180efebf
4 changed files with 50 additions and 14 deletions

View File

@@ -370,17 +370,21 @@ void generator::generate_relationship(
if (util::starts_with(destination, std::string{"::"})) if (util::starts_with(destination, std::string{"::"}))
destination = destination.substr(2, destination.size()); destination = destination.substr(2, destination.size());
std::string puml_relation; std::string mmd_relation;
if (!r.multiplicity_source().empty()) if (!r.multiplicity_source().empty())
puml_relation += "\"" + r.multiplicity_source() + "\" "; mmd_relation += "\"" + r.multiplicity_source() + "\" ";
puml_relation += mermaid_common::to_mermaid(r.type(), r.style()); mmd_relation += mermaid_common::to_mermaid(r.type(), r.style());
if (!r.multiplicity_destination().empty()) if (!r.multiplicity_destination().empty())
puml_relation += " \"" + r.multiplicity_destination() + "\""; mmd_relation += " \"" + r.multiplicity_destination() + "\"";
if (!r.label().empty()) { if (!r.label().empty()) {
rendered_relations.emplace(r.label()); if (r.type() == relationship_t::kFriendship)
rendered_relations.emplace(fmt::format(
"{}[friend]", mermaid_common::to_mermaid(r.access())));
else
rendered_relations.emplace(r.label());
} }
} }
@@ -444,7 +448,10 @@ void generator::generate_relationships(
relstr << " : "; relstr << " : ";
if (!r.label().empty()) { if (!r.label().empty()) {
relstr << mermaid_common::to_mermaid(r.access()) << r.label(); auto lbl = r.label();
if (r.type() == relationship_t::kFriendship)
lbl = "[friend]";
relstr << mermaid_common::to_mermaid(r.access()) << lbl;
rendered_relations.emplace(r.label()); rendered_relations.emplace(r.label());
} }
@@ -516,14 +523,14 @@ void generator::generate_relationships(
try { try {
destination = r.destination(); destination = r.destination();
std::string puml_relation; std::string mmd_relation;
if (!r.multiplicity_source().empty()) if (!r.multiplicity_source().empty())
puml_relation += "\"" + r.multiplicity_source() + "\" "; mmd_relation += "\"" + r.multiplicity_source() + "\" ";
puml_relation += mermaid_common::to_mermaid(r.type(), r.style()); mmd_relation += mermaid_common::to_mermaid(r.type(), r.style());
if (!r.multiplicity_destination().empty()) if (!r.multiplicity_destination().empty())
puml_relation += " \"" + r.multiplicity_destination() + "\""; mmd_relation += " \"" + r.multiplicity_destination() + "\"";
std::string target_alias; std::string target_alias;
try { try {
@@ -539,18 +546,21 @@ void generator::generate_relationships(
continue; continue;
if (r.type() == relationship_t::kContainment) { if (r.type() == relationship_t::kContainment) {
relstr << indent(1) << target_alias << " " << puml_relation relstr << indent(1) << target_alias << " " << mmd_relation
<< " " << c.alias(); << " " << c.alias();
} }
else { else {
relstr << indent(1) << c.alias() << " " << puml_relation << " " relstr << indent(1) << c.alias() << " " << mmd_relation << " "
<< target_alias; << target_alias;
} }
relstr << " : "; relstr << " : ";
if (!r.label().empty()) { if (!r.label().empty()) {
relstr << mermaid_common::to_mermaid(r.access()) << r.label(); auto lbl = r.label();
if (r.type() == relationship_t::kFriendship)
lbl = "[friend]";
relstr << mermaid_common::to_mermaid(r.access()) << lbl;
rendered_relations.emplace(r.label()); rendered_relations.emplace(r.label());
} }
@@ -605,6 +615,10 @@ void generator::generate_relationships(const enum_ &e, std::ostream &ostr) const
<< " " << target_alias; << " " << target_alias;
} }
auto lbl = r.label();
if (r.type() == relationship_t::kFriendship)
lbl = "[friend]";
relstr << " : " << r.label(); relstr << " : " << r.label();
relstr << '\n'; relstr << '\n';

View File

@@ -59,6 +59,7 @@ TEST_CASE("t00011", "[test-case][class]")
auto src = generate_class_mermaid(diagram, *model); auto src = generate_class_mermaid(diagram, *model);
mermaid::AliasMatcher _A(src); mermaid::AliasMatcher _A(src);
using mermaid::IsFriend;
REQUIRE_THAT(src, IsClass(_A("A"))); REQUIRE_THAT(src, IsClass(_A("A")));
REQUIRE_THAT(src, IsClass(_A("B"))); REQUIRE_THAT(src, IsClass(_A("B")));
@@ -67,7 +68,7 @@ TEST_CASE("t00011", "[test-case][class]")
REQUIRE_THAT(src, IsAssociation(_A("B"), _A("A"))); REQUIRE_THAT(src, IsAssociation(_A("B"), _A("A")));
REQUIRE_THAT(src, IsFriend<Public>(_A("A"), _A("B"))); REQUIRE_THAT(src, IsFriend<Public>(_A("A"), _A("B")));
// REQUIRE_THAT(puml, IsFriend(_A("A"), _A("D<T>"))); // REQUIRE_THAT(src, IsFriend(_A("A"), _A("D<T>")));
save_mermaid(config.output_directory(), diagram->name + ".mmd", src); save_mermaid(config.output_directory(), diagram->name + ".mmd", src);
} }

View File

@@ -89,6 +89,7 @@ TEST_CASE("t00045", "[test-case][class]")
auto src = generate_class_mermaid(diagram, *model); auto src = generate_class_mermaid(diagram, *model);
mermaid::AliasMatcher _A(src); mermaid::AliasMatcher _A(src);
using mermaid::IsFriend;
REQUIRE_THAT(src, IsClass(_A("A"))); REQUIRE_THAT(src, IsClass(_A("A")));
REQUIRE_THAT(src, IsClass(_A("ns1::A"))); REQUIRE_THAT(src, IsClass(_A("ns1::A")));

View File

@@ -905,6 +905,26 @@ ContainsMatcher IsFriend(std::string const &from, std::string const &to,
caseSensitivity)); caseSensitivity));
} }
namespace mermaid {
template <typename... Ts>
ContainsMatcher IsFriend(std::string const &from, std::string const &to,
CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes)
{
std::string pattern;
if constexpr (has_type<Public, Ts...>())
pattern = "+";
else if constexpr (has_type<Protected, Ts...>())
pattern = "#";
else
pattern = "-";
return ContainsMatcher(
CasedString(fmt::format("{} <.. {} : {}[friend]", from, to, pattern),
caseSensitivity));
}
}
ContainsMatcher IsPackage(std::string const &str, ContainsMatcher IsPackage(std::string const &str,
CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes)
{ {