Added relationship and scope filter test case

This commit is contained in:
Bartek Kryza
2022-03-30 01:01:01 +02:00
parent 7c7f8a3b14
commit a216a81e19
9 changed files with 166 additions and 55 deletions

View File

@@ -158,7 +158,7 @@ std::optional<bool> subclass_filter::match(
relationship_filter::relationship_filter( relationship_filter::relationship_filter(
filter_t type, std::vector<relationship_t> relationships) filter_t type, std::vector<relationship_t> relationships)
: filter_visitor{type} : filter_visitor{type}
, relationships_{std::move(relationships)} , relationships_{relationships}
{ {
} }
@@ -174,7 +174,7 @@ std::optional<bool> relationship_filter::match(
scope_filter::scope_filter(filter_t type, std::vector<scope_t> scopes) scope_filter::scope_filter(filter_t type, std::vector<scope_t> scopes)
: filter_visitor{type} : filter_visitor{type}
, scopes_{std::move(scopes)} , scopes_{scopes}
{ {
} }
@@ -263,9 +263,9 @@ void diagram_filter::init_filters(const config::diagram &c)
exclusive_.emplace_back(std::make_unique<element_filter>( exclusive_.emplace_back(std::make_unique<element_filter>(
filter_t::kExclusive, c.exclude().elements)); filter_t::kExclusive, c.exclude().elements));
exclusive_.emplace_back(std::make_unique<relationship_filter>( exclusive_.emplace_back(std::make_unique<relationship_filter>(
filter_t::kExclusive, c.include().relationships)); filter_t::kExclusive, c.exclude().relationships));
exclusive_.emplace_back(std::make_unique<scope_filter>( exclusive_.emplace_back(std::make_unique<scope_filter>(
filter_t::kExclusive, c.include().scopes)); filter_t::kExclusive, c.exclude().scopes));
exclusive_.emplace_back(std::make_unique<subclass_filter>( exclusive_.emplace_back(std::make_unique<subclass_filter>(
filter_t::kExclusive, c.exclude().subclasses)); filter_t::kExclusive, c.exclude().subclasses));
exclusive_.emplace_back(std::make_unique<context_filter>( exclusive_.emplace_back(std::make_unique<context_filter>(

View File

@@ -137,8 +137,8 @@ public:
bool exc = std::any_of( bool exc = std::any_of(
exclusive_.begin(), exclusive_.end(), [this, &e](const auto &ex) { exclusive_.begin(), exclusive_.end(), [this, &e](const auto &ex) {
auto m = ex->match(diagram_, e); auto m = ex->match(diagram_, e);
// Return a match if a filter is undefined for specific element // Return true if a filter is defined for specific element
// or it's a match // and it's a match
return m.has_value() && m.value(); return m.has_value() && m.value();
}); });
if (exc) if (exc)
@@ -147,7 +147,7 @@ public:
bool inc = std::all_of( bool inc = std::all_of(
inclusive_.begin(), inclusive_.end(), [this, &e](const auto &in) { inclusive_.begin(), inclusive_.end(), [this, &e](const auto &in) {
auto m = in->match(diagram_, e); auto m = in->match(diagram_, e);
// Return a match if a filter is undefined for specific element // Return true if a filter is undefined for specific element
// or it's a match // or it's a match
return !m.has_value() || m.value(); return !m.has_value() || m.value();
}); });

View File

@@ -250,6 +250,53 @@ template <> struct convert<scope_t> {
} }
}; };
//
// config relationship_t decoder
//
template <> struct convert<relationship_t> {
static bool decode(const Node &node, relationship_t &rhs)
{
assert(node.Type() == NodeType::Scalar);
auto relationship_name = node.as<std::string>();
if (relationship_name == "extension" ||
relationship_name == "inheritance") {
rhs = relationship_t::kExtension;
}
else if (relationship_name == "composition") {
rhs = relationship_t::kComposition;
}
else if (relationship_name == "aggregation") {
rhs = relationship_t::kAggregation;
}
else if (relationship_name == "containment") {
rhs = relationship_t::kContainment;
}
else if (relationship_name == "ownership") {
rhs = relationship_t::kOwnership;
}
else if (relationship_name == "association") {
rhs = relationship_t::kAssociation;
}
else if (relationship_name == "instantiation") {
rhs = relationship_t::kInstantiation;
}
else if (relationship_name == "friendship") {
rhs = relationship_t::kFriendship;
}
else if (relationship_name == "dependency") {
rhs = relationship_t::kDependency;
}
else if (relationship_name == "none") {
rhs = relationship_t::kNone;
}
else
return false;
return true;
}
};
template <> struct convert<std::vector<source_location>> { template <> struct convert<std::vector<source_location>> {
static bool decode(const Node &node, std::vector<source_location> &rhs) static bool decode(const Node &node, std::vector<source_location> &rhs)
{ {
@@ -465,53 +512,6 @@ template <> struct convert<layout_hint> {
} }
}; };
//
// config relationship_t decoder
//
template <> struct convert<relationship_t> {
static bool decode(const Node &node, relationship_t &rhs)
{
assert(node.Type() == NodeType::Scalar);
auto relationship_name = node.as<std::string>();
if (relationship_name == "extension" ||
relationship_name == "inheritance") {
rhs = relationship_t::kExtension;
}
else if (relationship_name == "composition") {
rhs = relationship_t::kComposition;
}
else if (relationship_name == "aggregation") {
rhs = relationship_t::kAggregation;
}
else if (relationship_name == "containment") {
rhs = relationship_t::kContainment;
}
else if (relationship_name == "ownership") {
rhs = relationship_t::kOwnership;
}
else if (relationship_name == "association") {
rhs = relationship_t::kAssociation;
}
else if (relationship_name == "instantiation") {
rhs = relationship_t::kInstantiation;
}
else if (relationship_name == "friendship") {
rhs = relationship_t::kFriendship;
}
else if (relationship_name == "dependency") {
rhs = relationship_t::kDependency;
}
else if (relationship_name == "none") {
rhs = relationship_t::kNone;
}
else
return false;
return true;
}
};
// //
// config Yaml decoder // config Yaml decoder
// //

21
tests/t00040/.clang-uml Normal file
View File

@@ -0,0 +1,21 @@
compilation_database_dir: ..
output_directory: puml
diagrams:
t00040_class:
type: class
generate_packages: false
glob:
- ../../tests/t00040/t00040.cc
using_namespace:
- clanguml::t00040
include:
namespaces:
- clanguml::t00040
scopes:
- public
- protected
exclude:
relationships:
- dependency
elements:
- clanguml::t00040::B

36
tests/t00040/t00040.cc Normal file
View File

@@ -0,0 +1,36 @@
namespace clanguml::t00040 {
struct B {
};
struct A {
public:
int get_a() { return hidden_a_; }
protected:
int ii_;
private:
void foo() { }
int hidden_a_;
};
class AA : public A {
public:
};
class AAA : public AA {
public:
int get_aaa() { return hidden_aaa_; }
B *b;
private:
int hidden_aaa_;
};
struct R {
void foo(A *a) { }
};
} // namespace clanguml::t00040

50
tests/t00040/test_case.h Normal file
View File

@@ -0,0 +1,50 @@
/**
* tests/t00040/test_case.cc
*
* Copyright (c) 2021-2022 Bartek Kryza <bkryza@gmail.com>
*
* 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("t00040", "[test-case][class]")
{
auto [config, db] = load_config("t00040");
auto diagram = config.diagrams["t00040_class"];
REQUIRE(diagram->name == "t00040_class");
REQUIRE(diagram->generate_packages() == false);
auto model = generate_class_diagram(db, diagram);
REQUIRE(model->name() == "t00040_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("A")));
REQUIRE_THAT(puml, IsClass(_A("AA")));
REQUIRE_THAT(puml, IsClass(_A("AAA")));
REQUIRE_THAT(puml, IsBaseClass(_A("A"), _A("AA")));
REQUIRE_THAT(puml, IsBaseClass(_A("AA"), _A("AAA")));
REQUIRE_THAT(puml, !IsClass(_A("B")));
REQUIRE_THAT(puml, !IsDependency(_A("R"), _A("A")));
save_puml(
"./" + config.output_directory() + "/" + diagram->name + ".puml", puml);
}

View File

@@ -198,6 +198,7 @@ using namespace clanguml::test::matchers;
#include "t00037/test_case.h" #include "t00037/test_case.h"
#include "t00038/test_case.h" #include "t00038/test_case.h"
#include "t00039/test_case.h" #include "t00039/test_case.h"
#include "t00040/test_case.h"
// //
// Sequence diagram tests // Sequence diagram tests

View File

@@ -245,7 +245,7 @@ ContainsMatcher IsInnerClass(std::string const &parent,
} }
ContainsMatcher IsAssociation(std::string const &from, std::string const &to, ContainsMatcher IsAssociation(std::string const &from, std::string const &to,
std::string const &label, std::string multiplicity_source = "", std::string const &label = "", std::string multiplicity_source = "",
std::string multiplicity_dest = "", std::string multiplicity_dest = "",
CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes)
{ {

View File

@@ -114,6 +114,9 @@ test_cases:
- name: t00039 - name: t00039
title: Subclass class diagram filter test title: Subclass class diagram filter test
description: description:
- name: t00040
title: Relationship and scope filter test
description:
Sequence diagrams: Sequence diagrams:
- name: t20001 - name: t20001
title: Basic sequence diagram test case title: Basic sequence diagram test case