Add more advanced mode diagram filter test cases
This commit is contained in:
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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:
|
||||
@@ -113,9 +114,12 @@ public:
|
||||
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 {
|
||||
@@ -155,8 +159,13 @@ private:
|
||||
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_;
|
||||
|
||||
@@ -80,9 +80,12 @@ private:
|
||||
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));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
20
tests/t00082/.clang-uml
Normal file
20
tests/t00082/.clang-uml
Normal file
@@ -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
tests/t00082/t00082.cc
Normal file
30
tests/t00082/t00082.cc
Normal file
@@ -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
tests/t00082/test_case.h
Normal file
46
tests/t00082/test_case.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* tests/t00082/test_case.h
|
||||
*
|
||||
* Copyright (c) 2021-2024 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("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
tests/t00083/.clang-uml
Normal file
16
tests/t00083/.clang-uml
Normal file
@@ -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
tests/t00083/t00083.cc
Normal file
30
tests/t00083/t00083.cc
Normal file
@@ -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
tests/t00083/test_case.h
Normal file
46
tests/t00083/test_case.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* tests/t00083/test_case.h
|
||||
*
|
||||
* Copyright (c) 2021-2024 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("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"}));
|
||||
});
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -28,12 +28,41 @@
|
||||
#include "sequence_diagram/model/diagram.h"
|
||||
|
||||
#include <filesystem>
|
||||
using clanguml::class_diagram::model::class_;
|
||||
using clanguml::class_diagram::model::class_method;
|
||||
using clanguml::common::eid_t;
|
||||
using clanguml::common::model::access_t;
|
||||
using clanguml::common::model::diagram_filter;
|
||||
using clanguml::common::model::diagram_filter_factory;
|
||||
using clanguml::common::model::namespace_;
|
||||
using clanguml::common::model::package;
|
||||
using clanguml::common::model::source_file;
|
||||
using clanguml::config::filter_mode_t;
|
||||
|
||||
TEST_CASE("Test diagram paths filter")
|
||||
{
|
||||
auto cfg =
|
||||
clanguml::config::load("./test_config_data/filters_advanced.yml");
|
||||
|
||||
auto &config = *cfg.diagrams["include_test"];
|
||||
clanguml::include_diagram::model::diagram diagram;
|
||||
|
||||
auto filter_ptr = diagram_filter_factory::create(diagram, config);
|
||||
diagram_filter &filter = *filter_ptr;
|
||||
|
||||
auto make_path = [&](std::string_view p) {
|
||||
return source_file{config.root_directory() / p};
|
||||
};
|
||||
|
||||
CHECK(filter.should_include(
|
||||
make_path("class_diagram/visitor/translation_unit_visitor.h")));
|
||||
CHECK(filter.should_include(make_path("main.cc")));
|
||||
CHECK(filter.should_include(make_path("util/util.cc")));
|
||||
CHECK_FALSE(filter.should_include(make_path("util/error.h")));
|
||||
CHECK_FALSE(filter.should_include(
|
||||
make_path("sequence_diagram/visitor/translation_unit_visitor.h")));
|
||||
}
|
||||
|
||||
TEST_CASE("Test advanced diagram filter anyof")
|
||||
{
|
||||
auto cfg =
|
||||
@@ -42,6 +71,8 @@ TEST_CASE("Test advanced diagram filter anyof")
|
||||
auto &config = *cfg.diagrams["anyof_test"];
|
||||
clanguml::include_diagram::model::diagram diagram;
|
||||
|
||||
diagram.set_complete(true);
|
||||
|
||||
auto filter_ptr = diagram_filter_factory::create(diagram, config);
|
||||
diagram_filter &filter = *filter_ptr;
|
||||
|
||||
@@ -67,6 +98,7 @@ TEST_CASE("Test advanced diagram filter modules")
|
||||
|
||||
auto &config = *cfg.diagrams["modules_test"];
|
||||
clanguml::include_diagram::model::diagram diagram;
|
||||
diagram.set_complete(true);
|
||||
|
||||
auto filter_ptr = diagram_filter_factory::create(diagram, config);
|
||||
diagram_filter &filter = *filter_ptr;
|
||||
@@ -93,6 +125,126 @@ TEST_CASE("Test advanced diagram filter modules")
|
||||
CHECK_FALSE(filter.should_include(e1));
|
||||
}
|
||||
|
||||
TEST_CASE("Test method_types include filter")
|
||||
{
|
||||
auto cfg =
|
||||
clanguml::config::load("./test_config_data/filters_advanced.yml");
|
||||
|
||||
auto &config = *cfg.diagrams["method_type_include_test"];
|
||||
clanguml::class_diagram::model::diagram diagram;
|
||||
diagram.set_complete(true);
|
||||
|
||||
auto filter_ptr = diagram_filter_factory::create(diagram, config);
|
||||
diagram_filter &filter = *filter_ptr;
|
||||
|
||||
class_method cm{access_t::kPublic, "A", ""};
|
||||
cm.is_constructor(true);
|
||||
|
||||
CHECK(filter.should_include(cm));
|
||||
|
||||
cm.is_constructor(false);
|
||||
cm.is_destructor(true);
|
||||
|
||||
CHECK_FALSE(filter.should_include(cm));
|
||||
}
|
||||
|
||||
TEST_CASE("Test elements and namespaces regexp filter")
|
||||
{
|
||||
auto cfg =
|
||||
clanguml::config::load("./test_config_data/filters_advanced.yml");
|
||||
|
||||
auto &config = *cfg.diagrams["regex_elements_and_namespaces"];
|
||||
clanguml::class_diagram::model::diagram diagram;
|
||||
|
||||
auto filter_ptr = diagram_filter_factory::create(diagram, config);
|
||||
diagram_filter &filter = *filter_ptr;
|
||||
|
||||
class_ c{{}};
|
||||
|
||||
c.set_namespace(namespace_{"ns1"});
|
||||
c.set_name("ClassA");
|
||||
|
||||
CHECK_FALSE(filter.should_include(c));
|
||||
|
||||
c.set_namespace(namespace_{"ns1::ns2"});
|
||||
c.set_name("ClassA");
|
||||
|
||||
CHECK(filter.should_include(c));
|
||||
|
||||
c.set_namespace(namespace_{"ns1::ns2"});
|
||||
c.set_name("ClassZ");
|
||||
|
||||
CHECK(filter.should_include(c));
|
||||
|
||||
c.set_namespace(namespace_{"ns1::ns5::ns3"});
|
||||
c.set_name("ClassA");
|
||||
|
||||
CHECK_FALSE(filter.should_include(c));
|
||||
}
|
||||
|
||||
TEST_CASE("Test edge filter and namespaces filter")
|
||||
{
|
||||
auto cfg =
|
||||
clanguml::config::load("./test_config_data/filters_advanced.yml");
|
||||
|
||||
auto &config = *cfg.diagrams["edge_filter_and_namespaces"];
|
||||
clanguml::class_diagram::model::diagram diagram;
|
||||
|
||||
auto filter_ptr = diagram_filter_factory::create(diagram, config);
|
||||
diagram_filter &filter = *filter_ptr;
|
||||
|
||||
diagram.set_complete(true);
|
||||
|
||||
uint64_t id{1};
|
||||
|
||||
{
|
||||
auto ns1 = std::make_unique<package>(namespace_{});
|
||||
ns1->set_name("ns1");
|
||||
ns1->set_id(eid_t{id++});
|
||||
diagram.add(namespace_{}, std::move(ns1));
|
||||
}
|
||||
{
|
||||
auto ns1__nsA = std::make_unique<package>(namespace_{});
|
||||
ns1__nsA->set_name("nsA");
|
||||
ns1__nsA->set_namespace(namespace_{"ns1"});
|
||||
ns1__nsA->set_id(eid_t{id++});
|
||||
diagram.add(namespace_{}, std::move(ns1__nsA));
|
||||
}
|
||||
{
|
||||
auto A = std::make_unique<class_>(namespace_{});
|
||||
A->set_namespace(namespace_{"ns1::nsA"});
|
||||
A->set_name("A");
|
||||
A->set_id(eid_t{id});
|
||||
diagram.add(namespace_{"ns1::nsA"}, std::move(A));
|
||||
}
|
||||
|
||||
CHECK(filter.should_include(*diagram.get(eid_t{id})));
|
||||
|
||||
class_ c{{}};
|
||||
c.set_namespace(namespace_{"ns2::nsB"});
|
||||
c.set_name("B");
|
||||
|
||||
CHECK(filter.should_include(c));
|
||||
|
||||
{
|
||||
auto C = std::make_unique<class_>(namespace_{});
|
||||
C->set_namespace(namespace_{"ns1::nsA"});
|
||||
C->set_name("C");
|
||||
C->set_id(eid_t{++id});
|
||||
diagram.add(namespace_{"ns1::nsA"}, std::move(C));
|
||||
}
|
||||
|
||||
c.set_namespace(namespace_{"ns2::nsB"});
|
||||
c.set_name("C");
|
||||
|
||||
CHECK(filter.should_include(c));
|
||||
|
||||
c.set_namespace(namespace_{"ns1::nsA"});
|
||||
c.set_name("R");
|
||||
|
||||
CHECK_FALSE(filter.should_include(c));
|
||||
}
|
||||
|
||||
///
|
||||
/// Main test function
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user