Skip to content

Commit

Permalink
Add more advanced mode diagram filter test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
bkryza committed Jul 9, 2024
1 parent 01c6264 commit cadbeba
Show file tree
Hide file tree
Showing 14 changed files with 433 additions and 5 deletions.
5 changes: 5 additions & 0 deletions src/common/model/diagram.cc
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ bool diagram::should_include(const element &e) const
if (filter_.get() == nullptr)
return true;

if (!complete()) {
return filter_->should_include(
dynamic_cast<const source_location &>(e));
}

return filter_->should_include(e) &&
filter_->should_include(dynamic_cast<const source_location &>(e));
}
Expand Down
4 changes: 4 additions & 0 deletions src/common/model/filters/diagram_filter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ bool filter_visitor::is_exclusive() const

filter_t filter_visitor::type() const { return type_; }

filter_mode_t filter_visitor::mode() const { return mode_; }

void filter_visitor::set_mode(filter_mode_t mode) { mode_ = mode; }

anyof_filter::anyof_filter(
filter_t type, std::vector<std::unique_ptr<filter_visitor>> filters)
: filter_visitor{type}
Expand Down
11 changes: 10 additions & 1 deletion src/common/model/filters/diagram_filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ namespace clanguml::common::model {
class diagram_filter_factory;

using clanguml::common::eid_t;
using clanguml::config::filter_mode_t;

/**
* Diagram filters can be add in 2 modes:
Expand Down Expand Up @@ -113,9 +114,12 @@ class filter_visitor {
bool is_exclusive() const;

filter_t type() const;
filter_mode_t mode() const;
void set_mode(filter_mode_t mode);

private:
filter_t type_;
filter_mode_t mode_{filter_mode_t::basic};
};

struct anyof_filter : public filter_visitor {
Expand Down Expand Up @@ -155,8 +159,13 @@ struct anyof_filter : public filter_visitor {
template <typename E>
tvl::value_t match_anyof(const diagram &d, const E &element) const
{
return tvl::any_of(filters_.begin(), filters_.end(),
auto result = tvl::any_of(filters_.begin(), filters_.end(),
[&d, &element](const auto &f) { return f->match(d, element); });

if (mode() == filter_mode_t::advanced && !d.complete())
return type() == filter_t::kInclusive;

return result;
}

std::vector<std::unique_ptr<filter_visitor>> filters_;
Expand Down
9 changes: 6 additions & 3 deletions src/common/model/filters/diagram_filter_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,12 @@ class advanced_diagram_filter_initializer : public diagram_filter_initializer {
const std::vector<T> &filter_config,
std::vector<std::unique_ptr<filter_visitor>> &result, Args &&...args)
{
if (!filter_config.empty())
result.emplace_back(std::make_unique<FT>(
filter_type, filter_config, std::forward<Args>(args)...));
if (!filter_config.empty()) {
auto filter = std::make_unique<FT>(
filter_type, filter_config, std::forward<Args>(args)...);
filter->set_mode(filter_mode_t::advanced);
result.emplace_back(std::move(filter));
}
}
};

Expand Down
20 changes: 20 additions & 0 deletions tests/t00082/.clang-uml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
diagrams:
t00082_class:
type: class
glob:
- t00082.cc
generate_packages: true
filter_mode: advanced
include:
anyof:
subclasses:
- clanguml::t00082::ns1::nsA::A1
namespaces:
- clanguml::t00082::ns2::nsB
context:
- clanguml::t00082::ns3::nsC::B3
exclude:
allof:
elements:
- clanguml::t00082::ns1::nsA::A1
using_namespace: clanguml::t00082
30 changes: 30 additions & 0 deletions tests/t00082/t00082.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
namespace clanguml::t00082 {
namespace ns1 {
namespace nsA {
struct A1 { };
struct B1 : public A1 { };
struct C1 : public B1 { };
struct D1 { };
}
}
namespace ns2 {
namespace nsB {
struct A2 { };
struct B2 : public A2 { };
struct C2 : public B2 { };
}
}
namespace ns3 {
namespace nsC {
struct A3 { };
struct B3 : public A3 { };
struct C3 : public B3 { };
struct D3 { };
}
}
namespace ns4 {
namespace nsD {
struct A4 { };
}
}
}
46 changes: 46 additions & 0 deletions tests/t00082/test_case.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* tests/t00082/test_case.h
*
* Copyright (c) 2021-2024 Bartek Kryza <[email protected]>
*
* 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("t00082")
{
using namespace clanguml::test;
using namespace std::string_literals;

auto [config, db, diagram, model] =
CHECK_CLASS_MODEL("t00082", "t00082_class");

CHECK_CLASS_DIAGRAM(*config, diagram, *model, [](const auto &src) {
REQUIRE(!IsClass(src, {"ns1::nsA", "A1"}));
REQUIRE(IsClass(src, {"ns1::nsA", "B1"}));
REQUIRE(IsClass(src, {"ns1::nsA", "C1"}));
REQUIRE(!IsClass(src, {"ns1::nsA", "D1"}));

REQUIRE(IsClass(src, {"ns2::nsB", "A2"}));
REQUIRE(IsClass(src, {"ns2::nsB", "B2"}));
REQUIRE(IsClass(src, {"ns2::nsB", "C2"}));

REQUIRE(IsClass(src, {"ns3::nsC", "A3"}));
REQUIRE(IsClass(src, {"ns3::nsC", "B3"}));
REQUIRE(IsClass(src, {"ns3::nsC", "C3"}));
REQUIRE(!IsClass(src, {"ns3::nsC", "D3"}));

REQUIRE(!IsNamespacePackage(src, "ns4"s));

REQUIRE(!IsClass(src, {"ns4::nsD", "A4"}));
});
}
16 changes: 16 additions & 0 deletions tests/t00083/.clang-uml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
diagrams:
t00083_class:
type: class
glob:
- t00083.cc
generate_packages: true
filter_mode: advanced
exclude:
anyof:
subclasses:
- clanguml::t00083::ns1::nsA::A1
namespaces:
- clanguml::t00083::ns2::nsB
context:
- clanguml::t00083::ns3::nsC::B3
using_namespace: clanguml::t00083
30 changes: 30 additions & 0 deletions tests/t00083/t00083.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
namespace clanguml::t00083 {
namespace ns1 {
namespace nsA {
struct A1 { };
struct B1 : public A1 { };
struct C1 : public B1 { };
struct D1 { };
}
}
namespace ns2 {
namespace nsB {
struct A2 { };
struct B2 : public A2 { };
struct C2 : public B2 { };
}
}
namespace ns3 {
namespace nsC {
struct A3 { };
struct B3 : public A3 { };
struct C3 : public B3 { };
struct D3 { };
}
}
namespace ns4 {
namespace nsD {
struct A4 { };
}
}
}
46 changes: 46 additions & 0 deletions tests/t00083/test_case.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* tests/t00083/test_case.h
*
* Copyright (c) 2021-2024 Bartek Kryza <[email protected]>
*
* 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("t00083")
{
using namespace clanguml::test;
using namespace std::string_literals;

auto [config, db, diagram, model] =
CHECK_CLASS_MODEL("t00083", "t00083_class");

CHECK_CLASS_DIAGRAM(*config, diagram, *model, [](const auto &src) {
REQUIRE(!IsClass(src, {"ns1::nsA", "A1"}));
REQUIRE(!IsClass(src, {"ns1::nsA", "B1"}));
REQUIRE(!IsClass(src, {"ns1::nsA", "C1"}));
REQUIRE(IsClass(src, {"ns1::nsA", "D1"}));

REQUIRE(!IsClass(src, {"ns2::nsB", "A2"}));
REQUIRE(!IsClass(src, {"ns2::nsB", "B2"}));
REQUIRE(!IsClass(src, {"ns2::nsB", "C2"}));

REQUIRE(!IsClass(src, {"ns3::nsC", "A3"}));
REQUIRE(!IsClass(src, {"ns3::nsC", "B3"}));
REQUIRE(!IsClass(src, {"ns3::nsC", "C3"}));
REQUIRE(IsClass(src, {"ns3::nsC", "D3"}));

REQUIRE(IsNamespacePackage(src, "ns4"s));

REQUIRE(IsClass(src, {"ns4::nsD", "A4"}));
});
}
2 changes: 2 additions & 0 deletions tests/test_cases.cc
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,8 @@ void CHECK_INCLUDE_DIAGRAM(const clanguml::config::config &config,
#include "t00079/test_case.h"
#include "t00080/test_case.h"
#include "t00081/test_case.h"
#include "t00082/test_case.h"
#include "t00083/test_case.h"

///
/// Sequence diagram tests
Expand Down
6 changes: 6 additions & 0 deletions tests/test_cases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,12 @@ test_cases:
- name: t00081
title: Test case for class members relationships to std types
description:
- name: t00082
title: Test case for advanced diagram filter inclusion test with subclasses and namespaces
description:
- name: t00083
title: Test case for advanced diagram filter exclusion test with subclasses and namespaces
description:
Sequence diagrams:
- name: t20001
title: Basic sequence diagram test case
Expand Down
61 changes: 60 additions & 1 deletion tests/test_config_data/filters_advanced.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,25 @@ compilation_database_dir: debug
output_directory: output
filter_mode: advanced
diagrams:
include_test:
type: include
relative_to: ../../../src
glob:
- src/**/*.cc
- src/**/*.h
include:
allof:
paths:
- class_d*/
- common
- util/*.h
- util/*.cc
- main.cc
exclude:
allof:
paths:
- sequence_diagram
- util/error.h
anyof_test:
type: class
relative_to: ../../../src
Expand All @@ -25,4 +44,44 @@ diagrams:
modules:
- mod1::mod2
namespaces:
- ns1::ns2
- ns1::ns2
method_type_include_test:
type: class
include:
anyof:
namespaces:
- ns1::ns2
method_types:
- constructor
- operator
regex_elements_test:
type: class
include:
elements:
- ns1::ClassA
- r: 'ns1::ns2::Class.+'
- r: 'ns1::.+::ns3::.+'
exclude:
elements:
- ns1::ns2::ClassZ
regex_elements_and_namespaces:
type: class
include:
allof:
elements:
- ns1::ClassA
- r: 'ns1::ns2::Class.+'
- r: 'ns1::.+::ns3::.+'
namespaces:
- r: '.+ns2.+'
edge_filter_and_namespaces:
type: class
filter_mode: advanced
include:
anyof:
subclasses:
- ns1::nsA::A
namespaces:
- ns2::nsB
context:
- ns1::nsA::C
Loading

0 comments on commit cadbeba

Please sign in to comment.