Skip to content

Commit 2faa9b5

Browse files
committed
Added nested trait += operator (#415)
1 parent a097dcc commit 2faa9b5

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed

src/common/model/nested_trait.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,34 @@ template <typename T, typename Path> class nested_trait {
325325
}
326326
}
327327

328+
nested_trait &operator+=(nested_trait &&other)
329+
{
330+
for (auto &element : other.elements_) {
331+
const auto element_id = element->id();
332+
333+
if (elements_by_id_.count(element_id) > 0) {
334+
auto existing_it = elements_by_id_[element_id];
335+
auto *existing_nested =
336+
dynamic_cast<nested_trait<T, Path> *>(existing_it->get());
337+
auto *other_nested =
338+
dynamic_cast<nested_trait<T, Path> *>(element.get());
339+
340+
if (existing_nested && other_nested) {
341+
*existing_nested += std::move(*other_nested);
342+
}
343+
}
344+
else {
345+
add_element(std::move(element));
346+
}
347+
}
348+
349+
other.elements_.clear();
350+
other.elements_by_id_.clear();
351+
other.elements_by_name_.clear();
352+
353+
return *this;
354+
}
355+
328356
private:
329357
/**
330358
* Returns true of this nested level contains an element with specified

tests/test_nested_trait.cc

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,94 @@ end package
336336
)");
337337
}
338338
}
339+
340+
TEST_CASE("Test nested trait operator +=")
341+
{
342+
using clanguml::test::diagram_model_mock;
343+
using clanguml::test::id;
344+
using clanguml::test::nested_trait_ns;
345+
346+
diagram_model_mock d1;
347+
diagram_model_mock d2;
348+
349+
namespace_ using_namespace{};
350+
351+
const auto ns1_id = id();
352+
const auto ns2_id = id();
353+
354+
auto p1 = std::make_unique<package>(using_namespace);
355+
p1->set_name("ns1");
356+
p1->set_id(ns1_id);
357+
auto prel1 = p1->path().relative_to(using_namespace);
358+
REQUIRE(d1.add_element(prel1, std::move(p1)));
359+
360+
auto c1 = std::make_unique<class_>(using_namespace);
361+
c1->set_name("A");
362+
c1->set_id(id());
363+
auto crel1 = c1->path().relative_to(using_namespace);
364+
REQUIRE(d1.add_element(crel1, std::move(c1)));
365+
366+
auto c2 = std::make_unique<class_>(using_namespace);
367+
c2->set_name("B");
368+
c2->set_namespace(namespace_{"ns1"});
369+
c2->set_id(id());
370+
auto crel2 = c2->path().relative_to(using_namespace);
371+
REQUIRE(d1.add_element(crel2, std::move(c2)));
372+
373+
auto p2 = std::make_unique<package>(using_namespace);
374+
p2->set_name("ns2");
375+
p2->set_id(ns2_id);
376+
auto prel2 = p2->path().relative_to(using_namespace);
377+
REQUIRE(d2.add_element(prel2, std::move(p2)));
378+
379+
auto c3 = std::make_unique<class_>(using_namespace);
380+
c3->set_name("C");
381+
c3->set_id(id());
382+
auto crel3 = c3->path().relative_to(using_namespace);
383+
REQUIRE(d2.add_element(crel3, std::move(c3)));
384+
385+
auto c4 = std::make_unique<class_>(using_namespace);
386+
c4->set_name("D");
387+
c4->set_namespace(namespace_{"ns2"});
388+
c4->set_id(id());
389+
auto crel4 = c4->path().relative_to(using_namespace);
390+
REQUIRE(d2.add_element(crel4, std::move(c4)));
391+
392+
auto p3 = std::make_unique<package>(using_namespace);
393+
p3->set_name("ns1");
394+
p3->set_id(ns1_id);
395+
auto prel3 = p3->path().relative_to(using_namespace);
396+
REQUIRE(d2.add_element(prel3, std::move(p3)));
397+
398+
auto c5 = std::make_unique<class_>(using_namespace);
399+
c5->set_name("E");
400+
c5->set_namespace(namespace_{"ns1"});
401+
c5->set_id(ns1_id);
402+
auto crel5 = c5->path().relative_to(using_namespace);
403+
REQUIRE(d2.add_element(crel5, std::move(c5)));
404+
405+
d1 += std::move(d2);
406+
407+
REQUIRE(d1.get_element(namespace_{"A"}).has_value());
408+
REQUIRE(d1.get_element(namespace_{"ns1::B"}).has_value());
409+
REQUIRE(d1.get_element(namespace_{"C"}).has_value());
410+
REQUIRE(d1.get_element(namespace_{"ns2::D"}).has_value());
411+
412+
auto ns1_element = d1.get_element(namespace_{"ns1::E"});
413+
REQUIRE(ns1_element.has_value());
414+
415+
{
416+
std::stringstream out;
417+
generate(d1, out);
418+
419+
auto result = out.str();
420+
REQUIRE(result.find("class A") != std::string::npos);
421+
REQUIRE(result.find("class ns1::B") != std::string::npos);
422+
REQUIRE(result.find("class ns1::E") != std::string::npos);
423+
REQUIRE(result.find("class C") != std::string::npos);
424+
REQUIRE(result.find("class ns2::D") != std::string::npos);
425+
}
426+
}
339427
///
340428
/// Main test function
341429
///

0 commit comments

Comments
 (0)