From baeda78c7e2a922f931c68c5300126c9bd976ae1 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sun, 12 May 2024 00:45:11 +0200 Subject: [PATCH 01/15] Added doctest to thirdparty deps --- tests/t00002/test_case.h | 244 +- thirdparty/doctest/LICENSE.txt | 21 + thirdparty/doctest/doctest.h | 7106 ++++++++++++++++++++++++++++++++ 3 files changed, 7265 insertions(+), 106 deletions(-) create mode 100644 thirdparty/doctest/LICENSE.txt create mode 100644 thirdparty/doctest/doctest.h diff --git a/tests/t00002/test_case.h b/tests/t00002/test_case.h index ed269e3a..9235c7af 100644 --- a/tests/t00002/test_case.h +++ b/tests/t00002/test_case.h @@ -16,8 +16,12 @@ * limitations under the License. */ -TEST_CASE("t00002", "[test-case][class]") +#include "../test_cases.h" + +TEST_CASE("t00002") { + using namespace clanguml::test; + auto [config, db] = load_config("t00002"); auto diagram = config.diagrams["t00002_class"]; @@ -35,131 +39,159 @@ TEST_CASE("t00002", "[test-case][class]") REQUIRE(model->should_include({"clanguml", "t00002"}, "A")); REQUIRE(!model->should_include({"std"}, "vector")); - { - auto puml = generate_class_puml(diagram, *model); - AliasMatcher _A(puml); + CHECK_CLASS_DIAGRAM( + diagram, *model, + // Common test case for all diagram types + [](const auto &src) { + REQUIRE(!IsClass(src, "NOSUCHCLASS")); + REQUIRE(IsClass(src, "A")); + }, + // Specific test case only for JSON diagram + [](const json_t &src) { + const auto &A = get_element(src, "A"); - REQUIRE_THAT(puml, StartsWith("@startuml")); - REQUIRE_THAT(puml, EndsWith("@enduml\n")); - REQUIRE_THAT(puml, HasTitle("Basic class diagram example")); - REQUIRE_THAT(puml, IsAbstractClass(_A("A"))); - REQUIRE_THAT(puml, IsClass(_A("B"))); - REQUIRE_THAT(puml, IsClass(_A("C"))); - REQUIRE_THAT(puml, IsClass(_A("D"))); - REQUIRE_THAT(puml, IsBaseClass(_A("A"), _A("B"))); - REQUIRE_THAT(puml, IsBaseClass(_A("A"), _A("C"))); - REQUIRE_THAT(puml, IsBaseClass(_A("B"), _A("D"))); - REQUIRE_THAT(puml, IsBaseClass(_A("C"), _A("D"))); - REQUIRE_THAT(puml, (IsMethod("foo_a"))); - REQUIRE_THAT(puml, (IsMethod("foo_c"))); + CHECK(A.has_value()); - REQUIRE_THAT(puml, IsAssociation(_A("D"), _A("A"), "-as")); + CHECK(A.value()["type"] == "class"); + CHECK(A.value()["name"] == "A"); + CHECK(A.value()["display_name"] == "A"); + CHECK(A.value()["namespace"] == "clanguml::t00002"); + CHECK(A.value()["source_location"]["file"] == "t00002.cc"); + CHECK(A.value()["source_location"]["line"] == 7); + }); - REQUIRE_THAT(puml, HasNote(_A("A"), "left", "This is class A")); - REQUIRE_THAT(puml, HasNote(_A("B"), "top", "This is class B")); + // auto src = render_class_diagram(diagram, *model); - REQUIRE_THAT(puml, - HasLink(_A("A"), - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t00002/t00002.cc#L7", - clanguml::util::get_git_commit()), - "This is class A")); + /* - REQUIRE_THAT(puml, - HasLink(_A("B"), - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t00002/t00002.cc#L16", - clanguml::util::get_git_commit()), - "This is class B")); - REQUIRE_THAT(puml, - HasMemberLink("+foo_a() : void", - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t00002/t00002.cc#L18", - clanguml::util::get_git_commit()), - "foo_a")); + { + auto puml = generate_class_puml(diagram, *model); + AliasMatcher _A(puml); - REQUIRE_THAT(puml, - HasMemberLink("-as : std::vector", - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t00002/t00002.cc#L83", - clanguml::util::get_git_commit()), - "as")); + REQUIRE_THAT(puml, StartsWith("@startuml")); + REQUIRE_THAT(puml, EndsWith("@enduml\n")); + REQUIRE_THAT(puml, HasTitle("Basic class diagram example")); + REQUIRE_THAT(puml, IsAbstractClass(_A("A"))); + REQUIRE_THAT(puml, IsClass(_A("B"))); + REQUIRE_THAT(puml, IsClass(_A("C"))); + REQUIRE_THAT(puml, IsClass(_A("D"))); + REQUIRE_THAT(puml, IsBaseClass(_A("A"), _A("B"))); + REQUIRE_THAT(puml, IsBaseClass(_A("A"), _A("C"))); + REQUIRE_THAT(puml, IsBaseClass(_A("B"), _A("D"))); + REQUIRE_THAT(puml, IsBaseClass(_A("C"), _A("D"))); + REQUIRE_THAT(puml, (IsMethod("foo_a"))); + REQUIRE_THAT(puml, (IsMethod("foo_c"))); - save_puml(config.output_directory(), diagram->name + ".puml", puml); - } - { - auto j = generate_class_json(diagram, *model); + REQUIRE_THAT(puml, IsAssociation(_A("D"), _A("A"), "-as")); - using namespace json; + REQUIRE_THAT(puml, HasNote(_A("A"), "left", "This is class A")); + REQUIRE_THAT(puml, HasNote(_A("B"), "top", "This is class B")); - const auto &A = get_element(j, "A"); + REQUIRE_THAT(puml, + HasLink(_A("A"), + fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" + "t00002/t00002.cc#L7", + clanguml::util::get_git_commit()), + "This is class A")); - CHECK(A.has_value()); + REQUIRE_THAT(puml, + HasLink(_A("B"), + fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" + "t00002/t00002.cc#L16", + clanguml::util::get_git_commit()), + "This is class B")); - CHECK(A.value()["type"] == "class"); - CHECK(A.value()["name"] == "A"); - CHECK(A.value()["display_name"] == "A"); - CHECK(A.value()["namespace"] == "clanguml::t00002"); - CHECK(A.value()["source_location"]["file"] == "t00002.cc"); - CHECK(A.value()["source_location"]["line"] == 7); + REQUIRE_THAT(puml, + HasMemberLink("+foo_a() : void", + fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" + "t00002/t00002.cc#L18", + clanguml::util::get_git_commit()), + "foo_a")); - REQUIRE(HasTitle(j, "Basic class diagram example")); - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - REQUIRE(IsClass(j, "C")); - REQUIRE(IsBaseClass(j, "A", "B")); - REQUIRE(IsBaseClass(j, "A", "C")); - REQUIRE(IsBaseClass(j, "B", "D")); - REQUIRE(IsBaseClass(j, "C", "D")); - REQUIRE(IsMethod(j, "A", "foo_a")); - REQUIRE(IsMethod(j, "C", "foo_c")); - REQUIRE(IsField(j, "E", "as", "std::vector")); - REQUIRE(IsAssociation(j, "D", "A", "as")); + REQUIRE_THAT(puml, + HasMemberLink("-as : std::vector", + fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" + "t00002/t00002.cc#L83", + clanguml::util::get_git_commit()), + "as")); - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto mmd = generate_class_mermaid(diagram, *model); + save_puml(config.output_directory(), diagram->name + ".puml", puml); + } + { + auto j = generate_class_json(diagram, *model); - mermaid::AliasMatcher _A(mmd); - using mermaid::HasNote; - using mermaid::HasTitle; - using mermaid::IsAbstractClass; + using namespace json; - REQUIRE_THAT(mmd, HasTitle("Basic class diagram example")); - REQUIRE_THAT(mmd, Contains("classDiagram")); - REQUIRE_THAT(mmd, IsAbstractClass(_A("A"))); - REQUIRE_THAT(mmd, IsClass(_A("B"))); - REQUIRE_THAT(mmd, IsClass(_A("C"))); - REQUIRE_THAT(mmd, IsClass(_A("D"))); - REQUIRE_THAT(mmd, IsBaseClass(_A("A"), _A("B"))); - REQUIRE_THAT(mmd, IsBaseClass(_A("A"), _A("C"))); - REQUIRE_THAT(mmd, IsBaseClass(_A("B"), _A("D"))); - REQUIRE_THAT(mmd, IsBaseClass(_A("C"), _A("D"))); + const auto &A = get_element(j, "A"); - REQUIRE_THAT(mmd, IsAssociation(_A("D"), _A("A"), "-as")); + CHECK(A.has_value()); - REQUIRE_THAT(mmd, (mermaid::IsMethod("foo_a"))); - REQUIRE_THAT(mmd, (mermaid::IsMethod("foo_c"))); + CHECK(A.value()["type"] == "class"); + CHECK(A.value()["name"] == "A"); + CHECK(A.value()["display_name"] == "A"); + CHECK(A.value()["namespace"] == "clanguml::t00002"); + CHECK(A.value()["source_location"]["file"] == "t00002.cc"); + CHECK(A.value()["source_location"]["line"] == 7); - REQUIRE_THAT(mmd, HasNote(_A("A"), "left", "This is class A")); - REQUIRE_THAT(mmd, HasNote(_A("B"), "top", "This is class B")); + REQUIRE(HasTitle(j, "Basic class diagram example")); + REQUIRE(IsClass(j, "A")); + REQUIRE(IsClass(j, "B")); + REQUIRE(IsClass(j, "C")); + REQUIRE(IsBaseClass(j, "A", "B")); + REQUIRE(IsBaseClass(j, "A", "C")); + REQUIRE(IsBaseClass(j, "B", "D")); + REQUIRE(IsBaseClass(j, "C", "D")); + REQUIRE(IsMethod(j, "A", "foo_a")); + REQUIRE(IsMethod(j, "C", "foo_c")); + REQUIRE(IsField(j, "E", "as", "std::vector")); + REQUIRE(IsAssociation(j, "D", "A", "as")); - REQUIRE_THAT(mmd, - mermaid::HasLink(_A("A"), - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t00002/t00002.cc#L7", - clanguml::util::get_git_commit()), - "This is class A")); + save_json(config.output_directory(), diagram->name + ".json", j); + } + { + auto mmd = generate_class_mermaid(diagram, *model); - REQUIRE_THAT(mmd, - mermaid::HasLink(_A("B"), - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t00002/t00002.cc#L16", - clanguml::util::get_git_commit()), - "This is class B")); + mermaid::AliasMatcher _A(mmd); + using mermaid::HasNote; + using mermaid::HasTitle; + using mermaid::IsAbstractClass; - save_mermaid(config.output_directory(), diagram->name + ".mmd", mmd); - } + REQUIRE_THAT(mmd, HasTitle("Basic class diagram example")); + REQUIRE_THAT(mmd, Contains("classDiagram")); + REQUIRE_THAT(mmd, IsAbstractClass(_A("A"))); + REQUIRE_THAT(mmd, IsClass(_A("B"))); + REQUIRE_THAT(mmd, IsClass(_A("C"))); + REQUIRE_THAT(mmd, IsClass(_A("D"))); + REQUIRE_THAT(mmd, IsBaseClass(_A("A"), _A("B"))); + REQUIRE_THAT(mmd, IsBaseClass(_A("A"), _A("C"))); + REQUIRE_THAT(mmd, IsBaseClass(_A("B"), _A("D"))); + REQUIRE_THAT(mmd, IsBaseClass(_A("C"), _A("D"))); + + REQUIRE_THAT(mmd, IsAssociation(_A("D"), _A("A"), "-as")); + + REQUIRE_THAT(mmd, (mermaid::IsMethod("foo_a"))); + REQUIRE_THAT(mmd, (mermaid::IsMethod("foo_c"))); + + REQUIRE_THAT(mmd, HasNote(_A("A"), "left", "This is class A")); + REQUIRE_THAT(mmd, HasNote(_A("B"), "top", "This is class B")); + + REQUIRE_THAT(mmd, + mermaid::HasLink(_A("A"), + fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" + "t00002/t00002.cc#L7", + clanguml::util::get_git_commit()), + "This is class A")); + + REQUIRE_THAT(mmd, + mermaid::HasLink(_A("B"), + fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" + "t00002/t00002.cc#L16", + clanguml::util::get_git_commit()), + "This is class B")); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + mmd); + } + */ } \ No newline at end of file diff --git a/thirdparty/doctest/LICENSE.txt b/thirdparty/doctest/LICENSE.txt new file mode 100644 index 00000000..5ae0eb10 --- /dev/null +++ b/thirdparty/doctest/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016-2023 Viktor Kirilov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/thirdparty/doctest/doctest.h b/thirdparty/doctest/doctest.h new file mode 100644 index 00000000..5c754cde --- /dev/null +++ b/thirdparty/doctest/doctest.h @@ -0,0 +1,7106 @@ +// ====================================================================== lgtm [cpp/missing-header-guard] +// == DO NOT MODIFY THIS FILE BY HAND - IT IS AUTO GENERATED BY CMAKE! == +// ====================================================================== +// +// doctest.h - the lightest feature-rich C++ single-header testing framework for unit tests and TDD +// +// Copyright (c) 2016-2023 Viktor Kirilov +// +// Distributed under the MIT Software License +// See accompanying file LICENSE.txt or copy at +// https://opensource.org/licenses/MIT +// +// The documentation can be found at the library's page: +// https://github.com/doctest/doctest/blob/master/doc/markdown/readme.md +// +// ================================================================================================= +// ================================================================================================= +// ================================================================================================= +// +// The library is heavily influenced by Catch - https://github.com/catchorg/Catch2 +// which uses the Boost Software License - Version 1.0 +// see here - https://github.com/catchorg/Catch2/blob/master/LICENSE.txt +// +// The concept of subcases (sections in Catch) and expression decomposition are from there. +// Some parts of the code are taken directly: +// - stringification - the detection of "ostream& operator<<(ostream&, const T&)" and StringMaker<> +// - the Approx() helper class for floating point comparison +// - colors in the console +// - breaking into a debugger +// - signal / SEH handling +// - timer +// - XmlWriter class - thanks to Phil Nash for allowing the direct reuse (AKA copy/paste) +// +// The expression decomposing templates are taken from lest - https://github.com/martinmoene/lest +// which uses the Boost Software License - Version 1.0 +// see here - https://github.com/martinmoene/lest/blob/master/LICENSE.txt +// +// ================================================================================================= +// ================================================================================================= +// ================================================================================================= + +#ifndef DOCTEST_LIBRARY_INCLUDED +#define DOCTEST_LIBRARY_INCLUDED + +// ================================================================================================= +// == VERSION ====================================================================================== +// ================================================================================================= + +#define DOCTEST_VERSION_MAJOR 2 +#define DOCTEST_VERSION_MINOR 4 +#define DOCTEST_VERSION_PATCH 11 + +// util we need here +#define DOCTEST_TOSTR_IMPL(x) #x +#define DOCTEST_TOSTR(x) DOCTEST_TOSTR_IMPL(x) + +#define DOCTEST_VERSION_STR \ + DOCTEST_TOSTR(DOCTEST_VERSION_MAJOR) "." \ + DOCTEST_TOSTR(DOCTEST_VERSION_MINOR) "." \ + DOCTEST_TOSTR(DOCTEST_VERSION_PATCH) + +#define DOCTEST_VERSION \ + (DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH) + +// ================================================================================================= +// == COMPILER VERSION ============================================================================= +// ================================================================================================= + +// ideas for the version stuff are taken from here: https://github.com/cxxstuff/cxx_detect + +#ifdef _MSC_VER +#define DOCTEST_CPLUSPLUS _MSVC_LANG +#else +#define DOCTEST_CPLUSPLUS __cplusplus +#endif + +#define DOCTEST_COMPILER(MAJOR, MINOR, PATCH) ((MAJOR)*10000000 + (MINOR)*100000 + (PATCH)) + +// GCC/Clang and GCC/MSVC are mutually exclusive, but Clang/MSVC are not because of clang-cl... +#if defined(_MSC_VER) && defined(_MSC_FULL_VER) +#if _MSC_VER == _MSC_FULL_VER / 10000 +#define DOCTEST_MSVC DOCTEST_COMPILER(_MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 10000) +#else // MSVC +#define DOCTEST_MSVC \ + DOCTEST_COMPILER(_MSC_VER / 100, (_MSC_FULL_VER / 100000) % 100, _MSC_FULL_VER % 100000) +#endif // MSVC +#endif // MSVC +#if defined(__clang__) && defined(__clang_minor__) && defined(__clang_patchlevel__) +#define DOCTEST_CLANG DOCTEST_COMPILER(__clang_major__, __clang_minor__, __clang_patchlevel__) +#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) && \ + !defined(__INTEL_COMPILER) +#define DOCTEST_GCC DOCTEST_COMPILER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) +#endif // GCC +#if defined(__INTEL_COMPILER) +#define DOCTEST_ICC DOCTEST_COMPILER(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0) +#endif // ICC + +#ifndef DOCTEST_MSVC +#define DOCTEST_MSVC 0 +#endif // DOCTEST_MSVC +#ifndef DOCTEST_CLANG +#define DOCTEST_CLANG 0 +#endif // DOCTEST_CLANG +#ifndef DOCTEST_GCC +#define DOCTEST_GCC 0 +#endif // DOCTEST_GCC +#ifndef DOCTEST_ICC +#define DOCTEST_ICC 0 +#endif // DOCTEST_ICC + +// ================================================================================================= +// == COMPILER WARNINGS HELPERS ==================================================================== +// ================================================================================================= + +#if DOCTEST_CLANG && !DOCTEST_ICC +#define DOCTEST_PRAGMA_TO_STR(x) _Pragma(#x) +#define DOCTEST_CLANG_SUPPRESS_WARNING_PUSH _Pragma("clang diagnostic push") +#define DOCTEST_CLANG_SUPPRESS_WARNING(w) DOCTEST_PRAGMA_TO_STR(clang diagnostic ignored w) +#define DOCTEST_CLANG_SUPPRESS_WARNING_POP _Pragma("clang diagnostic pop") +#define DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(w) \ + DOCTEST_CLANG_SUPPRESS_WARNING_PUSH DOCTEST_CLANG_SUPPRESS_WARNING(w) +#else // DOCTEST_CLANG +#define DOCTEST_CLANG_SUPPRESS_WARNING_PUSH +#define DOCTEST_CLANG_SUPPRESS_WARNING(w) +#define DOCTEST_CLANG_SUPPRESS_WARNING_POP +#define DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(w) +#endif // DOCTEST_CLANG + +#if DOCTEST_GCC +#define DOCTEST_PRAGMA_TO_STR(x) _Pragma(#x) +#define DOCTEST_GCC_SUPPRESS_WARNING_PUSH _Pragma("GCC diagnostic push") +#define DOCTEST_GCC_SUPPRESS_WARNING(w) DOCTEST_PRAGMA_TO_STR(GCC diagnostic ignored w) +#define DOCTEST_GCC_SUPPRESS_WARNING_POP _Pragma("GCC diagnostic pop") +#define DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(w) \ + DOCTEST_GCC_SUPPRESS_WARNING_PUSH DOCTEST_GCC_SUPPRESS_WARNING(w) +#else // DOCTEST_GCC +#define DOCTEST_GCC_SUPPRESS_WARNING_PUSH +#define DOCTEST_GCC_SUPPRESS_WARNING(w) +#define DOCTEST_GCC_SUPPRESS_WARNING_POP +#define DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(w) +#endif // DOCTEST_GCC + +#if DOCTEST_MSVC +#define DOCTEST_MSVC_SUPPRESS_WARNING_PUSH __pragma(warning(push)) +#define DOCTEST_MSVC_SUPPRESS_WARNING(w) __pragma(warning(disable : w)) +#define DOCTEST_MSVC_SUPPRESS_WARNING_POP __pragma(warning(pop)) +#define DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(w) \ + DOCTEST_MSVC_SUPPRESS_WARNING_PUSH DOCTEST_MSVC_SUPPRESS_WARNING(w) +#else // DOCTEST_MSVC +#define DOCTEST_MSVC_SUPPRESS_WARNING_PUSH +#define DOCTEST_MSVC_SUPPRESS_WARNING(w) +#define DOCTEST_MSVC_SUPPRESS_WARNING_POP +#define DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(w) +#endif // DOCTEST_MSVC + +// ================================================================================================= +// == COMPILER WARNINGS ============================================================================ +// ================================================================================================= + +// both the header and the implementation suppress all of these, +// so it only makes sense to aggregate them like so +#define DOCTEST_SUPPRESS_COMMON_WARNINGS_PUSH \ + DOCTEST_CLANG_SUPPRESS_WARNING_PUSH \ + DOCTEST_CLANG_SUPPRESS_WARNING("-Wunknown-pragmas") \ + DOCTEST_CLANG_SUPPRESS_WARNING("-Wweak-vtables") \ + DOCTEST_CLANG_SUPPRESS_WARNING("-Wpadded") \ + DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-prototypes") \ + DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat") \ + DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic") \ + \ + DOCTEST_GCC_SUPPRESS_WARNING_PUSH \ + DOCTEST_GCC_SUPPRESS_WARNING("-Wunknown-pragmas") \ + DOCTEST_GCC_SUPPRESS_WARNING("-Wpragmas") \ + DOCTEST_GCC_SUPPRESS_WARNING("-Weffc++") \ + DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-overflow") \ + DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-aliasing") \ + DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-declarations") \ + DOCTEST_GCC_SUPPRESS_WARNING("-Wuseless-cast") \ + DOCTEST_GCC_SUPPRESS_WARNING("-Wnoexcept") \ + \ + DOCTEST_MSVC_SUPPRESS_WARNING_PUSH \ + /* these 4 also disabled globally via cmake: */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4514) /* unreferenced inline function has been removed */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4571) /* SEH related */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4710) /* function not inlined */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4711) /* function selected for inline expansion*/ \ + /* common ones */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4616) /* invalid compiler warning */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4619) /* invalid compiler warning */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4996) /* The compiler encountered a deprecated declaration */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4706) /* assignment within conditional expression */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4512) /* 'class' : assignment operator could not be generated */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4127) /* conditional expression is constant */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4820) /* padding */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4625) /* copy constructor was implicitly deleted */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4626) /* assignment operator was implicitly deleted */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(5027) /* move assignment operator implicitly deleted */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(5026) /* move constructor was implicitly deleted */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4640) /* construction of local static object not thread-safe */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(5045) /* Spectre mitigation for memory load */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(5264) /* 'variable-name': 'const' variable is not used */ \ + /* static analysis */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(26439) /* Function may not throw. Declare it 'noexcept' */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(26495) /* Always initialize a member variable */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(26451) /* Arithmetic overflow ... */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(26444) /* Avoid unnamed objects with custom ctor and dtor... */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(26812) /* Prefer 'enum class' over 'enum' */ + +#define DOCTEST_SUPPRESS_COMMON_WARNINGS_POP \ + DOCTEST_CLANG_SUPPRESS_WARNING_POP \ + DOCTEST_GCC_SUPPRESS_WARNING_POP \ + DOCTEST_MSVC_SUPPRESS_WARNING_POP + +DOCTEST_SUPPRESS_COMMON_WARNINGS_PUSH + +DOCTEST_CLANG_SUPPRESS_WARNING_PUSH +DOCTEST_CLANG_SUPPRESS_WARNING("-Wnon-virtual-dtor") +DOCTEST_CLANG_SUPPRESS_WARNING("-Wdeprecated") + +DOCTEST_GCC_SUPPRESS_WARNING_PUSH +DOCTEST_GCC_SUPPRESS_WARNING("-Wctor-dtor-privacy") +DOCTEST_GCC_SUPPRESS_WARNING("-Wnon-virtual-dtor") +DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-promo") + +DOCTEST_MSVC_SUPPRESS_WARNING_PUSH +DOCTEST_MSVC_SUPPRESS_WARNING(4623) // default constructor was implicitly defined as deleted + +#define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN \ + DOCTEST_MSVC_SUPPRESS_WARNING_PUSH \ + DOCTEST_MSVC_SUPPRESS_WARNING(4548) /* before comma no effect; expected side - effect */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4265) /* virtual functions, but destructor is not virtual */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4986) /* exception specification does not match previous */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4350) /* 'member1' called instead of 'member2' */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4668) /* not defined as a preprocessor macro */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4365) /* signed/unsigned mismatch */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4774) /* format string not a string literal */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4820) /* padding */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4625) /* copy constructor was implicitly deleted */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4626) /* assignment operator was implicitly deleted */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(5027) /* move assignment operator implicitly deleted */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(5026) /* move constructor was implicitly deleted */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4623) /* default constructor was implicitly deleted */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(5039) /* pointer to pot. throwing function passed to extern C */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(5045) /* Spectre mitigation for memory load */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(5105) /* macro producing 'defined' has undefined behavior */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(4738) /* storing float result in memory, loss of performance */ \ + DOCTEST_MSVC_SUPPRESS_WARNING(5262) /* implicit fall-through */ + +#define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END DOCTEST_MSVC_SUPPRESS_WARNING_POP + +// ================================================================================================= +// == FEATURE DETECTION ============================================================================ +// ================================================================================================= + +// general compiler feature support table: https://en.cppreference.com/w/cpp/compiler_support +// MSVC C++11 feature support table: https://msdn.microsoft.com/en-us/library/hh567368.aspx +// GCC C++11 feature support table: https://gcc.gnu.org/projects/cxx-status.html +// MSVC version table: +// https://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B#Internal_version_numbering +// MSVC++ 14.3 (17) _MSC_VER == 1930 (Visual Studio 2022) +// MSVC++ 14.2 (16) _MSC_VER == 1920 (Visual Studio 2019) +// MSVC++ 14.1 (15) _MSC_VER == 1910 (Visual Studio 2017) +// MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015) +// MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013) +// MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012) +// MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010) +// MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008) +// MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005) + +// Universal Windows Platform support +#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) +#define DOCTEST_CONFIG_NO_WINDOWS_SEH +#endif // WINAPI_FAMILY +#if DOCTEST_MSVC && !defined(DOCTEST_CONFIG_WINDOWS_SEH) +#define DOCTEST_CONFIG_WINDOWS_SEH +#endif // MSVC +#if defined(DOCTEST_CONFIG_NO_WINDOWS_SEH) && defined(DOCTEST_CONFIG_WINDOWS_SEH) +#undef DOCTEST_CONFIG_WINDOWS_SEH +#endif // DOCTEST_CONFIG_NO_WINDOWS_SEH + +#if !defined(_WIN32) && !defined(__QNX__) && !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && \ + !defined(__EMSCRIPTEN__) && !defined(__wasi__) +#define DOCTEST_CONFIG_POSIX_SIGNALS +#endif // _WIN32 +#if defined(DOCTEST_CONFIG_NO_POSIX_SIGNALS) && defined(DOCTEST_CONFIG_POSIX_SIGNALS) +#undef DOCTEST_CONFIG_POSIX_SIGNALS +#endif // DOCTEST_CONFIG_NO_POSIX_SIGNALS + +#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS +#if !defined(__cpp_exceptions) && !defined(__EXCEPTIONS) && !defined(_CPPUNWIND) \ + || defined(__wasi__) +#define DOCTEST_CONFIG_NO_EXCEPTIONS +#endif // no exceptions +#endif // DOCTEST_CONFIG_NO_EXCEPTIONS + +#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS +#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS +#define DOCTEST_CONFIG_NO_EXCEPTIONS +#endif // DOCTEST_CONFIG_NO_EXCEPTIONS +#endif // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS + +#if defined(DOCTEST_CONFIG_NO_EXCEPTIONS) && !defined(DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS) +#define DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS +#endif // DOCTEST_CONFIG_NO_EXCEPTIONS && !DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS + +#ifdef __wasi__ +#define DOCTEST_CONFIG_NO_MULTITHREADING +#endif + +#if defined(DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN) && !defined(DOCTEST_CONFIG_IMPLEMENT) +#define DOCTEST_CONFIG_IMPLEMENT +#endif // DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN + +#if defined(_WIN32) || defined(__CYGWIN__) +#if DOCTEST_MSVC +#define DOCTEST_SYMBOL_EXPORT __declspec(dllexport) +#define DOCTEST_SYMBOL_IMPORT __declspec(dllimport) +#else // MSVC +#define DOCTEST_SYMBOL_EXPORT __attribute__((dllexport)) +#define DOCTEST_SYMBOL_IMPORT __attribute__((dllimport)) +#endif // MSVC +#else // _WIN32 +#define DOCTEST_SYMBOL_EXPORT __attribute__((visibility("default"))) +#define DOCTEST_SYMBOL_IMPORT +#endif // _WIN32 + +#ifdef DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL +#ifdef DOCTEST_CONFIG_IMPLEMENT +#define DOCTEST_INTERFACE DOCTEST_SYMBOL_EXPORT +#else // DOCTEST_CONFIG_IMPLEMENT +#define DOCTEST_INTERFACE DOCTEST_SYMBOL_IMPORT +#endif // DOCTEST_CONFIG_IMPLEMENT +#else // DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL +#define DOCTEST_INTERFACE +#endif // DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL + +// needed for extern template instantiations +// see https://github.com/fmtlib/fmt/issues/2228 +#if DOCTEST_MSVC +#define DOCTEST_INTERFACE_DECL +#define DOCTEST_INTERFACE_DEF DOCTEST_INTERFACE +#else // DOCTEST_MSVC +#define DOCTEST_INTERFACE_DECL DOCTEST_INTERFACE +#define DOCTEST_INTERFACE_DEF +#endif // DOCTEST_MSVC + +#define DOCTEST_EMPTY + +#if DOCTEST_MSVC +#define DOCTEST_NOINLINE __declspec(noinline) +#define DOCTEST_UNUSED +#define DOCTEST_ALIGNMENT(x) +#elif DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 5, 0) +#define DOCTEST_NOINLINE +#define DOCTEST_UNUSED +#define DOCTEST_ALIGNMENT(x) +#else +#define DOCTEST_NOINLINE __attribute__((noinline)) +#define DOCTEST_UNUSED __attribute__((unused)) +#define DOCTEST_ALIGNMENT(x) __attribute__((aligned(x))) +#endif + +#ifdef DOCTEST_CONFIG_NO_CONTRADICTING_INLINE +#define DOCTEST_INLINE_NOINLINE inline +#else +#define DOCTEST_INLINE_NOINLINE inline DOCTEST_NOINLINE +#endif + +#ifndef DOCTEST_NORETURN +#if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0)) +#define DOCTEST_NORETURN +#else // DOCTEST_MSVC +#define DOCTEST_NORETURN [[noreturn]] +#endif // DOCTEST_MSVC +#endif // DOCTEST_NORETURN + +#ifndef DOCTEST_NOEXCEPT +#if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0)) +#define DOCTEST_NOEXCEPT +#else // DOCTEST_MSVC +#define DOCTEST_NOEXCEPT noexcept +#endif // DOCTEST_MSVC +#endif // DOCTEST_NOEXCEPT + +#ifndef DOCTEST_CONSTEXPR +#if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0)) +#define DOCTEST_CONSTEXPR const +#define DOCTEST_CONSTEXPR_FUNC inline +#else // DOCTEST_MSVC +#define DOCTEST_CONSTEXPR constexpr +#define DOCTEST_CONSTEXPR_FUNC constexpr +#endif // DOCTEST_MSVC +#endif // DOCTEST_CONSTEXPR + +#ifndef DOCTEST_NO_SANITIZE_INTEGER +#if DOCTEST_CLANG >= DOCTEST_COMPILER(3, 7, 0) +#define DOCTEST_NO_SANITIZE_INTEGER __attribute__((no_sanitize("integer"))) +#else +#define DOCTEST_NO_SANITIZE_INTEGER +#endif +#endif // DOCTEST_NO_SANITIZE_INTEGER + +// ================================================================================================= +// == FEATURE DETECTION END ======================================================================== +// ================================================================================================= + +#define DOCTEST_DECLARE_INTERFACE(name) \ + virtual ~name(); \ + name() = default; \ + name(const name&) = delete; \ + name(name&&) = delete; \ + name& operator=(const name&) = delete; \ + name& operator=(name&&) = delete; + +#define DOCTEST_DEFINE_INTERFACE(name) \ + name::~name() = default; + +// internal macros for string concatenation and anonymous variable name generation +#define DOCTEST_CAT_IMPL(s1, s2) s1##s2 +#define DOCTEST_CAT(s1, s2) DOCTEST_CAT_IMPL(s1, s2) +#ifdef __COUNTER__ // not standard and may be missing for some compilers +#define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __COUNTER__) +#else // __COUNTER__ +#define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __LINE__) +#endif // __COUNTER__ + +#ifndef DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE +#define DOCTEST_REF_WRAP(x) x& +#else // DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE +#define DOCTEST_REF_WRAP(x) x +#endif // DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE + +// not using __APPLE__ because... this is how Catch does it +#ifdef __MAC_OS_X_VERSION_MIN_REQUIRED +#define DOCTEST_PLATFORM_MAC +#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) +#define DOCTEST_PLATFORM_IPHONE +#elif defined(_WIN32) +#define DOCTEST_PLATFORM_WINDOWS +#elif defined(__wasi__) +#define DOCTEST_PLATFORM_WASI +#else // DOCTEST_PLATFORM +#define DOCTEST_PLATFORM_LINUX +#endif // DOCTEST_PLATFORM + +namespace doctest { namespace detail { + static DOCTEST_CONSTEXPR int consume(const int*, int) noexcept { return 0; } +}} + +#define DOCTEST_GLOBAL_NO_WARNINGS(var, ...) \ + DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wglobal-constructors") \ + static const int var = doctest::detail::consume(&var, __VA_ARGS__); \ + DOCTEST_CLANG_SUPPRESS_WARNING_POP + +#ifndef DOCTEST_BREAK_INTO_DEBUGGER +// should probably take a look at https://github.com/scottt/debugbreak +#ifdef DOCTEST_PLATFORM_LINUX +#if defined(__GNUC__) && (defined(__i386) || defined(__x86_64)) +// Break at the location of the failing check if possible +#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :) // NOLINT(hicpp-no-assembler) +#else +#include +#define DOCTEST_BREAK_INTO_DEBUGGER() raise(SIGTRAP) +#endif +#elif defined(DOCTEST_PLATFORM_MAC) +#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(__i386) +#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :) // NOLINT(hicpp-no-assembler) +#elif defined(__ppc__) || defined(__ppc64__) +// https://www.cocoawithlove.com/2008/03/break-into-debugger.html +#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n": : : "memory","r0","r3","r4") // NOLINT(hicpp-no-assembler) +#else +#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("brk #0"); // NOLINT(hicpp-no-assembler) +#endif +#elif DOCTEST_MSVC +#define DOCTEST_BREAK_INTO_DEBUGGER() __debugbreak() +#elif defined(__MINGW32__) +DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wredundant-decls") +extern "C" __declspec(dllimport) void __stdcall DebugBreak(); +DOCTEST_GCC_SUPPRESS_WARNING_POP +#define DOCTEST_BREAK_INTO_DEBUGGER() ::DebugBreak() +#else // linux +#define DOCTEST_BREAK_INTO_DEBUGGER() (static_cast(0)) +#endif // linux +#endif // DOCTEST_BREAK_INTO_DEBUGGER + +// this is kept here for backwards compatibility since the config option was changed +#ifdef DOCTEST_CONFIG_USE_IOSFWD +#ifndef DOCTEST_CONFIG_USE_STD_HEADERS +#define DOCTEST_CONFIG_USE_STD_HEADERS +#endif +#endif // DOCTEST_CONFIG_USE_IOSFWD + +// for clang - always include ciso646 (which drags some std stuff) because +// we want to check if we are using libc++ with the _LIBCPP_VERSION macro in +// which case we don't want to forward declare stuff from std - for reference: +// https://github.com/doctest/doctest/issues/126 +// https://github.com/doctest/doctest/issues/356 +#if DOCTEST_CLANG +#include +#endif // clang + +#ifdef _LIBCPP_VERSION +#ifndef DOCTEST_CONFIG_USE_STD_HEADERS +#define DOCTEST_CONFIG_USE_STD_HEADERS +#endif +#endif // _LIBCPP_VERSION + +#ifdef DOCTEST_CONFIG_USE_STD_HEADERS +#ifndef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS +#define DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS +#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS +DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN +#include +#include +#include +DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END +#else // DOCTEST_CONFIG_USE_STD_HEADERS + +// Forward declaring 'X' in namespace std is not permitted by the C++ Standard. +DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4643) + +namespace std { // NOLINT(cert-dcl58-cpp) +typedef decltype(nullptr) nullptr_t; // NOLINT(modernize-use-using) +typedef decltype(sizeof(void*)) size_t; // NOLINT(modernize-use-using) +template +struct char_traits; +template <> +struct char_traits; +template +class basic_ostream; // NOLINT(fuchsia-virtual-inheritance) +typedef basic_ostream> ostream; // NOLINT(modernize-use-using) +template +// NOLINTNEXTLINE +basic_ostream& operator<<(basic_ostream&, const char*); +template +class basic_istream; +typedef basic_istream> istream; // NOLINT(modernize-use-using) +template +class tuple; +#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0) +// see this issue on why this is needed: https://github.com/doctest/doctest/issues/183 +template +class allocator; +template +class basic_string; +using string = basic_string, allocator>; +#endif // VS 2019 +} // namespace std + +DOCTEST_MSVC_SUPPRESS_WARNING_POP + +#endif // DOCTEST_CONFIG_USE_STD_HEADERS + +#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS +#include +#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS + +namespace doctest { + +using std::size_t; + +DOCTEST_INTERFACE extern bool is_running_in_test; + +#ifndef DOCTEST_CONFIG_STRING_SIZE_TYPE +#define DOCTEST_CONFIG_STRING_SIZE_TYPE unsigned +#endif + +// A 24 byte string class (can be as small as 17 for x64 and 13 for x86) that can hold strings with length +// of up to 23 chars on the stack before going on the heap - the last byte of the buffer is used for: +// - "is small" bit - the highest bit - if "0" then it is small - otherwise its "1" (128) +// - if small - capacity left before going on the heap - using the lowest 5 bits +// - if small - 2 bits are left unused - the second and third highest ones +// - if small - acts as a null terminator if strlen() is 23 (24 including the null terminator) +// and the "is small" bit remains "0" ("as well as the capacity left") so its OK +// Idea taken from this lecture about the string implementation of facebook/folly - fbstring +// https://www.youtube.com/watch?v=kPR8h4-qZdk +// TODO: +// - optimizations - like not deleting memory unnecessarily in operator= and etc. +// - resize/reserve/clear +// - replace +// - back/front +// - iterator stuff +// - find & friends +// - push_back/pop_back +// - assign/insert/erase +// - relational operators as free functions - taking const char* as one of the params +class DOCTEST_INTERFACE String +{ +public: + using size_type = DOCTEST_CONFIG_STRING_SIZE_TYPE; + +private: + static DOCTEST_CONSTEXPR size_type len = 24; //!OCLINT avoid private static members + static DOCTEST_CONSTEXPR size_type last = len - 1; //!OCLINT avoid private static members + + struct view // len should be more than sizeof(view) - because of the final byte for flags + { + char* ptr; + size_type size; + size_type capacity; + }; + + union + { + char buf[len]; // NOLINT(*-avoid-c-arrays) + view data; + }; + + char* allocate(size_type sz); + + bool isOnStack() const noexcept { return (buf[last] & 128) == 0; } + void setOnHeap() noexcept; + void setLast(size_type in = last) noexcept; + void setSize(size_type sz) noexcept; + + void copy(const String& other); + +public: + static DOCTEST_CONSTEXPR size_type npos = static_cast(-1); + + String() noexcept; + ~String(); + + // cppcheck-suppress noExplicitConstructor + String(const char* in); + String(const char* in, size_type in_size); + + String(std::istream& in, size_type in_size); + + String(const String& other); + String& operator=(const String& other); + + String& operator+=(const String& other); + + String(String&& other) noexcept; + String& operator=(String&& other) noexcept; + + char operator[](size_type i) const; + char& operator[](size_type i); + + // the only functions I'm willing to leave in the interface - available for inlining + const char* c_str() const { return const_cast(this)->c_str(); } // NOLINT + char* c_str() { + if (isOnStack()) { + return reinterpret_cast(buf); + } + return data.ptr; + } + + size_type size() const; + size_type capacity() const; + + String substr(size_type pos, size_type cnt = npos) &&; + String substr(size_type pos, size_type cnt = npos) const &; + + size_type find(char ch, size_type pos = 0) const; + size_type rfind(char ch, size_type pos = npos) const; + + int compare(const char* other, bool no_case = false) const; + int compare(const String& other, bool no_case = false) const; + +friend DOCTEST_INTERFACE std::ostream& operator<<(std::ostream& s, const String& in); +}; + +DOCTEST_INTERFACE String operator+(const String& lhs, const String& rhs); + +DOCTEST_INTERFACE bool operator==(const String& lhs, const String& rhs); +DOCTEST_INTERFACE bool operator!=(const String& lhs, const String& rhs); +DOCTEST_INTERFACE bool operator<(const String& lhs, const String& rhs); +DOCTEST_INTERFACE bool operator>(const String& lhs, const String& rhs); +DOCTEST_INTERFACE bool operator<=(const String& lhs, const String& rhs); +DOCTEST_INTERFACE bool operator>=(const String& lhs, const String& rhs); + +class DOCTEST_INTERFACE Contains { +public: + explicit Contains(const String& string); + + bool checkWith(const String& other) const; + + String string; +}; + +DOCTEST_INTERFACE String toString(const Contains& in); + +DOCTEST_INTERFACE bool operator==(const String& lhs, const Contains& rhs); +DOCTEST_INTERFACE bool operator==(const Contains& lhs, const String& rhs); +DOCTEST_INTERFACE bool operator!=(const String& lhs, const Contains& rhs); +DOCTEST_INTERFACE bool operator!=(const Contains& lhs, const String& rhs); + +namespace Color { + enum Enum + { + None = 0, + White, + Red, + Green, + Blue, + Cyan, + Yellow, + Grey, + + Bright = 0x10, + + BrightRed = Bright | Red, + BrightGreen = Bright | Green, + LightGrey = Bright | Grey, + BrightWhite = Bright | White + }; + + DOCTEST_INTERFACE std::ostream& operator<<(std::ostream& s, Color::Enum code); +} // namespace Color + +namespace assertType { + enum Enum + { + // macro traits + + is_warn = 1, + is_check = 2 * is_warn, + is_require = 2 * is_check, + + is_normal = 2 * is_require, + is_throws = 2 * is_normal, + is_throws_as = 2 * is_throws, + is_throws_with = 2 * is_throws_as, + is_nothrow = 2 * is_throws_with, + + is_false = 2 * is_nothrow, + is_unary = 2 * is_false, // not checked anywhere - used just to distinguish the types + + is_eq = 2 * is_unary, + is_ne = 2 * is_eq, + + is_lt = 2 * is_ne, + is_gt = 2 * is_lt, + + is_ge = 2 * is_gt, + is_le = 2 * is_ge, + + // macro types + + DT_WARN = is_normal | is_warn, + DT_CHECK = is_normal | is_check, + DT_REQUIRE = is_normal | is_require, + + DT_WARN_FALSE = is_normal | is_false | is_warn, + DT_CHECK_FALSE = is_normal | is_false | is_check, + DT_REQUIRE_FALSE = is_normal | is_false | is_require, + + DT_WARN_THROWS = is_throws | is_warn, + DT_CHECK_THROWS = is_throws | is_check, + DT_REQUIRE_THROWS = is_throws | is_require, + + DT_WARN_THROWS_AS = is_throws_as | is_warn, + DT_CHECK_THROWS_AS = is_throws_as | is_check, + DT_REQUIRE_THROWS_AS = is_throws_as | is_require, + + DT_WARN_THROWS_WITH = is_throws_with | is_warn, + DT_CHECK_THROWS_WITH = is_throws_with | is_check, + DT_REQUIRE_THROWS_WITH = is_throws_with | is_require, + + DT_WARN_THROWS_WITH_AS = is_throws_with | is_throws_as | is_warn, + DT_CHECK_THROWS_WITH_AS = is_throws_with | is_throws_as | is_check, + DT_REQUIRE_THROWS_WITH_AS = is_throws_with | is_throws_as | is_require, + + DT_WARN_NOTHROW = is_nothrow | is_warn, + DT_CHECK_NOTHROW = is_nothrow | is_check, + DT_REQUIRE_NOTHROW = is_nothrow | is_require, + + DT_WARN_EQ = is_normal | is_eq | is_warn, + DT_CHECK_EQ = is_normal | is_eq | is_check, + DT_REQUIRE_EQ = is_normal | is_eq | is_require, + + DT_WARN_NE = is_normal | is_ne | is_warn, + DT_CHECK_NE = is_normal | is_ne | is_check, + DT_REQUIRE_NE = is_normal | is_ne | is_require, + + DT_WARN_GT = is_normal | is_gt | is_warn, + DT_CHECK_GT = is_normal | is_gt | is_check, + DT_REQUIRE_GT = is_normal | is_gt | is_require, + + DT_WARN_LT = is_normal | is_lt | is_warn, + DT_CHECK_LT = is_normal | is_lt | is_check, + DT_REQUIRE_LT = is_normal | is_lt | is_require, + + DT_WARN_GE = is_normal | is_ge | is_warn, + DT_CHECK_GE = is_normal | is_ge | is_check, + DT_REQUIRE_GE = is_normal | is_ge | is_require, + + DT_WARN_LE = is_normal | is_le | is_warn, + DT_CHECK_LE = is_normal | is_le | is_check, + DT_REQUIRE_LE = is_normal | is_le | is_require, + + DT_WARN_UNARY = is_normal | is_unary | is_warn, + DT_CHECK_UNARY = is_normal | is_unary | is_check, + DT_REQUIRE_UNARY = is_normal | is_unary | is_require, + + DT_WARN_UNARY_FALSE = is_normal | is_false | is_unary | is_warn, + DT_CHECK_UNARY_FALSE = is_normal | is_false | is_unary | is_check, + DT_REQUIRE_UNARY_FALSE = is_normal | is_false | is_unary | is_require, + }; +} // namespace assertType + +DOCTEST_INTERFACE const char* assertString(assertType::Enum at); +DOCTEST_INTERFACE const char* failureString(assertType::Enum at); +DOCTEST_INTERFACE const char* skipPathFromFilename(const char* file); + +struct DOCTEST_INTERFACE TestCaseData +{ + String m_file; // the file in which the test was registered (using String - see #350) + unsigned m_line; // the line where the test was registered + const char* m_name; // name of the test case + const char* m_test_suite; // the test suite in which the test was added + const char* m_description; + bool m_skip; + bool m_no_breaks; + bool m_no_output; + bool m_may_fail; + bool m_should_fail; + int m_expected_failures; + double m_timeout; +}; + +struct DOCTEST_INTERFACE AssertData +{ + // common - for all asserts + const TestCaseData* m_test_case; + assertType::Enum m_at; + const char* m_file; + int m_line; + const char* m_expr; + bool m_failed; + + // exception-related - for all asserts + bool m_threw; + String m_exception; + + // for normal asserts + String m_decomp; + + // for specific exception-related asserts + bool m_threw_as; + const char* m_exception_type; + + class DOCTEST_INTERFACE StringContains { + private: + Contains content; + bool isContains; + + public: + StringContains(const String& str) : content(str), isContains(false) { } + StringContains(Contains cntn) : content(static_cast(cntn)), isContains(true) { } + + bool check(const String& str) { return isContains ? (content == str) : (content.string == str); } + + operator const String&() const { return content.string; } + + const char* c_str() const { return content.string.c_str(); } + } m_exception_string; + + AssertData(assertType::Enum at, const char* file, int line, const char* expr, + const char* exception_type, const StringContains& exception_string); +}; + +struct DOCTEST_INTERFACE MessageData +{ + String m_string; + const char* m_file; + int m_line; + assertType::Enum m_severity; +}; + +struct DOCTEST_INTERFACE SubcaseSignature +{ + String m_name; + const char* m_file; + int m_line; + + bool operator==(const SubcaseSignature& other) const; + bool operator<(const SubcaseSignature& other) const; +}; + +struct DOCTEST_INTERFACE IContextScope +{ + DOCTEST_DECLARE_INTERFACE(IContextScope) + virtual void stringify(std::ostream*) const = 0; +}; + +namespace detail { + struct DOCTEST_INTERFACE TestCase; +} // namespace detail + +struct ContextOptions //!OCLINT too many fields +{ + std::ostream* cout = nullptr; // stdout stream + String binary_name; // the test binary name + + const detail::TestCase* currentTest = nullptr; + + // == parameters from the command line + String out; // output filename + String order_by; // how tests should be ordered + unsigned rand_seed; // the seed for rand ordering + + unsigned first; // the first (matching) test to be executed + unsigned last; // the last (matching) test to be executed + + int abort_after; // stop tests after this many failed assertions + int subcase_filter_levels; // apply the subcase filters for the first N levels + + bool success; // include successful assertions in output + bool case_sensitive; // if filtering should be case sensitive + bool exit; // if the program should be exited after the tests are ran/whatever + bool duration; // print the time duration of each test case + bool minimal; // minimal console output (only test failures) + bool quiet; // no console output + bool no_throw; // to skip exceptions-related assertion macros + bool no_exitcode; // if the framework should return 0 as the exitcode + bool no_run; // to not run the tests at all (can be done with an "*" exclude) + bool no_intro; // to not print the intro of the framework + bool no_version; // to not print the version of the framework + bool no_colors; // if output to the console should be colorized + bool force_colors; // forces the use of colors even when a tty cannot be detected + bool no_breaks; // to not break into the debugger + bool no_skip; // don't skip test cases which are marked to be skipped + bool gnu_file_line; // if line numbers should be surrounded with :x: and not (x): + bool no_path_in_filenames; // if the path to files should be removed from the output + bool no_line_numbers; // if source code line numbers should be omitted from the output + bool no_debug_output; // no output in the debug console when a debugger is attached + bool no_skipped_summary; // don't print "skipped" in the summary !!! UNDOCUMENTED !!! + bool no_time_in_output; // omit any time/timestamps from output !!! UNDOCUMENTED !!! + + bool help; // to print the help + bool version; // to print the version + bool count; // if only the count of matching tests is to be retrieved + bool list_test_cases; // to list all tests matching the filters + bool list_test_suites; // to list all suites matching the filters + bool list_reporters; // lists all registered reporters +}; + +namespace detail { + namespace types { +#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS + using namespace std; +#else + template + struct enable_if { }; + + template + struct enable_if { using type = T; }; + + struct true_type { static DOCTEST_CONSTEXPR bool value = true; }; + struct false_type { static DOCTEST_CONSTEXPR bool value = false; }; + + template struct remove_reference { using type = T; }; + template struct remove_reference { using type = T; }; + template struct remove_reference { using type = T; }; + + template struct is_rvalue_reference : false_type { }; + template struct is_rvalue_reference : true_type { }; + + template struct remove_const { using type = T; }; + template struct remove_const { using type = T; }; + + // Compiler intrinsics + template struct is_enum { static DOCTEST_CONSTEXPR bool value = __is_enum(T); }; + template struct underlying_type { using type = __underlying_type(T); }; + + template struct is_pointer : false_type { }; + template struct is_pointer : true_type { }; + + template struct is_array : false_type { }; + // NOLINTNEXTLINE(*-avoid-c-arrays) + template struct is_array : true_type { }; +#endif + } + + // + template + T&& declval(); + + template + DOCTEST_CONSTEXPR_FUNC T&& forward(typename types::remove_reference::type& t) DOCTEST_NOEXCEPT { + return static_cast(t); + } + + template + DOCTEST_CONSTEXPR_FUNC T&& forward(typename types::remove_reference::type&& t) DOCTEST_NOEXCEPT { + return static_cast(t); + } + + template + struct deferred_false : types::false_type { }; + +// MSVS 2015 :( +#if !DOCTEST_CLANG && defined(_MSC_VER) && _MSC_VER <= 1900 + template + struct has_global_insertion_operator : types::false_type { }; + + template + struct has_global_insertion_operator(), declval()), void())> : types::true_type { }; + + template + struct has_insertion_operator { static DOCTEST_CONSTEXPR bool value = has_global_insertion_operator::value; }; + + template + struct insert_hack; + + template + struct insert_hack { + static void insert(std::ostream& os, const T& t) { ::operator<<(os, t); } + }; + + template + struct insert_hack { + static void insert(std::ostream& os, const T& t) { operator<<(os, t); } + }; + + template + using insert_hack_t = insert_hack::value>; +#else + template + struct has_insertion_operator : types::false_type { }; +#endif + + template + struct has_insertion_operator(), declval()), void())> : types::true_type { }; + + template + struct should_stringify_as_underlying_type { + static DOCTEST_CONSTEXPR bool value = detail::types::is_enum::value && !doctest::detail::has_insertion_operator::value; + }; + + DOCTEST_INTERFACE std::ostream* tlssPush(); + DOCTEST_INTERFACE String tlssPop(); + + template + struct StringMakerBase { + template + static String convert(const DOCTEST_REF_WRAP(T)) { +#ifdef DOCTEST_CONFIG_REQUIRE_STRINGIFICATION_FOR_ALL_USED_TYPES + static_assert(deferred_false::value, "No stringification detected for type T. See string conversion manual"); +#endif + return "{?}"; + } + }; + + template + struct filldata; + + template + void filloss(std::ostream* stream, const T& in) { + filldata::fill(stream, in); + } + + template + void filloss(std::ostream* stream, const T (&in)[N]) { // NOLINT(*-avoid-c-arrays) + // T[N], T(&)[N], T(&&)[N] have same behaviour. + // Hence remove reference. + filloss::type>(stream, in); + } + + template + String toStream(const T& in) { + std::ostream* stream = tlssPush(); + filloss(stream, in); + return tlssPop(); + } + + template <> + struct StringMakerBase { + template + static String convert(const DOCTEST_REF_WRAP(T) in) { + return toStream(in); + } + }; +} // namespace detail + +template +struct StringMaker : public detail::StringMakerBase< + detail::has_insertion_operator::value || detail::types::is_pointer::value || detail::types::is_array::value> +{}; + +#ifndef DOCTEST_STRINGIFY +#ifdef DOCTEST_CONFIG_DOUBLE_STRINGIFY +#define DOCTEST_STRINGIFY(...) toString(toString(__VA_ARGS__)) +#else +#define DOCTEST_STRINGIFY(...) toString(__VA_ARGS__) +#endif +#endif + +template +String toString() { +#if DOCTEST_CLANG == 0 && DOCTEST_GCC == 0 && DOCTEST_ICC == 0 + String ret = __FUNCSIG__; // class doctest::String __cdecl doctest::toString(void) + String::size_type beginPos = ret.find('<'); + return ret.substr(beginPos + 1, ret.size() - beginPos - static_cast(sizeof(">(void)"))); +#else + String ret = __PRETTY_FUNCTION__; // doctest::String toString() [with T = TYPE] + String::size_type begin = ret.find('=') + 2; + return ret.substr(begin, ret.size() - begin - 1); +#endif +} + +template ::value, bool>::type = true> +String toString(const DOCTEST_REF_WRAP(T) value) { + return StringMaker::convert(value); +} + +#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING +DOCTEST_INTERFACE String toString(const char* in); +#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING + +#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0) +// see this issue on why this is needed: https://github.com/doctest/doctest/issues/183 +DOCTEST_INTERFACE String toString(const std::string& in); +#endif // VS 2019 + +DOCTEST_INTERFACE String toString(String in); + +DOCTEST_INTERFACE String toString(std::nullptr_t); + +DOCTEST_INTERFACE String toString(bool in); + +DOCTEST_INTERFACE String toString(float in); +DOCTEST_INTERFACE String toString(double in); +DOCTEST_INTERFACE String toString(double long in); + +DOCTEST_INTERFACE String toString(char in); +DOCTEST_INTERFACE String toString(char signed in); +DOCTEST_INTERFACE String toString(char unsigned in); +DOCTEST_INTERFACE String toString(short in); +DOCTEST_INTERFACE String toString(short unsigned in); +DOCTEST_INTERFACE String toString(signed in); +DOCTEST_INTERFACE String toString(unsigned in); +DOCTEST_INTERFACE String toString(long in); +DOCTEST_INTERFACE String toString(long unsigned in); +DOCTEST_INTERFACE String toString(long long in); +DOCTEST_INTERFACE String toString(long long unsigned in); + +template ::value, bool>::type = true> +String toString(const DOCTEST_REF_WRAP(T) value) { + using UT = typename detail::types::underlying_type::type; + return (DOCTEST_STRINGIFY(static_cast(value))); +} + +namespace detail { + template + struct filldata + { + static void fill(std::ostream* stream, const T& in) { +#if defined(_MSC_VER) && _MSC_VER <= 1900 + insert_hack_t::insert(*stream, in); +#else + operator<<(*stream, in); +#endif + } + }; + +DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4866) +// NOLINTBEGIN(*-avoid-c-arrays) + template + struct filldata { + static void fill(std::ostream* stream, const T(&in)[N]) { + *stream << "["; + for (size_t i = 0; i < N; i++) { + if (i != 0) { *stream << ", "; } + *stream << (DOCTEST_STRINGIFY(in[i])); + } + *stream << "]"; + } + }; +// NOLINTEND(*-avoid-c-arrays) +DOCTEST_MSVC_SUPPRESS_WARNING_POP + + // Specialized since we don't want the terminating null byte! +// NOLINTBEGIN(*-avoid-c-arrays) + template + struct filldata { + static void fill(std::ostream* stream, const char (&in)[N]) { + *stream << String(in, in[N - 1] ? N : N - 1); + } // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks) + }; +// NOLINTEND(*-avoid-c-arrays) + + template <> + struct filldata { + static void fill(std::ostream* stream, const void* in); + }; + + template + struct filldata { +DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4180) + static void fill(std::ostream* stream, const T* in) { +DOCTEST_MSVC_SUPPRESS_WARNING_POP +DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wmicrosoft-cast") + filldata::fill(stream, +#if DOCTEST_GCC == 0 || DOCTEST_GCC >= DOCTEST_COMPILER(4, 9, 0) + reinterpret_cast(in) +#else + *reinterpret_cast(&in) +#endif + ); +DOCTEST_CLANG_SUPPRESS_WARNING_POP + } + }; +} + +struct DOCTEST_INTERFACE Approx +{ + Approx(double value); + + Approx operator()(double value) const; + +#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS + template + explicit Approx(const T& value, + typename detail::types::enable_if::value>::type* = + static_cast(nullptr)) { + *this = static_cast(value); + } +#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS + + Approx& epsilon(double newEpsilon); + +#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS + template + typename std::enable_if::value, Approx&>::type epsilon( + const T& newEpsilon) { + m_epsilon = static_cast(newEpsilon); + return *this; + } +#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS + + Approx& scale(double newScale); + +#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS + template + typename std::enable_if::value, Approx&>::type scale( + const T& newScale) { + m_scale = static_cast(newScale); + return *this; + } +#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS + + // clang-format off + DOCTEST_INTERFACE friend bool operator==(double lhs, const Approx & rhs); + DOCTEST_INTERFACE friend bool operator==(const Approx & lhs, double rhs); + DOCTEST_INTERFACE friend bool operator!=(double lhs, const Approx & rhs); + DOCTEST_INTERFACE friend bool operator!=(const Approx & lhs, double rhs); + DOCTEST_INTERFACE friend bool operator<=(double lhs, const Approx & rhs); + DOCTEST_INTERFACE friend bool operator<=(const Approx & lhs, double rhs); + DOCTEST_INTERFACE friend bool operator>=(double lhs, const Approx & rhs); + DOCTEST_INTERFACE friend bool operator>=(const Approx & lhs, double rhs); + DOCTEST_INTERFACE friend bool operator< (double lhs, const Approx & rhs); + DOCTEST_INTERFACE friend bool operator< (const Approx & lhs, double rhs); + DOCTEST_INTERFACE friend bool operator> (double lhs, const Approx & rhs); + DOCTEST_INTERFACE friend bool operator> (const Approx & lhs, double rhs); + +#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS +#define DOCTEST_APPROX_PREFIX \ + template friend typename std::enable_if::value, bool>::type + + DOCTEST_APPROX_PREFIX operator==(const T& lhs, const Approx& rhs) { return operator==(static_cast(lhs), rhs); } + DOCTEST_APPROX_PREFIX operator==(const Approx& lhs, const T& rhs) { return operator==(rhs, lhs); } + DOCTEST_APPROX_PREFIX operator!=(const T& lhs, const Approx& rhs) { return !operator==(lhs, rhs); } + DOCTEST_APPROX_PREFIX operator!=(const Approx& lhs, const T& rhs) { return !operator==(rhs, lhs); } + DOCTEST_APPROX_PREFIX operator<=(const T& lhs, const Approx& rhs) { return static_cast(lhs) < rhs.m_value || lhs == rhs; } + DOCTEST_APPROX_PREFIX operator<=(const Approx& lhs, const T& rhs) { return lhs.m_value < static_cast(rhs) || lhs == rhs; } + DOCTEST_APPROX_PREFIX operator>=(const T& lhs, const Approx& rhs) { return static_cast(lhs) > rhs.m_value || lhs == rhs; } + DOCTEST_APPROX_PREFIX operator>=(const Approx& lhs, const T& rhs) { return lhs.m_value > static_cast(rhs) || lhs == rhs; } + DOCTEST_APPROX_PREFIX operator< (const T& lhs, const Approx& rhs) { return static_cast(lhs) < rhs.m_value && lhs != rhs; } + DOCTEST_APPROX_PREFIX operator< (const Approx& lhs, const T& rhs) { return lhs.m_value < static_cast(rhs) && lhs != rhs; } + DOCTEST_APPROX_PREFIX operator> (const T& lhs, const Approx& rhs) { return static_cast(lhs) > rhs.m_value && lhs != rhs; } + DOCTEST_APPROX_PREFIX operator> (const Approx& lhs, const T& rhs) { return lhs.m_value > static_cast(rhs) && lhs != rhs; } +#undef DOCTEST_APPROX_PREFIX +#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS + + // clang-format on + + double m_epsilon; + double m_scale; + double m_value; +}; + +DOCTEST_INTERFACE String toString(const Approx& in); + +DOCTEST_INTERFACE const ContextOptions* getContextOptions(); + +template +struct DOCTEST_INTERFACE_DECL IsNaN +{ + F value; bool flipped; + IsNaN(F f, bool flip = false) : value(f), flipped(flip) { } + IsNaN operator!() const { return { value, !flipped }; } + operator bool() const; +}; +#ifndef __MINGW32__ +extern template struct DOCTEST_INTERFACE_DECL IsNaN; +extern template struct DOCTEST_INTERFACE_DECL IsNaN; +extern template struct DOCTEST_INTERFACE_DECL IsNaN; +#endif +DOCTEST_INTERFACE String toString(IsNaN in); +DOCTEST_INTERFACE String toString(IsNaN in); +DOCTEST_INTERFACE String toString(IsNaN in); + +#ifndef DOCTEST_CONFIG_DISABLE + +namespace detail { + // clang-format off +#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING + template struct decay_array { using type = T; }; + template struct decay_array { using type = T*; }; + template struct decay_array { using type = T*; }; + + template struct not_char_pointer { static DOCTEST_CONSTEXPR int value = 1; }; + template<> struct not_char_pointer { static DOCTEST_CONSTEXPR int value = 0; }; + template<> struct not_char_pointer { static DOCTEST_CONSTEXPR int value = 0; }; + + template struct can_use_op : public not_char_pointer::type> {}; +#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING + // clang-format on + + struct DOCTEST_INTERFACE TestFailureException + { + }; + + DOCTEST_INTERFACE bool checkIfShouldThrow(assertType::Enum at); + +#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS + DOCTEST_NORETURN +#endif // DOCTEST_CONFIG_NO_EXCEPTIONS + DOCTEST_INTERFACE void throwException(); + + struct DOCTEST_INTERFACE Subcase + { + SubcaseSignature m_signature; + bool m_entered = false; + + Subcase(const String& name, const char* file, int line); + Subcase(const Subcase&) = delete; + Subcase(Subcase&&) = delete; + Subcase& operator=(const Subcase&) = delete; + Subcase& operator=(Subcase&&) = delete; + ~Subcase(); + + operator bool() const; + + private: + bool checkFilters(); + }; + + template + String stringifyBinaryExpr(const DOCTEST_REF_WRAP(L) lhs, const char* op, + const DOCTEST_REF_WRAP(R) rhs) { + return (DOCTEST_STRINGIFY(lhs)) + op + (DOCTEST_STRINGIFY(rhs)); + } + +#if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0) +DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wunused-comparison") +#endif + +// This will check if there is any way it could find a operator like member or friend and uses it. +// If not it doesn't find the operator or if the operator at global scope is defined after +// this template, the template won't be instantiated due to SFINAE. Once the template is not +// instantiated it can look for global operator using normal conversions. +#ifdef __NVCC__ +#define SFINAE_OP(ret,op) ret +#else +#define SFINAE_OP(ret,op) decltype((void)(doctest::detail::declval() op doctest::detail::declval()),ret{}) +#endif + +#define DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(op, op_str, op_macro) \ + template \ + DOCTEST_NOINLINE SFINAE_OP(Result,op) operator op(R&& rhs) { \ + bool res = op_macro(doctest::detail::forward(lhs), doctest::detail::forward(rhs)); \ + if(m_at & assertType::is_false) \ + res = !res; \ + if(!res || doctest::getContextOptions()->success) \ + return Result(res, stringifyBinaryExpr(lhs, op_str, rhs)); \ + return Result(res); \ + } + + // more checks could be added - like in Catch: + // https://github.com/catchorg/Catch2/pull/1480/files + // https://github.com/catchorg/Catch2/pull/1481/files +#define DOCTEST_FORBIT_EXPRESSION(rt, op) \ + template \ + rt& operator op(const R&) { \ + static_assert(deferred_false::value, \ + "Expression Too Complex Please Rewrite As Binary Comparison!"); \ + return *this; \ + } + + struct DOCTEST_INTERFACE Result // NOLINT(*-member-init) + { + bool m_passed; + String m_decomp; + + Result() = default; // TODO: Why do we need this? (To remove NOLINT) + Result(bool passed, const String& decomposition = String()); + + // forbidding some expressions based on this table: https://en.cppreference.com/w/cpp/language/operator_precedence + DOCTEST_FORBIT_EXPRESSION(Result, &) + DOCTEST_FORBIT_EXPRESSION(Result, ^) + DOCTEST_FORBIT_EXPRESSION(Result, |) + DOCTEST_FORBIT_EXPRESSION(Result, &&) + DOCTEST_FORBIT_EXPRESSION(Result, ||) + DOCTEST_FORBIT_EXPRESSION(Result, ==) + DOCTEST_FORBIT_EXPRESSION(Result, !=) + DOCTEST_FORBIT_EXPRESSION(Result, <) + DOCTEST_FORBIT_EXPRESSION(Result, >) + DOCTEST_FORBIT_EXPRESSION(Result, <=) + DOCTEST_FORBIT_EXPRESSION(Result, >=) + DOCTEST_FORBIT_EXPRESSION(Result, =) + DOCTEST_FORBIT_EXPRESSION(Result, +=) + DOCTEST_FORBIT_EXPRESSION(Result, -=) + DOCTEST_FORBIT_EXPRESSION(Result, *=) + DOCTEST_FORBIT_EXPRESSION(Result, /=) + DOCTEST_FORBIT_EXPRESSION(Result, %=) + DOCTEST_FORBIT_EXPRESSION(Result, <<=) + DOCTEST_FORBIT_EXPRESSION(Result, >>=) + DOCTEST_FORBIT_EXPRESSION(Result, &=) + DOCTEST_FORBIT_EXPRESSION(Result, ^=) + DOCTEST_FORBIT_EXPRESSION(Result, |=) + }; + +#ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION + + DOCTEST_CLANG_SUPPRESS_WARNING_PUSH + DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-conversion") + DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-compare") + //DOCTEST_CLANG_SUPPRESS_WARNING("-Wdouble-promotion") + //DOCTEST_CLANG_SUPPRESS_WARNING("-Wconversion") + //DOCTEST_CLANG_SUPPRESS_WARNING("-Wfloat-equal") + + DOCTEST_GCC_SUPPRESS_WARNING_PUSH + DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-conversion") + DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-compare") + //DOCTEST_GCC_SUPPRESS_WARNING("-Wdouble-promotion") + //DOCTEST_GCC_SUPPRESS_WARNING("-Wconversion") + //DOCTEST_GCC_SUPPRESS_WARNING("-Wfloat-equal") + + DOCTEST_MSVC_SUPPRESS_WARNING_PUSH + // https://stackoverflow.com/questions/39479163 what's the difference between 4018 and 4389 + DOCTEST_MSVC_SUPPRESS_WARNING(4388) // signed/unsigned mismatch + DOCTEST_MSVC_SUPPRESS_WARNING(4389) // 'operator' : signed/unsigned mismatch + DOCTEST_MSVC_SUPPRESS_WARNING(4018) // 'expression' : signed/unsigned mismatch + //DOCTEST_MSVC_SUPPRESS_WARNING(4805) // 'operation' : unsafe mix of type 'type' and type 'type' in operation + +#endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION + + // clang-format off +#ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING +#define DOCTEST_COMPARISON_RETURN_TYPE bool +#else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING +#define DOCTEST_COMPARISON_RETURN_TYPE typename types::enable_if::value || can_use_op::value, bool>::type + inline bool eq(const char* lhs, const char* rhs) { return String(lhs) == String(rhs); } + inline bool ne(const char* lhs, const char* rhs) { return String(lhs) != String(rhs); } + inline bool lt(const char* lhs, const char* rhs) { return String(lhs) < String(rhs); } + inline bool gt(const char* lhs, const char* rhs) { return String(lhs) > String(rhs); } + inline bool le(const char* lhs, const char* rhs) { return String(lhs) <= String(rhs); } + inline bool ge(const char* lhs, const char* rhs) { return String(lhs) >= String(rhs); } +#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING + // clang-format on + +#define DOCTEST_RELATIONAL_OP(name, op) \ + template \ + DOCTEST_COMPARISON_RETURN_TYPE name(const DOCTEST_REF_WRAP(L) lhs, \ + const DOCTEST_REF_WRAP(R) rhs) { \ + return lhs op rhs; \ + } + + DOCTEST_RELATIONAL_OP(eq, ==) + DOCTEST_RELATIONAL_OP(ne, !=) + DOCTEST_RELATIONAL_OP(lt, <) + DOCTEST_RELATIONAL_OP(gt, >) + DOCTEST_RELATIONAL_OP(le, <=) + DOCTEST_RELATIONAL_OP(ge, >=) + +#ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING +#define DOCTEST_CMP_EQ(l, r) l == r +#define DOCTEST_CMP_NE(l, r) l != r +#define DOCTEST_CMP_GT(l, r) l > r +#define DOCTEST_CMP_LT(l, r) l < r +#define DOCTEST_CMP_GE(l, r) l >= r +#define DOCTEST_CMP_LE(l, r) l <= r +#else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING +#define DOCTEST_CMP_EQ(l, r) eq(l, r) +#define DOCTEST_CMP_NE(l, r) ne(l, r) +#define DOCTEST_CMP_GT(l, r) gt(l, r) +#define DOCTEST_CMP_LT(l, r) lt(l, r) +#define DOCTEST_CMP_GE(l, r) ge(l, r) +#define DOCTEST_CMP_LE(l, r) le(l, r) +#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING + + template + // cppcheck-suppress copyCtorAndEqOperator + struct Expression_lhs + { + L lhs; + assertType::Enum m_at; + + explicit Expression_lhs(L&& in, assertType::Enum at) + : lhs(static_cast(in)) + , m_at(at) {} + + DOCTEST_NOINLINE operator Result() { +// this is needed only for MSVC 2015 +DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4800) // 'int': forcing value to bool + bool res = static_cast(lhs); +DOCTEST_MSVC_SUPPRESS_WARNING_POP + if(m_at & assertType::is_false) { //!OCLINT bitwise operator in conditional + res = !res; + } + + if(!res || getContextOptions()->success) { + return { res, (DOCTEST_STRINGIFY(lhs)) }; + } + return { res }; + } + + /* This is required for user-defined conversions from Expression_lhs to L */ + operator L() const { return lhs; } + + // clang-format off + DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(==, " == ", DOCTEST_CMP_EQ) //!OCLINT bitwise operator in conditional + DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(!=, " != ", DOCTEST_CMP_NE) //!OCLINT bitwise operator in conditional + DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(>, " > ", DOCTEST_CMP_GT) //!OCLINT bitwise operator in conditional + DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(<, " < ", DOCTEST_CMP_LT) //!OCLINT bitwise operator in conditional + DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(>=, " >= ", DOCTEST_CMP_GE) //!OCLINT bitwise operator in conditional + DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(<=, " <= ", DOCTEST_CMP_LE) //!OCLINT bitwise operator in conditional + // clang-format on + + // forbidding some expressions based on this table: https://en.cppreference.com/w/cpp/language/operator_precedence + DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &) + DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ^) + DOCTEST_FORBIT_EXPRESSION(Expression_lhs, |) + DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &&) + DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ||) + DOCTEST_FORBIT_EXPRESSION(Expression_lhs, =) + DOCTEST_FORBIT_EXPRESSION(Expression_lhs, +=) + DOCTEST_FORBIT_EXPRESSION(Expression_lhs, -=) + DOCTEST_FORBIT_EXPRESSION(Expression_lhs, *=) + DOCTEST_FORBIT_EXPRESSION(Expression_lhs, /=) + DOCTEST_FORBIT_EXPRESSION(Expression_lhs, %=) + DOCTEST_FORBIT_EXPRESSION(Expression_lhs, <<=) + DOCTEST_FORBIT_EXPRESSION(Expression_lhs, >>=) + DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &=) + DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ^=) + DOCTEST_FORBIT_EXPRESSION(Expression_lhs, |=) + // these 2 are unfortunate because they should be allowed - they have higher precedence over the comparisons, but the + // ExpressionDecomposer class uses the left shift operator to capture the left operand of the binary expression... + DOCTEST_FORBIT_EXPRESSION(Expression_lhs, <<) + DOCTEST_FORBIT_EXPRESSION(Expression_lhs, >>) + }; + +#ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION + + DOCTEST_CLANG_SUPPRESS_WARNING_POP + DOCTEST_MSVC_SUPPRESS_WARNING_POP + DOCTEST_GCC_SUPPRESS_WARNING_POP + +#endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION + +#if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0) +DOCTEST_CLANG_SUPPRESS_WARNING_POP +#endif + + struct DOCTEST_INTERFACE ExpressionDecomposer + { + assertType::Enum m_at; + + ExpressionDecomposer(assertType::Enum at); + + // The right operator for capturing expressions is "<=" instead of "<<" (based on the operator precedence table) + // but then there will be warnings from GCC about "-Wparentheses" and since "_Pragma()" is problematic this will stay for now... + // https://github.com/catchorg/Catch2/issues/870 + // https://github.com/catchorg/Catch2/issues/565 + template + Expression_lhs operator<<(L&& operand) { + return Expression_lhs(static_cast(operand), m_at); + } + + template ::value,void >::type* = nullptr> + Expression_lhs operator<<(const L &operand) { + return Expression_lhs(operand, m_at); + } + }; + + struct DOCTEST_INTERFACE TestSuite + { + const char* m_test_suite = nullptr; + const char* m_description = nullptr; + bool m_skip = false; + bool m_no_breaks = false; + bool m_no_output = false; + bool m_may_fail = false; + bool m_should_fail = false; + int m_expected_failures = 0; + double m_timeout = 0; + + TestSuite& operator*(const char* in); + + template + TestSuite& operator*(const T& in) { + in.fill(*this); + return *this; + } + }; + + using funcType = void (*)(); + + struct DOCTEST_INTERFACE TestCase : public TestCaseData + { + funcType m_test; // a function pointer to the test case + + String m_type; // for templated test cases - gets appended to the real name + int m_template_id; // an ID used to distinguish between the different versions of a templated test case + String m_full_name; // contains the name (only for templated test cases!) + the template type + + TestCase(funcType test, const char* file, unsigned line, const TestSuite& test_suite, + const String& type = String(), int template_id = -1); + + TestCase(const TestCase& other); + TestCase(TestCase&&) = delete; + + DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(26434) // hides a non-virtual function + TestCase& operator=(const TestCase& other); + DOCTEST_MSVC_SUPPRESS_WARNING_POP + + TestCase& operator=(TestCase&&) = delete; + + TestCase& operator*(const char* in); + + template + TestCase& operator*(const T& in) { + in.fill(*this); + return *this; + } + + bool operator<(const TestCase& other) const; + + ~TestCase() = default; + }; + + // forward declarations of functions used by the macros + DOCTEST_INTERFACE int regTest(const TestCase& tc); + DOCTEST_INTERFACE int setTestSuite(const TestSuite& ts); + DOCTEST_INTERFACE bool isDebuggerActive(); + + template + int instantiationHelper(const T&) { return 0; } + + namespace binaryAssertComparison { + enum Enum + { + eq = 0, + ne, + gt, + lt, + ge, + le + }; + } // namespace binaryAssertComparison + + // clang-format off + template struct RelationalComparator { bool operator()(const DOCTEST_REF_WRAP(L), const DOCTEST_REF_WRAP(R) ) const { return false; } }; + +#define DOCTEST_BINARY_RELATIONAL_OP(n, op) \ + template struct RelationalComparator { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return op(lhs, rhs); } }; + // clang-format on + + DOCTEST_BINARY_RELATIONAL_OP(0, doctest::detail::eq) + DOCTEST_BINARY_RELATIONAL_OP(1, doctest::detail::ne) + DOCTEST_BINARY_RELATIONAL_OP(2, doctest::detail::gt) + DOCTEST_BINARY_RELATIONAL_OP(3, doctest::detail::lt) + DOCTEST_BINARY_RELATIONAL_OP(4, doctest::detail::ge) + DOCTEST_BINARY_RELATIONAL_OP(5, doctest::detail::le) + + struct DOCTEST_INTERFACE ResultBuilder : public AssertData + { + ResultBuilder(assertType::Enum at, const char* file, int line, const char* expr, + const char* exception_type = "", const String& exception_string = ""); + + ResultBuilder(assertType::Enum at, const char* file, int line, const char* expr, + const char* exception_type, const Contains& exception_string); + + void setResult(const Result& res); + + template + DOCTEST_NOINLINE bool binary_assert(const DOCTEST_REF_WRAP(L) lhs, + const DOCTEST_REF_WRAP(R) rhs) { + m_failed = !RelationalComparator()(lhs, rhs); + if (m_failed || getContextOptions()->success) { + m_decomp = stringifyBinaryExpr(lhs, ", ", rhs); + } + return !m_failed; + } + + template + DOCTEST_NOINLINE bool unary_assert(const DOCTEST_REF_WRAP(L) val) { + m_failed = !val; + + if (m_at & assertType::is_false) { //!OCLINT bitwise operator in conditional + m_failed = !m_failed; + } + + if (m_failed || getContextOptions()->success) { + m_decomp = (DOCTEST_STRINGIFY(val)); + } + + return !m_failed; + } + + void translateException(); + + bool log(); + void react() const; + }; + + namespace assertAction { + enum Enum + { + nothing = 0, + dbgbreak = 1, + shouldthrow = 2 + }; + } // namespace assertAction + + DOCTEST_INTERFACE void failed_out_of_a_testing_context(const AssertData& ad); + + DOCTEST_INTERFACE bool decomp_assert(assertType::Enum at, const char* file, int line, + const char* expr, const Result& result); + +#define DOCTEST_ASSERT_OUT_OF_TESTS(decomp) \ + do { \ + if(!is_running_in_test) { \ + if(failed) { \ + ResultBuilder rb(at, file, line, expr); \ + rb.m_failed = failed; \ + rb.m_decomp = decomp; \ + failed_out_of_a_testing_context(rb); \ + if(isDebuggerActive() && !getContextOptions()->no_breaks) \ + DOCTEST_BREAK_INTO_DEBUGGER(); \ + if(checkIfShouldThrow(at)) \ + throwException(); \ + } \ + return !failed; \ + } \ + } while(false) + +#define DOCTEST_ASSERT_IN_TESTS(decomp) \ + ResultBuilder rb(at, file, line, expr); \ + rb.m_failed = failed; \ + if(rb.m_failed || getContextOptions()->success) \ + rb.m_decomp = decomp; \ + if(rb.log()) \ + DOCTEST_BREAK_INTO_DEBUGGER(); \ + if(rb.m_failed && checkIfShouldThrow(at)) \ + throwException() + + template + DOCTEST_NOINLINE bool binary_assert(assertType::Enum at, const char* file, int line, + const char* expr, const DOCTEST_REF_WRAP(L) lhs, + const DOCTEST_REF_WRAP(R) rhs) { + bool failed = !RelationalComparator()(lhs, rhs); + + // ################################################################################### + // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT + // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED + // ################################################################################### + DOCTEST_ASSERT_OUT_OF_TESTS(stringifyBinaryExpr(lhs, ", ", rhs)); + DOCTEST_ASSERT_IN_TESTS(stringifyBinaryExpr(lhs, ", ", rhs)); + return !failed; + } + + template + DOCTEST_NOINLINE bool unary_assert(assertType::Enum at, const char* file, int line, + const char* expr, const DOCTEST_REF_WRAP(L) val) { + bool failed = !val; + + if(at & assertType::is_false) //!OCLINT bitwise operator in conditional + failed = !failed; + + // ################################################################################### + // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT + // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED + // ################################################################################### + DOCTEST_ASSERT_OUT_OF_TESTS((DOCTEST_STRINGIFY(val))); + DOCTEST_ASSERT_IN_TESTS((DOCTEST_STRINGIFY(val))); + return !failed; + } + + struct DOCTEST_INTERFACE IExceptionTranslator + { + DOCTEST_DECLARE_INTERFACE(IExceptionTranslator) + virtual bool translate(String&) const = 0; + }; + + template + class ExceptionTranslator : public IExceptionTranslator //!OCLINT destructor of virtual class + { + public: + explicit ExceptionTranslator(String (*translateFunction)(T)) + : m_translateFunction(translateFunction) {} + + bool translate(String& res) const override { +#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS + try { + throw; // lgtm [cpp/rethrow-no-exception] + // cppcheck-suppress catchExceptionByValue + } catch(const T& ex) { + res = m_translateFunction(ex); //!OCLINT parameter reassignment + return true; + } catch(...) {} //!OCLINT - empty catch statement +#endif // DOCTEST_CONFIG_NO_EXCEPTIONS + static_cast(res); // to silence -Wunused-parameter + return false; + } + + private: + String (*m_translateFunction)(T); + }; + + DOCTEST_INTERFACE void registerExceptionTranslatorImpl(const IExceptionTranslator* et); + + // ContextScope base class used to allow implementing methods of ContextScope + // that don't depend on the template parameter in doctest.cpp. + struct DOCTEST_INTERFACE ContextScopeBase : public IContextScope { + ContextScopeBase(const ContextScopeBase&) = delete; + + ContextScopeBase& operator=(const ContextScopeBase&) = delete; + ContextScopeBase& operator=(ContextScopeBase&&) = delete; + + ~ContextScopeBase() override = default; + + protected: + ContextScopeBase(); + ContextScopeBase(ContextScopeBase&& other) noexcept; + + void destroy(); + bool need_to_destroy{true}; + }; + + template class ContextScope : public ContextScopeBase + { + L lambda_; + + public: + explicit ContextScope(const L &lambda) : lambda_(lambda) {} + explicit ContextScope(L&& lambda) : lambda_(static_cast(lambda)) { } + + ContextScope(const ContextScope&) = delete; + ContextScope(ContextScope&&) noexcept = default; + + ContextScope& operator=(const ContextScope&) = delete; + ContextScope& operator=(ContextScope&&) = delete; + + void stringify(std::ostream* s) const override { lambda_(s); } + + ~ContextScope() override { + if (need_to_destroy) { + destroy(); + } + } + }; + + struct DOCTEST_INTERFACE MessageBuilder : public MessageData + { + std::ostream* m_stream; + bool logged = false; + + MessageBuilder(const char* file, int line, assertType::Enum severity); + + MessageBuilder(const MessageBuilder&) = delete; + MessageBuilder(MessageBuilder&&) = delete; + + MessageBuilder& operator=(const MessageBuilder&) = delete; + MessageBuilder& operator=(MessageBuilder&&) = delete; + + ~MessageBuilder(); + + // the preferred way of chaining parameters for stringification +DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4866) + template + MessageBuilder& operator,(const T& in) { + *m_stream << (DOCTEST_STRINGIFY(in)); + return *this; + } +DOCTEST_MSVC_SUPPRESS_WARNING_POP + + // kept here just for backwards-compatibility - the comma operator should be preferred now + template + MessageBuilder& operator<<(const T& in) { return this->operator,(in); } + + // the `,` operator has the lowest operator precedence - if `<<` is used by the user then + // the `,` operator will be called last which is not what we want and thus the `*` operator + // is used first (has higher operator precedence compared to `<<`) so that we guarantee that + // an operator of the MessageBuilder class is called first before the rest of the parameters + template + MessageBuilder& operator*(const T& in) { return this->operator,(in); } + + bool log(); + void react(); + }; + + template + ContextScope MakeContextScope(const L &lambda) { + return ContextScope(lambda); + } +} // namespace detail + +#define DOCTEST_DEFINE_DECORATOR(name, type, def) \ + struct name \ + { \ + type data; \ + name(type in = def) \ + : data(in) {} \ + void fill(detail::TestCase& state) const { state.DOCTEST_CAT(m_, name) = data; } \ + void fill(detail::TestSuite& state) const { state.DOCTEST_CAT(m_, name) = data; } \ + } + +DOCTEST_DEFINE_DECORATOR(test_suite, const char*, ""); +DOCTEST_DEFINE_DECORATOR(description, const char*, ""); +DOCTEST_DEFINE_DECORATOR(skip, bool, true); +DOCTEST_DEFINE_DECORATOR(no_breaks, bool, true); +DOCTEST_DEFINE_DECORATOR(no_output, bool, true); +DOCTEST_DEFINE_DECORATOR(timeout, double, 0); +DOCTEST_DEFINE_DECORATOR(may_fail, bool, true); +DOCTEST_DEFINE_DECORATOR(should_fail, bool, true); +DOCTEST_DEFINE_DECORATOR(expected_failures, int, 0); + +template +int registerExceptionTranslator(String (*translateFunction)(T)) { + DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wexit-time-destructors") + static detail::ExceptionTranslator exceptionTranslator(translateFunction); + DOCTEST_CLANG_SUPPRESS_WARNING_POP + detail::registerExceptionTranslatorImpl(&exceptionTranslator); + return 0; +} + +} // namespace doctest + +// in a separate namespace outside of doctest because the DOCTEST_TEST_SUITE macro +// introduces an anonymous namespace in which getCurrentTestSuite gets overridden +namespace doctest_detail_test_suite_ns { +DOCTEST_INTERFACE doctest::detail::TestSuite& getCurrentTestSuite(); +} // namespace doctest_detail_test_suite_ns + +namespace doctest { +#else // DOCTEST_CONFIG_DISABLE +template +int registerExceptionTranslator(String (*)(T)) { + return 0; +} +#endif // DOCTEST_CONFIG_DISABLE + +namespace detail { + using assert_handler = void (*)(const AssertData&); + struct ContextState; +} // namespace detail + +class DOCTEST_INTERFACE Context +{ + detail::ContextState* p; + + void parseArgs(int argc, const char* const* argv, bool withDefaults = false); + +public: + explicit Context(int argc = 0, const char* const* argv = nullptr); + + Context(const Context&) = delete; + Context(Context&&) = delete; + + Context& operator=(const Context&) = delete; + Context& operator=(Context&&) = delete; + + ~Context(); // NOLINT(performance-trivially-destructible) + + void applyCommandLine(int argc, const char* const* argv); + + void addFilter(const char* filter, const char* value); + void clearFilters(); + void setOption(const char* option, bool value); + void setOption(const char* option, int value); + void setOption(const char* option, const char* value); + + bool shouldExit(); + + void setAsDefaultForAssertsOutOfTestCases(); + + void setAssertHandler(detail::assert_handler ah); + + void setCout(std::ostream* out); + + int run(); +}; + +namespace TestCaseFailureReason { + enum Enum + { + None = 0, + AssertFailure = 1, // an assertion has failed in the test case + Exception = 2, // test case threw an exception + Crash = 4, // a crash... + TooManyFailedAsserts = 8, // the abort-after option + Timeout = 16, // see the timeout decorator + ShouldHaveFailedButDidnt = 32, // see the should_fail decorator + ShouldHaveFailedAndDid = 64, // see the should_fail decorator + DidntFailExactlyNumTimes = 128, // see the expected_failures decorator + FailedExactlyNumTimes = 256, // see the expected_failures decorator + CouldHaveFailedAndDid = 512 // see the may_fail decorator + }; +} // namespace TestCaseFailureReason + +struct DOCTEST_INTERFACE CurrentTestCaseStats +{ + int numAssertsCurrentTest; + int numAssertsFailedCurrentTest; + double seconds; + int failure_flags; // use TestCaseFailureReason::Enum + bool testCaseSuccess; +}; + +struct DOCTEST_INTERFACE TestCaseException +{ + String error_string; + bool is_crash; +}; + +struct DOCTEST_INTERFACE TestRunStats +{ + unsigned numTestCases; + unsigned numTestCasesPassingFilters; + unsigned numTestSuitesPassingFilters; + unsigned numTestCasesFailed; + int numAsserts; + int numAssertsFailed; +}; + +struct QueryData +{ + const TestRunStats* run_stats = nullptr; + const TestCaseData** data = nullptr; + unsigned num_data = 0; +}; + +struct DOCTEST_INTERFACE IReporter +{ + // The constructor has to accept "const ContextOptions&" as a single argument + // which has most of the options for the run + a pointer to the stdout stream + // Reporter(const ContextOptions& in) + + // called when a query should be reported (listing test cases, printing the version, etc.) + virtual void report_query(const QueryData&) = 0; + + // called when the whole test run starts + virtual void test_run_start() = 0; + // called when the whole test run ends (caching a pointer to the input doesn't make sense here) + virtual void test_run_end(const TestRunStats&) = 0; + + // called when a test case is started (safe to cache a pointer to the input) + virtual void test_case_start(const TestCaseData&) = 0; + // called when a test case is reentered because of unfinished subcases (safe to cache a pointer to the input) + virtual void test_case_reenter(const TestCaseData&) = 0; + // called when a test case has ended + virtual void test_case_end(const CurrentTestCaseStats&) = 0; + + // called when an exception is thrown from the test case (or it crashes) + virtual void test_case_exception(const TestCaseException&) = 0; + + // called whenever a subcase is entered (don't cache pointers to the input) + virtual void subcase_start(const SubcaseSignature&) = 0; + // called whenever a subcase is exited (don't cache pointers to the input) + virtual void subcase_end() = 0; + + // called for each assert (don't cache pointers to the input) + virtual void log_assert(const AssertData&) = 0; + // called for each message (don't cache pointers to the input) + virtual void log_message(const MessageData&) = 0; + + // called when a test case is skipped either because it doesn't pass the filters, has a skip decorator + // or isn't in the execution range (between first and last) (safe to cache a pointer to the input) + virtual void test_case_skipped(const TestCaseData&) = 0; + + DOCTEST_DECLARE_INTERFACE(IReporter) + + // can obtain all currently active contexts and stringify them if one wishes to do so + static int get_num_active_contexts(); + static const IContextScope* const* get_active_contexts(); + + // can iterate through contexts which have been stringified automatically in their destructors when an exception has been thrown + static int get_num_stringified_contexts(); + static const String* get_stringified_contexts(); +}; + +namespace detail { + using reporterCreatorFunc = IReporter* (*)(const ContextOptions&); + + DOCTEST_INTERFACE void registerReporterImpl(const char* name, int prio, reporterCreatorFunc c, bool isReporter); + + template + IReporter* reporterCreator(const ContextOptions& o) { + return new Reporter(o); + } +} // namespace detail + +template +int registerReporter(const char* name, int priority, bool isReporter) { + detail::registerReporterImpl(name, priority, detail::reporterCreator, isReporter); + return 0; +} +} // namespace doctest + +#ifdef DOCTEST_CONFIG_ASSERTS_RETURN_VALUES +#define DOCTEST_FUNC_EMPTY [] { return false; }() +#else +#define DOCTEST_FUNC_EMPTY (void)0 +#endif + +// if registering is not disabled +#ifndef DOCTEST_CONFIG_DISABLE + +#ifdef DOCTEST_CONFIG_ASSERTS_RETURN_VALUES +#define DOCTEST_FUNC_SCOPE_BEGIN [&] +#define DOCTEST_FUNC_SCOPE_END () +#define DOCTEST_FUNC_SCOPE_RET(v) return v +#else +#define DOCTEST_FUNC_SCOPE_BEGIN do +#define DOCTEST_FUNC_SCOPE_END while(false) +#define DOCTEST_FUNC_SCOPE_RET(v) (void)0 +#endif + +// common code in asserts - for convenience +#define DOCTEST_ASSERT_LOG_REACT_RETURN(b) \ + if(b.log()) DOCTEST_BREAK_INTO_DEBUGGER(); \ + b.react(); \ + DOCTEST_FUNC_SCOPE_RET(!b.m_failed) + +#ifdef DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS +#define DOCTEST_WRAP_IN_TRY(x) x; +#else // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS +#define DOCTEST_WRAP_IN_TRY(x) \ + try { \ + x; \ + } catch(...) { DOCTEST_RB.translateException(); } +#endif // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS + +#ifdef DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS +#define DOCTEST_CAST_TO_VOID(...) \ + DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wuseless-cast") \ + static_cast(__VA_ARGS__); \ + DOCTEST_GCC_SUPPRESS_WARNING_POP +#else // DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS +#define DOCTEST_CAST_TO_VOID(...) __VA_ARGS__; +#endif // DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS + +// registers the test by initializing a dummy var with a function +#define DOCTEST_REGISTER_FUNCTION(global_prefix, f, decorators) \ + global_prefix DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_), /* NOLINT */ \ + doctest::detail::regTest( \ + doctest::detail::TestCase( \ + f, __FILE__, __LINE__, \ + doctest_detail_test_suite_ns::getCurrentTestSuite()) * \ + decorators)) + +#define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, decorators) \ + namespace { /* NOLINT */ \ + struct der : public base \ + { \ + void f(); \ + }; \ + static DOCTEST_INLINE_NOINLINE void func() { \ + der v; \ + v.f(); \ + } \ + DOCTEST_REGISTER_FUNCTION(DOCTEST_EMPTY, func, decorators) \ + } \ + DOCTEST_INLINE_NOINLINE void der::f() // NOLINT(misc-definitions-in-headers) + +#define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, decorators) \ + static void f(); \ + DOCTEST_REGISTER_FUNCTION(DOCTEST_EMPTY, f, decorators) \ + static void f() + +#define DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS(f, proxy, decorators) \ + static doctest::detail::funcType proxy() { return f; } \ + DOCTEST_REGISTER_FUNCTION(inline, proxy(), decorators) \ + static void f() + +// for registering tests +#define DOCTEST_TEST_CASE(decorators) \ + DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), decorators) + +// for registering tests in classes - requires C++17 for inline variables! +#if DOCTEST_CPLUSPLUS >= 201703L +#define DOCTEST_TEST_CASE_CLASS(decorators) \ + DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), \ + DOCTEST_ANONYMOUS(DOCTEST_ANON_PROXY_), \ + decorators) +#else // DOCTEST_TEST_CASE_CLASS +#define DOCTEST_TEST_CASE_CLASS(...) \ + TEST_CASES_CAN_BE_REGISTERED_IN_CLASSES_ONLY_IN_CPP17_MODE_OR_WITH_VS_2017_OR_NEWER +#endif // DOCTEST_TEST_CASE_CLASS + +// for registering tests with a fixture +#define DOCTEST_TEST_CASE_FIXTURE(c, decorators) \ + DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(DOCTEST_ANON_CLASS_), c, \ + DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), decorators) + +// for converting types to strings without the header and demangling +#define DOCTEST_TYPE_TO_STRING_AS(str, ...) \ + namespace doctest { \ + template <> \ + inline String toString<__VA_ARGS__>() { \ + return str; \ + } \ + } \ + static_assert(true, "") + +#define DOCTEST_TYPE_TO_STRING(...) DOCTEST_TYPE_TO_STRING_AS(#__VA_ARGS__, __VA_ARGS__) + +#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, iter, func) \ + template \ + static void func(); \ + namespace { /* NOLINT */ \ + template \ + struct iter; \ + template \ + struct iter> \ + { \ + iter(const char* file, unsigned line, int index) { \ + doctest::detail::regTest(doctest::detail::TestCase(func, file, line, \ + doctest_detail_test_suite_ns::getCurrentTestSuite(), \ + doctest::toString(), \ + int(line) * 1000 + index) \ + * dec); \ + iter>(file, line, index + 1); \ + } \ + }; \ + template <> \ + struct iter> \ + { \ + iter(const char*, unsigned, int) {} \ + }; \ + } \ + template \ + static void func() + +#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(dec, T, id) \ + DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(id, ITERATOR), \ + DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_)) + +#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, anon, ...) \ + DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_CAT(anon, DUMMY), /* NOLINT(cert-err58-cpp, fuchsia-statically-constructed-objects) */ \ + doctest::detail::instantiationHelper( \ + DOCTEST_CAT(id, ITERATOR)<__VA_ARGS__>(__FILE__, __LINE__, 0))) + +#define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...) \ + DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), std::tuple<__VA_ARGS__>) \ + static_assert(true, "") + +#define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...) \ + DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), __VA_ARGS__) \ + static_assert(true, "") + +#define DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T, anon, ...) \ + DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(anon, ITERATOR), anon); \ + DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(anon, anon, std::tuple<__VA_ARGS__>) \ + template \ + static void anon() + +#define DOCTEST_TEST_CASE_TEMPLATE(dec, T, ...) \ + DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T, DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), __VA_ARGS__) + +// for subcases +#define DOCTEST_SUBCASE(name) \ + if(const doctest::detail::Subcase & DOCTEST_ANONYMOUS(DOCTEST_ANON_SUBCASE_) DOCTEST_UNUSED = \ + doctest::detail::Subcase(name, __FILE__, __LINE__)) + +// for grouping tests in test suites by using code blocks +#define DOCTEST_TEST_SUITE_IMPL(decorators, ns_name) \ + namespace ns_name { namespace doctest_detail_test_suite_ns { \ + static DOCTEST_NOINLINE doctest::detail::TestSuite& getCurrentTestSuite() noexcept { \ + DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4640) \ + DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wexit-time-destructors") \ + DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wmissing-field-initializers") \ + static doctest::detail::TestSuite data{}; \ + static bool inited = false; \ + DOCTEST_MSVC_SUPPRESS_WARNING_POP \ + DOCTEST_CLANG_SUPPRESS_WARNING_POP \ + DOCTEST_GCC_SUPPRESS_WARNING_POP \ + if(!inited) { \ + data* decorators; \ + inited = true; \ + } \ + return data; \ + } \ + } \ + } \ + namespace ns_name + +#define DOCTEST_TEST_SUITE(decorators) \ + DOCTEST_TEST_SUITE_IMPL(decorators, DOCTEST_ANONYMOUS(DOCTEST_ANON_SUITE_)) + +// for starting a testsuite block +#define DOCTEST_TEST_SUITE_BEGIN(decorators) \ + DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_), /* NOLINT(cert-err58-cpp) */ \ + doctest::detail::setTestSuite(doctest::detail::TestSuite() * decorators)) \ + static_assert(true, "") + +// for ending a testsuite block +#define DOCTEST_TEST_SUITE_END \ + DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_), /* NOLINT(cert-err58-cpp) */ \ + doctest::detail::setTestSuite(doctest::detail::TestSuite() * "")) \ + using DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_) = int + +// for registering exception translators +#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(translatorName, signature) \ + inline doctest::String translatorName(signature); \ + DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_), /* NOLINT(cert-err58-cpp) */ \ + doctest::registerExceptionTranslator(translatorName)) \ + doctest::String translatorName(signature) + +#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature) \ + DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_), \ + signature) + +// for registering reporters +#define DOCTEST_REGISTER_REPORTER(name, priority, reporter) \ + DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_REPORTER_), /* NOLINT(cert-err58-cpp) */ \ + doctest::registerReporter(name, priority, true)) \ + static_assert(true, "") + +// for registering listeners +#define DOCTEST_REGISTER_LISTENER(name, priority, reporter) \ + DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(DOCTEST_ANON_REPORTER_), /* NOLINT(cert-err58-cpp) */ \ + doctest::registerReporter(name, priority, false)) \ + static_assert(true, "") + +// clang-format off +// for logging - disabling formatting because it's important to have these on 2 separate lines - see PR #557 +#define DOCTEST_INFO(...) \ + DOCTEST_INFO_IMPL(DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_), \ + DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_OTHER_), \ + __VA_ARGS__) +// clang-format on + +#define DOCTEST_INFO_IMPL(mb_name, s_name, ...) \ + auto DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_) = doctest::detail::MakeContextScope( \ + [&](std::ostream* s_name) { \ + doctest::detail::MessageBuilder mb_name(__FILE__, __LINE__, doctest::assertType::is_warn); \ + mb_name.m_stream = s_name; \ + mb_name * __VA_ARGS__; \ + }) + +#define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x " := ", x) + +#define DOCTEST_ADD_AT_IMPL(type, file, line, mb, ...) \ + DOCTEST_FUNC_SCOPE_BEGIN { \ + doctest::detail::MessageBuilder mb(file, line, doctest::assertType::type); \ + mb * __VA_ARGS__; \ + if(mb.log()) \ + DOCTEST_BREAK_INTO_DEBUGGER(); \ + mb.react(); \ + } DOCTEST_FUNC_SCOPE_END + +// clang-format off +#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_warn, file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__) +#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__) +#define DOCTEST_ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_require, file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__) +// clang-format on + +#define DOCTEST_MESSAGE(...) DOCTEST_ADD_MESSAGE_AT(__FILE__, __LINE__, __VA_ARGS__) +#define DOCTEST_FAIL_CHECK(...) DOCTEST_ADD_FAIL_CHECK_AT(__FILE__, __LINE__, __VA_ARGS__) +#define DOCTEST_FAIL(...) DOCTEST_ADD_FAIL_AT(__FILE__, __LINE__, __VA_ARGS__) + +#define DOCTEST_TO_LVALUE(...) __VA_ARGS__ // Not removed to keep backwards compatibility. + +#ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS + +#define DOCTEST_ASSERT_IMPLEMENT_2(assert_type, ...) \ + DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Woverloaded-shift-op-parentheses") \ + /* NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) */ \ + doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \ + __LINE__, #__VA_ARGS__); \ + DOCTEST_WRAP_IN_TRY(DOCTEST_RB.setResult( \ + doctest::detail::ExpressionDecomposer(doctest::assertType::assert_type) \ + << __VA_ARGS__)) /* NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) */ \ + DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB) \ + DOCTEST_CLANG_SUPPRESS_WARNING_POP + +#define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...) \ + DOCTEST_FUNC_SCOPE_BEGIN { \ + DOCTEST_ASSERT_IMPLEMENT_2(assert_type, __VA_ARGS__); \ + } DOCTEST_FUNC_SCOPE_END // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks) + +#define DOCTEST_BINARY_ASSERT(assert_type, comp, ...) \ + DOCTEST_FUNC_SCOPE_BEGIN { \ + doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \ + __LINE__, #__VA_ARGS__); \ + DOCTEST_WRAP_IN_TRY( \ + DOCTEST_RB.binary_assert( \ + __VA_ARGS__)) \ + DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \ + } DOCTEST_FUNC_SCOPE_END + +#define DOCTEST_UNARY_ASSERT(assert_type, ...) \ + DOCTEST_FUNC_SCOPE_BEGIN { \ + doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \ + __LINE__, #__VA_ARGS__); \ + DOCTEST_WRAP_IN_TRY(DOCTEST_RB.unary_assert(__VA_ARGS__)) \ + DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \ + } DOCTEST_FUNC_SCOPE_END + +#else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS + +// necessary for _MESSAGE +#define DOCTEST_ASSERT_IMPLEMENT_2 DOCTEST_ASSERT_IMPLEMENT_1 + +#define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...) \ + DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Woverloaded-shift-op-parentheses") \ + doctest::detail::decomp_assert( \ + doctest::assertType::assert_type, __FILE__, __LINE__, #__VA_ARGS__, \ + doctest::detail::ExpressionDecomposer(doctest::assertType::assert_type) \ + << __VA_ARGS__) DOCTEST_CLANG_SUPPRESS_WARNING_POP + +#define DOCTEST_BINARY_ASSERT(assert_type, comparison, ...) \ + doctest::detail::binary_assert( \ + doctest::assertType::assert_type, __FILE__, __LINE__, #__VA_ARGS__, __VA_ARGS__) + +#define DOCTEST_UNARY_ASSERT(assert_type, ...) \ + doctest::detail::unary_assert(doctest::assertType::assert_type, __FILE__, __LINE__, \ + #__VA_ARGS__, __VA_ARGS__) + +#endif // DOCTEST_CONFIG_SUPER_FAST_ASSERTS + +#define DOCTEST_WARN(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_WARN, __VA_ARGS__) +#define DOCTEST_CHECK(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_CHECK, __VA_ARGS__) +#define DOCTEST_REQUIRE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE, __VA_ARGS__) +#define DOCTEST_WARN_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_WARN_FALSE, __VA_ARGS__) +#define DOCTEST_CHECK_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_CHECK_FALSE, __VA_ARGS__) +#define DOCTEST_REQUIRE_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE_FALSE, __VA_ARGS__) + +// clang-format off +#define DOCTEST_WARN_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN, cond); } DOCTEST_FUNC_SCOPE_END +#define DOCTEST_CHECK_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK, cond); } DOCTEST_FUNC_SCOPE_END +#define DOCTEST_REQUIRE_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE, cond); } DOCTEST_FUNC_SCOPE_END +#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN_FALSE, cond); } DOCTEST_FUNC_SCOPE_END +#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK_FALSE, cond); } DOCTEST_FUNC_SCOPE_END +#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE_FALSE, cond); } DOCTEST_FUNC_SCOPE_END +// clang-format on + +#define DOCTEST_WARN_EQ(...) DOCTEST_BINARY_ASSERT(DT_WARN_EQ, eq, __VA_ARGS__) +#define DOCTEST_CHECK_EQ(...) DOCTEST_BINARY_ASSERT(DT_CHECK_EQ, eq, __VA_ARGS__) +#define DOCTEST_REQUIRE_EQ(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_EQ, eq, __VA_ARGS__) +#define DOCTEST_WARN_NE(...) DOCTEST_BINARY_ASSERT(DT_WARN_NE, ne, __VA_ARGS__) +#define DOCTEST_CHECK_NE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_NE, ne, __VA_ARGS__) +#define DOCTEST_REQUIRE_NE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_NE, ne, __VA_ARGS__) +#define DOCTEST_WARN_GT(...) DOCTEST_BINARY_ASSERT(DT_WARN_GT, gt, __VA_ARGS__) +#define DOCTEST_CHECK_GT(...) DOCTEST_BINARY_ASSERT(DT_CHECK_GT, gt, __VA_ARGS__) +#define DOCTEST_REQUIRE_GT(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GT, gt, __VA_ARGS__) +#define DOCTEST_WARN_LT(...) DOCTEST_BINARY_ASSERT(DT_WARN_LT, lt, __VA_ARGS__) +#define DOCTEST_CHECK_LT(...) DOCTEST_BINARY_ASSERT(DT_CHECK_LT, lt, __VA_ARGS__) +#define DOCTEST_REQUIRE_LT(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LT, lt, __VA_ARGS__) +#define DOCTEST_WARN_GE(...) DOCTEST_BINARY_ASSERT(DT_WARN_GE, ge, __VA_ARGS__) +#define DOCTEST_CHECK_GE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_GE, ge, __VA_ARGS__) +#define DOCTEST_REQUIRE_GE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GE, ge, __VA_ARGS__) +#define DOCTEST_WARN_LE(...) DOCTEST_BINARY_ASSERT(DT_WARN_LE, le, __VA_ARGS__) +#define DOCTEST_CHECK_LE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_LE, le, __VA_ARGS__) +#define DOCTEST_REQUIRE_LE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LE, le, __VA_ARGS__) + +#define DOCTEST_WARN_UNARY(...) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY, __VA_ARGS__) +#define DOCTEST_CHECK_UNARY(...) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY, __VA_ARGS__) +#define DOCTEST_REQUIRE_UNARY(...) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY, __VA_ARGS__) +#define DOCTEST_WARN_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY_FALSE, __VA_ARGS__) +#define DOCTEST_CHECK_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY_FALSE, __VA_ARGS__) +#define DOCTEST_REQUIRE_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY_FALSE, __VA_ARGS__) + +#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS + +#define DOCTEST_ASSERT_THROWS_AS(expr, assert_type, message, ...) \ + DOCTEST_FUNC_SCOPE_BEGIN { \ + if(!doctest::getContextOptions()->no_throw) { \ + doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \ + __LINE__, #expr, #__VA_ARGS__, message); \ + try { \ + DOCTEST_CAST_TO_VOID(expr) \ + } catch(const typename doctest::detail::types::remove_const< \ + typename doctest::detail::types::remove_reference<__VA_ARGS__>::type>::type&) {\ + DOCTEST_RB.translateException(); \ + DOCTEST_RB.m_threw_as = true; \ + } catch(...) { DOCTEST_RB.translateException(); } \ + DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \ + } else { /* NOLINT(*-else-after-return) */ \ + DOCTEST_FUNC_SCOPE_RET(false); \ + } \ + } DOCTEST_FUNC_SCOPE_END + +#define DOCTEST_ASSERT_THROWS_WITH(expr, expr_str, assert_type, ...) \ + DOCTEST_FUNC_SCOPE_BEGIN { \ + if(!doctest::getContextOptions()->no_throw) { \ + doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \ + __LINE__, expr_str, "", __VA_ARGS__); \ + try { \ + DOCTEST_CAST_TO_VOID(expr) \ + } catch(...) { DOCTEST_RB.translateException(); } \ + DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \ + } else { /* NOLINT(*-else-after-return) */ \ + DOCTEST_FUNC_SCOPE_RET(false); \ + } \ + } DOCTEST_FUNC_SCOPE_END + +#define DOCTEST_ASSERT_NOTHROW(assert_type, ...) \ + DOCTEST_FUNC_SCOPE_BEGIN { \ + doctest::detail::ResultBuilder DOCTEST_RB(doctest::assertType::assert_type, __FILE__, \ + __LINE__, #__VA_ARGS__); \ + try { \ + DOCTEST_CAST_TO_VOID(__VA_ARGS__) \ + } catch(...) { DOCTEST_RB.translateException(); } \ + DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \ + } DOCTEST_FUNC_SCOPE_END + +// clang-format off +#define DOCTEST_WARN_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_WARN_THROWS, "") +#define DOCTEST_CHECK_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_CHECK_THROWS, "") +#define DOCTEST_REQUIRE_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_REQUIRE_THROWS, "") + +#define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_AS, "", __VA_ARGS__) +#define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_AS, "", __VA_ARGS__) +#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_AS, "", __VA_ARGS__) + +#define DOCTEST_WARN_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_WARN_THROWS_WITH, __VA_ARGS__) +#define DOCTEST_CHECK_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_CHECK_THROWS_WITH, __VA_ARGS__) +#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_REQUIRE_THROWS_WITH, __VA_ARGS__) + +#define DOCTEST_WARN_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_WITH_AS, message, __VA_ARGS__) +#define DOCTEST_CHECK_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_WITH_AS, message, __VA_ARGS__) +#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_WITH_AS, message, __VA_ARGS__) + +#define DOCTEST_WARN_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_WARN_NOTHROW, __VA_ARGS__) +#define DOCTEST_CHECK_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_CHECK_NOTHROW, __VA_ARGS__) +#define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_REQUIRE_NOTHROW, __VA_ARGS__) + +#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS(expr); } DOCTEST_FUNC_SCOPE_END +#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS(expr); } DOCTEST_FUNC_SCOPE_END +#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS(expr); } DOCTEST_FUNC_SCOPE_END +#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_AS(expr, ex); } DOCTEST_FUNC_SCOPE_END +#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_AS(expr, ex); } DOCTEST_FUNC_SCOPE_END +#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_AS(expr, ex); } DOCTEST_FUNC_SCOPE_END +#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH(expr, with); } DOCTEST_FUNC_SCOPE_END +#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH(expr, with); } DOCTEST_FUNC_SCOPE_END +#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH(expr, with); } DOCTEST_FUNC_SCOPE_END +#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex); } DOCTEST_FUNC_SCOPE_END +#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex); } DOCTEST_FUNC_SCOPE_END +#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex); } DOCTEST_FUNC_SCOPE_END +#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_NOTHROW(expr); } DOCTEST_FUNC_SCOPE_END +#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_NOTHROW(expr); } DOCTEST_FUNC_SCOPE_END +#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_NOTHROW(expr); } DOCTEST_FUNC_SCOPE_END +// clang-format on + +#endif // DOCTEST_CONFIG_NO_EXCEPTIONS + +// ================================================================================================= +// == WHAT FOLLOWS IS VERSIONS OF THE MACROS THAT DO NOT DO ANY REGISTERING! == +// == THIS CAN BE ENABLED BY DEFINING DOCTEST_CONFIG_DISABLE GLOBALLY! == +// ================================================================================================= +#else // DOCTEST_CONFIG_DISABLE + +#define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, name) \ + namespace /* NOLINT */ { \ + template \ + struct der : public base \ + { void f(); }; \ + } \ + template \ + inline void der::f() + +#define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, name) \ + template \ + static inline void f() + +// for registering tests +#define DOCTEST_TEST_CASE(name) \ + DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), name) + +// for registering tests in classes +#define DOCTEST_TEST_CASE_CLASS(name) \ + DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), name) + +// for registering tests with a fixture +#define DOCTEST_TEST_CASE_FIXTURE(x, name) \ + DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(DOCTEST_ANON_CLASS_), x, \ + DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), name) + +// for converting types to strings without the header and demangling +#define DOCTEST_TYPE_TO_STRING_AS(str, ...) static_assert(true, "") +#define DOCTEST_TYPE_TO_STRING(...) static_assert(true, "") + +// for typed tests +#define DOCTEST_TEST_CASE_TEMPLATE(name, type, ...) \ + template \ + inline void DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_)() + +#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, type, id) \ + template \ + inline void DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_)() + +#define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...) static_assert(true, "") +#define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...) static_assert(true, "") + +// for subcases +#define DOCTEST_SUBCASE(name) + +// for a testsuite block +#define DOCTEST_TEST_SUITE(name) namespace // NOLINT + +// for starting a testsuite block +#define DOCTEST_TEST_SUITE_BEGIN(name) static_assert(true, "") + +// for ending a testsuite block +#define DOCTEST_TEST_SUITE_END using DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_) = int + +#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature) \ + template \ + static inline doctest::String DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_)(signature) + +#define DOCTEST_REGISTER_REPORTER(name, priority, reporter) +#define DOCTEST_REGISTER_LISTENER(name, priority, reporter) + +#define DOCTEST_INFO(...) (static_cast(0)) +#define DOCTEST_CAPTURE(x) (static_cast(0)) +#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) (static_cast(0)) +#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) (static_cast(0)) +#define DOCTEST_ADD_FAIL_AT(file, line, ...) (static_cast(0)) +#define DOCTEST_MESSAGE(...) (static_cast(0)) +#define DOCTEST_FAIL_CHECK(...) (static_cast(0)) +#define DOCTEST_FAIL(...) (static_cast(0)) + +#if defined(DOCTEST_CONFIG_EVALUATE_ASSERTS_EVEN_WHEN_DISABLED) \ + && defined(DOCTEST_CONFIG_ASSERTS_RETURN_VALUES) + +#define DOCTEST_WARN(...) [&] { return __VA_ARGS__; }() +#define DOCTEST_CHECK(...) [&] { return __VA_ARGS__; }() +#define DOCTEST_REQUIRE(...) [&] { return __VA_ARGS__; }() +#define DOCTEST_WARN_FALSE(...) [&] { return !(__VA_ARGS__); }() +#define DOCTEST_CHECK_FALSE(...) [&] { return !(__VA_ARGS__); }() +#define DOCTEST_REQUIRE_FALSE(...) [&] { return !(__VA_ARGS__); }() + +#define DOCTEST_WARN_MESSAGE(cond, ...) [&] { return cond; }() +#define DOCTEST_CHECK_MESSAGE(cond, ...) [&] { return cond; }() +#define DOCTEST_REQUIRE_MESSAGE(cond, ...) [&] { return cond; }() +#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) [&] { return !(cond); }() +#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) [&] { return !(cond); }() +#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) [&] { return !(cond); }() + +namespace doctest { +namespace detail { +#define DOCTEST_RELATIONAL_OP(name, op) \ + template \ + bool name(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) { return lhs op rhs; } + + DOCTEST_RELATIONAL_OP(eq, ==) + DOCTEST_RELATIONAL_OP(ne, !=) + DOCTEST_RELATIONAL_OP(lt, <) + DOCTEST_RELATIONAL_OP(gt, >) + DOCTEST_RELATIONAL_OP(le, <=) + DOCTEST_RELATIONAL_OP(ge, >=) +} // namespace detail +} // namespace doctest + +#define DOCTEST_WARN_EQ(...) [&] { return doctest::detail::eq(__VA_ARGS__); }() +#define DOCTEST_CHECK_EQ(...) [&] { return doctest::detail::eq(__VA_ARGS__); }() +#define DOCTEST_REQUIRE_EQ(...) [&] { return doctest::detail::eq(__VA_ARGS__); }() +#define DOCTEST_WARN_NE(...) [&] { return doctest::detail::ne(__VA_ARGS__); }() +#define DOCTEST_CHECK_NE(...) [&] { return doctest::detail::ne(__VA_ARGS__); }() +#define DOCTEST_REQUIRE_NE(...) [&] { return doctest::detail::ne(__VA_ARGS__); }() +#define DOCTEST_WARN_LT(...) [&] { return doctest::detail::lt(__VA_ARGS__); }() +#define DOCTEST_CHECK_LT(...) [&] { return doctest::detail::lt(__VA_ARGS__); }() +#define DOCTEST_REQUIRE_LT(...) [&] { return doctest::detail::lt(__VA_ARGS__); }() +#define DOCTEST_WARN_GT(...) [&] { return doctest::detail::gt(__VA_ARGS__); }() +#define DOCTEST_CHECK_GT(...) [&] { return doctest::detail::gt(__VA_ARGS__); }() +#define DOCTEST_REQUIRE_GT(...) [&] { return doctest::detail::gt(__VA_ARGS__); }() +#define DOCTEST_WARN_LE(...) [&] { return doctest::detail::le(__VA_ARGS__); }() +#define DOCTEST_CHECK_LE(...) [&] { return doctest::detail::le(__VA_ARGS__); }() +#define DOCTEST_REQUIRE_LE(...) [&] { return doctest::detail::le(__VA_ARGS__); }() +#define DOCTEST_WARN_GE(...) [&] { return doctest::detail::ge(__VA_ARGS__); }() +#define DOCTEST_CHECK_GE(...) [&] { return doctest::detail::ge(__VA_ARGS__); }() +#define DOCTEST_REQUIRE_GE(...) [&] { return doctest::detail::ge(__VA_ARGS__); }() +#define DOCTEST_WARN_UNARY(...) [&] { return __VA_ARGS__; }() +#define DOCTEST_CHECK_UNARY(...) [&] { return __VA_ARGS__; }() +#define DOCTEST_REQUIRE_UNARY(...) [&] { return __VA_ARGS__; }() +#define DOCTEST_WARN_UNARY_FALSE(...) [&] { return !(__VA_ARGS__); }() +#define DOCTEST_CHECK_UNARY_FALSE(...) [&] { return !(__VA_ARGS__); }() +#define DOCTEST_REQUIRE_UNARY_FALSE(...) [&] { return !(__VA_ARGS__); }() + +#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS + +#define DOCTEST_WARN_THROWS_WITH(expr, with, ...) [] { static_assert(false, "Exception translation is not available when doctest is disabled."); return false; }() +#define DOCTEST_CHECK_THROWS_WITH(expr, with, ...) DOCTEST_WARN_THROWS_WITH(,,) +#define DOCTEST_REQUIRE_THROWS_WITH(expr, with, ...) DOCTEST_WARN_THROWS_WITH(,,) +#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,) +#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,) +#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,) + +#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_WARN_THROWS_WITH(,,) +#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_WARN_THROWS_WITH(,,) +#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_WARN_THROWS_WITH(,,) +#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,) +#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,) +#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH(,,) + +#define DOCTEST_WARN_THROWS(...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }() +#define DOCTEST_CHECK_THROWS(...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }() +#define DOCTEST_REQUIRE_THROWS(...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }() +#define DOCTEST_WARN_THROWS_AS(expr, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }() +#define DOCTEST_CHECK_THROWS_AS(expr, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }() +#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }() +#define DOCTEST_WARN_NOTHROW(...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }() +#define DOCTEST_CHECK_NOTHROW(...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }() +#define DOCTEST_REQUIRE_NOTHROW(...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }() + +#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }() +#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }() +#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return false; } catch (...) { return true; } }() +#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }() +#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }() +#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) [&] { try { expr; } catch (__VA_ARGS__) { return true; } catch (...) { } return false; }() +#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }() +#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }() +#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) [&] { try { __VA_ARGS__; return true; } catch (...) { return false; } }() + +#endif // DOCTEST_CONFIG_NO_EXCEPTIONS + +#else // DOCTEST_CONFIG_EVALUATE_ASSERTS_EVEN_WHEN_DISABLED + +#define DOCTEST_WARN(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_CHECK(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_REQUIRE(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_WARN_FALSE(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_CHECK_FALSE(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_REQUIRE_FALSE(...) DOCTEST_FUNC_EMPTY + +#define DOCTEST_WARN_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_CHECK_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_REQUIRE_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY + +#define DOCTEST_WARN_EQ(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_CHECK_EQ(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_REQUIRE_EQ(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_WARN_NE(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_CHECK_NE(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_REQUIRE_NE(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_WARN_GT(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_CHECK_GT(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_REQUIRE_GT(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_WARN_LT(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_CHECK_LT(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_REQUIRE_LT(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_WARN_GE(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_CHECK_GE(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_REQUIRE_GE(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_WARN_LE(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_CHECK_LE(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_REQUIRE_LE(...) DOCTEST_FUNC_EMPTY + +#define DOCTEST_WARN_UNARY(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_CHECK_UNARY(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_REQUIRE_UNARY(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_WARN_UNARY_FALSE(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_CHECK_UNARY_FALSE(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_REQUIRE_UNARY_FALSE(...) DOCTEST_FUNC_EMPTY + +#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS + +#define DOCTEST_WARN_THROWS(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_CHECK_THROWS(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_REQUIRE_THROWS(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_WARN_THROWS_WITH(expr, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_CHECK_THROWS_WITH(expr, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_WARN_NOTHROW(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_CHECK_NOTHROW(...) DOCTEST_FUNC_EMPTY +#define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_FUNC_EMPTY + +#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY +#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY + +#endif // DOCTEST_CONFIG_NO_EXCEPTIONS + +#endif // DOCTEST_CONFIG_EVALUATE_ASSERTS_EVEN_WHEN_DISABLED + +#endif // DOCTEST_CONFIG_DISABLE + +#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS + +#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS +#define DOCTEST_EXCEPTION_EMPTY_FUNC DOCTEST_FUNC_EMPTY +#else // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS +#define DOCTEST_EXCEPTION_EMPTY_FUNC [] { static_assert(false, "Exceptions are disabled! " \ + "Use DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS if you want to compile with exceptions disabled."); return false; }() + +#undef DOCTEST_REQUIRE +#undef DOCTEST_REQUIRE_FALSE +#undef DOCTEST_REQUIRE_MESSAGE +#undef DOCTEST_REQUIRE_FALSE_MESSAGE +#undef DOCTEST_REQUIRE_EQ +#undef DOCTEST_REQUIRE_NE +#undef DOCTEST_REQUIRE_GT +#undef DOCTEST_REQUIRE_LT +#undef DOCTEST_REQUIRE_GE +#undef DOCTEST_REQUIRE_LE +#undef DOCTEST_REQUIRE_UNARY +#undef DOCTEST_REQUIRE_UNARY_FALSE + +#define DOCTEST_REQUIRE DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_REQUIRE_FALSE DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_REQUIRE_MESSAGE DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_REQUIRE_FALSE_MESSAGE DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_REQUIRE_EQ DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_REQUIRE_NE DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_REQUIRE_GT DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_REQUIRE_LT DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_REQUIRE_GE DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_REQUIRE_LE DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_REQUIRE_UNARY DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_REQUIRE_UNARY_FALSE DOCTEST_EXCEPTION_EMPTY_FUNC + +#endif // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS + +#define DOCTEST_WARN_THROWS(...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_CHECK_THROWS(...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_REQUIRE_THROWS(...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_WARN_THROWS_WITH(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_CHECK_THROWS_WITH(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_WARN_NOTHROW(...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_CHECK_NOTHROW(...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_EXCEPTION_EMPTY_FUNC + +#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC +#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC + +#endif // DOCTEST_CONFIG_NO_EXCEPTIONS + +// clang-format off +// KEPT FOR BACKWARDS COMPATIBILITY - FORWARDING TO THE RIGHT MACROS +#define DOCTEST_FAST_WARN_EQ DOCTEST_WARN_EQ +#define DOCTEST_FAST_CHECK_EQ DOCTEST_CHECK_EQ +#define DOCTEST_FAST_REQUIRE_EQ DOCTEST_REQUIRE_EQ +#define DOCTEST_FAST_WARN_NE DOCTEST_WARN_NE +#define DOCTEST_FAST_CHECK_NE DOCTEST_CHECK_NE +#define DOCTEST_FAST_REQUIRE_NE DOCTEST_REQUIRE_NE +#define DOCTEST_FAST_WARN_GT DOCTEST_WARN_GT +#define DOCTEST_FAST_CHECK_GT DOCTEST_CHECK_GT +#define DOCTEST_FAST_REQUIRE_GT DOCTEST_REQUIRE_GT +#define DOCTEST_FAST_WARN_LT DOCTEST_WARN_LT +#define DOCTEST_FAST_CHECK_LT DOCTEST_CHECK_LT +#define DOCTEST_FAST_REQUIRE_LT DOCTEST_REQUIRE_LT +#define DOCTEST_FAST_WARN_GE DOCTEST_WARN_GE +#define DOCTEST_FAST_CHECK_GE DOCTEST_CHECK_GE +#define DOCTEST_FAST_REQUIRE_GE DOCTEST_REQUIRE_GE +#define DOCTEST_FAST_WARN_LE DOCTEST_WARN_LE +#define DOCTEST_FAST_CHECK_LE DOCTEST_CHECK_LE +#define DOCTEST_FAST_REQUIRE_LE DOCTEST_REQUIRE_LE + +#define DOCTEST_FAST_WARN_UNARY DOCTEST_WARN_UNARY +#define DOCTEST_FAST_CHECK_UNARY DOCTEST_CHECK_UNARY +#define DOCTEST_FAST_REQUIRE_UNARY DOCTEST_REQUIRE_UNARY +#define DOCTEST_FAST_WARN_UNARY_FALSE DOCTEST_WARN_UNARY_FALSE +#define DOCTEST_FAST_CHECK_UNARY_FALSE DOCTEST_CHECK_UNARY_FALSE +#define DOCTEST_FAST_REQUIRE_UNARY_FALSE DOCTEST_REQUIRE_UNARY_FALSE + +#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id,__VA_ARGS__) +// clang-format on + +// BDD style macros +// clang-format off +#define DOCTEST_SCENARIO(name) DOCTEST_TEST_CASE(" Scenario: " name) +#define DOCTEST_SCENARIO_CLASS(name) DOCTEST_TEST_CASE_CLASS(" Scenario: " name) +#define DOCTEST_SCENARIO_TEMPLATE(name, T, ...) DOCTEST_TEST_CASE_TEMPLATE(" Scenario: " name, T, __VA_ARGS__) +#define DOCTEST_SCENARIO_TEMPLATE_DEFINE(name, T, id) DOCTEST_TEST_CASE_TEMPLATE_DEFINE(" Scenario: " name, T, id) + +#define DOCTEST_GIVEN(name) DOCTEST_SUBCASE(" Given: " name) +#define DOCTEST_WHEN(name) DOCTEST_SUBCASE(" When: " name) +#define DOCTEST_AND_WHEN(name) DOCTEST_SUBCASE("And when: " name) +#define DOCTEST_THEN(name) DOCTEST_SUBCASE(" Then: " name) +#define DOCTEST_AND_THEN(name) DOCTEST_SUBCASE(" And: " name) +// clang-format on + +// == SHORT VERSIONS OF THE MACROS +#ifndef DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES + +#define TEST_CASE(name) DOCTEST_TEST_CASE(name) +#define TEST_CASE_CLASS(name) DOCTEST_TEST_CASE_CLASS(name) +#define TEST_CASE_FIXTURE(x, name) DOCTEST_TEST_CASE_FIXTURE(x, name) +#define TYPE_TO_STRING_AS(str, ...) DOCTEST_TYPE_TO_STRING_AS(str, __VA_ARGS__) +#define TYPE_TO_STRING(...) DOCTEST_TYPE_TO_STRING(__VA_ARGS__) +#define TEST_CASE_TEMPLATE(name, T, ...) DOCTEST_TEST_CASE_TEMPLATE(name, T, __VA_ARGS__) +#define TEST_CASE_TEMPLATE_DEFINE(name, T, id) DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, T, id) +#define TEST_CASE_TEMPLATE_INVOKE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, __VA_ARGS__) +#define TEST_CASE_TEMPLATE_APPLY(id, ...) DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, __VA_ARGS__) +#define SUBCASE(name) DOCTEST_SUBCASE(name) +#define TEST_SUITE(decorators) DOCTEST_TEST_SUITE(decorators) +#define TEST_SUITE_BEGIN(name) DOCTEST_TEST_SUITE_BEGIN(name) +#define TEST_SUITE_END DOCTEST_TEST_SUITE_END +#define REGISTER_EXCEPTION_TRANSLATOR(signature) DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature) +#define REGISTER_REPORTER(name, priority, reporter) DOCTEST_REGISTER_REPORTER(name, priority, reporter) +#define REGISTER_LISTENER(name, priority, reporter) DOCTEST_REGISTER_LISTENER(name, priority, reporter) +#define INFO(...) DOCTEST_INFO(__VA_ARGS__) +#define CAPTURE(x) DOCTEST_CAPTURE(x) +#define ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_MESSAGE_AT(file, line, __VA_ARGS__) +#define ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_FAIL_CHECK_AT(file, line, __VA_ARGS__) +#define ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_FAIL_AT(file, line, __VA_ARGS__) +#define MESSAGE(...) DOCTEST_MESSAGE(__VA_ARGS__) +#define FAIL_CHECK(...) DOCTEST_FAIL_CHECK(__VA_ARGS__) +#define FAIL(...) DOCTEST_FAIL(__VA_ARGS__) +#define TO_LVALUE(...) DOCTEST_TO_LVALUE(__VA_ARGS__) + +#define WARN(...) DOCTEST_WARN(__VA_ARGS__) +#define WARN_FALSE(...) DOCTEST_WARN_FALSE(__VA_ARGS__) +#define WARN_THROWS(...) DOCTEST_WARN_THROWS(__VA_ARGS__) +#define WARN_THROWS_AS(expr, ...) DOCTEST_WARN_THROWS_AS(expr, __VA_ARGS__) +#define WARN_THROWS_WITH(expr, ...) DOCTEST_WARN_THROWS_WITH(expr, __VA_ARGS__) +#define WARN_THROWS_WITH_AS(expr, with, ...) DOCTEST_WARN_THROWS_WITH_AS(expr, with, __VA_ARGS__) +#define WARN_NOTHROW(...) DOCTEST_WARN_NOTHROW(__VA_ARGS__) +#define CHECK(...) DOCTEST_CHECK(__VA_ARGS__) +#define CHECK_FALSE(...) DOCTEST_CHECK_FALSE(__VA_ARGS__) +#define CHECK_THROWS(...) DOCTEST_CHECK_THROWS(__VA_ARGS__) +#define CHECK_THROWS_AS(expr, ...) DOCTEST_CHECK_THROWS_AS(expr, __VA_ARGS__) +#define CHECK_THROWS_WITH(expr, ...) DOCTEST_CHECK_THROWS_WITH(expr, __VA_ARGS__) +#define CHECK_THROWS_WITH_AS(expr, with, ...) DOCTEST_CHECK_THROWS_WITH_AS(expr, with, __VA_ARGS__) +#define CHECK_NOTHROW(...) DOCTEST_CHECK_NOTHROW(__VA_ARGS__) +#define REQUIRE(...) DOCTEST_REQUIRE(__VA_ARGS__) +#define REQUIRE_FALSE(...) DOCTEST_REQUIRE_FALSE(__VA_ARGS__) +#define REQUIRE_THROWS(...) DOCTEST_REQUIRE_THROWS(__VA_ARGS__) +#define REQUIRE_THROWS_AS(expr, ...) DOCTEST_REQUIRE_THROWS_AS(expr, __VA_ARGS__) +#define REQUIRE_THROWS_WITH(expr, ...) DOCTEST_REQUIRE_THROWS_WITH(expr, __VA_ARGS__) +#define REQUIRE_THROWS_WITH_AS(expr, with, ...) DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, __VA_ARGS__) +#define REQUIRE_NOTHROW(...) DOCTEST_REQUIRE_NOTHROW(__VA_ARGS__) + +#define WARN_MESSAGE(cond, ...) DOCTEST_WARN_MESSAGE(cond, __VA_ARGS__) +#define WARN_FALSE_MESSAGE(cond, ...) DOCTEST_WARN_FALSE_MESSAGE(cond, __VA_ARGS__) +#define WARN_THROWS_MESSAGE(expr, ...) DOCTEST_WARN_THROWS_MESSAGE(expr, __VA_ARGS__) +#define WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__) +#define WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__) +#define WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__) +#define WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_WARN_NOTHROW_MESSAGE(expr, __VA_ARGS__) +#define CHECK_MESSAGE(cond, ...) DOCTEST_CHECK_MESSAGE(cond, __VA_ARGS__) +#define CHECK_FALSE_MESSAGE(cond, ...) DOCTEST_CHECK_FALSE_MESSAGE(cond, __VA_ARGS__) +#define CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_CHECK_THROWS_MESSAGE(expr, __VA_ARGS__) +#define CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__) +#define CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__) +#define CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__) +#define CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_CHECK_NOTHROW_MESSAGE(expr, __VA_ARGS__) +#define REQUIRE_MESSAGE(cond, ...) DOCTEST_REQUIRE_MESSAGE(cond, __VA_ARGS__) +#define REQUIRE_FALSE_MESSAGE(cond, ...) DOCTEST_REQUIRE_FALSE_MESSAGE(cond, __VA_ARGS__) +#define REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_REQUIRE_THROWS_MESSAGE(expr, __VA_ARGS__) +#define REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__) +#define REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__) +#define REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__) +#define REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, __VA_ARGS__) + +#define SCENARIO(name) DOCTEST_SCENARIO(name) +#define SCENARIO_CLASS(name) DOCTEST_SCENARIO_CLASS(name) +#define SCENARIO_TEMPLATE(name, T, ...) DOCTEST_SCENARIO_TEMPLATE(name, T, __VA_ARGS__) +#define SCENARIO_TEMPLATE_DEFINE(name, T, id) DOCTEST_SCENARIO_TEMPLATE_DEFINE(name, T, id) +#define GIVEN(name) DOCTEST_GIVEN(name) +#define WHEN(name) DOCTEST_WHEN(name) +#define AND_WHEN(name) DOCTEST_AND_WHEN(name) +#define THEN(name) DOCTEST_THEN(name) +#define AND_THEN(name) DOCTEST_AND_THEN(name) + +#define WARN_EQ(...) DOCTEST_WARN_EQ(__VA_ARGS__) +#define CHECK_EQ(...) DOCTEST_CHECK_EQ(__VA_ARGS__) +#define REQUIRE_EQ(...) DOCTEST_REQUIRE_EQ(__VA_ARGS__) +#define WARN_NE(...) DOCTEST_WARN_NE(__VA_ARGS__) +#define CHECK_NE(...) DOCTEST_CHECK_NE(__VA_ARGS__) +#define REQUIRE_NE(...) DOCTEST_REQUIRE_NE(__VA_ARGS__) +#define WARN_GT(...) DOCTEST_WARN_GT(__VA_ARGS__) +#define CHECK_GT(...) DOCTEST_CHECK_GT(__VA_ARGS__) +#define REQUIRE_GT(...) DOCTEST_REQUIRE_GT(__VA_ARGS__) +#define WARN_LT(...) DOCTEST_WARN_LT(__VA_ARGS__) +#define CHECK_LT(...) DOCTEST_CHECK_LT(__VA_ARGS__) +#define REQUIRE_LT(...) DOCTEST_REQUIRE_LT(__VA_ARGS__) +#define WARN_GE(...) DOCTEST_WARN_GE(__VA_ARGS__) +#define CHECK_GE(...) DOCTEST_CHECK_GE(__VA_ARGS__) +#define REQUIRE_GE(...) DOCTEST_REQUIRE_GE(__VA_ARGS__) +#define WARN_LE(...) DOCTEST_WARN_LE(__VA_ARGS__) +#define CHECK_LE(...) DOCTEST_CHECK_LE(__VA_ARGS__) +#define REQUIRE_LE(...) DOCTEST_REQUIRE_LE(__VA_ARGS__) +#define WARN_UNARY(...) DOCTEST_WARN_UNARY(__VA_ARGS__) +#define CHECK_UNARY(...) DOCTEST_CHECK_UNARY(__VA_ARGS__) +#define REQUIRE_UNARY(...) DOCTEST_REQUIRE_UNARY(__VA_ARGS__) +#define WARN_UNARY_FALSE(...) DOCTEST_WARN_UNARY_FALSE(__VA_ARGS__) +#define CHECK_UNARY_FALSE(...) DOCTEST_CHECK_UNARY_FALSE(__VA_ARGS__) +#define REQUIRE_UNARY_FALSE(...) DOCTEST_REQUIRE_UNARY_FALSE(__VA_ARGS__) + +// KEPT FOR BACKWARDS COMPATIBILITY +#define FAST_WARN_EQ(...) DOCTEST_FAST_WARN_EQ(__VA_ARGS__) +#define FAST_CHECK_EQ(...) DOCTEST_FAST_CHECK_EQ(__VA_ARGS__) +#define FAST_REQUIRE_EQ(...) DOCTEST_FAST_REQUIRE_EQ(__VA_ARGS__) +#define FAST_WARN_NE(...) DOCTEST_FAST_WARN_NE(__VA_ARGS__) +#define FAST_CHECK_NE(...) DOCTEST_FAST_CHECK_NE(__VA_ARGS__) +#define FAST_REQUIRE_NE(...) DOCTEST_FAST_REQUIRE_NE(__VA_ARGS__) +#define FAST_WARN_GT(...) DOCTEST_FAST_WARN_GT(__VA_ARGS__) +#define FAST_CHECK_GT(...) DOCTEST_FAST_CHECK_GT(__VA_ARGS__) +#define FAST_REQUIRE_GT(...) DOCTEST_FAST_REQUIRE_GT(__VA_ARGS__) +#define FAST_WARN_LT(...) DOCTEST_FAST_WARN_LT(__VA_ARGS__) +#define FAST_CHECK_LT(...) DOCTEST_FAST_CHECK_LT(__VA_ARGS__) +#define FAST_REQUIRE_LT(...) DOCTEST_FAST_REQUIRE_LT(__VA_ARGS__) +#define FAST_WARN_GE(...) DOCTEST_FAST_WARN_GE(__VA_ARGS__) +#define FAST_CHECK_GE(...) DOCTEST_FAST_CHECK_GE(__VA_ARGS__) +#define FAST_REQUIRE_GE(...) DOCTEST_FAST_REQUIRE_GE(__VA_ARGS__) +#define FAST_WARN_LE(...) DOCTEST_FAST_WARN_LE(__VA_ARGS__) +#define FAST_CHECK_LE(...) DOCTEST_FAST_CHECK_LE(__VA_ARGS__) +#define FAST_REQUIRE_LE(...) DOCTEST_FAST_REQUIRE_LE(__VA_ARGS__) + +#define FAST_WARN_UNARY(...) DOCTEST_FAST_WARN_UNARY(__VA_ARGS__) +#define FAST_CHECK_UNARY(...) DOCTEST_FAST_CHECK_UNARY(__VA_ARGS__) +#define FAST_REQUIRE_UNARY(...) DOCTEST_FAST_REQUIRE_UNARY(__VA_ARGS__) +#define FAST_WARN_UNARY_FALSE(...) DOCTEST_FAST_WARN_UNARY_FALSE(__VA_ARGS__) +#define FAST_CHECK_UNARY_FALSE(...) DOCTEST_FAST_CHECK_UNARY_FALSE(__VA_ARGS__) +#define FAST_REQUIRE_UNARY_FALSE(...) DOCTEST_FAST_REQUIRE_UNARY_FALSE(__VA_ARGS__) + +#define TEST_CASE_TEMPLATE_INSTANTIATE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, __VA_ARGS__) + +#endif // DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES + +#ifndef DOCTEST_CONFIG_DISABLE + +// this is here to clear the 'current test suite' for the current translation unit - at the top +DOCTEST_TEST_SUITE_END(); + +#endif // DOCTEST_CONFIG_DISABLE + +DOCTEST_CLANG_SUPPRESS_WARNING_POP +DOCTEST_MSVC_SUPPRESS_WARNING_POP +DOCTEST_GCC_SUPPRESS_WARNING_POP + +DOCTEST_SUPPRESS_COMMON_WARNINGS_POP + +#endif // DOCTEST_LIBRARY_INCLUDED + +#ifndef DOCTEST_SINGLE_HEADER +#define DOCTEST_SINGLE_HEADER +#endif // DOCTEST_SINGLE_HEADER + +#if defined(DOCTEST_CONFIG_IMPLEMENT) || !defined(DOCTEST_SINGLE_HEADER) + +#ifndef DOCTEST_SINGLE_HEADER +#include "doctest_fwd.h" +#endif // DOCTEST_SINGLE_HEADER + +DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wunused-macros") + +#ifndef DOCTEST_LIBRARY_IMPLEMENTATION +#define DOCTEST_LIBRARY_IMPLEMENTATION + +DOCTEST_CLANG_SUPPRESS_WARNING_POP + +DOCTEST_SUPPRESS_COMMON_WARNINGS_PUSH + +DOCTEST_CLANG_SUPPRESS_WARNING_PUSH +DOCTEST_CLANG_SUPPRESS_WARNING("-Wglobal-constructors") +DOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors") +DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-conversion") +DOCTEST_CLANG_SUPPRESS_WARNING("-Wshorten-64-to-32") +DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-variable-declarations") +DOCTEST_CLANG_SUPPRESS_WARNING("-Wswitch") +DOCTEST_CLANG_SUPPRESS_WARNING("-Wswitch-enum") +DOCTEST_CLANG_SUPPRESS_WARNING("-Wcovered-switch-default") +DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-noreturn") +DOCTEST_CLANG_SUPPRESS_WARNING("-Wdisabled-macro-expansion") +DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-braces") +DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-field-initializers") +DOCTEST_CLANG_SUPPRESS_WARNING("-Wunused-member-function") +DOCTEST_CLANG_SUPPRESS_WARNING("-Wnonportable-system-include-path") + +DOCTEST_GCC_SUPPRESS_WARNING_PUSH +DOCTEST_GCC_SUPPRESS_WARNING("-Wconversion") +DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-conversion") +DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-field-initializers") +DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-braces") +DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch") +DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch-enum") +DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch-default") +DOCTEST_GCC_SUPPRESS_WARNING("-Wunsafe-loop-optimizations") +DOCTEST_GCC_SUPPRESS_WARNING("-Wold-style-cast") +DOCTEST_GCC_SUPPRESS_WARNING("-Wunused-function") +DOCTEST_GCC_SUPPRESS_WARNING("-Wmultiple-inheritance") +DOCTEST_GCC_SUPPRESS_WARNING("-Wsuggest-attribute") + +DOCTEST_MSVC_SUPPRESS_WARNING_PUSH +DOCTEST_MSVC_SUPPRESS_WARNING(4267) // 'var' : conversion from 'x' to 'y', possible loss of data +DOCTEST_MSVC_SUPPRESS_WARNING(4530) // C++ exception handler used, but unwind semantics not enabled +DOCTEST_MSVC_SUPPRESS_WARNING(4577) // 'noexcept' used with no exception handling mode specified +DOCTEST_MSVC_SUPPRESS_WARNING(4774) // format string expected in argument is not a string literal +DOCTEST_MSVC_SUPPRESS_WARNING(4365) // conversion from 'int' to 'unsigned', signed/unsigned mismatch +DOCTEST_MSVC_SUPPRESS_WARNING(5039) // pointer to potentially throwing function passed to extern C +DOCTEST_MSVC_SUPPRESS_WARNING(4800) // forcing value to bool 'true' or 'false' (performance warning) +DOCTEST_MSVC_SUPPRESS_WARNING(5245) // unreferenced function with internal linkage has been removed + +DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN + +// required includes - will go only in one translation unit! +#include +#include +#include +// borland (Embarcadero) compiler requires math.h and not cmath - https://github.com/doctest/doctest/pull/37 +#ifdef __BORLANDC__ +#include +#endif // __BORLANDC__ +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM +#include +#endif // DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM +#include +#include +#include +#ifndef DOCTEST_CONFIG_NO_MULTITHREADING +#include +#include +#define DOCTEST_DECLARE_MUTEX(name) std::mutex name; +#define DOCTEST_DECLARE_STATIC_MUTEX(name) static DOCTEST_DECLARE_MUTEX(name) +#define DOCTEST_LOCK_MUTEX(name) std::lock_guard DOCTEST_ANONYMOUS(DOCTEST_ANON_LOCK_)(name); +#else // DOCTEST_CONFIG_NO_MULTITHREADING +#define DOCTEST_DECLARE_MUTEX(name) +#define DOCTEST_DECLARE_STATIC_MUTEX(name) +#define DOCTEST_LOCK_MUTEX(name) +#endif // DOCTEST_CONFIG_NO_MULTITHREADING +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef DOCTEST_PLATFORM_MAC +#include +#include +#include +#endif // DOCTEST_PLATFORM_MAC + +#ifdef DOCTEST_PLATFORM_WINDOWS + +// defines for a leaner windows.h +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#define DOCTEST_UNDEF_WIN32_LEAN_AND_MEAN +#endif // WIN32_LEAN_AND_MEAN +#ifndef NOMINMAX +#define NOMINMAX +#define DOCTEST_UNDEF_NOMINMAX +#endif // NOMINMAX + +// not sure what AfxWin.h is for - here I do what Catch does +#ifdef __AFXDLL +#include +#else +#include +#endif +#include + +#else // DOCTEST_PLATFORM_WINDOWS + +#include +#include + +#endif // DOCTEST_PLATFORM_WINDOWS + +// this is a fix for https://github.com/doctest/doctest/issues/348 +// https://mail.gnome.org/archives/xml/2012-January/msg00000.html +#if !defined(HAVE_UNISTD_H) && !defined(STDOUT_FILENO) +#define STDOUT_FILENO fileno(stdout) +#endif // HAVE_UNISTD_H + +DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END + +// counts the number of elements in a C array +#define DOCTEST_COUNTOF(x) (sizeof(x) / sizeof(x[0])) + +#ifdef DOCTEST_CONFIG_DISABLE +#define DOCTEST_BRANCH_ON_DISABLED(if_disabled, if_not_disabled) if_disabled +#else // DOCTEST_CONFIG_DISABLE +#define DOCTEST_BRANCH_ON_DISABLED(if_disabled, if_not_disabled) if_not_disabled +#endif // DOCTEST_CONFIG_DISABLE + +#ifndef DOCTEST_CONFIG_OPTIONS_PREFIX +#define DOCTEST_CONFIG_OPTIONS_PREFIX "dt-" +#endif + +#ifndef DOCTEST_THREAD_LOCAL +#if defined(DOCTEST_CONFIG_NO_MULTITHREADING) || DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0)) +#define DOCTEST_THREAD_LOCAL +#else // DOCTEST_MSVC +#define DOCTEST_THREAD_LOCAL thread_local +#endif // DOCTEST_MSVC +#endif // DOCTEST_THREAD_LOCAL + +#ifndef DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES +#define DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES 32 +#endif + +#ifndef DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE +#define DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE 64 +#endif + +#ifdef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS +#define DOCTEST_OPTIONS_PREFIX_DISPLAY DOCTEST_CONFIG_OPTIONS_PREFIX +#else +#define DOCTEST_OPTIONS_PREFIX_DISPLAY "" +#endif + +#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) +#define DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS +#endif + +#ifndef DOCTEST_CDECL +#define DOCTEST_CDECL __cdecl +#endif + +namespace doctest { + +bool is_running_in_test = false; + +namespace { + using namespace detail; + + template + DOCTEST_NORETURN void throw_exception(Ex const& e) { +#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS + throw e; +#else // DOCTEST_CONFIG_NO_EXCEPTIONS +#ifdef DOCTEST_CONFIG_HANDLE_EXCEPTION + DOCTEST_CONFIG_HANDLE_EXCEPTION(e); +#else // DOCTEST_CONFIG_HANDLE_EXCEPTION +#ifndef DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM + std::cerr << "doctest will terminate because it needed to throw an exception.\n" + << "The message was: " << e.what() << '\n'; +#endif // DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM +#endif // DOCTEST_CONFIG_HANDLE_EXCEPTION + std::terminate(); +#endif // DOCTEST_CONFIG_NO_EXCEPTIONS + } + +#ifndef DOCTEST_INTERNAL_ERROR +#define DOCTEST_INTERNAL_ERROR(msg) \ + throw_exception(std::logic_error( \ + __FILE__ ":" DOCTEST_TOSTR(__LINE__) ": Internal doctest error: " msg)) +#endif // DOCTEST_INTERNAL_ERROR + + // case insensitive strcmp + int stricmp(const char* a, const char* b) { + for(;; a++, b++) { + const int d = tolower(*a) - tolower(*b); + if(d != 0 || !*a) + return d; + } + } + + struct Endianness + { + enum Arch + { + Big, + Little + }; + + static Arch which() { + int x = 1; + // casting any data pointer to char* is allowed + auto ptr = reinterpret_cast(&x); + if(*ptr) + return Little; + return Big; + } + }; +} // namespace + +namespace detail { + DOCTEST_THREAD_LOCAL class + { + std::vector stack; + std::stringstream ss; + + public: + std::ostream* push() { + stack.push_back(ss.tellp()); + return &ss; + } + + String pop() { + if (stack.empty()) + DOCTEST_INTERNAL_ERROR("TLSS was empty when trying to pop!"); + + std::streampos pos = stack.back(); + stack.pop_back(); + unsigned sz = static_cast(ss.tellp() - pos); + ss.rdbuf()->pubseekpos(pos, std::ios::in | std::ios::out); + return String(ss, sz); + } + } g_oss; + + std::ostream* tlssPush() { + return g_oss.push(); + } + + String tlssPop() { + return g_oss.pop(); + } + +#ifndef DOCTEST_CONFIG_DISABLE + +namespace timer_large_integer +{ + +#if defined(DOCTEST_PLATFORM_WINDOWS) + using type = ULONGLONG; +#else // DOCTEST_PLATFORM_WINDOWS + using type = std::uint64_t; +#endif // DOCTEST_PLATFORM_WINDOWS +} + +using ticks_t = timer_large_integer::type; + +#ifdef DOCTEST_CONFIG_GETCURRENTTICKS + ticks_t getCurrentTicks() { return DOCTEST_CONFIG_GETCURRENTTICKS(); } +#elif defined(DOCTEST_PLATFORM_WINDOWS) + ticks_t getCurrentTicks() { + static LARGE_INTEGER hz = { {0} }, hzo = { {0} }; + if(!hz.QuadPart) { + QueryPerformanceFrequency(&hz); + QueryPerformanceCounter(&hzo); + } + LARGE_INTEGER t; + QueryPerformanceCounter(&t); + return ((t.QuadPart - hzo.QuadPart) * LONGLONG(1000000)) / hz.QuadPart; + } +#else // DOCTEST_PLATFORM_WINDOWS + ticks_t getCurrentTicks() { + timeval t; + gettimeofday(&t, nullptr); + return static_cast(t.tv_sec) * 1000000 + static_cast(t.tv_usec); + } +#endif // DOCTEST_PLATFORM_WINDOWS + + struct Timer + { + void start() { m_ticks = getCurrentTicks(); } + unsigned int getElapsedMicroseconds() const { + return static_cast(getCurrentTicks() - m_ticks); + } + //unsigned int getElapsedMilliseconds() const { + // return static_cast(getElapsedMicroseconds() / 1000); + //} + double getElapsedSeconds() const { return static_cast(getCurrentTicks() - m_ticks) / 1000000.0; } + + private: + ticks_t m_ticks = 0; + }; + +#ifdef DOCTEST_CONFIG_NO_MULTITHREADING + template + using Atomic = T; +#else // DOCTEST_CONFIG_NO_MULTITHREADING + template + using Atomic = std::atomic; +#endif // DOCTEST_CONFIG_NO_MULTITHREADING + +#if defined(DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS) || defined(DOCTEST_CONFIG_NO_MULTITHREADING) + template + using MultiLaneAtomic = Atomic; +#else // DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS + // Provides a multilane implementation of an atomic variable that supports add, sub, load, + // store. Instead of using a single atomic variable, this splits up into multiple ones, + // each sitting on a separate cache line. The goal is to provide a speedup when most + // operations are modifying. It achieves this with two properties: + // + // * Multiple atomics are used, so chance of congestion from the same atomic is reduced. + // * Each atomic sits on a separate cache line, so false sharing is reduced. + // + // The disadvantage is that there is a small overhead due to the use of TLS, and load/store + // is slower because all atomics have to be accessed. + template + class MultiLaneAtomic + { + struct CacheLineAlignedAtomic + { + Atomic atomic{}; + char padding[DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE - sizeof(Atomic)]; + }; + CacheLineAlignedAtomic m_atomics[DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES]; + + static_assert(sizeof(CacheLineAlignedAtomic) == DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE, + "guarantee one atomic takes exactly one cache line"); + + public: + T operator++() DOCTEST_NOEXCEPT { return fetch_add(1) + 1; } + + T operator++(int) DOCTEST_NOEXCEPT { return fetch_add(1); } + + T fetch_add(T arg, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT { + return myAtomic().fetch_add(arg, order); + } + + T fetch_sub(T arg, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT { + return myAtomic().fetch_sub(arg, order); + } + + operator T() const DOCTEST_NOEXCEPT { return load(); } + + T load(std::memory_order order = std::memory_order_seq_cst) const DOCTEST_NOEXCEPT { + auto result = T(); + for(auto const& c : m_atomics) { + result += c.atomic.load(order); + } + return result; + } + + T operator=(T desired) DOCTEST_NOEXCEPT { // lgtm [cpp/assignment-does-not-return-this] + store(desired); + return desired; + } + + void store(T desired, std::memory_order order = std::memory_order_seq_cst) DOCTEST_NOEXCEPT { + // first value becomes desired", all others become 0. + for(auto& c : m_atomics) { + c.atomic.store(desired, order); + desired = {}; + } + } + + private: + // Each thread has a different atomic that it operates on. If more than NumLanes threads + // use this, some will use the same atomic. So performance will degrade a bit, but still + // everything will work. + // + // The logic here is a bit tricky. The call should be as fast as possible, so that there + // is minimal to no overhead in determining the correct atomic for the current thread. + // + // 1. A global static counter laneCounter counts continuously up. + // 2. Each successive thread will use modulo operation of that counter so it gets an atomic + // assigned in a round-robin fashion. + // 3. This tlsLaneIdx is stored in the thread local data, so it is directly available with + // little overhead. + Atomic& myAtomic() DOCTEST_NOEXCEPT { + static Atomic laneCounter; + DOCTEST_THREAD_LOCAL size_t tlsLaneIdx = + laneCounter++ % DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES; + + return m_atomics[tlsLaneIdx].atomic; + } + }; +#endif // DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS + + // this holds both parameters from the command line and runtime data for tests + struct ContextState : ContextOptions, TestRunStats, CurrentTestCaseStats + { + MultiLaneAtomic numAssertsCurrentTest_atomic; + MultiLaneAtomic numAssertsFailedCurrentTest_atomic; + + std::vector> filters = decltype(filters)(9); // 9 different filters + + std::vector reporters_currently_used; + + assert_handler ah = nullptr; + + Timer timer; + + std::vector stringifiedContexts; // logging from INFO() due to an exception + + // stuff for subcases + bool reachedLeaf; + std::vector subcaseStack; + std::vector nextSubcaseStack; + std::unordered_set fullyTraversedSubcases; + size_t currentSubcaseDepth; + Atomic shouldLogCurrentException; + + void resetRunData() { + numTestCases = 0; + numTestCasesPassingFilters = 0; + numTestSuitesPassingFilters = 0; + numTestCasesFailed = 0; + numAsserts = 0; + numAssertsFailed = 0; + numAssertsCurrentTest = 0; + numAssertsFailedCurrentTest = 0; + } + + void finalizeTestCaseData() { + seconds = timer.getElapsedSeconds(); + + // update the non-atomic counters + numAsserts += numAssertsCurrentTest_atomic; + numAssertsFailed += numAssertsFailedCurrentTest_atomic; + numAssertsCurrentTest = numAssertsCurrentTest_atomic; + numAssertsFailedCurrentTest = numAssertsFailedCurrentTest_atomic; + + if(numAssertsFailedCurrentTest) + failure_flags |= TestCaseFailureReason::AssertFailure; + + if(Approx(currentTest->m_timeout).epsilon(DBL_EPSILON) != 0 && + Approx(seconds).epsilon(DBL_EPSILON) > currentTest->m_timeout) + failure_flags |= TestCaseFailureReason::Timeout; + + if(currentTest->m_should_fail) { + if(failure_flags) { + failure_flags |= TestCaseFailureReason::ShouldHaveFailedAndDid; + } else { + failure_flags |= TestCaseFailureReason::ShouldHaveFailedButDidnt; + } + } else if(failure_flags && currentTest->m_may_fail) { + failure_flags |= TestCaseFailureReason::CouldHaveFailedAndDid; + } else if(currentTest->m_expected_failures > 0) { + if(numAssertsFailedCurrentTest == currentTest->m_expected_failures) { + failure_flags |= TestCaseFailureReason::FailedExactlyNumTimes; + } else { + failure_flags |= TestCaseFailureReason::DidntFailExactlyNumTimes; + } + } + + bool ok_to_fail = (TestCaseFailureReason::ShouldHaveFailedAndDid & failure_flags) || + (TestCaseFailureReason::CouldHaveFailedAndDid & failure_flags) || + (TestCaseFailureReason::FailedExactlyNumTimes & failure_flags); + + // if any subcase has failed - the whole test case has failed + testCaseSuccess = !(failure_flags && !ok_to_fail); + if(!testCaseSuccess) + numTestCasesFailed++; + } + }; + + ContextState* g_cs = nullptr; + + // used to avoid locks for the debug output + // TODO: figure out if this is indeed necessary/correct - seems like either there still + // could be a race or that there wouldn't be a race even if using the context directly + DOCTEST_THREAD_LOCAL bool g_no_colors; + +#endif // DOCTEST_CONFIG_DISABLE +} // namespace detail + +char* String::allocate(size_type sz) { + if (sz <= last) { + buf[sz] = '\0'; + setLast(last - sz); + return buf; + } else { + setOnHeap(); + data.size = sz; + data.capacity = data.size + 1; + data.ptr = new char[data.capacity]; + data.ptr[sz] = '\0'; + return data.ptr; + } +} + +void String::setOnHeap() noexcept { *reinterpret_cast(&buf[last]) = 128; } +void String::setLast(size_type in) noexcept { buf[last] = char(in); } +void String::setSize(size_type sz) noexcept { + if (isOnStack()) { buf[sz] = '\0'; setLast(last - sz); } + else { data.ptr[sz] = '\0'; data.size = sz; } +} + +void String::copy(const String& other) { + if(other.isOnStack()) { + memcpy(buf, other.buf, len); + } else { + memcpy(allocate(other.data.size), other.data.ptr, other.data.size); + } +} + +String::String() noexcept { + buf[0] = '\0'; + setLast(); +} + +String::~String() { + if(!isOnStack()) + delete[] data.ptr; +} // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks) + +String::String(const char* in) + : String(in, strlen(in)) {} + +String::String(const char* in, size_type in_size) { + memcpy(allocate(in_size), in, in_size); +} + +String::String(std::istream& in, size_type in_size) { + in.read(allocate(in_size), in_size); +} + +String::String(const String& other) { copy(other); } + +String& String::operator=(const String& other) { + if(this != &other) { + if(!isOnStack()) + delete[] data.ptr; + + copy(other); + } + + return *this; +} + +String& String::operator+=(const String& other) { + const size_type my_old_size = size(); + const size_type other_size = other.size(); + const size_type total_size = my_old_size + other_size; + if(isOnStack()) { + if(total_size < len) { + // append to the current stack space + memcpy(buf + my_old_size, other.c_str(), other_size + 1); + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) + setLast(last - total_size); + } else { + // alloc new chunk + char* temp = new char[total_size + 1]; + // copy current data to new location before writing in the union + memcpy(temp, buf, my_old_size); // skip the +1 ('\0') for speed + // update data in union + setOnHeap(); + data.size = total_size; + data.capacity = data.size + 1; + data.ptr = temp; + // transfer the rest of the data + memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1); + } + } else { + if(data.capacity > total_size) { + // append to the current heap block + data.size = total_size; + memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1); + } else { + // resize + data.capacity *= 2; + if(data.capacity <= total_size) + data.capacity = total_size + 1; + // alloc new chunk + char* temp = new char[data.capacity]; + // copy current data to new location before releasing it + memcpy(temp, data.ptr, my_old_size); // skip the +1 ('\0') for speed + // release old chunk + delete[] data.ptr; + // update the rest of the union members + data.size = total_size; + data.ptr = temp; + // transfer the rest of the data + memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1); + } + } + + return *this; +} + +String::String(String&& other) noexcept { + memcpy(buf, other.buf, len); + other.buf[0] = '\0'; + other.setLast(); +} + +String& String::operator=(String&& other) noexcept { + if(this != &other) { + if(!isOnStack()) + delete[] data.ptr; + memcpy(buf, other.buf, len); + other.buf[0] = '\0'; + other.setLast(); + } + return *this; +} + +char String::operator[](size_type i) const { + return const_cast(this)->operator[](i); +} + +char& String::operator[](size_type i) { + if(isOnStack()) + return reinterpret_cast(buf)[i]; + return data.ptr[i]; +} + +DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wmaybe-uninitialized") +String::size_type String::size() const { + if(isOnStack()) + return last - (size_type(buf[last]) & 31); // using "last" would work only if "len" is 32 + return data.size; +} +DOCTEST_GCC_SUPPRESS_WARNING_POP + +String::size_type String::capacity() const { + if(isOnStack()) + return len; + return data.capacity; +} + +String String::substr(size_type pos, size_type cnt) && { + cnt = std::min(cnt, size() - 1 - pos); + char* cptr = c_str(); + memmove(cptr, cptr + pos, cnt); + setSize(cnt); + return std::move(*this); +} + +String String::substr(size_type pos, size_type cnt) const & { + cnt = std::min(cnt, size() - 1 - pos); + return String{ c_str() + pos, cnt }; +} + +String::size_type String::find(char ch, size_type pos) const { + const char* begin = c_str(); + const char* end = begin + size(); + const char* it = begin + pos; + for (; it < end && *it != ch; it++); + if (it < end) { return static_cast(it - begin); } + else { return npos; } +} + +String::size_type String::rfind(char ch, size_type pos) const { + const char* begin = c_str(); + const char* it = begin + std::min(pos, size() - 1); + for (; it >= begin && *it != ch; it--); + if (it >= begin) { return static_cast(it - begin); } + else { return npos; } +} + +int String::compare(const char* other, bool no_case) const { + if(no_case) + return doctest::stricmp(c_str(), other); + return std::strcmp(c_str(), other); +} + +int String::compare(const String& other, bool no_case) const { + return compare(other.c_str(), no_case); +} + +String operator+(const String& lhs, const String& rhs) { return String(lhs) += rhs; } + +bool operator==(const String& lhs, const String& rhs) { return lhs.compare(rhs) == 0; } +bool operator!=(const String& lhs, const String& rhs) { return lhs.compare(rhs) != 0; } +bool operator< (const String& lhs, const String& rhs) { return lhs.compare(rhs) < 0; } +bool operator> (const String& lhs, const String& rhs) { return lhs.compare(rhs) > 0; } +bool operator<=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) < 0 : true; } +bool operator>=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) > 0 : true; } + +std::ostream& operator<<(std::ostream& s, const String& in) { return s << in.c_str(); } + +Contains::Contains(const String& str) : string(str) { } + +bool Contains::checkWith(const String& other) const { + return strstr(other.c_str(), string.c_str()) != nullptr; +} + +String toString(const Contains& in) { + return "Contains( " + in.string + " )"; +} + +bool operator==(const String& lhs, const Contains& rhs) { return rhs.checkWith(lhs); } +bool operator==(const Contains& lhs, const String& rhs) { return lhs.checkWith(rhs); } +bool operator!=(const String& lhs, const Contains& rhs) { return !rhs.checkWith(lhs); } +bool operator!=(const Contains& lhs, const String& rhs) { return !lhs.checkWith(rhs); } + +namespace { + void color_to_stream(std::ostream&, Color::Enum) DOCTEST_BRANCH_ON_DISABLED({}, ;) +} // namespace + +namespace Color { + std::ostream& operator<<(std::ostream& s, Color::Enum code) { + color_to_stream(s, code); + return s; + } +} // namespace Color + +// clang-format off +const char* assertString(assertType::Enum at) { + DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4061) // enum 'x' in switch of enum 'y' is not explicitly handled + #define DOCTEST_GENERATE_ASSERT_TYPE_CASE(assert_type) case assertType::DT_ ## assert_type: return #assert_type + #define DOCTEST_GENERATE_ASSERT_TYPE_CASES(assert_type) \ + DOCTEST_GENERATE_ASSERT_TYPE_CASE(WARN_ ## assert_type); \ + DOCTEST_GENERATE_ASSERT_TYPE_CASE(CHECK_ ## assert_type); \ + DOCTEST_GENERATE_ASSERT_TYPE_CASE(REQUIRE_ ## assert_type) + switch(at) { + DOCTEST_GENERATE_ASSERT_TYPE_CASE(WARN); + DOCTEST_GENERATE_ASSERT_TYPE_CASE(CHECK); + DOCTEST_GENERATE_ASSERT_TYPE_CASE(REQUIRE); + + DOCTEST_GENERATE_ASSERT_TYPE_CASES(FALSE); + + DOCTEST_GENERATE_ASSERT_TYPE_CASES(THROWS); + + DOCTEST_GENERATE_ASSERT_TYPE_CASES(THROWS_AS); + + DOCTEST_GENERATE_ASSERT_TYPE_CASES(THROWS_WITH); + + DOCTEST_GENERATE_ASSERT_TYPE_CASES(THROWS_WITH_AS); + + DOCTEST_GENERATE_ASSERT_TYPE_CASES(NOTHROW); + + DOCTEST_GENERATE_ASSERT_TYPE_CASES(EQ); + DOCTEST_GENERATE_ASSERT_TYPE_CASES(NE); + DOCTEST_GENERATE_ASSERT_TYPE_CASES(GT); + DOCTEST_GENERATE_ASSERT_TYPE_CASES(LT); + DOCTEST_GENERATE_ASSERT_TYPE_CASES(GE); + DOCTEST_GENERATE_ASSERT_TYPE_CASES(LE); + + DOCTEST_GENERATE_ASSERT_TYPE_CASES(UNARY); + DOCTEST_GENERATE_ASSERT_TYPE_CASES(UNARY_FALSE); + + default: DOCTEST_INTERNAL_ERROR("Tried stringifying invalid assert type!"); + } + DOCTEST_MSVC_SUPPRESS_WARNING_POP +} +// clang-format on + +const char* failureString(assertType::Enum at) { + if(at & assertType::is_warn) //!OCLINT bitwise operator in conditional + return "WARNING"; + if(at & assertType::is_check) //!OCLINT bitwise operator in conditional + return "ERROR"; + if(at & assertType::is_require) //!OCLINT bitwise operator in conditional + return "FATAL ERROR"; + return ""; +} + +DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference") +DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference") +// depending on the current options this will remove the path of filenames +const char* skipPathFromFilename(const char* file) { +#ifndef DOCTEST_CONFIG_DISABLE + if(getContextOptions()->no_path_in_filenames) { + auto back = std::strrchr(file, '\\'); + auto forward = std::strrchr(file, '/'); + if(back || forward) { + if(back > forward) + forward = back; + return forward + 1; + } + } +#endif // DOCTEST_CONFIG_DISABLE + return file; +} +DOCTEST_CLANG_SUPPRESS_WARNING_POP +DOCTEST_GCC_SUPPRESS_WARNING_POP + +bool SubcaseSignature::operator==(const SubcaseSignature& other) const { + return m_line == other.m_line + && std::strcmp(m_file, other.m_file) == 0 + && m_name == other.m_name; +} + +bool SubcaseSignature::operator<(const SubcaseSignature& other) const { + if(m_line != other.m_line) + return m_line < other.m_line; + if(std::strcmp(m_file, other.m_file) != 0) + return std::strcmp(m_file, other.m_file) < 0; + return m_name.compare(other.m_name) < 0; +} + +DOCTEST_DEFINE_INTERFACE(IContextScope) + +namespace detail { + void filldata::fill(std::ostream* stream, const void* in) { + if (in) { *stream << in; } + else { *stream << "nullptr"; } + } + + template + String toStreamLit(T t) { + std::ostream* os = tlssPush(); + os->operator<<(t); + return tlssPop(); + } +} + +#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING +String toString(const char* in) { return String("\"") + (in ? in : "{null string}") + "\""; } +#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING + +#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0) +// see this issue on why this is needed: https://github.com/doctest/doctest/issues/183 +String toString(const std::string& in) { return in.c_str(); } +#endif // VS 2019 + +String toString(String in) { return in; } + +String toString(std::nullptr_t) { return "nullptr"; } + +String toString(bool in) { return in ? "true" : "false"; } + +String toString(float in) { return toStreamLit(in); } +String toString(double in) { return toStreamLit(in); } +String toString(double long in) { return toStreamLit(in); } + +String toString(char in) { return toStreamLit(static_cast(in)); } +String toString(char signed in) { return toStreamLit(static_cast(in)); } +String toString(char unsigned in) { return toStreamLit(static_cast(in)); } +String toString(short in) { return toStreamLit(in); } +String toString(short unsigned in) { return toStreamLit(in); } +String toString(signed in) { return toStreamLit(in); } +String toString(unsigned in) { return toStreamLit(in); } +String toString(long in) { return toStreamLit(in); } +String toString(long unsigned in) { return toStreamLit(in); } +String toString(long long in) { return toStreamLit(in); } +String toString(long long unsigned in) { return toStreamLit(in); } + +Approx::Approx(double value) + : m_epsilon(static_cast(std::numeric_limits::epsilon()) * 100) + , m_scale(1.0) + , m_value(value) {} + +Approx Approx::operator()(double value) const { + Approx approx(value); + approx.epsilon(m_epsilon); + approx.scale(m_scale); + return approx; +} + +Approx& Approx::epsilon(double newEpsilon) { + m_epsilon = newEpsilon; + return *this; +} +Approx& Approx::scale(double newScale) { + m_scale = newScale; + return *this; +} + +bool operator==(double lhs, const Approx& rhs) { + // Thanks to Richard Harris for his help refining this formula + return std::fabs(lhs - rhs.m_value) < + rhs.m_epsilon * (rhs.m_scale + std::max(std::fabs(lhs), std::fabs(rhs.m_value))); +} +bool operator==(const Approx& lhs, double rhs) { return operator==(rhs, lhs); } +bool operator!=(double lhs, const Approx& rhs) { return !operator==(lhs, rhs); } +bool operator!=(const Approx& lhs, double rhs) { return !operator==(rhs, lhs); } +bool operator<=(double lhs, const Approx& rhs) { return lhs < rhs.m_value || lhs == rhs; } +bool operator<=(const Approx& lhs, double rhs) { return lhs.m_value < rhs || lhs == rhs; } +bool operator>=(double lhs, const Approx& rhs) { return lhs > rhs.m_value || lhs == rhs; } +bool operator>=(const Approx& lhs, double rhs) { return lhs.m_value > rhs || lhs == rhs; } +bool operator<(double lhs, const Approx& rhs) { return lhs < rhs.m_value && lhs != rhs; } +bool operator<(const Approx& lhs, double rhs) { return lhs.m_value < rhs && lhs != rhs; } +bool operator>(double lhs, const Approx& rhs) { return lhs > rhs.m_value && lhs != rhs; } +bool operator>(const Approx& lhs, double rhs) { return lhs.m_value > rhs && lhs != rhs; } + +String toString(const Approx& in) { + return "Approx( " + doctest::toString(in.m_value) + " )"; +} +const ContextOptions* getContextOptions() { return DOCTEST_BRANCH_ON_DISABLED(nullptr, g_cs); } + +DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4738) +template +IsNaN::operator bool() const { + return std::isnan(value) ^ flipped; +} +DOCTEST_MSVC_SUPPRESS_WARNING_POP +template struct DOCTEST_INTERFACE_DEF IsNaN; +template struct DOCTEST_INTERFACE_DEF IsNaN; +template struct DOCTEST_INTERFACE_DEF IsNaN; +template +String toString(IsNaN in) { return String(in.flipped ? "! " : "") + "IsNaN( " + doctest::toString(in.value) + " )"; } +String toString(IsNaN in) { return toString(in); } +String toString(IsNaN in) { return toString(in); } +String toString(IsNaN in) { return toString(in); } + +} // namespace doctest + +#ifdef DOCTEST_CONFIG_DISABLE +namespace doctest { +Context::Context(int, const char* const*) {} +Context::~Context() = default; +void Context::applyCommandLine(int, const char* const*) {} +void Context::addFilter(const char*, const char*) {} +void Context::clearFilters() {} +void Context::setOption(const char*, bool) {} +void Context::setOption(const char*, int) {} +void Context::setOption(const char*, const char*) {} +bool Context::shouldExit() { return false; } +void Context::setAsDefaultForAssertsOutOfTestCases() {} +void Context::setAssertHandler(detail::assert_handler) {} +void Context::setCout(std::ostream*) {} +int Context::run() { return 0; } + +int IReporter::get_num_active_contexts() { return 0; } +const IContextScope* const* IReporter::get_active_contexts() { return nullptr; } +int IReporter::get_num_stringified_contexts() { return 0; } +const String* IReporter::get_stringified_contexts() { return nullptr; } + +int registerReporter(const char*, int, IReporter*) { return 0; } + +} // namespace doctest +#else // DOCTEST_CONFIG_DISABLE + +#if !defined(DOCTEST_CONFIG_COLORS_NONE) +#if !defined(DOCTEST_CONFIG_COLORS_WINDOWS) && !defined(DOCTEST_CONFIG_COLORS_ANSI) +#ifdef DOCTEST_PLATFORM_WINDOWS +#define DOCTEST_CONFIG_COLORS_WINDOWS +#else // linux +#define DOCTEST_CONFIG_COLORS_ANSI +#endif // platform +#endif // DOCTEST_CONFIG_COLORS_WINDOWS && DOCTEST_CONFIG_COLORS_ANSI +#endif // DOCTEST_CONFIG_COLORS_NONE + +namespace doctest_detail_test_suite_ns { +// holds the current test suite +doctest::detail::TestSuite& getCurrentTestSuite() { + static doctest::detail::TestSuite data{}; + return data; +} +} // namespace doctest_detail_test_suite_ns + +namespace doctest { +namespace { + // the int (priority) is part of the key for automatic sorting - sadly one can register a + // reporter with a duplicate name and a different priority but hopefully that won't happen often :| + using reporterMap = std::map, reporterCreatorFunc>; + + reporterMap& getReporters() { + static reporterMap data; + return data; + } + reporterMap& getListeners() { + static reporterMap data; + return data; + } +} // namespace +namespace detail { +#define DOCTEST_ITERATE_THROUGH_REPORTERS(function, ...) \ + for(auto& curr_rep : g_cs->reporters_currently_used) \ + curr_rep->function(__VA_ARGS__) + + bool checkIfShouldThrow(assertType::Enum at) { + if(at & assertType::is_require) //!OCLINT bitwise operator in conditional + return true; + + if((at & assertType::is_check) //!OCLINT bitwise operator in conditional + && getContextOptions()->abort_after > 0 && + (g_cs->numAssertsFailed + g_cs->numAssertsFailedCurrentTest_atomic) >= + getContextOptions()->abort_after) + return true; + + return false; + } + +#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS + DOCTEST_NORETURN void throwException() { + g_cs->shouldLogCurrentException = false; + throw TestFailureException(); // NOLINT(hicpp-exception-baseclass) + } +#else // DOCTEST_CONFIG_NO_EXCEPTIONS + void throwException() {} +#endif // DOCTEST_CONFIG_NO_EXCEPTIONS +} // namespace detail + +namespace { + using namespace detail; + // matching of a string against a wildcard mask (case sensitivity configurable) taken from + // https://www.codeproject.com/Articles/1088/Wildcard-string-compare-globbing + int wildcmp(const char* str, const char* wild, bool caseSensitive) { + const char* cp = str; + const char* mp = wild; + + while((*str) && (*wild != '*')) { + if((caseSensitive ? (*wild != *str) : (tolower(*wild) != tolower(*str))) && + (*wild != '?')) { + return 0; + } + wild++; + str++; + } + + while(*str) { + if(*wild == '*') { + if(!*++wild) { + return 1; + } + mp = wild; + cp = str + 1; + } else if((caseSensitive ? (*wild == *str) : (tolower(*wild) == tolower(*str))) || + (*wild == '?')) { + wild++; + str++; + } else { + wild = mp; //!OCLINT parameter reassignment + str = cp++; //!OCLINT parameter reassignment + } + } + + while(*wild == '*') { + wild++; + } + return !*wild; + } + + // checks if the name matches any of the filters (and can be configured what to do when empty) + bool matchesAny(const char* name, const std::vector& filters, bool matchEmpty, + bool caseSensitive) { + if (filters.empty() && matchEmpty) + return true; + for (auto& curr : filters) + if (wildcmp(name, curr.c_str(), caseSensitive)) + return true; + return false; + } + + DOCTEST_NO_SANITIZE_INTEGER + unsigned long long hash(unsigned long long a, unsigned long long b) { + return (a << 5) + b; + } + + // C string hash function (djb2) - taken from http://www.cse.yorku.ca/~oz/hash.html + DOCTEST_NO_SANITIZE_INTEGER + unsigned long long hash(const char* str) { + unsigned long long hash = 5381; + char c; + while ((c = *str++)) + hash = ((hash << 5) + hash) + c; // hash * 33 + c + return hash; + } + + unsigned long long hash(const SubcaseSignature& sig) { + return hash(hash(hash(sig.m_file), hash(sig.m_name.c_str())), sig.m_line); + } + + unsigned long long hash(const std::vector& sigs, size_t count) { + unsigned long long running = 0; + auto end = sigs.begin() + count; + for (auto it = sigs.begin(); it != end; it++) { + running = hash(running, hash(*it)); + } + return running; + } + + unsigned long long hash(const std::vector& sigs) { + unsigned long long running = 0; + for (const SubcaseSignature& sig : sigs) { + running = hash(running, hash(sig)); + } + return running; + } +} // namespace +namespace detail { + bool Subcase::checkFilters() { + if (g_cs->subcaseStack.size() < size_t(g_cs->subcase_filter_levels)) { + if (!matchesAny(m_signature.m_name.c_str(), g_cs->filters[6], true, g_cs->case_sensitive)) + return true; + if (matchesAny(m_signature.m_name.c_str(), g_cs->filters[7], false, g_cs->case_sensitive)) + return true; + } + return false; + } + + Subcase::Subcase(const String& name, const char* file, int line) + : m_signature({name, file, line}) { + if (!g_cs->reachedLeaf) { + if (g_cs->nextSubcaseStack.size() <= g_cs->subcaseStack.size() + || g_cs->nextSubcaseStack[g_cs->subcaseStack.size()] == m_signature) { + // Going down. + if (checkFilters()) { return; } + + g_cs->subcaseStack.push_back(m_signature); + g_cs->currentSubcaseDepth++; + m_entered = true; + DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_start, m_signature); + } + } else { + if (g_cs->subcaseStack[g_cs->currentSubcaseDepth] == m_signature) { + // This subcase is reentered via control flow. + g_cs->currentSubcaseDepth++; + m_entered = true; + DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_start, m_signature); + } else if (g_cs->nextSubcaseStack.size() <= g_cs->currentSubcaseDepth + && g_cs->fullyTraversedSubcases.find(hash(hash(g_cs->subcaseStack, g_cs->currentSubcaseDepth), hash(m_signature))) + == g_cs->fullyTraversedSubcases.end()) { + if (checkFilters()) { return; } + // This subcase is part of the one to be executed next. + g_cs->nextSubcaseStack.clear(); + g_cs->nextSubcaseStack.insert(g_cs->nextSubcaseStack.end(), + g_cs->subcaseStack.begin(), g_cs->subcaseStack.begin() + g_cs->currentSubcaseDepth); + g_cs->nextSubcaseStack.push_back(m_signature); + } + } + } + + DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception is deprecated in C++17 + DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") + DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") + + Subcase::~Subcase() { + if (m_entered) { + g_cs->currentSubcaseDepth--; + + if (!g_cs->reachedLeaf) { + // Leaf. + g_cs->fullyTraversedSubcases.insert(hash(g_cs->subcaseStack)); + g_cs->nextSubcaseStack.clear(); + g_cs->reachedLeaf = true; + } else if (g_cs->nextSubcaseStack.empty()) { + // All children are finished. + g_cs->fullyTraversedSubcases.insert(hash(g_cs->subcaseStack)); + } + +#if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) + if(std::uncaught_exceptions() > 0 +#else + if(std::uncaught_exception() +#endif + && g_cs->shouldLogCurrentException) { + DOCTEST_ITERATE_THROUGH_REPORTERS( + test_case_exception, {"exception thrown in subcase - will translate later " + "when the whole test case has been exited (cannot " + "translate while there is an active exception)", + false}); + g_cs->shouldLogCurrentException = false; + } + + DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY); + } + } + + DOCTEST_CLANG_SUPPRESS_WARNING_POP + DOCTEST_GCC_SUPPRESS_WARNING_POP + DOCTEST_MSVC_SUPPRESS_WARNING_POP + + Subcase::operator bool() const { return m_entered; } + + Result::Result(bool passed, const String& decomposition) + : m_passed(passed) + , m_decomp(decomposition) {} + + ExpressionDecomposer::ExpressionDecomposer(assertType::Enum at) + : m_at(at) {} + + TestSuite& TestSuite::operator*(const char* in) { + m_test_suite = in; + return *this; + } + + TestCase::TestCase(funcType test, const char* file, unsigned line, const TestSuite& test_suite, + const String& type, int template_id) { + m_file = file; + m_line = line; + m_name = nullptr; // will be later overridden in operator* + m_test_suite = test_suite.m_test_suite; + m_description = test_suite.m_description; + m_skip = test_suite.m_skip; + m_no_breaks = test_suite.m_no_breaks; + m_no_output = test_suite.m_no_output; + m_may_fail = test_suite.m_may_fail; + m_should_fail = test_suite.m_should_fail; + m_expected_failures = test_suite.m_expected_failures; + m_timeout = test_suite.m_timeout; + + m_test = test; + m_type = type; + m_template_id = template_id; + } + + TestCase::TestCase(const TestCase& other) + : TestCaseData() { + *this = other; + } + + DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(26434) // hides a non-virtual function + TestCase& TestCase::operator=(const TestCase& other) { + TestCaseData::operator=(other); + m_test = other.m_test; + m_type = other.m_type; + m_template_id = other.m_template_id; + m_full_name = other.m_full_name; + + if(m_template_id != -1) + m_name = m_full_name.c_str(); + return *this; + } + DOCTEST_MSVC_SUPPRESS_WARNING_POP + + TestCase& TestCase::operator*(const char* in) { + m_name = in; + // make a new name with an appended type for templated test case + if(m_template_id != -1) { + m_full_name = String(m_name) + "<" + m_type + ">"; + // redirect the name to point to the newly constructed full name + m_name = m_full_name.c_str(); + } + return *this; + } + + bool TestCase::operator<(const TestCase& other) const { + // this will be used only to differentiate between test cases - not relevant for sorting + if(m_line != other.m_line) + return m_line < other.m_line; + const int name_cmp = strcmp(m_name, other.m_name); + if(name_cmp != 0) + return name_cmp < 0; + const int file_cmp = m_file.compare(other.m_file); + if(file_cmp != 0) + return file_cmp < 0; + return m_template_id < other.m_template_id; + } + + // all the registered tests + std::set& getRegisteredTests() { + static std::set data; + return data; + } +} // namespace detail +namespace { + using namespace detail; + // for sorting tests by file/line + bool fileOrderComparator(const TestCase* lhs, const TestCase* rhs) { + // this is needed because MSVC gives different case for drive letters + // for __FILE__ when evaluated in a header and a source file + const int res = lhs->m_file.compare(rhs->m_file, bool(DOCTEST_MSVC)); + if(res != 0) + return res < 0; + if(lhs->m_line != rhs->m_line) + return lhs->m_line < rhs->m_line; + return lhs->m_template_id < rhs->m_template_id; + } + + // for sorting tests by suite/file/line + bool suiteOrderComparator(const TestCase* lhs, const TestCase* rhs) { + const int res = std::strcmp(lhs->m_test_suite, rhs->m_test_suite); + if(res != 0) + return res < 0; + return fileOrderComparator(lhs, rhs); + } + + // for sorting tests by name/suite/file/line + bool nameOrderComparator(const TestCase* lhs, const TestCase* rhs) { + const int res = std::strcmp(lhs->m_name, rhs->m_name); + if(res != 0) + return res < 0; + return suiteOrderComparator(lhs, rhs); + } + + DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") + void color_to_stream(std::ostream& s, Color::Enum code) { + static_cast(s); // for DOCTEST_CONFIG_COLORS_NONE or DOCTEST_CONFIG_COLORS_WINDOWS + static_cast(code); // for DOCTEST_CONFIG_COLORS_NONE +#ifdef DOCTEST_CONFIG_COLORS_ANSI + if(g_no_colors || + (isatty(STDOUT_FILENO) == false && getContextOptions()->force_colors == false)) + return; + + auto col = ""; + // clang-format off + switch(code) { //!OCLINT missing break in switch statement / unnecessary default statement in covered switch statement + case Color::Red: col = "[0;31m"; break; + case Color::Green: col = "[0;32m"; break; + case Color::Blue: col = "[0;34m"; break; + case Color::Cyan: col = "[0;36m"; break; + case Color::Yellow: col = "[0;33m"; break; + case Color::Grey: col = "[1;30m"; break; + case Color::LightGrey: col = "[0;37m"; break; + case Color::BrightRed: col = "[1;31m"; break; + case Color::BrightGreen: col = "[1;32m"; break; + case Color::BrightWhite: col = "[1;37m"; break; + case Color::Bright: // invalid + case Color::None: + case Color::White: + default: col = "[0m"; + } + // clang-format on + s << "\033" << col; +#endif // DOCTEST_CONFIG_COLORS_ANSI + +#ifdef DOCTEST_CONFIG_COLORS_WINDOWS + if(g_no_colors || + (_isatty(_fileno(stdout)) == false && getContextOptions()->force_colors == false)) + return; + + static struct ConsoleHelper { + HANDLE stdoutHandle; + WORD origFgAttrs; + WORD origBgAttrs; + + ConsoleHelper() { + stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE); + CONSOLE_SCREEN_BUFFER_INFO csbiInfo; + GetConsoleScreenBufferInfo(stdoutHandle, &csbiInfo); + origFgAttrs = csbiInfo.wAttributes & ~(BACKGROUND_GREEN | BACKGROUND_RED | + BACKGROUND_BLUE | BACKGROUND_INTENSITY); + origBgAttrs = csbiInfo.wAttributes & ~(FOREGROUND_GREEN | FOREGROUND_RED | + FOREGROUND_BLUE | FOREGROUND_INTENSITY); + } + } ch; + +#define DOCTEST_SET_ATTR(x) SetConsoleTextAttribute(ch.stdoutHandle, x | ch.origBgAttrs) + + // clang-format off + switch (code) { + case Color::White: DOCTEST_SET_ATTR(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break; + case Color::Red: DOCTEST_SET_ATTR(FOREGROUND_RED); break; + case Color::Green: DOCTEST_SET_ATTR(FOREGROUND_GREEN); break; + case Color::Blue: DOCTEST_SET_ATTR(FOREGROUND_BLUE); break; + case Color::Cyan: DOCTEST_SET_ATTR(FOREGROUND_BLUE | FOREGROUND_GREEN); break; + case Color::Yellow: DOCTEST_SET_ATTR(FOREGROUND_RED | FOREGROUND_GREEN); break; + case Color::Grey: DOCTEST_SET_ATTR(0); break; + case Color::LightGrey: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY); break; + case Color::BrightRed: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_RED); break; + case Color::BrightGreen: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN); break; + case Color::BrightWhite: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break; + case Color::None: + case Color::Bright: // invalid + default: DOCTEST_SET_ATTR(ch.origFgAttrs); + } + // clang-format on +#endif // DOCTEST_CONFIG_COLORS_WINDOWS + } + DOCTEST_CLANG_SUPPRESS_WARNING_POP + + std::vector& getExceptionTranslators() { + static std::vector data; + return data; + } + + String translateActiveException() { +#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS + String res; + auto& translators = getExceptionTranslators(); + for(auto& curr : translators) + if(curr->translate(res)) + return res; + // clang-format off + DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wcatch-value") + try { + throw; + } catch(std::exception& ex) { + return ex.what(); + } catch(std::string& msg) { + return msg.c_str(); + } catch(const char* msg) { + return msg; + } catch(...) { + return "unknown exception"; + } + DOCTEST_GCC_SUPPRESS_WARNING_POP +// clang-format on +#else // DOCTEST_CONFIG_NO_EXCEPTIONS + return ""; +#endif // DOCTEST_CONFIG_NO_EXCEPTIONS + } +} // namespace + +namespace detail { + // used by the macros for registering tests + int regTest(const TestCase& tc) { + getRegisteredTests().insert(tc); + return 0; + } + + // sets the current test suite + int setTestSuite(const TestSuite& ts) { + doctest_detail_test_suite_ns::getCurrentTestSuite() = ts; + return 0; + } + +#ifdef DOCTEST_IS_DEBUGGER_ACTIVE + bool isDebuggerActive() { return DOCTEST_IS_DEBUGGER_ACTIVE(); } +#else // DOCTEST_IS_DEBUGGER_ACTIVE +#ifdef DOCTEST_PLATFORM_LINUX + class ErrnoGuard { + public: + ErrnoGuard() : m_oldErrno(errno) {} + ~ErrnoGuard() { errno = m_oldErrno; } + private: + int m_oldErrno; + }; + // See the comments in Catch2 for the reasoning behind this implementation: + // https://github.com/catchorg/Catch2/blob/v2.13.1/include/internal/catch_debugger.cpp#L79-L102 + bool isDebuggerActive() { + ErrnoGuard guard; + std::ifstream in("/proc/self/status"); + for(std::string line; std::getline(in, line);) { + static const int PREFIX_LEN = 11; + if(line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0) { + return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0'; + } + } + return false; + } +#elif defined(DOCTEST_PLATFORM_MAC) + // The following function is taken directly from the following technical note: + // https://developer.apple.com/library/archive/qa/qa1361/_index.html + // Returns true if the current process is being debugged (either + // running under the debugger or has a debugger attached post facto). + bool isDebuggerActive() { + int mib[4]; + kinfo_proc info; + size_t size; + // Initialize the flags so that, if sysctl fails for some bizarre + // reason, we get a predictable result. + info.kp_proc.p_flag = 0; + // Initialize mib, which tells sysctl the info we want, in this case + // we're looking for information about a specific process ID. + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = getpid(); + // Call sysctl. + size = sizeof(info); + if(sysctl(mib, DOCTEST_COUNTOF(mib), &info, &size, 0, 0) != 0) { + std::cerr << "\nCall to sysctl failed - unable to determine if debugger is active **\n"; + return false; + } + // We're being debugged if the P_TRACED flag is set. + return ((info.kp_proc.p_flag & P_TRACED) != 0); + } +#elif DOCTEST_MSVC || defined(__MINGW32__) || defined(__MINGW64__) + bool isDebuggerActive() { return ::IsDebuggerPresent() != 0; } +#else + bool isDebuggerActive() { return false; } +#endif // Platform +#endif // DOCTEST_IS_DEBUGGER_ACTIVE + + void registerExceptionTranslatorImpl(const IExceptionTranslator* et) { + if(std::find(getExceptionTranslators().begin(), getExceptionTranslators().end(), et) == + getExceptionTranslators().end()) + getExceptionTranslators().push_back(et); + } + + DOCTEST_THREAD_LOCAL std::vector g_infoContexts; // for logging with INFO() + + ContextScopeBase::ContextScopeBase() { + g_infoContexts.push_back(this); + } + + ContextScopeBase::ContextScopeBase(ContextScopeBase&& other) noexcept { + if (other.need_to_destroy) { + other.destroy(); + } + other.need_to_destroy = false; + g_infoContexts.push_back(this); + } + + DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4996) // std::uncaught_exception is deprecated in C++17 + DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") + DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") + + // destroy cannot be inlined into the destructor because that would mean calling stringify after + // ContextScope has been destroyed (base class destructors run after derived class destructors). + // Instead, ContextScope calls this method directly from its destructor. + void ContextScopeBase::destroy() { +#if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411L && (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) + if(std::uncaught_exceptions() > 0) { +#else + if(std::uncaught_exception()) { +#endif + std::ostringstream s; + this->stringify(&s); + g_cs->stringifiedContexts.push_back(s.str().c_str()); + } + g_infoContexts.pop_back(); + } + + DOCTEST_CLANG_SUPPRESS_WARNING_POP + DOCTEST_GCC_SUPPRESS_WARNING_POP + DOCTEST_MSVC_SUPPRESS_WARNING_POP +} // namespace detail +namespace { + using namespace detail; + +#if !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && !defined(DOCTEST_CONFIG_WINDOWS_SEH) + struct FatalConditionHandler + { + static void reset() {} + static void allocateAltStackMem() {} + static void freeAltStackMem() {} + }; +#else // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH + + void reportFatal(const std::string&); + +#ifdef DOCTEST_PLATFORM_WINDOWS + + struct SignalDefs + { + DWORD id; + const char* name; + }; + // There is no 1-1 mapping between signals and windows exceptions. + // Windows can easily distinguish between SO and SigSegV, + // but SigInt, SigTerm, etc are handled differently. + SignalDefs signalDefs[] = { + {static_cast(EXCEPTION_ILLEGAL_INSTRUCTION), + "SIGILL - Illegal instruction signal"}, + {static_cast(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow"}, + {static_cast(EXCEPTION_ACCESS_VIOLATION), + "SIGSEGV - Segmentation violation signal"}, + {static_cast(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error"}, + }; + + struct FatalConditionHandler + { + static LONG CALLBACK handleException(PEXCEPTION_POINTERS ExceptionInfo) { + // Multiple threads may enter this filter/handler at once. We want the error message to be printed on the + // console just once no matter how many threads have crashed. + DOCTEST_DECLARE_STATIC_MUTEX(mutex) + static bool execute = true; + { + DOCTEST_LOCK_MUTEX(mutex) + if(execute) { + bool reported = false; + for(size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) { + if(ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) { + reportFatal(signalDefs[i].name); + reported = true; + break; + } + } + if(reported == false) + reportFatal("Unhandled SEH exception caught"); + if(isDebuggerActive() && !g_cs->no_breaks) + DOCTEST_BREAK_INTO_DEBUGGER(); + } + execute = false; + } + std::exit(EXIT_FAILURE); + } + + static void allocateAltStackMem() {} + static void freeAltStackMem() {} + + FatalConditionHandler() { + isSet = true; + // 32k seems enough for doctest to handle stack overflow, + // but the value was found experimentally, so there is no strong guarantee + guaranteeSize = 32 * 1024; + // Register an unhandled exception filter + previousTop = SetUnhandledExceptionFilter(handleException); + // Pass in guarantee size to be filled + SetThreadStackGuarantee(&guaranteeSize); + + // On Windows uncaught exceptions from another thread, exceptions from + // destructors, or calls to std::terminate are not a SEH exception + + // The terminal handler gets called when: + // - std::terminate is called FROM THE TEST RUNNER THREAD + // - an exception is thrown from a destructor FROM THE TEST RUNNER THREAD + original_terminate_handler = std::get_terminate(); + std::set_terminate([]() DOCTEST_NOEXCEPT { + reportFatal("Terminate handler called"); + if(isDebuggerActive() && !g_cs->no_breaks) + DOCTEST_BREAK_INTO_DEBUGGER(); + std::exit(EXIT_FAILURE); // explicitly exit - otherwise the SIGABRT handler may be called as well + }); + + // SIGABRT is raised when: + // - std::terminate is called FROM A DIFFERENT THREAD + // - an exception is thrown from a destructor FROM A DIFFERENT THREAD + // - an uncaught exception is thrown FROM A DIFFERENT THREAD + prev_sigabrt_handler = std::signal(SIGABRT, [](int signal) DOCTEST_NOEXCEPT { + if(signal == SIGABRT) { + reportFatal("SIGABRT - Abort (abnormal termination) signal"); + if(isDebuggerActive() && !g_cs->no_breaks) + DOCTEST_BREAK_INTO_DEBUGGER(); + std::exit(EXIT_FAILURE); + } + }); + + // The following settings are taken from google test, and more + // specifically from UnitTest::Run() inside of gtest.cc + + // the user does not want to see pop-up dialogs about crashes + prev_error_mode_1 = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | + SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); + // This forces the abort message to go to stderr in all circumstances. + prev_error_mode_2 = _set_error_mode(_OUT_TO_STDERR); + // In the debug version, Visual Studio pops up a separate dialog + // offering a choice to debug the aborted program - we want to disable that. + prev_abort_behavior = _set_abort_behavior(0x0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); + // In debug mode, the Windows CRT can crash with an assertion over invalid + // input (e.g. passing an invalid file descriptor). The default handling + // for these assertions is to pop up a dialog and wait for user input. + // Instead ask the CRT to dump such assertions to stderr non-interactively. + prev_report_mode = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); + prev_report_file = _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); + } + + static void reset() { + if(isSet) { + // Unregister handler and restore the old guarantee + SetUnhandledExceptionFilter(previousTop); + SetThreadStackGuarantee(&guaranteeSize); + std::set_terminate(original_terminate_handler); + std::signal(SIGABRT, prev_sigabrt_handler); + SetErrorMode(prev_error_mode_1); + _set_error_mode(prev_error_mode_2); + _set_abort_behavior(prev_abort_behavior, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); + static_cast(_CrtSetReportMode(_CRT_ASSERT, prev_report_mode)); + static_cast(_CrtSetReportFile(_CRT_ASSERT, prev_report_file)); + isSet = false; + } + } + + ~FatalConditionHandler() { reset(); } + + private: + static UINT prev_error_mode_1; + static int prev_error_mode_2; + static unsigned int prev_abort_behavior; + static int prev_report_mode; + static _HFILE prev_report_file; + static void (DOCTEST_CDECL *prev_sigabrt_handler)(int); + static std::terminate_handler original_terminate_handler; + static bool isSet; + static ULONG guaranteeSize; + static LPTOP_LEVEL_EXCEPTION_FILTER previousTop; + }; + + UINT FatalConditionHandler::prev_error_mode_1; + int FatalConditionHandler::prev_error_mode_2; + unsigned int FatalConditionHandler::prev_abort_behavior; + int FatalConditionHandler::prev_report_mode; + _HFILE FatalConditionHandler::prev_report_file; + void (DOCTEST_CDECL *FatalConditionHandler::prev_sigabrt_handler)(int); + std::terminate_handler FatalConditionHandler::original_terminate_handler; + bool FatalConditionHandler::isSet = false; + ULONG FatalConditionHandler::guaranteeSize = 0; + LPTOP_LEVEL_EXCEPTION_FILTER FatalConditionHandler::previousTop = nullptr; + +#else // DOCTEST_PLATFORM_WINDOWS + + struct SignalDefs + { + int id; + const char* name; + }; + SignalDefs signalDefs[] = {{SIGINT, "SIGINT - Terminal interrupt signal"}, + {SIGILL, "SIGILL - Illegal instruction signal"}, + {SIGFPE, "SIGFPE - Floating point error signal"}, + {SIGSEGV, "SIGSEGV - Segmentation violation signal"}, + {SIGTERM, "SIGTERM - Termination request signal"}, + {SIGABRT, "SIGABRT - Abort (abnormal termination) signal"}}; + + struct FatalConditionHandler + { + static bool isSet; + static struct sigaction oldSigActions[DOCTEST_COUNTOF(signalDefs)]; + static stack_t oldSigStack; + static size_t altStackSize; + static char* altStackMem; + + static void handleSignal(int sig) { + const char* name = ""; + for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) { + SignalDefs& def = signalDefs[i]; + if(sig == def.id) { + name = def.name; + break; + } + } + reset(); + reportFatal(name); + raise(sig); + } + + static void allocateAltStackMem() { + altStackMem = new char[altStackSize]; + } + + static void freeAltStackMem() { + delete[] altStackMem; + } + + FatalConditionHandler() { + isSet = true; + stack_t sigStack; + sigStack.ss_sp = altStackMem; + sigStack.ss_size = altStackSize; + sigStack.ss_flags = 0; + sigaltstack(&sigStack, &oldSigStack); + struct sigaction sa = {}; + sa.sa_handler = handleSignal; + sa.sa_flags = SA_ONSTACK; + for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) { + sigaction(signalDefs[i].id, &sa, &oldSigActions[i]); + } + } + + ~FatalConditionHandler() { reset(); } + static void reset() { + if(isSet) { + // Set signals back to previous values -- hopefully nobody overwrote them in the meantime + for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) { + sigaction(signalDefs[i].id, &oldSigActions[i], nullptr); + } + // Return the old stack + sigaltstack(&oldSigStack, nullptr); + isSet = false; + } + } + }; + + bool FatalConditionHandler::isSet = false; + struct sigaction FatalConditionHandler::oldSigActions[DOCTEST_COUNTOF(signalDefs)] = {}; + stack_t FatalConditionHandler::oldSigStack = {}; + size_t FatalConditionHandler::altStackSize = 4 * SIGSTKSZ; + char* FatalConditionHandler::altStackMem = nullptr; + +#endif // DOCTEST_PLATFORM_WINDOWS +#endif // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH + +} // namespace + +namespace { + using namespace detail; + +#ifdef DOCTEST_PLATFORM_WINDOWS +#define DOCTEST_OUTPUT_DEBUG_STRING(text) ::OutputDebugStringA(text) +#else + // TODO: integration with XCode and other IDEs +#define DOCTEST_OUTPUT_DEBUG_STRING(text) +#endif // Platform + + void addAssert(assertType::Enum at) { + if((at & assertType::is_warn) == 0) //!OCLINT bitwise operator in conditional + g_cs->numAssertsCurrentTest_atomic++; + } + + void addFailedAssert(assertType::Enum at) { + if((at & assertType::is_warn) == 0) //!OCLINT bitwise operator in conditional + g_cs->numAssertsFailedCurrentTest_atomic++; + } + +#if defined(DOCTEST_CONFIG_POSIX_SIGNALS) || defined(DOCTEST_CONFIG_WINDOWS_SEH) + void reportFatal(const std::string& message) { + g_cs->failure_flags |= TestCaseFailureReason::Crash; + + DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_exception, {message.c_str(), true}); + + while (g_cs->subcaseStack.size()) { + g_cs->subcaseStack.pop_back(); + DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY); + } + + g_cs->finalizeTestCaseData(); + + DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_end, *g_cs); + + DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_end, *g_cs); + } +#endif // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH +} // namespace + +AssertData::AssertData(assertType::Enum at, const char* file, int line, const char* expr, + const char* exception_type, const StringContains& exception_string) + : m_test_case(g_cs->currentTest), m_at(at), m_file(file), m_line(line), m_expr(expr), + m_failed(true), m_threw(false), m_threw_as(false), m_exception_type(exception_type), + m_exception_string(exception_string) { +#if DOCTEST_MSVC + if (m_expr[0] == ' ') // this happens when variadic macros are disabled under MSVC + ++m_expr; +#endif // MSVC +} + +namespace detail { + ResultBuilder::ResultBuilder(assertType::Enum at, const char* file, int line, const char* expr, + const char* exception_type, const String& exception_string) + : AssertData(at, file, line, expr, exception_type, exception_string) { } + + ResultBuilder::ResultBuilder(assertType::Enum at, const char* file, int line, const char* expr, + const char* exception_type, const Contains& exception_string) + : AssertData(at, file, line, expr, exception_type, exception_string) { } + + void ResultBuilder::setResult(const Result& res) { + m_decomp = res.m_decomp; + m_failed = !res.m_passed; + } + + void ResultBuilder::translateException() { + m_threw = true; + m_exception = translateActiveException(); + } + + bool ResultBuilder::log() { + if(m_at & assertType::is_throws) { //!OCLINT bitwise operator in conditional + m_failed = !m_threw; + } else if((m_at & assertType::is_throws_as) && (m_at & assertType::is_throws_with)) { //!OCLINT + m_failed = !m_threw_as || !m_exception_string.check(m_exception); + } else if(m_at & assertType::is_throws_as) { //!OCLINT bitwise operator in conditional + m_failed = !m_threw_as; + } else if(m_at & assertType::is_throws_with) { //!OCLINT bitwise operator in conditional + m_failed = !m_exception_string.check(m_exception); + } else if(m_at & assertType::is_nothrow) { //!OCLINT bitwise operator in conditional + m_failed = m_threw; + } + + if(m_exception.size()) + m_exception = "\"" + m_exception + "\""; + + if(is_running_in_test) { + addAssert(m_at); + DOCTEST_ITERATE_THROUGH_REPORTERS(log_assert, *this); + + if(m_failed) + addFailedAssert(m_at); + } else if(m_failed) { + failed_out_of_a_testing_context(*this); + } + + return m_failed && isDebuggerActive() && !getContextOptions()->no_breaks && + (g_cs->currentTest == nullptr || !g_cs->currentTest->m_no_breaks); // break into debugger + } + + void ResultBuilder::react() const { + if(m_failed && checkIfShouldThrow(m_at)) + throwException(); + } + + void failed_out_of_a_testing_context(const AssertData& ad) { + if(g_cs->ah) + g_cs->ah(ad); + else + std::abort(); + } + + bool decomp_assert(assertType::Enum at, const char* file, int line, const char* expr, + const Result& result) { + bool failed = !result.m_passed; + + // ################################################################################### + // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE FAILING ASSERT + // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED + // ################################################################################### + DOCTEST_ASSERT_OUT_OF_TESTS(result.m_decomp); + DOCTEST_ASSERT_IN_TESTS(result.m_decomp); + return !failed; + } + + MessageBuilder::MessageBuilder(const char* file, int line, assertType::Enum severity) { + m_stream = tlssPush(); + m_file = file; + m_line = line; + m_severity = severity; + } + + MessageBuilder::~MessageBuilder() { + if (!logged) + tlssPop(); + } + + DOCTEST_DEFINE_INTERFACE(IExceptionTranslator) + + bool MessageBuilder::log() { + if (!logged) { + m_string = tlssPop(); + logged = true; + } + + DOCTEST_ITERATE_THROUGH_REPORTERS(log_message, *this); + + const bool isWarn = m_severity & assertType::is_warn; + + // warn is just a message in this context so we don't treat it as an assert + if(!isWarn) { + addAssert(m_severity); + addFailedAssert(m_severity); + } + + return isDebuggerActive() && !getContextOptions()->no_breaks && !isWarn && + (g_cs->currentTest == nullptr || !g_cs->currentTest->m_no_breaks); // break into debugger + } + + void MessageBuilder::react() { + if(m_severity & assertType::is_require) //!OCLINT bitwise operator in conditional + throwException(); + } +} // namespace detail +namespace { + using namespace detail; + + // clang-format off + +// ================================================================================================= +// The following code has been taken verbatim from Catch2/include/internal/catch_xmlwriter.h/cpp +// This is done so cherry-picking bug fixes is trivial - even the style/formatting is untouched. +// ================================================================================================= + + class XmlEncode { + public: + enum ForWhat { ForTextNodes, ForAttributes }; + + XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes ); + + void encodeTo( std::ostream& os ) const; + + friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ); + + private: + std::string m_str; + ForWhat m_forWhat; + }; + + class XmlWriter { + public: + + class ScopedElement { + public: + ScopedElement( XmlWriter* writer ); + + ScopedElement( ScopedElement&& other ) DOCTEST_NOEXCEPT; + ScopedElement& operator=( ScopedElement&& other ) DOCTEST_NOEXCEPT; + + ~ScopedElement(); + + ScopedElement& writeText( std::string const& text, bool indent = true ); + + template + ScopedElement& writeAttribute( std::string const& name, T const& attribute ) { + m_writer->writeAttribute( name, attribute ); + return *this; + } + + private: + mutable XmlWriter* m_writer = nullptr; + }; + +#ifndef DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM + XmlWriter( std::ostream& os = std::cout ); +#else // DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM + XmlWriter( std::ostream& os ); +#endif // DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM + ~XmlWriter(); + + XmlWriter( XmlWriter const& ) = delete; + XmlWriter& operator=( XmlWriter const& ) = delete; + + XmlWriter& startElement( std::string const& name ); + + ScopedElement scopedElement( std::string const& name ); + + XmlWriter& endElement(); + + XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ); + + XmlWriter& writeAttribute( std::string const& name, const char* attribute ); + + XmlWriter& writeAttribute( std::string const& name, bool attribute ); + + template + XmlWriter& writeAttribute( std::string const& name, T const& attribute ) { + std::stringstream rss; + rss << attribute; + return writeAttribute( name, rss.str() ); + } + + XmlWriter& writeText( std::string const& text, bool indent = true ); + + //XmlWriter& writeComment( std::string const& text ); + + //void writeStylesheetRef( std::string const& url ); + + //XmlWriter& writeBlankLine(); + + void ensureTagClosed(); + + void writeDeclaration(); + + private: + + void newlineIfNecessary(); + + bool m_tagIsOpen = false; + bool m_needsNewline = false; + std::vector m_tags; + std::string m_indent; + std::ostream& m_os; + }; + +// ================================================================================================= +// The following code has been taken verbatim from Catch2/include/internal/catch_xmlwriter.h/cpp +// This is done so cherry-picking bug fixes is trivial - even the style/formatting is untouched. +// ================================================================================================= + +using uchar = unsigned char; + +namespace { + + size_t trailingBytes(unsigned char c) { + if ((c & 0xE0) == 0xC0) { + return 2; + } + if ((c & 0xF0) == 0xE0) { + return 3; + } + if ((c & 0xF8) == 0xF0) { + return 4; + } + DOCTEST_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered"); + } + + uint32_t headerValue(unsigned char c) { + if ((c & 0xE0) == 0xC0) { + return c & 0x1F; + } + if ((c & 0xF0) == 0xE0) { + return c & 0x0F; + } + if ((c & 0xF8) == 0xF0) { + return c & 0x07; + } + DOCTEST_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered"); + } + + void hexEscapeChar(std::ostream& os, unsigned char c) { + std::ios_base::fmtflags f(os.flags()); + os << "\\x" + << std::uppercase << std::hex << std::setfill('0') << std::setw(2) + << static_cast(c); + os.flags(f); + } + +} // anonymous namespace + + XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat ) + : m_str( str ), + m_forWhat( forWhat ) + {} + + void XmlEncode::encodeTo( std::ostream& os ) const { + // Apostrophe escaping not necessary if we always use " to write attributes + // (see: https://www.w3.org/TR/xml/#syntax) + + for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) { + uchar c = m_str[idx]; + switch (c) { + case '<': os << "<"; break; + case '&': os << "&"; break; + + case '>': + // See: https://www.w3.org/TR/xml/#syntax + if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']') + os << ">"; + else + os << c; + break; + + case '\"': + if (m_forWhat == ForAttributes) + os << """; + else + os << c; + break; + + default: + // Check for control characters and invalid utf-8 + + // Escape control characters in standard ascii + // see https://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 + if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) { + hexEscapeChar(os, c); + break; + } + + // Plain ASCII: Write it to stream + if (c < 0x7F) { + os << c; + break; + } + + // UTF-8 territory + // Check if the encoding is valid and if it is not, hex escape bytes. + // Important: We do not check the exact decoded values for validity, only the encoding format + // First check that this bytes is a valid lead byte: + // This means that it is not encoded as 1111 1XXX + // Or as 10XX XXXX + if (c < 0xC0 || + c >= 0xF8) { + hexEscapeChar(os, c); + break; + } + + auto encBytes = trailingBytes(c); + // Are there enough bytes left to avoid accessing out-of-bounds memory? + if (idx + encBytes - 1 >= m_str.size()) { + hexEscapeChar(os, c); + break; + } + // The header is valid, check data + // The next encBytes bytes must together be a valid utf-8 + // This means: bitpattern 10XX XXXX and the extracted value is sane (ish) + bool valid = true; + uint32_t value = headerValue(c); + for (std::size_t n = 1; n < encBytes; ++n) { + uchar nc = m_str[idx + n]; + valid &= ((nc & 0xC0) == 0x80); + value = (value << 6) | (nc & 0x3F); + } + + if ( + // Wrong bit pattern of following bytes + (!valid) || + // Overlong encodings + (value < 0x80) || + ( value < 0x800 && encBytes > 2) || // removed "0x80 <= value &&" because redundant + (0x800 < value && value < 0x10000 && encBytes > 3) || + // Encoded value out of range + (value >= 0x110000) + ) { + hexEscapeChar(os, c); + break; + } + + // If we got here, this is in fact a valid(ish) utf-8 sequence + for (std::size_t n = 0; n < encBytes; ++n) { + os << m_str[idx + n]; + } + idx += encBytes - 1; + break; + } + } + } + + std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) { + xmlEncode.encodeTo( os ); + return os; + } + + XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer ) + : m_writer( writer ) + {} + + XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) DOCTEST_NOEXCEPT + : m_writer( other.m_writer ){ + other.m_writer = nullptr; + } + XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) DOCTEST_NOEXCEPT { + if ( m_writer ) { + m_writer->endElement(); + } + m_writer = other.m_writer; + other.m_writer = nullptr; + return *this; + } + + + XmlWriter::ScopedElement::~ScopedElement() { + if( m_writer ) + m_writer->endElement(); + } + + XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, bool indent ) { + m_writer->writeText( text, indent ); + return *this; + } + + XmlWriter::XmlWriter( std::ostream& os ) : m_os( os ) + { + // writeDeclaration(); // called explicitly by the reporters that use the writer class - see issue #627 + } + + XmlWriter::~XmlWriter() { + while( !m_tags.empty() ) + endElement(); + } + + XmlWriter& XmlWriter::startElement( std::string const& name ) { + ensureTagClosed(); + newlineIfNecessary(); + m_os << m_indent << '<' << name; + m_tags.push_back( name ); + m_indent += " "; + m_tagIsOpen = true; + return *this; + } + + XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name ) { + ScopedElement scoped( this ); + startElement( name ); + return scoped; + } + + XmlWriter& XmlWriter::endElement() { + newlineIfNecessary(); + m_indent = m_indent.substr( 0, m_indent.size()-2 ); + if( m_tagIsOpen ) { + m_os << "/>"; + m_tagIsOpen = false; + } + else { + m_os << m_indent << ""; + } + m_os << std::endl; + m_tags.pop_back(); + return *this; + } + + XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) { + if( !name.empty() && !attribute.empty() ) + m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"'; + return *this; + } + + XmlWriter& XmlWriter::writeAttribute( std::string const& name, const char* attribute ) { + if( !name.empty() && attribute && attribute[0] != '\0' ) + m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"'; + return *this; + } + + XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) { + m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"'; + return *this; + } + + XmlWriter& XmlWriter::writeText( std::string const& text, bool indent ) { + if( !text.empty() ){ + bool tagWasOpen = m_tagIsOpen; + ensureTagClosed(); + if( tagWasOpen && indent ) + m_os << m_indent; + m_os << XmlEncode( text ); + m_needsNewline = true; + } + return *this; + } + + //XmlWriter& XmlWriter::writeComment( std::string const& text ) { + // ensureTagClosed(); + // m_os << m_indent << ""; + // m_needsNewline = true; + // return *this; + //} + + //void XmlWriter::writeStylesheetRef( std::string const& url ) { + // m_os << "\n"; + //} + + //XmlWriter& XmlWriter::writeBlankLine() { + // ensureTagClosed(); + // m_os << '\n'; + // return *this; + //} + + void XmlWriter::ensureTagClosed() { + if( m_tagIsOpen ) { + m_os << ">" << std::endl; + m_tagIsOpen = false; + } + } + + void XmlWriter::writeDeclaration() { + m_os << "\n"; + } + + void XmlWriter::newlineIfNecessary() { + if( m_needsNewline ) { + m_os << std::endl; + m_needsNewline = false; + } + } + +// ================================================================================================= +// End of copy-pasted code from Catch +// ================================================================================================= + + // clang-format on + + struct XmlReporter : public IReporter + { + XmlWriter xml; + DOCTEST_DECLARE_MUTEX(mutex) + + // caching pointers/references to objects of these types - safe to do + const ContextOptions& opt; + const TestCaseData* tc = nullptr; + + XmlReporter(const ContextOptions& co) + : xml(*co.cout) + , opt(co) {} + + void log_contexts() { + int num_contexts = get_num_active_contexts(); + if(num_contexts) { + auto contexts = get_active_contexts(); + std::stringstream ss; + for(int i = 0; i < num_contexts; ++i) { + contexts[i]->stringify(&ss); + xml.scopedElement("Info").writeText(ss.str()); + ss.str(""); + } + } + } + + unsigned line(unsigned l) const { return opt.no_line_numbers ? 0 : l; } + + void test_case_start_impl(const TestCaseData& in) { + bool open_ts_tag = false; + if(tc != nullptr) { // we have already opened a test suite + if(std::strcmp(tc->m_test_suite, in.m_test_suite) != 0) { + xml.endElement(); + open_ts_tag = true; + } + } + else { + open_ts_tag = true; // first test case ==> first test suite + } + + if(open_ts_tag) { + xml.startElement("TestSuite"); + xml.writeAttribute("name", in.m_test_suite); + } + + tc = ∈ + xml.startElement("TestCase") + .writeAttribute("name", in.m_name) + .writeAttribute("filename", skipPathFromFilename(in.m_file.c_str())) + .writeAttribute("line", line(in.m_line)) + .writeAttribute("description", in.m_description); + + if(Approx(in.m_timeout) != 0) + xml.writeAttribute("timeout", in.m_timeout); + if(in.m_may_fail) + xml.writeAttribute("may_fail", true); + if(in.m_should_fail) + xml.writeAttribute("should_fail", true); + } + + // ========================================================================================= + // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE + // ========================================================================================= + + void report_query(const QueryData& in) override { + test_run_start(); + if(opt.list_reporters) { + for(auto& curr : getListeners()) + xml.scopedElement("Listener") + .writeAttribute("priority", curr.first.first) + .writeAttribute("name", curr.first.second); + for(auto& curr : getReporters()) + xml.scopedElement("Reporter") + .writeAttribute("priority", curr.first.first) + .writeAttribute("name", curr.first.second); + } else if(opt.count || opt.list_test_cases) { + for(unsigned i = 0; i < in.num_data; ++i) { + xml.scopedElement("TestCase").writeAttribute("name", in.data[i]->m_name) + .writeAttribute("testsuite", in.data[i]->m_test_suite) + .writeAttribute("filename", skipPathFromFilename(in.data[i]->m_file.c_str())) + .writeAttribute("line", line(in.data[i]->m_line)) + .writeAttribute("skipped", in.data[i]->m_skip); + } + xml.scopedElement("OverallResultsTestCases") + .writeAttribute("unskipped", in.run_stats->numTestCasesPassingFilters); + } else if(opt.list_test_suites) { + for(unsigned i = 0; i < in.num_data; ++i) + xml.scopedElement("TestSuite").writeAttribute("name", in.data[i]->m_test_suite); + xml.scopedElement("OverallResultsTestCases") + .writeAttribute("unskipped", in.run_stats->numTestCasesPassingFilters); + xml.scopedElement("OverallResultsTestSuites") + .writeAttribute("unskipped", in.run_stats->numTestSuitesPassingFilters); + } + xml.endElement(); + } + + void test_run_start() override { + xml.writeDeclaration(); + + // remove .exe extension - mainly to have the same output on UNIX and Windows + std::string binary_name = skipPathFromFilename(opt.binary_name.c_str()); +#ifdef DOCTEST_PLATFORM_WINDOWS + if(binary_name.rfind(".exe") != std::string::npos) + binary_name = binary_name.substr(0, binary_name.length() - 4); +#endif // DOCTEST_PLATFORM_WINDOWS + + xml.startElement("doctest").writeAttribute("binary", binary_name); + if(opt.no_version == false) + xml.writeAttribute("version", DOCTEST_VERSION_STR); + + // only the consequential ones (TODO: filters) + xml.scopedElement("Options") + .writeAttribute("order_by", opt.order_by.c_str()) + .writeAttribute("rand_seed", opt.rand_seed) + .writeAttribute("first", opt.first) + .writeAttribute("last", opt.last) + .writeAttribute("abort_after", opt.abort_after) + .writeAttribute("subcase_filter_levels", opt.subcase_filter_levels) + .writeAttribute("case_sensitive", opt.case_sensitive) + .writeAttribute("no_throw", opt.no_throw) + .writeAttribute("no_skip", opt.no_skip); + } + + void test_run_end(const TestRunStats& p) override { + if(tc) // the TestSuite tag - only if there has been at least 1 test case + xml.endElement(); + + xml.scopedElement("OverallResultsAsserts") + .writeAttribute("successes", p.numAsserts - p.numAssertsFailed) + .writeAttribute("failures", p.numAssertsFailed); + + xml.startElement("OverallResultsTestCases") + .writeAttribute("successes", + p.numTestCasesPassingFilters - p.numTestCasesFailed) + .writeAttribute("failures", p.numTestCasesFailed); + if(opt.no_skipped_summary == false) + xml.writeAttribute("skipped", p.numTestCases - p.numTestCasesPassingFilters); + xml.endElement(); + + xml.endElement(); + } + + void test_case_start(const TestCaseData& in) override { + test_case_start_impl(in); + xml.ensureTagClosed(); + } + + void test_case_reenter(const TestCaseData&) override {} + + void test_case_end(const CurrentTestCaseStats& st) override { + xml.startElement("OverallResultsAsserts") + .writeAttribute("successes", + st.numAssertsCurrentTest - st.numAssertsFailedCurrentTest) + .writeAttribute("failures", st.numAssertsFailedCurrentTest) + .writeAttribute("test_case_success", st.testCaseSuccess); + if(opt.duration) + xml.writeAttribute("duration", st.seconds); + if(tc->m_expected_failures) + xml.writeAttribute("expected_failures", tc->m_expected_failures); + xml.endElement(); + + xml.endElement(); + } + + void test_case_exception(const TestCaseException& e) override { + DOCTEST_LOCK_MUTEX(mutex) + + xml.scopedElement("Exception") + .writeAttribute("crash", e.is_crash) + .writeText(e.error_string.c_str()); + } + + void subcase_start(const SubcaseSignature& in) override { + xml.startElement("SubCase") + .writeAttribute("name", in.m_name) + .writeAttribute("filename", skipPathFromFilename(in.m_file)) + .writeAttribute("line", line(in.m_line)); + xml.ensureTagClosed(); + } + + void subcase_end() override { xml.endElement(); } + + void log_assert(const AssertData& rb) override { + if(!rb.m_failed && !opt.success) + return; + + DOCTEST_LOCK_MUTEX(mutex) + + xml.startElement("Expression") + .writeAttribute("success", !rb.m_failed) + .writeAttribute("type", assertString(rb.m_at)) + .writeAttribute("filename", skipPathFromFilename(rb.m_file)) + .writeAttribute("line", line(rb.m_line)); + + xml.scopedElement("Original").writeText(rb.m_expr); + + if(rb.m_threw) + xml.scopedElement("Exception").writeText(rb.m_exception.c_str()); + + if(rb.m_at & assertType::is_throws_as) + xml.scopedElement("ExpectedException").writeText(rb.m_exception_type); + if(rb.m_at & assertType::is_throws_with) + xml.scopedElement("ExpectedExceptionString").writeText(rb.m_exception_string.c_str()); + if((rb.m_at & assertType::is_normal) && !rb.m_threw) + xml.scopedElement("Expanded").writeText(rb.m_decomp.c_str()); + + log_contexts(); + + xml.endElement(); + } + + void log_message(const MessageData& mb) override { + DOCTEST_LOCK_MUTEX(mutex) + + xml.startElement("Message") + .writeAttribute("type", failureString(mb.m_severity)) + .writeAttribute("filename", skipPathFromFilename(mb.m_file)) + .writeAttribute("line", line(mb.m_line)); + + xml.scopedElement("Text").writeText(mb.m_string.c_str()); + + log_contexts(); + + xml.endElement(); + } + + void test_case_skipped(const TestCaseData& in) override { + if(opt.no_skipped_summary == false) { + test_case_start_impl(in); + xml.writeAttribute("skipped", "true"); + xml.endElement(); + } + } + }; + + DOCTEST_REGISTER_REPORTER("xml", 0, XmlReporter); + + void fulltext_log_assert_to_stream(std::ostream& s, const AssertData& rb) { + if((rb.m_at & (assertType::is_throws_as | assertType::is_throws_with)) == + 0) //!OCLINT bitwise operator in conditional + s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << " ) " + << Color::None; + + if(rb.m_at & assertType::is_throws) { //!OCLINT bitwise operator in conditional + s << (rb.m_threw ? "threw as expected!" : "did NOT throw at all!") << "\n"; + } else if((rb.m_at & assertType::is_throws_as) && + (rb.m_at & assertType::is_throws_with)) { //!OCLINT + s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", \"" + << rb.m_exception_string.c_str() + << "\", " << rb.m_exception_type << " ) " << Color::None; + if(rb.m_threw) { + if(!rb.m_failed) { + s << "threw as expected!\n"; + } else { + s << "threw a DIFFERENT exception! (contents: " << rb.m_exception << ")\n"; + } + } else { + s << "did NOT throw at all!\n"; + } + } else if(rb.m_at & + assertType::is_throws_as) { //!OCLINT bitwise operator in conditional + s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", " + << rb.m_exception_type << " ) " << Color::None + << (rb.m_threw ? (rb.m_threw_as ? "threw as expected!" : + "threw a DIFFERENT exception: ") : + "did NOT throw at all!") + << Color::Cyan << rb.m_exception << "\n"; + } else if(rb.m_at & + assertType::is_throws_with) { //!OCLINT bitwise operator in conditional + s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", \"" + << rb.m_exception_string.c_str() + << "\" ) " << Color::None + << (rb.m_threw ? (!rb.m_failed ? "threw as expected!" : + "threw a DIFFERENT exception: ") : + "did NOT throw at all!") + << Color::Cyan << rb.m_exception << "\n"; + } else if(rb.m_at & assertType::is_nothrow) { //!OCLINT bitwise operator in conditional + s << (rb.m_threw ? "THREW exception: " : "didn't throw!") << Color::Cyan + << rb.m_exception << "\n"; + } else { + s << (rb.m_threw ? "THREW exception: " : + (!rb.m_failed ? "is correct!\n" : "is NOT correct!\n")); + if(rb.m_threw) + s << rb.m_exception << "\n"; + else + s << " values: " << assertString(rb.m_at) << "( " << rb.m_decomp << " )\n"; + } + } + + // TODO: + // - log_message() + // - respond to queries + // - honor remaining options + // - more attributes in tags + struct JUnitReporter : public IReporter + { + XmlWriter xml; + DOCTEST_DECLARE_MUTEX(mutex) + Timer timer; + std::vector deepestSubcaseStackNames; + + struct JUnitTestCaseData + { + static std::string getCurrentTimestamp() { + // Beware, this is not reentrant because of backward compatibility issues + // Also, UTC only, again because of backward compatibility (%z is C++11) + time_t rawtime; + std::time(&rawtime); + auto const timeStampSize = sizeof("2017-01-16T17:06:45Z"); + + std::tm timeInfo; +#ifdef DOCTEST_PLATFORM_WINDOWS + gmtime_s(&timeInfo, &rawtime); +#else // DOCTEST_PLATFORM_WINDOWS + gmtime_r(&rawtime, &timeInfo); +#endif // DOCTEST_PLATFORM_WINDOWS + + char timeStamp[timeStampSize]; + const char* const fmt = "%Y-%m-%dT%H:%M:%SZ"; + + std::strftime(timeStamp, timeStampSize, fmt, &timeInfo); + return std::string(timeStamp); + } + + struct JUnitTestMessage + { + JUnitTestMessage(const std::string& _message, const std::string& _type, const std::string& _details) + : message(_message), type(_type), details(_details) {} + + JUnitTestMessage(const std::string& _message, const std::string& _details) + : message(_message), type(), details(_details) {} + + std::string message, type, details; + }; + + struct JUnitTestCase + { + JUnitTestCase(const std::string& _classname, const std::string& _name) + : classname(_classname), name(_name), time(0), failures() {} + + std::string classname, name; + double time; + std::vector failures, errors; + }; + + void add(const std::string& classname, const std::string& name) { + testcases.emplace_back(classname, name); + } + + void appendSubcaseNamesToLastTestcase(std::vector nameStack) { + for(auto& curr: nameStack) + if(curr.size()) + testcases.back().name += std::string("/") + curr.c_str(); + } + + void addTime(double time) { + if(time < 1e-4) + time = 0; + testcases.back().time = time; + totalSeconds += time; + } + + void addFailure(const std::string& message, const std::string& type, const std::string& details) { + testcases.back().failures.emplace_back(message, type, details); + ++totalFailures; + } + + void addError(const std::string& message, const std::string& details) { + testcases.back().errors.emplace_back(message, details); + ++totalErrors; + } + + std::vector testcases; + double totalSeconds = 0; + int totalErrors = 0, totalFailures = 0; + }; + + JUnitTestCaseData testCaseData; + + // caching pointers/references to objects of these types - safe to do + const ContextOptions& opt; + const TestCaseData* tc = nullptr; + + JUnitReporter(const ContextOptions& co) + : xml(*co.cout) + , opt(co) {} + + unsigned line(unsigned l) const { return opt.no_line_numbers ? 0 : l; } + + // ========================================================================================= + // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE + // ========================================================================================= + + void report_query(const QueryData&) override { + xml.writeDeclaration(); + } + + void test_run_start() override { + xml.writeDeclaration(); + } + + void test_run_end(const TestRunStats& p) override { + // remove .exe extension - mainly to have the same output on UNIX and Windows + std::string binary_name = skipPathFromFilename(opt.binary_name.c_str()); +#ifdef DOCTEST_PLATFORM_WINDOWS + if(binary_name.rfind(".exe") != std::string::npos) + binary_name = binary_name.substr(0, binary_name.length() - 4); +#endif // DOCTEST_PLATFORM_WINDOWS + xml.startElement("testsuites"); + xml.startElement("testsuite").writeAttribute("name", binary_name) + .writeAttribute("errors", testCaseData.totalErrors) + .writeAttribute("failures", testCaseData.totalFailures) + .writeAttribute("tests", p.numAsserts); + if(opt.no_time_in_output == false) { + xml.writeAttribute("time", testCaseData.totalSeconds); + xml.writeAttribute("timestamp", JUnitTestCaseData::getCurrentTimestamp()); + } + if(opt.no_version == false) + xml.writeAttribute("doctest_version", DOCTEST_VERSION_STR); + + for(const auto& testCase : testCaseData.testcases) { + xml.startElement("testcase") + .writeAttribute("classname", testCase.classname) + .writeAttribute("name", testCase.name); + if(opt.no_time_in_output == false) + xml.writeAttribute("time", testCase.time); + // This is not ideal, but it should be enough to mimic gtest's junit output. + xml.writeAttribute("status", "run"); + + for(const auto& failure : testCase.failures) { + xml.scopedElement("failure") + .writeAttribute("message", failure.message) + .writeAttribute("type", failure.type) + .writeText(failure.details, false); + } + + for(const auto& error : testCase.errors) { + xml.scopedElement("error") + .writeAttribute("message", error.message) + .writeText(error.details); + } + + xml.endElement(); + } + xml.endElement(); + xml.endElement(); + } + + void test_case_start(const TestCaseData& in) override { + testCaseData.add(skipPathFromFilename(in.m_file.c_str()), in.m_name); + timer.start(); + } + + void test_case_reenter(const TestCaseData& in) override { + testCaseData.addTime(timer.getElapsedSeconds()); + testCaseData.appendSubcaseNamesToLastTestcase(deepestSubcaseStackNames); + deepestSubcaseStackNames.clear(); + + timer.start(); + testCaseData.add(skipPathFromFilename(in.m_file.c_str()), in.m_name); + } + + void test_case_end(const CurrentTestCaseStats&) override { + testCaseData.addTime(timer.getElapsedSeconds()); + testCaseData.appendSubcaseNamesToLastTestcase(deepestSubcaseStackNames); + deepestSubcaseStackNames.clear(); + } + + void test_case_exception(const TestCaseException& e) override { + DOCTEST_LOCK_MUTEX(mutex) + testCaseData.addError("exception", e.error_string.c_str()); + } + + void subcase_start(const SubcaseSignature& in) override { + deepestSubcaseStackNames.push_back(in.m_name); + } + + void subcase_end() override {} + + void log_assert(const AssertData& rb) override { + if(!rb.m_failed) // report only failures & ignore the `success` option + return; + + DOCTEST_LOCK_MUTEX(mutex) + + std::ostringstream os; + os << skipPathFromFilename(rb.m_file) << (opt.gnu_file_line ? ":" : "(") + << line(rb.m_line) << (opt.gnu_file_line ? ":" : "):") << std::endl; + + fulltext_log_assert_to_stream(os, rb); + log_contexts(os); + testCaseData.addFailure(rb.m_decomp.c_str(), assertString(rb.m_at), os.str()); + } + + void log_message(const MessageData& mb) override { + if(mb.m_severity & assertType::is_warn) // report only failures + return; + + DOCTEST_LOCK_MUTEX(mutex) + + std::ostringstream os; + os << skipPathFromFilename(mb.m_file) << (opt.gnu_file_line ? ":" : "(") + << line(mb.m_line) << (opt.gnu_file_line ? ":" : "):") << std::endl; + + os << mb.m_string.c_str() << "\n"; + log_contexts(os); + + testCaseData.addFailure(mb.m_string.c_str(), + mb.m_severity & assertType::is_check ? "FAIL_CHECK" : "FAIL", os.str()); + } + + void test_case_skipped(const TestCaseData&) override {} + + void log_contexts(std::ostringstream& s) { + int num_contexts = get_num_active_contexts(); + if(num_contexts) { + auto contexts = get_active_contexts(); + + s << " logged: "; + for(int i = 0; i < num_contexts; ++i) { + s << (i == 0 ? "" : " "); + contexts[i]->stringify(&s); + s << std::endl; + } + } + } + }; + + DOCTEST_REGISTER_REPORTER("junit", 0, JUnitReporter); + + struct Whitespace + { + int nrSpaces; + explicit Whitespace(int nr) + : nrSpaces(nr) {} + }; + + std::ostream& operator<<(std::ostream& out, const Whitespace& ws) { + if(ws.nrSpaces != 0) + out << std::setw(ws.nrSpaces) << ' '; + return out; + } + + struct ConsoleReporter : public IReporter + { + std::ostream& s; + bool hasLoggedCurrentTestStart; + std::vector subcasesStack; + size_t currentSubcaseLevel; + DOCTEST_DECLARE_MUTEX(mutex) + + // caching pointers/references to objects of these types - safe to do + const ContextOptions& opt; + const TestCaseData* tc; + + ConsoleReporter(const ContextOptions& co) + : s(*co.cout) + , opt(co) {} + + ConsoleReporter(const ContextOptions& co, std::ostream& ostr) + : s(ostr) + , opt(co) {} + + // ========================================================================================= + // WHAT FOLLOWS ARE HELPERS USED BY THE OVERRIDES OF THE VIRTUAL METHODS OF THE INTERFACE + // ========================================================================================= + + void separator_to_stream() { + s << Color::Yellow + << "===============================================================================" + "\n"; + } + + const char* getSuccessOrFailString(bool success, assertType::Enum at, + const char* success_str) { + if(success) + return success_str; + return failureString(at); + } + + Color::Enum getSuccessOrFailColor(bool success, assertType::Enum at) { + return success ? Color::BrightGreen : + (at & assertType::is_warn) ? Color::Yellow : Color::Red; + } + + void successOrFailColoredStringToStream(bool success, assertType::Enum at, + const char* success_str = "SUCCESS") { + s << getSuccessOrFailColor(success, at) + << getSuccessOrFailString(success, at, success_str) << ": "; + } + + void log_contexts() { + int num_contexts = get_num_active_contexts(); + if(num_contexts) { + auto contexts = get_active_contexts(); + + s << Color::None << " logged: "; + for(int i = 0; i < num_contexts; ++i) { + s << (i == 0 ? "" : " "); + contexts[i]->stringify(&s); + s << "\n"; + } + } + + s << "\n"; + } + + // this was requested to be made virtual so users could override it + virtual void file_line_to_stream(const char* file, int line, + const char* tail = "") { + s << Color::LightGrey << skipPathFromFilename(file) << (opt.gnu_file_line ? ":" : "(") + << (opt.no_line_numbers ? 0 : line) // 0 or the real num depending on the option + << (opt.gnu_file_line ? ":" : "):") << tail; + } + + void logTestStart() { + if(hasLoggedCurrentTestStart) + return; + + separator_to_stream(); + file_line_to_stream(tc->m_file.c_str(), tc->m_line, "\n"); + if(tc->m_description) + s << Color::Yellow << "DESCRIPTION: " << Color::None << tc->m_description << "\n"; + if(tc->m_test_suite && tc->m_test_suite[0] != '\0') + s << Color::Yellow << "TEST SUITE: " << Color::None << tc->m_test_suite << "\n"; + if(strncmp(tc->m_name, " Scenario:", 11) != 0) + s << Color::Yellow << "TEST CASE: "; + s << Color::None << tc->m_name << "\n"; + + for(size_t i = 0; i < currentSubcaseLevel; ++i) { + if(subcasesStack[i].m_name[0] != '\0') + s << " " << subcasesStack[i].m_name << "\n"; + } + + if(currentSubcaseLevel != subcasesStack.size()) { + s << Color::Yellow << "\nDEEPEST SUBCASE STACK REACHED (DIFFERENT FROM THE CURRENT ONE):\n" << Color::None; + for(size_t i = 0; i < subcasesStack.size(); ++i) { + if(subcasesStack[i].m_name[0] != '\0') + s << " " << subcasesStack[i].m_name << "\n"; + } + } + + s << "\n"; + + hasLoggedCurrentTestStart = true; + } + + void printVersion() { + if(opt.no_version == false) + s << Color::Cyan << "[doctest] " << Color::None << "doctest version is \"" + << DOCTEST_VERSION_STR << "\"\n"; + } + + void printIntro() { + if(opt.no_intro == false) { + printVersion(); + s << Color::Cyan << "[doctest] " << Color::None + << "run with \"--" DOCTEST_OPTIONS_PREFIX_DISPLAY "help\" for options\n"; + } + } + + void printHelp() { + int sizePrefixDisplay = static_cast(strlen(DOCTEST_OPTIONS_PREFIX_DISPLAY)); + printVersion(); + // clang-format off + s << Color::Cyan << "[doctest]\n" << Color::None; + s << Color::Cyan << "[doctest] " << Color::None; + s << "boolean values: \"1/on/yes/true\" or \"0/off/no/false\"\n"; + s << Color::Cyan << "[doctest] " << Color::None; + s << "filter values: \"str1,str2,str3\" (comma separated strings)\n"; + s << Color::Cyan << "[doctest]\n" << Color::None; + s << Color::Cyan << "[doctest] " << Color::None; + s << "filters use wildcards for matching strings\n"; + s << Color::Cyan << "[doctest] " << Color::None; + s << "something passes a filter if any of the strings in a filter matches\n"; +#ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS + s << Color::Cyan << "[doctest]\n" << Color::None; + s << Color::Cyan << "[doctest] " << Color::None; + s << "ALL FLAGS, OPTIONS AND FILTERS ALSO AVAILABLE WITH A \"" DOCTEST_CONFIG_OPTIONS_PREFIX "\" PREFIX!!!\n"; +#endif + s << Color::Cyan << "[doctest]\n" << Color::None; + s << Color::Cyan << "[doctest] " << Color::None; + s << "Query flags - the program quits after them. Available:\n\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "?, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "help, -" DOCTEST_OPTIONS_PREFIX_DISPLAY "h " + << Whitespace(sizePrefixDisplay*0) << "prints this message\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "v, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "version " + << Whitespace(sizePrefixDisplay*1) << "prints the version\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "c, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "count " + << Whitespace(sizePrefixDisplay*1) << "prints the number of matching tests\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ltc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "list-test-cases " + << Whitespace(sizePrefixDisplay*1) << "lists all matching tests by name\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "lts, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "list-test-suites " + << Whitespace(sizePrefixDisplay*1) << "lists all matching test suites\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "lr, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "list-reporters " + << Whitespace(sizePrefixDisplay*1) << "lists all registered reporters\n\n"; + // ================================================================================== << 79 + s << Color::Cyan << "[doctest] " << Color::None; + s << "The available / options/filters are:\n\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "tc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-case= " + << Whitespace(sizePrefixDisplay*1) << "filters tests by their name\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "tce, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-case-exclude= " + << Whitespace(sizePrefixDisplay*1) << "filters OUT tests by their name\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sf, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "source-file= " + << Whitespace(sizePrefixDisplay*1) << "filters tests by their file\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sfe, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "source-file-exclude= " + << Whitespace(sizePrefixDisplay*1) << "filters OUT tests by their file\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ts, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-suite= " + << Whitespace(sizePrefixDisplay*1) << "filters tests by their test suite\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "tse, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-suite-exclude= " + << Whitespace(sizePrefixDisplay*1) << "filters OUT tests by their test suite\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "subcase= " + << Whitespace(sizePrefixDisplay*1) << "filters subcases by their name\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sce, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "subcase-exclude= " + << Whitespace(sizePrefixDisplay*1) << "filters OUT subcases by their name\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "r, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "reporters= " + << Whitespace(sizePrefixDisplay*1) << "reporters to use (console is default)\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "o, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "out= " + << Whitespace(sizePrefixDisplay*1) << "output filename\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ob, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "order-by= " + << Whitespace(sizePrefixDisplay*1) << "how the tests should be ordered\n"; + s << Whitespace(sizePrefixDisplay*3) << " - [file/suite/name/rand/none]\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "rs, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "rand-seed= " + << Whitespace(sizePrefixDisplay*1) << "seed for random ordering\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "f, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "first= " + << Whitespace(sizePrefixDisplay*1) << "the first test passing the filters to\n"; + s << Whitespace(sizePrefixDisplay*3) << " execute - for range-based execution\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "l, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "last= " + << Whitespace(sizePrefixDisplay*1) << "the last test passing the filters to\n"; + s << Whitespace(sizePrefixDisplay*3) << " execute - for range-based execution\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "aa, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "abort-after= " + << Whitespace(sizePrefixDisplay*1) << "stop after failed assertions\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "scfl,--" DOCTEST_OPTIONS_PREFIX_DISPLAY "subcase-filter-levels= " + << Whitespace(sizePrefixDisplay*1) << "apply filters for the first levels\n"; + s << Color::Cyan << "\n[doctest] " << Color::None; + s << "Bool options - can be used like flags and true is assumed. Available:\n\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "s, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "success= " + << Whitespace(sizePrefixDisplay*1) << "include successful assertions in output\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "cs, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "case-sensitive= " + << Whitespace(sizePrefixDisplay*1) << "filters being treated as case sensitive\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "e, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "exit= " + << Whitespace(sizePrefixDisplay*1) << "exits after the tests finish\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "d, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "duration= " + << Whitespace(sizePrefixDisplay*1) << "prints the time duration of each test\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "m, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "minimal= " + << Whitespace(sizePrefixDisplay*1) << "minimal console output (only failures)\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "q, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "quiet= " + << Whitespace(sizePrefixDisplay*1) << "no console output\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nt, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-throw= " + << Whitespace(sizePrefixDisplay*1) << "skips exceptions-related assert checks\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ne, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-exitcode= " + << Whitespace(sizePrefixDisplay*1) << "returns (or exits) always with success\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nr, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-run= " + << Whitespace(sizePrefixDisplay*1) << "skips all runtime doctest operations\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ni, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-intro= " + << Whitespace(sizePrefixDisplay*1) << "omit the framework intro in the output\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nv, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-version= " + << Whitespace(sizePrefixDisplay*1) << "omit the framework version in the output\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-colors= " + << Whitespace(sizePrefixDisplay*1) << "disables colors in output\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "fc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "force-colors= " + << Whitespace(sizePrefixDisplay*1) << "use colors even when not in a tty\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nb, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-breaks= " + << Whitespace(sizePrefixDisplay*1) << "disables breakpoints in debuggers\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ns, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-skip= " + << Whitespace(sizePrefixDisplay*1) << "don't skip test cases marked as skip\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "gfl, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "gnu-file-line= " + << Whitespace(sizePrefixDisplay*1) << ":n: vs (n): for line numbers in output\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "npf, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-path-filenames= " + << Whitespace(sizePrefixDisplay*1) << "only filenames and no paths in output\n"; + s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nln, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-line-numbers= " + << Whitespace(sizePrefixDisplay*1) << "0 instead of real line numbers in output\n"; + // ================================================================================== << 79 + // clang-format on + + s << Color::Cyan << "\n[doctest] " << Color::None; + s << "for more information visit the project documentation\n\n"; + } + + void printRegisteredReporters() { + printVersion(); + auto printReporters = [this] (const reporterMap& reporters, const char* type) { + if(reporters.size()) { + s << Color::Cyan << "[doctest] " << Color::None << "listing all registered " << type << "\n"; + for(auto& curr : reporters) + s << "priority: " << std::setw(5) << curr.first.first + << " name: " << curr.first.second << "\n"; + } + }; + printReporters(getListeners(), "listeners"); + printReporters(getReporters(), "reporters"); + } + + // ========================================================================================= + // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE + // ========================================================================================= + + void report_query(const QueryData& in) override { + if(opt.version) { + printVersion(); + } else if(opt.help) { + printHelp(); + } else if(opt.list_reporters) { + printRegisteredReporters(); + } else if(opt.count || opt.list_test_cases) { + if(opt.list_test_cases) { + s << Color::Cyan << "[doctest] " << Color::None + << "listing all test case names\n"; + separator_to_stream(); + } + + for(unsigned i = 0; i < in.num_data; ++i) + s << Color::None << in.data[i]->m_name << "\n"; + + separator_to_stream(); + + s << Color::Cyan << "[doctest] " << Color::None + << "unskipped test cases passing the current filters: " + << g_cs->numTestCasesPassingFilters << "\n"; + + } else if(opt.list_test_suites) { + s << Color::Cyan << "[doctest] " << Color::None << "listing all test suites\n"; + separator_to_stream(); + + for(unsigned i = 0; i < in.num_data; ++i) + s << Color::None << in.data[i]->m_test_suite << "\n"; + + separator_to_stream(); + + s << Color::Cyan << "[doctest] " << Color::None + << "unskipped test cases passing the current filters: " + << g_cs->numTestCasesPassingFilters << "\n"; + s << Color::Cyan << "[doctest] " << Color::None + << "test suites with unskipped test cases passing the current filters: " + << g_cs->numTestSuitesPassingFilters << "\n"; + } + } + + void test_run_start() override { + if(!opt.minimal) + printIntro(); + } + + void test_run_end(const TestRunStats& p) override { + if(opt.minimal && p.numTestCasesFailed == 0) + return; + + separator_to_stream(); + s << std::dec; + + auto totwidth = int(std::ceil(log10(static_cast(std::max(p.numTestCasesPassingFilters, static_cast(p.numAsserts))) + 1))); + auto passwidth = int(std::ceil(log10(static_cast(std::max(p.numTestCasesPassingFilters - p.numTestCasesFailed, static_cast(p.numAsserts - p.numAssertsFailed))) + 1))); + auto failwidth = int(std::ceil(log10(static_cast(std::max(p.numTestCasesFailed, static_cast(p.numAssertsFailed))) + 1))); + const bool anythingFailed = p.numTestCasesFailed > 0 || p.numAssertsFailed > 0; + s << Color::Cyan << "[doctest] " << Color::None << "test cases: " << std::setw(totwidth) + << p.numTestCasesPassingFilters << " | " + << ((p.numTestCasesPassingFilters == 0 || anythingFailed) ? Color::None : + Color::Green) + << std::setw(passwidth) << p.numTestCasesPassingFilters - p.numTestCasesFailed << " passed" + << Color::None << " | " << (p.numTestCasesFailed > 0 ? Color::Red : Color::None) + << std::setw(failwidth) << p.numTestCasesFailed << " failed" << Color::None << " |"; + if(opt.no_skipped_summary == false) { + const int numSkipped = p.numTestCases - p.numTestCasesPassingFilters; + s << " " << (numSkipped == 0 ? Color::None : Color::Yellow) << numSkipped + << " skipped" << Color::None; + } + s << "\n"; + s << Color::Cyan << "[doctest] " << Color::None << "assertions: " << std::setw(totwidth) + << p.numAsserts << " | " + << ((p.numAsserts == 0 || anythingFailed) ? Color::None : Color::Green) + << std::setw(passwidth) << (p.numAsserts - p.numAssertsFailed) << " passed" << Color::None + << " | " << (p.numAssertsFailed > 0 ? Color::Red : Color::None) << std::setw(failwidth) + << p.numAssertsFailed << " failed" << Color::None << " |\n"; + s << Color::Cyan << "[doctest] " << Color::None + << "Status: " << (p.numTestCasesFailed > 0 ? Color::Red : Color::Green) + << ((p.numTestCasesFailed > 0) ? "FAILURE!" : "SUCCESS!") << Color::None << std::endl; + } + + void test_case_start(const TestCaseData& in) override { + hasLoggedCurrentTestStart = false; + tc = ∈ + subcasesStack.clear(); + currentSubcaseLevel = 0; + } + + void test_case_reenter(const TestCaseData&) override { + subcasesStack.clear(); + } + + void test_case_end(const CurrentTestCaseStats& st) override { + if(tc->m_no_output) + return; + + // log the preamble of the test case only if there is something + // else to print - something other than that an assert has failed + if(opt.duration || + (st.failure_flags && st.failure_flags != static_cast(TestCaseFailureReason::AssertFailure))) + logTestStart(); + + if(opt.duration) + s << Color::None << std::setprecision(6) << std::fixed << st.seconds + << " s: " << tc->m_name << "\n"; + + if(st.failure_flags & TestCaseFailureReason::Timeout) + s << Color::Red << "Test case exceeded time limit of " << std::setprecision(6) + << std::fixed << tc->m_timeout << "!\n"; + + if(st.failure_flags & TestCaseFailureReason::ShouldHaveFailedButDidnt) { + s << Color::Red << "Should have failed but didn't! Marking it as failed!\n"; + } else if(st.failure_flags & TestCaseFailureReason::ShouldHaveFailedAndDid) { + s << Color::Yellow << "Failed as expected so marking it as not failed\n"; + } else if(st.failure_flags & TestCaseFailureReason::CouldHaveFailedAndDid) { + s << Color::Yellow << "Allowed to fail so marking it as not failed\n"; + } else if(st.failure_flags & TestCaseFailureReason::DidntFailExactlyNumTimes) { + s << Color::Red << "Didn't fail exactly " << tc->m_expected_failures + << " times so marking it as failed!\n"; + } else if(st.failure_flags & TestCaseFailureReason::FailedExactlyNumTimes) { + s << Color::Yellow << "Failed exactly " << tc->m_expected_failures + << " times as expected so marking it as not failed!\n"; + } + if(st.failure_flags & TestCaseFailureReason::TooManyFailedAsserts) { + s << Color::Red << "Aborting - too many failed asserts!\n"; + } + s << Color::None; // lgtm [cpp/useless-expression] + } + + void test_case_exception(const TestCaseException& e) override { + DOCTEST_LOCK_MUTEX(mutex) + if(tc->m_no_output) + return; + + logTestStart(); + + file_line_to_stream(tc->m_file.c_str(), tc->m_line, " "); + successOrFailColoredStringToStream(false, e.is_crash ? assertType::is_require : + assertType::is_check); + s << Color::Red << (e.is_crash ? "test case CRASHED: " : "test case THREW exception: ") + << Color::Cyan << e.error_string << "\n"; + + int num_stringified_contexts = get_num_stringified_contexts(); + if(num_stringified_contexts) { + auto stringified_contexts = get_stringified_contexts(); + s << Color::None << " logged: "; + for(int i = num_stringified_contexts; i > 0; --i) { + s << (i == num_stringified_contexts ? "" : " ") + << stringified_contexts[i - 1] << "\n"; + } + } + s << "\n" << Color::None; + } + + void subcase_start(const SubcaseSignature& subc) override { + subcasesStack.push_back(subc); + ++currentSubcaseLevel; + hasLoggedCurrentTestStart = false; + } + + void subcase_end() override { + --currentSubcaseLevel; + hasLoggedCurrentTestStart = false; + } + + void log_assert(const AssertData& rb) override { + if((!rb.m_failed && !opt.success) || tc->m_no_output) + return; + + DOCTEST_LOCK_MUTEX(mutex) + + logTestStart(); + + file_line_to_stream(rb.m_file, rb.m_line, " "); + successOrFailColoredStringToStream(!rb.m_failed, rb.m_at); + + fulltext_log_assert_to_stream(s, rb); + + log_contexts(); + } + + void log_message(const MessageData& mb) override { + if(tc->m_no_output) + return; + + DOCTEST_LOCK_MUTEX(mutex) + + logTestStart(); + + file_line_to_stream(mb.m_file, mb.m_line, " "); + s << getSuccessOrFailColor(false, mb.m_severity) + << getSuccessOrFailString(mb.m_severity & assertType::is_warn, mb.m_severity, + "MESSAGE") << ": "; + s << Color::None << mb.m_string << "\n"; + log_contexts(); + } + + void test_case_skipped(const TestCaseData&) override {} + }; + + DOCTEST_REGISTER_REPORTER("console", 0, ConsoleReporter); + +#ifdef DOCTEST_PLATFORM_WINDOWS + struct DebugOutputWindowReporter : public ConsoleReporter + { + DOCTEST_THREAD_LOCAL static std::ostringstream oss; + + DebugOutputWindowReporter(const ContextOptions& co) + : ConsoleReporter(co, oss) {} + +#define DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(func, type, arg) \ + void func(type arg) override { \ + bool with_col = g_no_colors; \ + g_no_colors = false; \ + ConsoleReporter::func(arg); \ + if(oss.tellp() != std::streampos{}) { \ + DOCTEST_OUTPUT_DEBUG_STRING(oss.str().c_str()); \ + oss.str(""); \ + } \ + g_no_colors = with_col; \ + } + + DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_run_start, DOCTEST_EMPTY, DOCTEST_EMPTY) + DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_run_end, const TestRunStats&, in) + DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_start, const TestCaseData&, in) + DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_reenter, const TestCaseData&, in) + DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_end, const CurrentTestCaseStats&, in) + DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_exception, const TestCaseException&, in) + DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(subcase_start, const SubcaseSignature&, in) + DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(subcase_end, DOCTEST_EMPTY, DOCTEST_EMPTY) + DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(log_assert, const AssertData&, in) + DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(log_message, const MessageData&, in) + DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_skipped, const TestCaseData&, in) + }; + + DOCTEST_THREAD_LOCAL std::ostringstream DebugOutputWindowReporter::oss; +#endif // DOCTEST_PLATFORM_WINDOWS + + // the implementation of parseOption() + bool parseOptionImpl(int argc, const char* const* argv, const char* pattern, String* value) { + // going from the end to the beginning and stopping on the first occurrence from the end + for(int i = argc; i > 0; --i) { + auto index = i - 1; + auto temp = std::strstr(argv[index], pattern); + if(temp && (value || strlen(temp) == strlen(pattern))) { //!OCLINT prefer early exits and continue + // eliminate matches in which the chars before the option are not '-' + bool noBadCharsFound = true; + auto curr = argv[index]; + while(curr != temp) { + if(*curr++ != '-') { + noBadCharsFound = false; + break; + } + } + if(noBadCharsFound && argv[index][0] == '-') { + if(value) { + // parsing the value of an option + temp += strlen(pattern); + const unsigned len = strlen(temp); + if(len) { + *value = temp; + return true; + } + } else { + // just a flag - no value + return true; + } + } + } + } + return false; + } + + // parses an option and returns the string after the '=' character + bool parseOption(int argc, const char* const* argv, const char* pattern, String* value = nullptr, + const String& defaultVal = String()) { + if(value) + *value = defaultVal; +#ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS + // offset (normally 3 for "dt-") to skip prefix + if(parseOptionImpl(argc, argv, pattern + strlen(DOCTEST_CONFIG_OPTIONS_PREFIX), value)) + return true; +#endif // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS + return parseOptionImpl(argc, argv, pattern, value); + } + + // locates a flag on the command line + bool parseFlag(int argc, const char* const* argv, const char* pattern) { + return parseOption(argc, argv, pattern); + } + + // parses a comma separated list of words after a pattern in one of the arguments in argv + bool parseCommaSepArgs(int argc, const char* const* argv, const char* pattern, + std::vector& res) { + String filtersString; + if(parseOption(argc, argv, pattern, &filtersString)) { + // tokenize with "," as a separator, unless escaped with backslash + std::ostringstream s; + auto flush = [&s, &res]() { + auto string = s.str(); + if(string.size() > 0) { + res.push_back(string.c_str()); + } + s.str(""); + }; + + bool seenBackslash = false; + const char* current = filtersString.c_str(); + const char* end = current + strlen(current); + while(current != end) { + char character = *current++; + if(seenBackslash) { + seenBackslash = false; + if(character == ',' || character == '\\') { + s.put(character); + continue; + } + s.put('\\'); + } + if(character == '\\') { + seenBackslash = true; + } else if(character == ',') { + flush(); + } else { + s.put(character); + } + } + + if(seenBackslash) { + s.put('\\'); + } + flush(); + return true; + } + return false; + } + + enum optionType + { + option_bool, + option_int + }; + + // parses an int/bool option from the command line + bool parseIntOption(int argc, const char* const* argv, const char* pattern, optionType type, + int& res) { + String parsedValue; + if(!parseOption(argc, argv, pattern, &parsedValue)) + return false; + + if(type) { + // integer + // TODO: change this to use std::stoi or something else! currently it uses undefined behavior - assumes '0' on failed parse... + int theInt = std::atoi(parsedValue.c_str()); + if (theInt != 0) { + res = theInt; //!OCLINT parameter reassignment + return true; + } + } else { + // boolean + const char positive[][5] = { "1", "true", "on", "yes" }; // 5 - strlen("true") + 1 + const char negative[][6] = { "0", "false", "off", "no" }; // 6 - strlen("false") + 1 + + // if the value matches any of the positive/negative possibilities + for (unsigned i = 0; i < 4; i++) { + if (parsedValue.compare(positive[i], true) == 0) { + res = 1; //!OCLINT parameter reassignment + return true; + } + if (parsedValue.compare(negative[i], true) == 0) { + res = 0; //!OCLINT parameter reassignment + return true; + } + } + } + return false; + } +} // namespace + +Context::Context(int argc, const char* const* argv) + : p(new detail::ContextState) { + parseArgs(argc, argv, true); + if(argc) + p->binary_name = argv[0]; +} + +Context::~Context() { + if(g_cs == p) + g_cs = nullptr; + delete p; +} + +void Context::applyCommandLine(int argc, const char* const* argv) { + parseArgs(argc, argv); + if(argc) + p->binary_name = argv[0]; +} + +// parses args +void Context::parseArgs(int argc, const char* const* argv, bool withDefaults) { + using namespace detail; + + // clang-format off + parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "source-file=", p->filters[0]); + parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sf=", p->filters[0]); + parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "source-file-exclude=",p->filters[1]); + parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sfe=", p->filters[1]); + parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-suite=", p->filters[2]); + parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "ts=", p->filters[2]); + parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-suite-exclude=", p->filters[3]); + parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "tse=", p->filters[3]); + parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-case=", p->filters[4]); + parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "tc=", p->filters[4]); + parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-case-exclude=", p->filters[5]); + parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "tce=", p->filters[5]); + parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "subcase=", p->filters[6]); + parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sc=", p->filters[6]); + parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "subcase-exclude=", p->filters[7]); + parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sce=", p->filters[7]); + parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "reporters=", p->filters[8]); + parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "r=", p->filters[8]); + // clang-format on + + int intRes = 0; + String strRes; + +#define DOCTEST_PARSE_AS_BOOL_OR_FLAG(name, sname, var, default) \ + if(parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", option_bool, intRes) || \ + parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", option_bool, intRes)) \ + p->var = static_cast(intRes); \ + else if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name) || \ + parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname)) \ + p->var = true; \ + else if(withDefaults) \ + p->var = default + +#define DOCTEST_PARSE_INT_OPTION(name, sname, var, default) \ + if(parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", option_int, intRes) || \ + parseIntOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", option_int, intRes)) \ + p->var = intRes; \ + else if(withDefaults) \ + p->var = default + +#define DOCTEST_PARSE_STR_OPTION(name, sname, var, default) \ + if(parseOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name "=", &strRes, default) || \ + parseOption(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", &strRes, default) || \ + withDefaults) \ + p->var = strRes + + // clang-format off + DOCTEST_PARSE_STR_OPTION("out", "o", out, ""); + DOCTEST_PARSE_STR_OPTION("order-by", "ob", order_by, "file"); + DOCTEST_PARSE_INT_OPTION("rand-seed", "rs", rand_seed, 0); + + DOCTEST_PARSE_INT_OPTION("first", "f", first, 0); + DOCTEST_PARSE_INT_OPTION("last", "l", last, UINT_MAX); + + DOCTEST_PARSE_INT_OPTION("abort-after", "aa", abort_after, 0); + DOCTEST_PARSE_INT_OPTION("subcase-filter-levels", "scfl", subcase_filter_levels, INT_MAX); + + DOCTEST_PARSE_AS_BOOL_OR_FLAG("success", "s", success, false); + DOCTEST_PARSE_AS_BOOL_OR_FLAG("case-sensitive", "cs", case_sensitive, false); + DOCTEST_PARSE_AS_BOOL_OR_FLAG("exit", "e", exit, false); + DOCTEST_PARSE_AS_BOOL_OR_FLAG("duration", "d", duration, false); + DOCTEST_PARSE_AS_BOOL_OR_FLAG("minimal", "m", minimal, false); + DOCTEST_PARSE_AS_BOOL_OR_FLAG("quiet", "q", quiet, false); + DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-throw", "nt", no_throw, false); + DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-exitcode", "ne", no_exitcode, false); + DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-run", "nr", no_run, false); + DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-intro", "ni", no_intro, false); + DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-version", "nv", no_version, false); + DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-colors", "nc", no_colors, false); + DOCTEST_PARSE_AS_BOOL_OR_FLAG("force-colors", "fc", force_colors, false); + DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-breaks", "nb", no_breaks, false); + DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-skip", "ns", no_skip, false); + DOCTEST_PARSE_AS_BOOL_OR_FLAG("gnu-file-line", "gfl", gnu_file_line, !bool(DOCTEST_MSVC)); + DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-path-filenames", "npf", no_path_in_filenames, false); + DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-line-numbers", "nln", no_line_numbers, false); + DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-debug-output", "ndo", no_debug_output, false); + DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-skipped-summary", "nss", no_skipped_summary, false); + DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-time-in-output", "ntio", no_time_in_output, false); + // clang-format on + + if(withDefaults) { + p->help = false; + p->version = false; + p->count = false; + p->list_test_cases = false; + p->list_test_suites = false; + p->list_reporters = false; + } + if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "help") || + parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "h") || + parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "?")) { + p->help = true; + p->exit = true; + } + if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "version") || + parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "v")) { + p->version = true; + p->exit = true; + } + if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "count") || + parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "c")) { + p->count = true; + p->exit = true; + } + if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "list-test-cases") || + parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "ltc")) { + p->list_test_cases = true; + p->exit = true; + } + if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "list-test-suites") || + parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "lts")) { + p->list_test_suites = true; + p->exit = true; + } + if(parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "list-reporters") || + parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "lr")) { + p->list_reporters = true; + p->exit = true; + } +} + +// allows the user to add procedurally to the filters from the command line +void Context::addFilter(const char* filter, const char* value) { setOption(filter, value); } + +// allows the user to clear all filters from the command line +void Context::clearFilters() { + for(auto& curr : p->filters) + curr.clear(); +} + +// allows the user to override procedurally the bool options from the command line +void Context::setOption(const char* option, bool value) { + setOption(option, value ? "true" : "false"); +} + +// allows the user to override procedurally the int options from the command line +void Context::setOption(const char* option, int value) { + setOption(option, toString(value).c_str()); +} + +// allows the user to override procedurally the string options from the command line +void Context::setOption(const char* option, const char* value) { + auto argv = String("-") + option + "=" + value; + auto lvalue = argv.c_str(); + parseArgs(1, &lvalue); +} + +// users should query this in their main() and exit the program if true +bool Context::shouldExit() { return p->exit; } + +void Context::setAsDefaultForAssertsOutOfTestCases() { g_cs = p; } + +void Context::setAssertHandler(detail::assert_handler ah) { p->ah = ah; } + +void Context::setCout(std::ostream* out) { p->cout = out; } + +static class DiscardOStream : public std::ostream +{ +private: + class : public std::streambuf + { + private: + // allowing some buffering decreases the amount of calls to overflow + char buf[1024]; + + protected: + std::streamsize xsputn(const char_type*, std::streamsize count) override { return count; } + + int_type overflow(int_type ch) override { + setp(std::begin(buf), std::end(buf)); + return traits_type::not_eof(ch); + } + } discardBuf; + +public: + DiscardOStream() + : std::ostream(&discardBuf) {} +} discardOut; + +// the main function that does all the filtering and test running +int Context::run() { + using namespace detail; + + // save the old context state in case such was setup - for using asserts out of a testing context + auto old_cs = g_cs; + // this is the current contest + g_cs = p; + is_running_in_test = true; + + g_no_colors = p->no_colors; + p->resetRunData(); + + std::fstream fstr; + if(p->cout == nullptr) { + if(p->quiet) { + p->cout = &discardOut; + } else if(p->out.size()) { + // to a file if specified + fstr.open(p->out.c_str(), std::fstream::out); + p->cout = &fstr; + } else { +#ifndef DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM + // stdout by default + p->cout = &std::cout; +#else // DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM + return EXIT_FAILURE; +#endif // DOCTEST_CONFIG_NO_INCLUDE_IOSTREAM + } + } + + FatalConditionHandler::allocateAltStackMem(); + + auto cleanup_and_return = [&]() { + FatalConditionHandler::freeAltStackMem(); + + if(fstr.is_open()) + fstr.close(); + + // restore context + g_cs = old_cs; + is_running_in_test = false; + + // we have to free the reporters which were allocated when the run started + for(auto& curr : p->reporters_currently_used) + delete curr; + p->reporters_currently_used.clear(); + + if(p->numTestCasesFailed && !p->no_exitcode) + return EXIT_FAILURE; + return EXIT_SUCCESS; + }; + + // setup default reporter if none is given through the command line + if(p->filters[8].empty()) + p->filters[8].push_back("console"); + + // check to see if any of the registered reporters has been selected + for(auto& curr : getReporters()) { + if(matchesAny(curr.first.second.c_str(), p->filters[8], false, p->case_sensitive)) + p->reporters_currently_used.push_back(curr.second(*g_cs)); + } + + // TODO: check if there is nothing in reporters_currently_used + + // prepend all listeners + for(auto& curr : getListeners()) + p->reporters_currently_used.insert(p->reporters_currently_used.begin(), curr.second(*g_cs)); + +#ifdef DOCTEST_PLATFORM_WINDOWS + if(isDebuggerActive() && p->no_debug_output == false) + p->reporters_currently_used.push_back(new DebugOutputWindowReporter(*g_cs)); +#endif // DOCTEST_PLATFORM_WINDOWS + + // handle version, help and no_run + if(p->no_run || p->version || p->help || p->list_reporters) { + DOCTEST_ITERATE_THROUGH_REPORTERS(report_query, QueryData()); + + return cleanup_and_return(); + } + + std::vector testArray; + for(auto& curr : getRegisteredTests()) + testArray.push_back(&curr); + p->numTestCases = testArray.size(); + + // sort the collected records + if(!testArray.empty()) { + if(p->order_by.compare("file", true) == 0) { + std::sort(testArray.begin(), testArray.end(), fileOrderComparator); + } else if(p->order_by.compare("suite", true) == 0) { + std::sort(testArray.begin(), testArray.end(), suiteOrderComparator); + } else if(p->order_by.compare("name", true) == 0) { + std::sort(testArray.begin(), testArray.end(), nameOrderComparator); + } else if(p->order_by.compare("rand", true) == 0) { + std::srand(p->rand_seed); + + // random_shuffle implementation + const auto first = &testArray[0]; + for(size_t i = testArray.size() - 1; i > 0; --i) { + int idxToSwap = std::rand() % (i + 1); + + const auto temp = first[i]; + + first[i] = first[idxToSwap]; + first[idxToSwap] = temp; + } + } else if(p->order_by.compare("none", true) == 0) { + // means no sorting - beneficial for death tests which call into the executable + // with a specific test case in mind - we don't want to slow down the startup times + } + } + + std::set testSuitesPassingFilt; + + bool query_mode = p->count || p->list_test_cases || p->list_test_suites; + std::vector queryResults; + + if(!query_mode) + DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_start, DOCTEST_EMPTY); + + // invoke the registered functions if they match the filter criteria (or just count them) + for(auto& curr : testArray) { + const auto& tc = *curr; + + bool skip_me = false; + if(tc.m_skip && !p->no_skip) + skip_me = true; + + if(!matchesAny(tc.m_file.c_str(), p->filters[0], true, p->case_sensitive)) + skip_me = true; + if(matchesAny(tc.m_file.c_str(), p->filters[1], false, p->case_sensitive)) + skip_me = true; + if(!matchesAny(tc.m_test_suite, p->filters[2], true, p->case_sensitive)) + skip_me = true; + if(matchesAny(tc.m_test_suite, p->filters[3], false, p->case_sensitive)) + skip_me = true; + if(!matchesAny(tc.m_name, p->filters[4], true, p->case_sensitive)) + skip_me = true; + if(matchesAny(tc.m_name, p->filters[5], false, p->case_sensitive)) + skip_me = true; + + if(!skip_me) + p->numTestCasesPassingFilters++; + + // skip the test if it is not in the execution range + if((p->last < p->numTestCasesPassingFilters && p->first <= p->last) || + (p->first > p->numTestCasesPassingFilters)) + skip_me = true; + + if(skip_me) { + if(!query_mode) + DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_skipped, tc); + continue; + } + + // do not execute the test if we are to only count the number of filter passing tests + if(p->count) + continue; + + // print the name of the test and don't execute it + if(p->list_test_cases) { + queryResults.push_back(&tc); + continue; + } + + // print the name of the test suite if not done already and don't execute it + if(p->list_test_suites) { + if((testSuitesPassingFilt.count(tc.m_test_suite) == 0) && tc.m_test_suite[0] != '\0') { + queryResults.push_back(&tc); + testSuitesPassingFilt.insert(tc.m_test_suite); + p->numTestSuitesPassingFilters++; + } + continue; + } + + // execute the test if it passes all the filtering + { + p->currentTest = &tc; + + p->failure_flags = TestCaseFailureReason::None; + p->seconds = 0; + + // reset atomic counters + p->numAssertsFailedCurrentTest_atomic = 0; + p->numAssertsCurrentTest_atomic = 0; + + p->fullyTraversedSubcases.clear(); + + DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_start, tc); + + p->timer.start(); + + bool run_test = true; + + do { + // reset some of the fields for subcases (except for the set of fully passed ones) + p->reachedLeaf = false; + // May not be empty if previous subcase exited via exception. + p->subcaseStack.clear(); + p->currentSubcaseDepth = 0; + + p->shouldLogCurrentException = true; + + // reset stuff for logging with INFO() + p->stringifiedContexts.clear(); + +#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS + try { +#endif // DOCTEST_CONFIG_NO_EXCEPTIONS +// MSVC 2015 diagnoses fatalConditionHandler as unused (because reset() is a static method) +DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4101) // unreferenced local variable + FatalConditionHandler fatalConditionHandler; // Handle signals + // execute the test + tc.m_test(); + fatalConditionHandler.reset(); +DOCTEST_MSVC_SUPPRESS_WARNING_POP +#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS + } catch(const TestFailureException&) { + p->failure_flags |= TestCaseFailureReason::AssertFailure; + } catch(...) { + DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_exception, + {translateActiveException(), false}); + p->failure_flags |= TestCaseFailureReason::Exception; + } +#endif // DOCTEST_CONFIG_NO_EXCEPTIONS + + // exit this loop if enough assertions have failed - even if there are more subcases + if(p->abort_after > 0 && + p->numAssertsFailed + p->numAssertsFailedCurrentTest_atomic >= p->abort_after) { + run_test = false; + p->failure_flags |= TestCaseFailureReason::TooManyFailedAsserts; + } + + if(!p->nextSubcaseStack.empty() && run_test) + DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_reenter, tc); + if(p->nextSubcaseStack.empty()) + run_test = false; + } while(run_test); + + p->finalizeTestCaseData(); + + DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_end, *g_cs); + + p->currentTest = nullptr; + + // stop executing tests if enough assertions have failed + if(p->abort_after > 0 && p->numAssertsFailed >= p->abort_after) + break; + } + } + + if(!query_mode) { + DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_end, *g_cs); + } else { + QueryData qdata; + qdata.run_stats = g_cs; + qdata.data = queryResults.data(); + qdata.num_data = unsigned(queryResults.size()); + DOCTEST_ITERATE_THROUGH_REPORTERS(report_query, qdata); + } + + return cleanup_and_return(); +} + +DOCTEST_DEFINE_INTERFACE(IReporter) + +int IReporter::get_num_active_contexts() { return detail::g_infoContexts.size(); } +const IContextScope* const* IReporter::get_active_contexts() { + return get_num_active_contexts() ? &detail::g_infoContexts[0] : nullptr; +} + +int IReporter::get_num_stringified_contexts() { return detail::g_cs->stringifiedContexts.size(); } +const String* IReporter::get_stringified_contexts() { + return get_num_stringified_contexts() ? &detail::g_cs->stringifiedContexts[0] : nullptr; +} + +namespace detail { + void registerReporterImpl(const char* name, int priority, reporterCreatorFunc c, bool isReporter) { + if(isReporter) + getReporters().insert(reporterMap::value_type(reporterMap::key_type(priority, name), c)); + else + getListeners().insert(reporterMap::value_type(reporterMap::key_type(priority, name), c)); + } +} // namespace detail + +} // namespace doctest + +#endif // DOCTEST_CONFIG_DISABLE + +#ifdef DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN +DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4007) // 'function' : must be 'attribute' - see issue #182 +int main(int argc, char** argv) { return doctest::Context(argc, argv).run(); } +DOCTEST_MSVC_SUPPRESS_WARNING_POP +#endif // DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN + +DOCTEST_CLANG_SUPPRESS_WARNING_POP +DOCTEST_MSVC_SUPPRESS_WARNING_POP +DOCTEST_GCC_SUPPRESS_WARNING_POP + +DOCTEST_SUPPRESS_COMMON_WARNINGS_POP + +#endif // DOCTEST_LIBRARY_IMPLEMENTATION +#endif // DOCTEST_CONFIG_IMPLEMENT + +#ifdef DOCTEST_UNDEF_WIN32_LEAN_AND_MEAN +#undef WIN32_LEAN_AND_MEAN +#undef DOCTEST_UNDEF_WIN32_LEAN_AND_MEAN +#endif // DOCTEST_UNDEF_WIN32_LEAN_AND_MEAN + +#ifdef DOCTEST_UNDEF_NOMINMAX +#undef NOMINMAX +#undef DOCTEST_UNDEF_NOMINMAX +#endif // DOCTEST_UNDEF_NOMINMAX From 235533d9fa3bbf0654af415506587863620072e1 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Sun, 12 May 2024 00:45:45 +0200 Subject: [PATCH 02/15] WIP --- tests/CMakeLists.txt | 2 +- tests/t00002/test_case.h | 204 +--- tests/t00003/test_case.h | 138 +-- tests/t00004/test_case.h | 117 +- tests/t00005/test_case.h | 142 +-- tests/t00006/test_case.h | 165 +-- tests/t00007/test_case.h | 62 +- tests/t00008/test_case.h | 102 +- tests/t00009/test_case.h | 94 +- tests/t00010/test_case.h | 73 +- tests/t00011/test_case.h | 57 +- tests/t00012/test_case.h | 69 +- tests/t00013/test_case.h | 120 +- tests/t00014/test_case.h | 528 ++++---- tests/t00015/test_case.h | 53 +- tests/t00016/test_case.h | 85 +- tests/t00017/test_case.h | 148 +-- tests/t00018/test_case.h | 54 +- tests/t00019/test_case.h | 116 +- tests/t00020/test_case.h | 101 +- tests/t00021/test_case.h | 57 +- tests/t00022/test_case.h | 45 +- tests/t00023/test_case.h | 46 +- tests/t00024/test_case.h | 61 +- tests/t00025/test_case.h | 86 +- tests/t00026/test_case.h | 59 +- tests/t00027/test_case.h | 29 +- tests/t00028/test_case.h | 161 ++- tests/t00029/test_case.h | 81 +- tests/t00030/test_case.h | 67 +- tests/t30001/test_case.h | 127 +- tests/t30002/test_case.h | 308 +++-- tests/t30003/test_case.h | 69 +- tests/t30004/test_case.h | 19 +- tests/t30005/test_case.h | 24 +- tests/t30006/test_case.h | 17 +- tests/t30007/test_case.h | 93 +- tests/t30008/test_case.h | 136 ++- tests/t30009/test_case.h | 103 +- tests/t30010/test_case.h | 109 +- tests/t30011/test_case.h | 118 +- tests/t30012/test_case.h | 15 +- tests/t30013/test_case.h | 276 +++-- tests/t30014/test_case.h | 15 +- tests/t30015/test_case.h | 283 +++-- tests/t40001/test_case.h | 102 +- tests/t40002/test_case.h | 180 +-- tests/t40003/test_case.h | 88 +- tests/test_cases.cc | 735 ++++++++++- tests/test_cases.h | 1819 +++++++++++++++++++++++++++- tests/test_thread_pool_executor.cc | 6 +- tests/test_util.cc | 33 +- 52 files changed, 4641 insertions(+), 3156 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3ce15f5f..dec53b5c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -102,7 +102,7 @@ foreach(TEST_NAME ${TEST_NAMES}) target_sources(${TEST_NAME} PUBLIC FILE_SET CXX_MODULES FILES ${TEST_CASE_MODULE_SOURCES}) endif(ENABLE_CXX_MODULES_TEST_CASES) - target_sources(${TEST_NAME} PUBLIC ${TEST_NAME}.cc + target_sources(${TEST_NAME} PUBLIC ${TEST_NAME}.cc test_cases_checks.h ${TEST_CASE_SOURCES} catch.h) else() target_sources(${TEST_NAME} PUBLIC ${TEST_NAME}.cc catch.h) diff --git a/tests/t00002/test_case.h b/tests/t00002/test_case.h index 9235c7af..463c0675 100644 --- a/tests/t00002/test_case.h +++ b/tests/t00002/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00002/test_case.cc + * tests/t00002/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,11 +16,10 @@ * limitations under the License. */ -#include "../test_cases.h" - TEST_CASE("t00002") { using namespace clanguml::test; + using namespace std::string_literals; auto [config, db] = load_config("t00002"); @@ -40,158 +39,69 @@ TEST_CASE("t00002") REQUIRE(!model->should_include({"std"}, "vector")); CHECK_CLASS_DIAGRAM( - diagram, *model, + config, diagram, *model, // Common test case for all diagram types [](const auto &src) { + REQUIRE(HasTitle(src, "Basic class diagram example")); + REQUIRE(!IsClass(src, "NOSUCHCLASS")); - REQUIRE(IsClass(src, "A")); + REQUIRE(IsAbstractClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClass(src, "C")); + REQUIRE(IsClass(src, "D")); + REQUIRE(IsBaseClass(src, "A", "B")); + REQUIRE(IsBaseClass(src, "A", "C")); + REQUIRE(IsBaseClass(src, "B", "D")); + REQUIRE(IsBaseClass(src, "C", "D")); + + REQUIRE(IsMethod(src, "A", "foo_a")); + REQUIRE(IsMethod(src, "C", "foo_c")); + + REQUIRE(IsAssociation(src, "D", "A", "as")); + + REQUIRE(HasNote(src, "A", "left", "This is class A")); + REQUIRE(HasNote(src, "B", "top", "This is class B")); + + REQUIRE(HasLink(src, "A", + fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" + "t00002/t00002.cc#L7", + clanguml::util::get_git_commit()), + "This is class A")); + + REQUIRE(HasLink(src, "B", + fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" + "t00002/t00002.cc#L16", + clanguml::util::get_git_commit()), + "This is class B")); + + REQUIRE(HasMemberLink(src, "+foo_a() : void", + fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" + "t00002/t00002.cc#L18", + clanguml::util::get_git_commit()), + "foo_a")); + + REQUIRE(HasMemberLink(src, "-as : std::vector", + fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" + "t00002/t00002.cc#L83", + clanguml::util::get_git_commit()), + "as")); + }, + // Specific test case only for PlantUML diagram + [](const plantuml_t &src) { + REQUIRE(StartsWith(src, "@startuml"s)); + REQUIRE(EndsWith(src, "@enduml\n"s)); }, // Specific test case only for JSON diagram [](const json_t &src) { const auto &A = get_element(src, "A"); - CHECK(A.has_value()); + REQUIRE(A.has_value()); - CHECK(A.value()["type"] == "class"); - CHECK(A.value()["name"] == "A"); - CHECK(A.value()["display_name"] == "A"); - CHECK(A.value()["namespace"] == "clanguml::t00002"); - CHECK(A.value()["source_location"]["file"] == "t00002.cc"); - CHECK(A.value()["source_location"]["line"] == 7); + REQUIRE(A.value()["type"] == "class"); + REQUIRE(A.value()["name"] == "A"); + REQUIRE(A.value()["display_name"] == "A"); + REQUIRE(A.value()["namespace"] == "clanguml::t00002"); + REQUIRE(A.value()["source_location"]["file"] == "t00002.cc"); + REQUIRE(A.value()["source_location"]["line"] == 7); }); - - // auto src = render_class_diagram(diagram, *model); - - /* - - - { - auto puml = generate_class_puml(diagram, *model); - AliasMatcher _A(puml); - - REQUIRE_THAT(puml, StartsWith("@startuml")); - REQUIRE_THAT(puml, EndsWith("@enduml\n")); - REQUIRE_THAT(puml, HasTitle("Basic class diagram example")); - REQUIRE_THAT(puml, IsAbstractClass(_A("A"))); - REQUIRE_THAT(puml, IsClass(_A("B"))); - REQUIRE_THAT(puml, IsClass(_A("C"))); - REQUIRE_THAT(puml, IsClass(_A("D"))); - REQUIRE_THAT(puml, IsBaseClass(_A("A"), _A("B"))); - REQUIRE_THAT(puml, IsBaseClass(_A("A"), _A("C"))); - REQUIRE_THAT(puml, IsBaseClass(_A("B"), _A("D"))); - REQUIRE_THAT(puml, IsBaseClass(_A("C"), _A("D"))); - REQUIRE_THAT(puml, (IsMethod("foo_a"))); - REQUIRE_THAT(puml, (IsMethod("foo_c"))); - - REQUIRE_THAT(puml, IsAssociation(_A("D"), _A("A"), "-as")); - - REQUIRE_THAT(puml, HasNote(_A("A"), "left", "This is class A")); - REQUIRE_THAT(puml, HasNote(_A("B"), "top", "This is class B")); - - REQUIRE_THAT(puml, - HasLink(_A("A"), - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t00002/t00002.cc#L7", - clanguml::util::get_git_commit()), - "This is class A")); - - REQUIRE_THAT(puml, - HasLink(_A("B"), - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t00002/t00002.cc#L16", - clanguml::util::get_git_commit()), - "This is class B")); - - REQUIRE_THAT(puml, - HasMemberLink("+foo_a() : void", - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t00002/t00002.cc#L18", - clanguml::util::get_git_commit()), - "foo_a")); - - REQUIRE_THAT(puml, - HasMemberLink("-as : std::vector", - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t00002/t00002.cc#L83", - clanguml::util::get_git_commit()), - "as")); - - save_puml(config.output_directory(), diagram->name + ".puml", puml); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - const auto &A = get_element(j, "A"); - - CHECK(A.has_value()); - - CHECK(A.value()["type"] == "class"); - CHECK(A.value()["name"] == "A"); - CHECK(A.value()["display_name"] == "A"); - CHECK(A.value()["namespace"] == "clanguml::t00002"); - CHECK(A.value()["source_location"]["file"] == "t00002.cc"); - CHECK(A.value()["source_location"]["line"] == 7); - - REQUIRE(HasTitle(j, "Basic class diagram example")); - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - REQUIRE(IsClass(j, "C")); - REQUIRE(IsBaseClass(j, "A", "B")); - REQUIRE(IsBaseClass(j, "A", "C")); - REQUIRE(IsBaseClass(j, "B", "D")); - REQUIRE(IsBaseClass(j, "C", "D")); - REQUIRE(IsMethod(j, "A", "foo_a")); - REQUIRE(IsMethod(j, "C", "foo_c")); - REQUIRE(IsField(j, "E", "as", "std::vector")); - REQUIRE(IsAssociation(j, "D", "A", "as")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto mmd = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(mmd); - using mermaid::HasNote; - using mermaid::HasTitle; - using mermaid::IsAbstractClass; - - REQUIRE_THAT(mmd, HasTitle("Basic class diagram example")); - REQUIRE_THAT(mmd, Contains("classDiagram")); - REQUIRE_THAT(mmd, IsAbstractClass(_A("A"))); - REQUIRE_THAT(mmd, IsClass(_A("B"))); - REQUIRE_THAT(mmd, IsClass(_A("C"))); - REQUIRE_THAT(mmd, IsClass(_A("D"))); - REQUIRE_THAT(mmd, IsBaseClass(_A("A"), _A("B"))); - REQUIRE_THAT(mmd, IsBaseClass(_A("A"), _A("C"))); - REQUIRE_THAT(mmd, IsBaseClass(_A("B"), _A("D"))); - REQUIRE_THAT(mmd, IsBaseClass(_A("C"), _A("D"))); - - REQUIRE_THAT(mmd, IsAssociation(_A("D"), _A("A"), "-as")); - - REQUIRE_THAT(mmd, (mermaid::IsMethod("foo_a"))); - REQUIRE_THAT(mmd, (mermaid::IsMethod("foo_c"))); - - REQUIRE_THAT(mmd, HasNote(_A("A"), "left", "This is class A")); - REQUIRE_THAT(mmd, HasNote(_A("B"), "top", "This is class B")); - - REQUIRE_THAT(mmd, - mermaid::HasLink(_A("A"), - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t00002/t00002.cc#L7", - clanguml::util::get_git_commit()), - "This is class A")); - - REQUIRE_THAT(mmd, - mermaid::HasLink(_A("B"), - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t00002/t00002.cc#L16", - clanguml::util::get_git_commit()), - "This is class B")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - mmd); - } - */ } \ No newline at end of file diff --git a/tests/t00003/test_case.h b/tests/t00003/test_case.h index 9fc98f5a..64f4eae0 100644 --- a/tests/t00003/test_case.h +++ b/tests/t00003/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00003/test_case.cc + * tests/t00003/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,13 @@ * limitations under the License. */ -TEST_CASE("t00003", "[test-case][class]") +// #include "../test_cases.h" + +TEST_CASE("t00003") { + using namespace clanguml::test; + using namespace std::string_literals; + auto [config, db] = load_config("t00003"); auto diagram = config.diagrams["t00003_class"]; @@ -32,111 +37,40 @@ TEST_CASE("t00003", "[test-case][class]") REQUIRE(model->name() == "t00003_class"); - { - auto puml = generate_class_puml(diagram, *model); - AliasMatcher _A(puml); + CHECK_CLASS_DIAGRAM(config, diagram, *model, + [](const auto &src) { + REQUIRE(IsClass(src, "A")); - REQUIRE_THAT(puml, StartsWith("@startuml")); - REQUIRE_THAT(puml, EndsWith("@enduml\n")); - REQUIRE_THAT(puml, IsClass(_A("A"))); + REQUIRE(!IsDependency(src, "A", "A")); - REQUIRE_THAT(puml, !IsDependency(_A("A"), _A("A"))); + REQUIRE(IsMethod(src, "A", "A")); + REQUIRE(IsMethod(src, "A", "A", "void", "A &&")); + REQUIRE( + IsMethod(src, "A", "A", "void", "const A &")); - REQUIRE_THAT(puml, (IsMethod("A"))); - REQUIRE_THAT(puml, (IsMethod("A", "void", "A &&"))); - REQUIRE_THAT( - puml, (IsMethod("A", "void", "const A &"))); + REQUIRE(IsMethod(src, "A", "~A")); - REQUIRE_THAT(puml, (IsMethod("~A"))); + REQUIRE(IsMethod(src, "A", "basic_method")); + REQUIRE(IsMethod(src, "A", "static_method", "int")); + REQUIRE(IsMethod(src, "A", "const_method")); + REQUIRE( + IsMethod(src, "A", "default_int", "int", "int i = 12")); + REQUIRE(IsMethod(src, "A", "default_string", "std::string", + "int i, std::string s = \"abc\"")); - REQUIRE_THAT(puml, (IsMethod("basic_method"))); - REQUIRE_THAT(puml, (IsMethod("static_method", "int"))); - REQUIRE_THAT(puml, (IsMethod("const_method"))); - REQUIRE_THAT( - puml, (IsMethod("default_int", "int", "int i = 12"))); - REQUIRE_THAT(puml, - (IsMethod("default_string", "std::string", - "int i, std::string s = \"abc\""))); + REQUIRE(IsMethod( + src, "A", "size", "std::size_t")); - REQUIRE_THAT( - puml, (IsMethod("size", "std::size_t"))); + REQUIRE(IsMethod(src, "A", "protected_method")); + REQUIRE(IsMethod(src, "A", "private_method")); + REQUIRE(IsField(src, "A", "public_member", "int")); + REQUIRE(IsField(src, "A", "protected_member", "int")); + REQUIRE(IsField(src, "A", "private_member", "int")); + REQUIRE(IsField( + src, "A", "auto_member", "const unsigned long")); - REQUIRE_THAT(puml, (IsMethod("protected_method"))); - REQUIRE_THAT(puml, (IsMethod("private_method"))); - REQUIRE_THAT(puml, (IsField("public_member", "int"))); - REQUIRE_THAT(puml, (IsField("protected_member", "int"))); - REQUIRE_THAT(puml, (IsField("private_member", "int"))); - REQUIRE_THAT(puml, - (IsField("auto_member", "const unsigned long"))); - - REQUIRE_THAT(puml, (IsField("a_", "int"))); - REQUIRE_THAT(puml, (IsField("b_", "int"))); - REQUIRE_THAT(puml, (IsField("c_", "int"))); - - save_puml(config.output_directory(), diagram->name + ".puml", puml); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsMethod(j, "A", "A")); - REQUIRE(IsMethod(j, "A", "~A")); - REQUIRE(IsMethod(j, "A", "basic_method")); - REQUIRE(IsMethod(j, "A", "static_method")); - REQUIRE(IsMethod(j, "A", "const_method")); - REQUIRE(IsMethod(j, "A", "default_int")); - REQUIRE(IsMethod(j, "A", "default_string")); - - REQUIRE(!IsDependency(j, "A", "A")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto mmd = generate_class_mermaid(diagram, *model); - mermaid::AliasMatcher _A(mmd); - - REQUIRE_THAT(mmd, IsClass(_A("A"))); - - REQUIRE_THAT(mmd, !IsDependency(_A("A"), _A("A"))); - - REQUIRE_THAT(mmd, (mermaid::IsMethod("A"))); - REQUIRE_THAT( - mmd, (mermaid::IsMethod("A", "void", "A &&"))); - REQUIRE_THAT(mmd, - (mermaid::IsMethod("A", "void", "const A &"))); - - REQUIRE_THAT(mmd, (mermaid::IsMethod("~A"))); - - REQUIRE_THAT(mmd, (mermaid::IsMethod("basic_method"))); - REQUIRE_THAT( - mmd, (mermaid::IsMethod("static_method", "int"))); - REQUIRE_THAT(mmd, (mermaid::IsMethod("const_method"))); - REQUIRE_THAT(mmd, - (mermaid::IsMethod("default_int", "int", "int i = 12"))); - REQUIRE_THAT(mmd, - (mermaid::IsMethod("default_string", "std::string", - "int i, std::string s = \"abc\""))); - - REQUIRE_THAT(mmd, - (mermaid::IsMethod( - "size", "std::size_t"))); - - REQUIRE_THAT(mmd, (mermaid::IsMethod("protected_method"))); - REQUIRE_THAT(mmd, (mermaid::IsMethod("private_method"))); - - REQUIRE_THAT(mmd, (IsField("public_member", "int"))); - REQUIRE_THAT(mmd, (IsField("protected_member", "int"))); - REQUIRE_THAT(mmd, (IsField("private_member", "int"))); - REQUIRE_THAT(mmd, - (IsField("auto_member", "const unsigned long"))); - - REQUIRE_THAT(mmd, (IsField("a_", "int"))); - REQUIRE_THAT(mmd, (IsField("b_", "int"))); - REQUIRE_THAT(mmd, (IsField("c_", "int"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", mmd); - } + REQUIRE(IsField(src, "A", "a_", "int")); + REQUIRE(IsField(src, "A", "b_", "int")); + REQUIRE(IsField(src, "A", "c_", "int")); + }); } \ No newline at end of file diff --git a/tests/t00004/test_case.h b/tests/t00004/test_case.h index 1cf42b89..71a24a4a 100644 --- a/tests/t00004/test_case.h +++ b/tests/t00004/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00004/test_case.cc + * tests/t00004/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00004", "[test-case][class]") +TEST_CASE("t00004") { + using namespace clanguml::test; + auto [config, db] = load_config("t00004"); auto diagram = config.diagrams["t00004_class"]; @@ -31,94 +33,33 @@ TEST_CASE("t00004", "[test-case][class]") REQUIRE(model->name() == "t00004_class"); - { - auto puml = generate_class_puml(diagram, *model); - AliasMatcher _A(puml); + CHECK_CLASS_DIAGRAM(config, diagram, *model, + [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "A::AA")); + REQUIRE(IsClass(src, "A::AA::AAA")); + REQUIRE(IsEnum(src, "B::AA")); + REQUIRE(IsEnum(src, "A::AA::Lights")); + REQUIRE(IsInnerClass(src, "A", "A::AA")); + REQUIRE(IsInnerClass(src, "A::AA", "A::AA::AAA")); + REQUIRE(IsInnerClass(src, "A::AA", "A::AA::Lights")); - REQUIRE_THAT(puml, StartsWith("@startuml")); - REQUIRE_THAT(puml, EndsWith("@enduml\n")); - REQUIRE_THAT(puml, IsClass(_A("A"))); - REQUIRE_THAT(puml, IsClass(_A("A::AA"))); - REQUIRE_THAT(puml, IsClass(_A("A::AA::AAA"))); - REQUIRE_THAT(puml, IsEnum(_A("B::AA"))); - REQUIRE_THAT(puml, IsEnum(_A("A::AA::Lights"))); - REQUIRE_THAT(puml, IsInnerClass(_A("A"), _A("A::AA"))); - REQUIRE_THAT(puml, IsInnerClass(_A("A::AA"), _A("A::AA::AAA"))); - REQUIRE_THAT(puml, IsInnerClass(_A("A::AA"), _A("A::AA::Lights"))); + REQUIRE(IsMethod(src, "A", "foo")); + REQUIRE(IsMethod(src, "A", "foo2")); - REQUIRE_THAT(puml, (IsMethod("foo"))); - REQUIRE_THAT(puml, (IsMethod("foo2"))); + REQUIRE(IsClassTemplate(src, "C")); + REQUIRE(IsInnerClass(src, "C", "C::AA")); + REQUIRE(IsInnerClass(src, "C::AA", "C::AA::AAA")); + REQUIRE(IsInnerClass(src, "C", "C::CC")); + REQUIRE(IsInnerClass(src, "C::AA", "C::AA::CCC")); - REQUIRE_THAT(puml, IsClassTemplate("C", "T")); - REQUIRE_THAT(puml, IsInnerClass(_A("C"), _A("C::AA"))); - REQUIRE_THAT(puml, IsInnerClass(_A("C::AA"), _A("C::AA::AAA"))); - REQUIRE_THAT(puml, IsInnerClass(_A("C"), _A("C::CC"))); - REQUIRE_THAT(puml, IsInnerClass(_A("C::AA"), _A("C::AA::CCC"))); + REQUIRE(IsInnerClass(src, "C", "C::B")); + REQUIRE(IsAggregation(src, "C", "C::B", "b_int")); + REQUIRE(!IsInnerClass(src, "C", "C::B")); + REQUIRE(IsInstantiation(src, "C::B", "C::B")); - REQUIRE_THAT(puml, IsInnerClass(_A("C"), _A("C::B"))); - REQUIRE_THAT( - puml, IsAggregation(_A("C"), _A("C::B"), "+b_int")); - REQUIRE_THAT(puml, !IsInnerClass(_A("C"), _A("C::B"))); - REQUIRE_THAT(puml, IsInstantiation(_A("C::B"), _A("C::B"))); - - REQUIRE_THAT(puml, IsClass(_A("detail::D"))); - REQUIRE_THAT(puml, IsClass(_A("detail::D::DD"))); - REQUIRE_THAT(puml, IsEnum(_A("detail::D::AA"))); - - save_puml(config.output_directory(), diagram->name + ".puml", puml); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "A::AA")); - REQUIRE(IsClass(j, "A::AA::AAA")); - REQUIRE(IsEnum(j, "B::AA")); - REQUIRE(IsEnum(j, "A::AA::Lights")); - REQUIRE(IsInnerClass(j, "A", "A::AA")); - REQUIRE(IsInnerClass(j, "A::AA", "A::AA::AAA")); - REQUIRE(IsInnerClass(j, "A::AA", "A::AA::Lights")); - - REQUIRE(IsClassTemplate(j, "C")); - - REQUIRE(IsClass(j, "detail::D")); - REQUIRE(IsClass(j, "detail::D::DD")); - REQUIRE(IsEnum(j, "detail::D::AA")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto mmd = generate_class_mermaid(diagram, *model); - mermaid::AliasMatcher _A(mmd); - - REQUIRE_THAT(mmd, IsClass(_A("A"))); - REQUIRE_THAT(mmd, IsClass(_A("A::AA"))); - REQUIRE_THAT(mmd, IsClass(_A("A::AA::AAA"))); - REQUIRE_THAT(mmd, mermaid::IsEnum(_A("B::AA"))); - REQUIRE_THAT(mmd, mermaid::IsEnum(_A("A::AA::Lights"))); - REQUIRE_THAT(mmd, mermaid::IsInnerClass(_A("A"), _A("A::AA"))); - REQUIRE_THAT(mmd, mermaid::IsInnerClass(_A("A::AA"), _A("A::AA::AAA"))); - REQUIRE_THAT( - mmd, mermaid::IsInnerClass(_A("A::AA"), _A("A::AA::Lights"))); - - REQUIRE_THAT(mmd, IsClass(_A("C"))); - REQUIRE_THAT(mmd, mermaid::IsInnerClass(_A("C"), _A("C::AA"))); - REQUIRE_THAT(mmd, mermaid::IsInnerClass(_A("C::AA"), _A("C::AA::AAA"))); - REQUIRE_THAT(mmd, mermaid::IsInnerClass(_A("C"), _A("C::CC"))); - REQUIRE_THAT(mmd, mermaid::IsInnerClass(_A("C::AA"), _A("C::AA::CCC"))); - - REQUIRE_THAT(mmd, mermaid::IsInnerClass(_A("C"), _A("C::B"))); - REQUIRE_THAT(mmd, IsAggregation(_A("C"), _A("C::B"), "+b_int")); - REQUIRE_THAT(mmd, !mermaid::IsInnerClass(_A("C"), _A("C::B"))); - REQUIRE_THAT(mmd, IsInstantiation(_A("C::B"), _A("C::B"))); - - REQUIRE_THAT(mmd, IsClass(_A("detail::D"))); - REQUIRE_THAT(mmd, IsClass(_A("detail::D::DD"))); - REQUIRE_THAT(mmd, mermaid::IsEnum(_A("detail::D::AA"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", mmd); - } + REQUIRE(IsClass(src, "detail::D")); + REQUIRE(IsClass(src, "detail::D::DD")); + REQUIRE(IsEnum(src, "detail::D::AA")); + }); } \ No newline at end of file diff --git a/tests/t00005/test_case.h b/tests/t00005/test_case.h index b759a51f..1a6a5aff 100644 --- a/tests/t00005/test_case.h +++ b/tests/t00005/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00005/test_case.cc + * tests/t00005/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00005", "[test-case][class]") +TEST_CASE("t00005") { + using namespace clanguml::test; + auto [config, db] = load_config("t00005"); auto diagram = config.diagrams["t00005_class"]; @@ -28,112 +30,36 @@ TEST_CASE("t00005", "[test-case][class]") REQUIRE(model->name() == "t00005_class"); - { - auto puml = generate_class_puml(diagram, *model); - AliasMatcher _A(puml); + CHECK_CLASS_DIAGRAM(config, diagram, *model, + [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClass(src, "C")); + REQUIRE(IsClass(src, "D")); + REQUIRE(IsClass(src, "E")); + REQUIRE(IsClass(src, "F")); + REQUIRE(IsClass(src, "G")); + REQUIRE(IsClass(src, "H")); + REQUIRE(IsClass(src, "I")); + REQUIRE(IsClass(src, "J")); + REQUIRE(IsClass(src, "K")); + REQUIRE(IsClass(src, "R")); - REQUIRE_THAT(puml, StartsWith("@startuml")); - REQUIRE_THAT(puml, EndsWith("@enduml\n")); - REQUIRE_THAT(puml, IsClass(_A("A"))); - REQUIRE_THAT(puml, IsClass(_A("B"))); - REQUIRE_THAT(puml, IsClass(_A("C"))); - REQUIRE_THAT(puml, IsClass(_A("D"))); - REQUIRE_THAT(puml, IsClass(_A("E"))); - REQUIRE_THAT(puml, IsClass(_A("F"))); - REQUIRE_THAT(puml, IsClass(_A("G"))); - REQUIRE_THAT(puml, IsClass(_A("H"))); - REQUIRE_THAT(puml, IsClass(_A("I"))); - REQUIRE_THAT(puml, IsClass(_A("J"))); - REQUIRE_THAT(puml, IsClass(_A("K"))); - REQUIRE_THAT(puml, IsClass(_A("R"))); + REQUIRE((IsField(src, "R", "some_int", "int"))); + REQUIRE((IsField(src, "R", "some_int_pointer", "int *"))); + REQUIRE((IsField( + src, "R", "some_int_pointer_pointer", "int **"))); - REQUIRE_THAT(puml, (IsField("some_int", "int"))); - REQUIRE_THAT(puml, (IsField("some_int_pointer", "int *"))); - REQUIRE_THAT( - puml, (IsField("some_int_pointer_pointer", "int **"))); - - REQUIRE_THAT(puml, IsAggregation(_A("R"), _A("A"), "+a")); - REQUIRE_THAT(puml, IsAssociation(_A("R"), _A("B"), "+b")); - REQUIRE_THAT(puml, IsAssociation(_A("R"), _A("C"), "+c")); - REQUIRE_THAT(puml, IsAssociation(_A("R"), _A("D"), "+d")); - REQUIRE_THAT(puml, IsAssociation(_A("R"), _A("E"), "+e")); - REQUIRE_THAT(puml, IsAggregation(_A("R"), _A("F"), "+f")); - REQUIRE_THAT(puml, IsAssociation(_A("R"), _A("G"), "+g")); - REQUIRE_THAT(puml, IsAssociation(_A("R"), _A("H"), "+h")); - REQUIRE_THAT(puml, IsAssociation(_A("R"), _A("I"), "+i")); - REQUIRE_THAT(puml, IsAssociation(_A("R"), _A("J"), "+j")); - REQUIRE_THAT(puml, IsAssociation(_A("R"), _A("K"), "+k")); - - save_puml(config.output_directory(), diagram->name + ".puml", puml); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - REQUIRE(IsClass(j, "C")); - REQUIRE(IsClass(j, "D")); - REQUIRE(IsClass(j, "E")); - REQUIRE(IsClass(j, "F")); - REQUIRE(IsClass(j, "G")); - REQUIRE(IsClass(j, "H")); - REQUIRE(IsClass(j, "I")); - REQUIRE(IsClass(j, "J")); - REQUIRE(IsClass(j, "K")); - REQUIRE(IsClass(j, "R")); - - REQUIRE(IsAggregation(j, "R", "A", "a")); - REQUIRE(IsAssociation(j, "R", "B", "b")); - REQUIRE(IsAssociation(j, "R", "C", "c")); - REQUIRE(IsAssociation(j, "R", "D", "d")); - REQUIRE(IsAssociation(j, "R", "E", "e")); - REQUIRE(IsAggregation(j, "R", "F", "f")); - REQUIRE(IsAssociation(j, "R", "G", "g")); - REQUIRE(IsAssociation(j, "R", "H", "h")); - REQUIRE(IsAssociation(j, "R", "I", "i")); - REQUIRE(IsAssociation(j, "R", "J", "j")); - REQUIRE(IsAssociation(j, "R", "K", "k")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto mmd = generate_class_mermaid(diagram, *model); - mermaid::AliasMatcher _A(mmd); - - REQUIRE_THAT(mmd, StartsWith("classDiagram")); - REQUIRE_THAT(mmd, IsClass(_A("A"))); - REQUIRE_THAT(mmd, IsClass(_A("B"))); - REQUIRE_THAT(mmd, IsClass(_A("C"))); - REQUIRE_THAT(mmd, IsClass(_A("D"))); - REQUIRE_THAT(mmd, IsClass(_A("E"))); - REQUIRE_THAT(mmd, IsClass(_A("F"))); - REQUIRE_THAT(mmd, IsClass(_A("G"))); - REQUIRE_THAT(mmd, IsClass(_A("H"))); - REQUIRE_THAT(mmd, IsClass(_A("I"))); - REQUIRE_THAT(mmd, IsClass(_A("J"))); - REQUIRE_THAT(mmd, IsClass(_A("K"))); - REQUIRE_THAT(mmd, IsClass(_A("R"))); - - REQUIRE_THAT(mmd, (IsField("some_int", "int"))); - REQUIRE_THAT(mmd, (IsField("some_int_pointer", "int *"))); - REQUIRE_THAT( - mmd, (IsField("some_int_pointer_pointer", "int **"))); - - REQUIRE_THAT(mmd, IsAggregation(_A("R"), _A("A"), "+a")); - REQUIRE_THAT(mmd, IsAssociation(_A("R"), _A("B"), "+b")); - REQUIRE_THAT(mmd, IsAssociation(_A("R"), _A("C"), "+c")); - REQUIRE_THAT(mmd, IsAssociation(_A("R"), _A("D"), "+d")); - REQUIRE_THAT(mmd, IsAssociation(_A("R"), _A("E"), "+e")); - REQUIRE_THAT(mmd, IsAggregation(_A("R"), _A("F"), "+f")); - REQUIRE_THAT(mmd, IsAssociation(_A("R"), _A("G"), "+g")); - REQUIRE_THAT(mmd, IsAssociation(_A("R"), _A("H"), "+h")); - REQUIRE_THAT(mmd, IsAssociation(_A("R"), _A("I"), "+i")); - REQUIRE_THAT(mmd, IsAssociation(_A("R"), _A("J"), "+j")); - REQUIRE_THAT(mmd, IsAssociation(_A("R"), _A("K"), "+k")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", mmd); - } + REQUIRE(IsAggregation(src, "R", "A", "a")); + REQUIRE(IsAssociation(src, "R", "B", "b")); + REQUIRE(IsAssociation(src, "R", "C", "c")); + REQUIRE(IsAssociation(src, "R", "D", "d")); + REQUIRE(IsAssociation(src, "R", "E", "e")); + REQUIRE(IsAggregation(src, "R", "F", "f")); + REQUIRE(IsAssociation(src, "R", "G", "g")); + REQUIRE(IsAssociation(src, "R", "H", "h")); + REQUIRE(IsAssociation(src, "R", "I", "i")); + REQUIRE(IsAssociation(src, "R", "J", "j")); + REQUIRE(IsAssociation(src, "R", "K", "k")); + }); } \ No newline at end of file diff --git a/tests/t00006/test_case.h b/tests/t00006/test_case.h index 7757aa7f..15372092 100644 --- a/tests/t00006/test_case.h +++ b/tests/t00006/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00006/test_case.cc + * tests/t00006/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00006", "[test-case][class]") +TEST_CASE("t00006") { + using namespace clanguml::test; + auto [config, db] = load_config("t00006"); auto diagram = config.diagrams["t00006_class"]; @@ -28,127 +30,44 @@ TEST_CASE("t00006", "[test-case][class]") REQUIRE(model->name() == "t00006_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, + [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClass(src, "C")); + REQUIRE(IsClass(src, "D")); + REQUIRE(IsClass(src, "E")); + REQUIRE(IsClass(src, "F")); + REQUIRE(IsClass(src, "G")); + REQUIRE(IsClass(src, "H")); + REQUIRE(IsClass(src, "I")); + REQUIRE(IsClass(src, "J")); + REQUIRE(IsClass(src, "K")); + REQUIRE(IsClass(src, "L")); + REQUIRE(IsClass(src, "M")); + REQUIRE(IsClass(src, "N")); + REQUIRE(IsClass(src, "NN")); + REQUIRE(IsClass(src, "NNN")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - REQUIRE_THAT(src, IsClass(_A("F"))); - REQUIRE_THAT(src, IsClass(_A("G"))); - REQUIRE_THAT(src, IsClass(_A("H"))); - REQUIRE_THAT(src, IsClass(_A("I"))); - REQUIRE_THAT(src, IsClass(_A("J"))); - REQUIRE_THAT(src, IsClass(_A("K"))); - REQUIRE_THAT(src, IsClass(_A("L"))); - REQUIRE_THAT(src, IsClass(_A("M"))); - REQUIRE_THAT(src, IsClass(_A("N"))); - REQUIRE_THAT(src, IsClass(_A("NN"))); - REQUIRE_THAT(src, IsClass(_A("NNN"))); + REQUIRE(IsInstantiation( + src, "custom_container", "custom_container")); - REQUIRE_THAT(src, - IsInstantiation( - _A("custom_container"), _A("custom_container"))); - - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("A"), "+a")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("B"), "+b")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("C"), "+c")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("D"), "+d")); - REQUIRE_THAT( - src, IsAggregation(_A("R"), _A("custom_container"), "+e")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("F"), "+f")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("G"), "+g")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("H"), "+h")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("I"), "+i")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("J"), "+j")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("K"), "+k")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("L"), "+lm")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("M"), "+lm")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("N"), "+ns")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("NN"), "+ns")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("NNN"), "+ns")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - REQUIRE(IsClass(j, "C")); - REQUIRE(IsClass(j, "D")); - REQUIRE(IsClass(j, "E")); - REQUIRE(IsClass(j, "F")); - REQUIRE(IsClass(j, "G")); - REQUIRE(IsClass(j, "H")); - REQUIRE(IsClass(j, "I")); - REQUIRE(IsClass(j, "J")); - REQUIRE(IsClass(j, "K")); - REQUIRE(IsClass(j, "L")); - REQUIRE(IsClass(j, "M")); - REQUIRE(IsClass(j, "N")); - REQUIRE(IsClass(j, "NN")); - REQUIRE(IsClass(j, "NNN")); - - REQUIRE(IsAggregation(j, "R", "custom_container", "e")); - REQUIRE( - IsInstantiation(j, "custom_container", "custom_container")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - using mermaid::AliasMatcher; - - AliasMatcher _A(src); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - REQUIRE_THAT(src, IsClass(_A("F"))); - REQUIRE_THAT(src, IsClass(_A("G"))); - REQUIRE_THAT(src, IsClass(_A("H"))); - REQUIRE_THAT(src, IsClass(_A("I"))); - REQUIRE_THAT(src, IsClass(_A("J"))); - REQUIRE_THAT(src, IsClass(_A("K"))); - REQUIRE_THAT(src, IsClass(_A("L"))); - REQUIRE_THAT(src, IsClass(_A("M"))); - REQUIRE_THAT(src, IsClass(_A("N"))); - REQUIRE_THAT(src, IsClass(_A("NN"))); - REQUIRE_THAT(src, IsClass(_A("NNN"))); - - REQUIRE_THAT(src, - IsInstantiation( - _A("custom_container"), _A("custom_container"))); - - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("A"), "+a")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("B"), "+b")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("C"), "+c")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("D"), "+d")); - REQUIRE_THAT( - src, IsAggregation(_A("R"), _A("custom_container"), "+e")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("F"), "+f")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("G"), "+g")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("H"), "+h")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("I"), "+i")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("J"), "+j")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("K"), "+k")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("L"), "+lm")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("M"), "+lm")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("N"), "+ns")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("NN"), "+ns")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("NNN"), "+ns")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsAggregation(src, "R", "A", "a")); + REQUIRE(IsAssociation(src, "R", "B", "b")); + REQUIRE(IsAggregation(src, "R", "C", "c")); + REQUIRE(IsAssociation(src, "R", "D", "d")); + REQUIRE( + IsAggregation(src, "R", "custom_container", "e")); + REQUIRE(IsAggregation(src, "R", "F", "f")); + REQUIRE(IsAssociation(src, "R", "G", "g")); + REQUIRE(IsAggregation(src, "R", "H", "h")); + REQUIRE(IsAssociation(src, "R", "I", "i")); + REQUIRE(IsAggregation(src, "R", "J", "j")); + REQUIRE(IsAssociation(src, "R", "K", "k")); + REQUIRE(IsAggregation(src, "R", "L", "lm")); + REQUIRE(IsAggregation(src, "R", "M", "lm")); + REQUIRE(IsAggregation(src, "R", "N", "ns")); + REQUIRE(IsAggregation(src, "R", "NN", "ns")); + REQUIRE(IsAggregation(src, "R", "NNN", "ns")); + }); } \ No newline at end of file diff --git a/tests/t00007/test_case.h b/tests/t00007/test_case.h index 98bf9855..7de1274d 100644 --- a/tests/t00007/test_case.h +++ b/tests/t00007/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00007/test_case.cc + * tests/t00007/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00007", "[test-case][class]") +TEST_CASE("t00007") { + using namespace clanguml::test; + auto [config, db] = load_config("t00007"); auto diagram = config.diagrams["t00007_class"]; @@ -28,52 +30,14 @@ TEST_CASE("t00007", "[test-case][class]") REQUIRE(model->name() == "t00007_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClass(src, "C")); + REQUIRE(IsClass(src, "R")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("A"), "+a")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("B"), "+b")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("C"), "+c")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - REQUIRE(IsClass(j, "C")); - REQUIRE(IsClass(j, "R")); - REQUIRE(IsAggregation(j, "R", "A", "a")); - REQUIRE(IsAssociation(j, "R", "B", "b")); - REQUIRE(IsAssociation(j, "R", "C", "c")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("A"), "+a")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("B"), "+b")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("C"), "+c")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsAggregation(src, "R", "A", "a")); + REQUIRE(IsAssociation(src, "R", "B", "b")); + REQUIRE(IsAssociation(src, "R", "C", "c")); + }); } \ No newline at end of file diff --git a/tests/t00008/test_case.h b/tests/t00008/test_case.h index 480500be..6ca63719 100644 --- a/tests/t00008/test_case.h +++ b/tests/t00008/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00008/test_case.cc + * tests/t00008/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00008", "[test-case][class]") +TEST_CASE("t00008") { + using namespace clanguml::test; + auto [config, db] = load_config("t00008"); auto diagram = config.diagrams["t00008_class"]; @@ -28,73 +30,35 @@ TEST_CASE("t00008", "[test-case][class]") REQUIRE(model->name() == "t00008_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM( + config, diagram, *model, + [](const auto &src) { + // TODO: add option to resolve using declared types + // REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "B>")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - // TODO: add option to resolve using declared types - // REQUIRE_THAT(puml, IsClassTemplate("A", "T, P, bool (*)(int, int), - // int N")); - REQUIRE_THAT(src, IsClassTemplate("A", "T,P=T,CMP=nullptr,int N=3")); - REQUIRE_THAT(src, IsClassTemplate("B", "T,C<>")); + REQUIRE(IsField( + src, "A", "value", "T")); + REQUIRE(IsField( + src, "A", "pointer", "T *")); + REQUIRE(IsField( + src, "A", "reference", "T &")); + REQUIRE(IsField(src, "A", + "values", "std::vector

")); + REQUIRE(IsField(src, "A", "ints", + "std::array")); + // TODO: add option to resolve using declared types + // REQUIRE(IsField(src, Public("bool (*)(int, int) comparator")); + REQUIRE(IsField( + src, "A", "comparator", "CMP")); - REQUIRE_THAT(src, (IsField("value", "T"))); - REQUIRE_THAT(src, (IsField("pointer", "T *"))); - REQUIRE_THAT(src, (IsField("reference", "T &"))); - REQUIRE_THAT(src, (IsField("values", "std::vector

"))); - REQUIRE_THAT(src, (IsField("ints", "std::array"))); - // TODO: add option to resolve using declared types - // REQUIRE_THAT(puml, IsField(Public("bool (*)(int, int) comparator"))); - REQUIRE_THAT(src, (IsField("comparator", "CMP"))); - - REQUIRE_THAT(src, !IsClass(_A("E::nested_template"))); - REQUIRE_THAT(src, IsClassTemplate("E::nested_template", "ET")); - REQUIRE_THAT(src, IsClassTemplate("E::nested_template", "char")); - REQUIRE_THAT(src, - IsInstantiation( - _A("E::nested_template"), _A("E::nested_template"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClassTemplate(j, "A")); - REQUIRE(IsClassTemplate(j, "E::nested_template")); - REQUIRE(IsClass(j, "E::nested_template")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - using mermaid::IsField; - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B>"))); - - REQUIRE_THAT(src, (IsField("value", "T"))); - REQUIRE_THAT(src, (IsField("pointer", "T *"))); - REQUIRE_THAT(src, (IsField("reference", "T &"))); - REQUIRE_THAT(src, (IsField("values", "std::vector

"))); - REQUIRE_THAT(src, (IsField("ints", "std::array"))); - // TODO: add option to resolve using declared types - // REQUIRE_THAT(puml, IsField(Public("bool (*)(int, int) comparator"))); - REQUIRE_THAT(src, (IsField("comparator", "CMP"))); - - REQUIRE_THAT(src, !IsClass(_A("E::nested_template"))); - REQUIRE_THAT(src, IsClass(_A("E::nested_template"))); - REQUIRE_THAT(src, IsClass(_A("E::nested_template"))); - REQUIRE_THAT(src, - IsInstantiation( - _A("E::nested_template"), _A("E::nested_template"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsClassTemplate(src, "E::nested_template")); + REQUIRE(IsClassTemplate(src, "E::nested_template")); + REQUIRE(IsInstantiation( + src, "E::nested_template", "E::nested_template")); + }, + [](const plantuml_t &src) { + REQUIRE(!IsClass(src, "E::nested_template")); + }); } \ No newline at end of file diff --git a/tests/t00009/test_case.h b/tests/t00009/test_case.h index 77885a25..10667f94 100644 --- a/tests/t00009/test_case.h +++ b/tests/t00009/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00009/test_case.cc + * tests/t00009/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00009", "[test-case][class]") +TEST_CASE("t00009") { + using namespace clanguml::test; + auto [config, db] = load_config("t00009"); auto diagram = config.diagrams["t00009_class"]; @@ -28,78 +30,24 @@ TEST_CASE("t00009", "[test-case][class]") REQUIRE(model->name() == "t00009_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClass(src, "B")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsClassTemplate("A", "T")); - REQUIRE_THAT(src, IsClass(_A("B"))); + REQUIRE(IsField(src, "A", "value", "T")); + REQUIRE(IsField(src, "B", "aint", "A")); + REQUIRE(IsField(src, "B", "astring", "A *")); + REQUIRE(IsField( + src, "B", "avector", "A> &")); - REQUIRE_THAT(src, (IsField("value", "T"))); - REQUIRE_THAT(src, (IsField("aint", "A"))); - REQUIRE_THAT(src, (IsField("astring", "A *"))); - REQUIRE_THAT( - src, (IsField("avector", "A> &"))); + REQUIRE(IsInstantiation(src, "A", "A", "up")); + REQUIRE(IsInstantiation(src, "A", "A", "up")); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"), "up")); - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"), "up")); - - REQUIRE_THAT( - src, IsAggregation(_A("B"), _A("A"), "+aint", "", "", "up")); - REQUIRE_THAT(src, - IsAssociation( - _A("B"), _A("A"), "+astring", "", "", "up")); - REQUIRE_THAT(src, - IsAssociation(_A("B"), _A("A>"), - "+avector", "", "", "up")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClassTemplate(j, "A")); - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "A>")); - - REQUIRE(IsField(j, "A", "value", "T")); - REQUIRE(IsField(j, "B", "aint", "A")); - REQUIRE(IsField(j, "B", "astring", "A *")); - REQUIRE(IsField(j, "B", "avector", "A> &")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsField; - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - - REQUIRE_THAT(src, (IsField("value", "T"))); - REQUIRE_THAT(src, (IsField("aint", "A"))); - REQUIRE_THAT(src, (IsField("astring", "A *"))); - REQUIRE_THAT( - src, (IsField("avector", "A> &"))); - - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - - REQUIRE_THAT(src, IsAggregation(_A("B"), _A("A"), "+aint")); - REQUIRE_THAT( - src, IsAssociation(_A("B"), _A("A"), "+astring")); - REQUIRE_THAT(src, - IsAssociation( - _A("B"), _A("A>"), "+avector")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE( + IsAggregation(src, "B", "A", "aint", "", "", "up")); + REQUIRE(IsAssociation( + src, "B", "A", "astring", "", "", "up")); + REQUIRE(IsAssociation( + src, "B", "A>", "avector", "", "", "up")); + }); } \ No newline at end of file diff --git a/tests/t00010/test_case.h b/tests/t00010/test_case.h index 83dca628..e1d15a9c 100644 --- a/tests/t00010/test_case.h +++ b/tests/t00010/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00010/test_case.cc + * tests/t00010/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00010", "[test-case][class]") +TEST_CASE("t00010") { + using namespace clanguml::test; + auto [config, db] = load_config("t00010"); auto diagram = config.diagrams["t00010_class"]; @@ -28,63 +30,18 @@ TEST_CASE("t00010", "[test-case][class]") REQUIRE(model->name() == "t00010_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "B")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsClassTemplate("A", "T,P")); - REQUIRE_THAT(src, IsClassTemplate("B", "T")); + REQUIRE(IsField(src, "B", "astring", "A")); + REQUIRE(IsField(src, "C", "aintstring", "B")); - REQUIRE_THAT(src, (IsField("astring", "A"))); - REQUIRE_THAT(src, (IsField("aintstring", "B"))); + REQUIRE(IsInstantiation(src, "A", "A")); + REQUIRE(IsInstantiation(src, "B", "B")); - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("B"), _A("B"))); - - REQUIRE_THAT( - src, IsAggregation(_A("B"), _A("A"), "+astring")); - REQUIRE_THAT(src, IsAggregation(_A("C"), _A("B"), "+aintstring")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClassTemplate(j, "A")); - REQUIRE(IsClassTemplate(j, "B")); - REQUIRE(IsClass(j, "B")); - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - - REQUIRE(IsField(j, "C", "aintstring", "B")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsField; - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - - REQUIRE_THAT(src, (IsField("astring", "A"))); - REQUIRE_THAT(src, (IsField("aintstring", "B"))); - - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("B"), _A("B"))); - - REQUIRE_THAT( - src, IsAggregation(_A("B"), _A("A"), "+astring")); - REQUIRE_THAT(src, IsAggregation(_A("C"), _A("B"), "+aintstring")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE( + IsAggregation(src, "B", "A", "astring")); + REQUIRE(IsAggregation(src, "C", "B", "aintstring")); + }); } \ No newline at end of file diff --git a/tests/t00011/test_case.h b/tests/t00011/test_case.h index a5c7d53a..115c41e6 100644 --- a/tests/t00011/test_case.h +++ b/tests/t00011/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00011/test_case.cc + * tests/t00011/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00011", "[test-case][class]") +TEST_CASE("t00011") { + using namespace clanguml::test; + auto [config, db] = load_config("t00011"); auto diagram = config.diagrams["t00011_class"]; @@ -28,48 +30,13 @@ TEST_CASE("t00011", "[test-case][class]") REQUIRE(model->name() == "t00011_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(!IsClass(src, "external::C")); + REQUIRE(IsClassTemplate(src, "D")); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, !IsClass(_A("external::C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - - REQUIRE_THAT(src, IsAssociation(_A("B"), _A("A"))); - REQUIRE_THAT(src, IsFriend(_A("A"), _A("B"))); - // REQUIRE_THAT(puml, IsFriend(_A("A"), _A("D"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - REQUIRE(IsClassTemplate(j, "D")); - REQUIRE(IsFriend(j, "A", "B")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsFriend; - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, !IsClass(_A("external::C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - - REQUIRE_THAT(src, IsAssociation(_A("B"), _A("A"))); - REQUIRE_THAT(src, IsFriend(_A("A"), _A("B"))); - // REQUIRE_THAT(src, IsFriend(_A("A"), _A("D"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsAssociation(src, "B", "A")); + REQUIRE(IsFriend(src, "A", "B")); + }); } \ No newline at end of file diff --git a/tests/t00012/test_case.h b/tests/t00012/test_case.h index 8b1a9d6a..b2bba300 100644 --- a/tests/t00012/test_case.h +++ b/tests/t00012/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00012/test_case.cc + * tests/t00012/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00012", "[test-case][class]") +TEST_CASE("t00012") { + using namespace clanguml::test; + auto [config, db] = load_config("t00012"); auto diagram = config.diagrams["t00012_class"]; @@ -28,58 +30,15 @@ TEST_CASE("t00012", "[test-case][class]") REQUIRE(model->name() == "t00012_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "B")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsClassTemplate("A", "T,Ts...")); - REQUIRE_THAT(src, IsClassTemplate("B", "int... Is")); - - REQUIRE_THAT(src, IsInstantiation(_A("B"), _A("B<3,2,1>"))); - REQUIRE_THAT( - src, IsInstantiation(_A("B"), _A("B<1,1,1,1>"))); - REQUIRE_THAT(src, - IsInstantiation(_A("C"), - _A("C>>>,3,3," - "3>"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClassTemplate(j, "A")); - REQUIRE(IsClassTemplate(j, "B")); - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, - "C>>>" - ",3,3,3>")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - - REQUIRE_THAT(src, IsInstantiation(_A("B"), _A("B<3,2,1>"))); - REQUIRE_THAT( - src, IsInstantiation(_A("B"), _A("B<1,1,1,1>"))); - REQUIRE_THAT(src, - IsInstantiation(_A("C"), - _A("C>>>,3,3," - "3>"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsInstantiation(src, "B", "B<3,2,1>")); + REQUIRE(IsInstantiation(src, "B", "B<1,1,1,1>")); + REQUIRE(IsInstantiation(src, "C", + "C>>>,3,3," + "3>")); + }); } \ No newline at end of file diff --git a/tests/t00013/test_case.h b/tests/t00013/test_case.h index f12a999b..f97c1cb8 100644 --- a/tests/t00013/test_case.h +++ b/tests/t00013/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00013/test_case.cc + * tests/t00013/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00013", "[test-case][class]") +TEST_CASE("t00013") { + using namespace clanguml::test; + auto [config, db] = load_config("t00013"); auto diagram = config.diagrams["t00013_class"]; @@ -28,95 +30,29 @@ TEST_CASE("t00013", "[test-case][class]") REQUIRE(model->name() == "t00013_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClass(src, "C")); + REQUIRE(IsClass(src, "D")); + REQUIRE(IsClassTemplate(src, "E")); + REQUIRE(IsClassTemplate(src, "G")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClassTemplate("E", "T")); - REQUIRE_THAT(src, IsClassTemplate("G", "T,Args...")); - - REQUIRE_THAT(src, !IsDependency(_A("R"), _A("R"))); - REQUIRE_THAT(src, IsDependency(_A("R"), _A("A"))); - REQUIRE_THAT(src, IsDependency(_A("R"), _A("B"))); - REQUIRE_THAT(src, IsDependency(_A("R"), _A("C"))); - REQUIRE_THAT(src, IsDependency(_A("R"), _A("D"))); - REQUIRE_THAT(src, IsDependency(_A("D"), _A("R"))); - REQUIRE_THAT(src, IsDependency(_A("R"), _A("E"))); - REQUIRE_THAT(src, IsDependency(_A("R"), _A("E"))); - REQUIRE_THAT(src, IsInstantiation(_A("E"), _A("E"))); - REQUIRE_THAT(src, IsInstantiation(_A("E"), _A("E"))); - REQUIRE_THAT( - src, IsAggregation(_A("R"), _A("E"), "-estring")); - REQUIRE_THAT(src, IsDependency(_A("R"), _A("ABCD::F"))); - REQUIRE_THAT( - src, IsInstantiation(_A("ABCD::F"), _A("ABCD::F"))); - REQUIRE_THAT(src, IsDependency(_A("R"), _A("ABCD::F"))); - - REQUIRE_THAT(src, - IsInstantiation( - _A("G"), _A("G"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - REQUIRE(IsClass(j, "C")); - REQUIRE(IsClass(j, "D")); - REQUIRE(IsInstantiation(j, "E", "E")); - REQUIRE(IsDependency(j, "R", "A")); - REQUIRE(IsDependency(j, "R", "B")); - REQUIRE(IsDependency(j, "R", "C")); - REQUIRE(IsDependency(j, "R", "D")); - REQUIRE(IsDependency(j, "D", "R")); - REQUIRE(IsDependency(j, "R", "E")); - REQUIRE(IsInstantiation(j, "G", "G")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - REQUIRE_THAT(src, IsClass(_A("G"))); - - REQUIRE_THAT(src, !IsDependency(_A("R"), _A("R"))); - REQUIRE_THAT(src, IsDependency(_A("R"), _A("A"))); - REQUIRE_THAT(src, IsDependency(_A("R"), _A("B"))); - REQUIRE_THAT(src, IsDependency(_A("R"), _A("C"))); - REQUIRE_THAT(src, IsDependency(_A("R"), _A("D"))); - REQUIRE_THAT(src, IsDependency(_A("D"), _A("R"))); - REQUIRE_THAT(src, IsDependency(_A("R"), _A("E"))); - REQUIRE_THAT(src, IsDependency(_A("R"), _A("E"))); - REQUIRE_THAT(src, IsInstantiation(_A("E"), _A("E"))); - REQUIRE_THAT(src, IsInstantiation(_A("E"), _A("E"))); - REQUIRE_THAT( - src, IsAggregation(_A("R"), _A("E"), "-estring")); - REQUIRE_THAT(src, IsDependency(_A("R"), _A("ABCD::F"))); - REQUIRE_THAT( - src, IsInstantiation(_A("ABCD::F"), _A("ABCD::F"))); - REQUIRE_THAT(src, IsDependency(_A("R"), _A("ABCD::F"))); - - REQUIRE_THAT(src, - IsInstantiation( - _A("G"), _A("G"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(!IsDependency(src, "R", "R")); + REQUIRE(IsDependency(src, "R", "A")); + REQUIRE(IsDependency(src, "R", "B")); + REQUIRE(IsDependency(src, "R", "C")); + REQUIRE(IsDependency(src, "R", "D")); + REQUIRE(IsDependency(src, "D", "R")); + REQUIRE(IsDependency(src, "R", "E")); + REQUIRE(IsDependency(src, "R", "E")); + REQUIRE(IsInstantiation(src, "E", "E")); + REQUIRE(IsInstantiation(src, "E", "E")); + REQUIRE(IsAggregation(src, "R", "E", "estring")); + REQUIRE(IsDependency(src, "R", "ABCD::F")); + REQUIRE(IsInstantiation(src, "ABCD::F", "ABCD::F")); + REQUIRE(IsDependency(src, "R", "ABCD::F")); + REQUIRE( + IsInstantiation(src, "G", "G")); + }); } \ No newline at end of file diff --git a/tests/t00014/test_case.h b/tests/t00014/test_case.h index 0368ba2d..bc9c1f97 100644 --- a/tests/t00014/test_case.h +++ b/tests/t00014/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00014", "[test-case][class]") +TEST_CASE("t00014") { + using namespace clanguml::test; + auto [config, db] = load_config("t00014"); auto diagram = config.diagrams["t00014_class"]; @@ -28,255 +30,345 @@ TEST_CASE("t00014", "[test-case][class]") REQUIRE(model->name() == "t00014_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(!src.contains("type-parameter-")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, !Contains("type-parameter-")); - - REQUIRE_THAT(src, IsClassTemplate("A", "T,P")); - REQUIRE_THAT(src, IsClassTemplate("A", "T,std::string")); - REQUIRE_THAT( - src, IsClassTemplate("A", "T,std::unique_ptr")); - REQUIRE_THAT(src, IsClassTemplate("A", "double,T")); + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A>")); + REQUIRE(IsClassTemplate(src, "A")); // TODO: Figure out how to handle the same templates with different // template // parameter names - // REQUIRE_THAT(puml, !IsClassTemplate("A", "long,U")); - REQUIRE_THAT(src, IsClassTemplate("A", "long,T")); - REQUIRE_THAT(src, IsClassTemplate("A", "long,bool")); - REQUIRE_THAT(src, IsClassTemplate("A", "double,bool")); - REQUIRE_THAT(src, IsClassTemplate("A", "long,float")); - REQUIRE_THAT(src, IsClassTemplate("A", "double,float")); - REQUIRE_THAT(src, IsClassTemplate("A", "bool,std::string")); - REQUIRE_THAT(src, IsClassTemplate("A", "std::string,std::string")); - REQUIRE_THAT(src, IsClassTemplate("A", "char,std::string")); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClassTemplate("R", "T")); + // REQUIRE(puml, !IsClassTemplate("A", "long,U")); + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClassTemplate(src, "R")); - REQUIRE_THAT(src, IsField("bapair", "PairPairBA")); - REQUIRE_THAT(src, IsField("abool", "APtr")); - REQUIRE_THAT(src, IsField("aboolfloat", "AAPtr")); - REQUIRE_THAT(src, IsField("afloat", "ASharedPtr")); - REQUIRE_THAT( - src, IsField("boolstring", "A")); - REQUIRE_THAT(src, IsField("floatstring", "AStringPtr")); - REQUIRE_THAT(src, IsField("atfloat", "AAPtr")); + REQUIRE(IsField(src, "R", "bapair", "PairPairBA")); + REQUIRE(IsField(src, "R", "abool", "APtr")); + REQUIRE( + IsField(src, "R", "aboolfloat", "AAPtr")); + REQUIRE(IsField(src, "R", "afloat", "ASharedPtr")); + REQUIRE( + IsField(src, "R", "boolstring", "A")); + REQUIRE( + IsField(src, "R", "floatstring", "AStringPtr")); + REQUIRE(IsField(src, "R", "atfloat", "AAPtr")); - REQUIRE_THAT(src, IsField("intstring", "AIntString")); - REQUIRE_THAT(src, IsField("stringstring", "AStringString")); - REQUIRE_THAT(src, IsField("bstringstring", "BStringString")); + REQUIRE(IsField(src, "R", "intstring", "AIntString")); + REQUIRE(IsField(src, "R", "stringstring", "AStringString")); + REQUIRE( + IsField(src, "R", "bstringstring", "BStringString")); - REQUIRE_THAT(src, IsField("bs", "BVector")); + REQUIRE(IsField(src, "R", "bs", "BVector")); - REQUIRE_THAT(src, IsField("cb", "SimpleCallback")); + REQUIRE( + IsField(src, "R", "cb", "SimpleCallback")); #if LLVM_VERSION_MAJOR >= 16 - REQUIRE_THAT( - src, IsField("gcb", "GenericCallback")); + REQUIRE(IsField( + src, "R", "gcb", "GenericCallback")); #else - REQUIRE_THAT( - src, IsField("gcb", "GenericCallback")); + REQUIRE( + IsField(src, "R", "gcb", "GenericCallback")); #endif - REQUIRE_THAT(src, IsField("vcb", "VoidCallback")); + REQUIRE(IsField(src, "R", "vcb", "VoidCallback")); - REQUIRE_THAT( - src, !IsClassTemplate("std::std::function", "void(T...,int),int)")); + REQUIRE( + !IsClassTemplate(src, "std::std::function")); - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); + REQUIRE(IsInstantiation(src, "A", "A")); + REQUIRE(IsInstantiation(src, "A", "A")); + REQUIRE(IsInstantiation(src, "A", "A")); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - // REQUIRE_THAT(puml, !IsInstantiation(_A("A"), + REQUIRE(IsInstantiation(src, "A", "A")); + // REQUIRE(puml, !IsInstantiation(_A("A"), // _A("A"))); - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, - IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, - IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, - IsInstantiation( - _A("A"), _A("A"))); + REQUIRE(IsInstantiation(src, "A", "A")); + REQUIRE(IsInstantiation(src, "A", "A")); + REQUIRE(IsInstantiation(src, "A", "A")); + REQUIRE(IsInstantiation(src, "A", "A")); + REQUIRE( + IsInstantiation(src, "A", "A")); + REQUIRE( + IsInstantiation(src, "A", "A")); + REQUIRE( + IsInstantiation(src, "A", "A")); - REQUIRE_THAT(src, - IsInstantiation(_A("A>"), - _A("A>"))); - REQUIRE_THAT(src, - IsInstantiation( - _A("A"), _A("A>"))); + REQUIRE(IsInstantiation(src, "A>", + "A>")); + REQUIRE(IsInstantiation( + src, "A", "A>")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("B"), "+vps")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("B"), "-bapair")); - REQUIRE_THAT( - src, IsAggregation(_A("R"), _A("A"), "-aboolfloat")); - REQUIRE_THAT( - src, IsAggregation(_A("R"), _A("A"), "-bapair")); - REQUIRE_THAT(src, - IsAggregation(_A("R"), _A("A"), "-aboolfloat")); - REQUIRE_THAT( - src, IsAggregation(_A("R"), _A("A"), "-atfloat")); - REQUIRE_THAT( - src, IsAggregation(_A("R"), _A("A"), "-atfloat")); - REQUIRE_THAT( - src, IsAssociation(_A("R"), _A("A"), "-afloat")); - REQUIRE_THAT(src, - IsAggregation( - _A("R"), _A("A"), "-boolstring")); - REQUIRE_THAT(src, - IsAggregation(_A("R"), - _A("A>"), "-floatstring")); - REQUIRE_THAT(src, IsDependency(_A("R"), _A("A"))); - REQUIRE_THAT( - src, IsDependency(_A("R"), _A("A"))); + REQUIRE(IsAggregation(src, "R", "B", "vps")); + REQUIRE(IsAggregation(src, "R", "B", "bapair")); + REQUIRE( + IsAggregation(src, "R", "A", "aboolfloat")); + REQUIRE(IsAggregation(src, "R", "A", "bapair")); + REQUIRE(IsAggregation( + src, "R", "A", "aboolfloat")); + REQUIRE(IsAggregation(src, "R", "A", "atfloat")); + REQUIRE( + IsAggregation(src, "R", "A", "atfloat")); + REQUIRE( + IsAssociation(src, "R", "A", "afloat")); + REQUIRE(IsAggregation( + src, "R", "A", "boolstring")); + REQUIRE(IsAggregation(src, "R", + "A>", "floatstring")); + REQUIRE(IsDependency(src, "R", "A")); + REQUIRE(IsDependency(src, "R", "A")); + }); + /* + { + auto src = generate_class_puml(diagram, *model); + AliasMatcher _A(src); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - using namespace json; + REQUIRE_THAT(src, !Contains("type-parameter-")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "A>")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "B")); + REQUIRE_THAT(src, IsClassTemplate("A", "T,P")); + REQUIRE_THAT(src, IsClassTemplate("A", "T,std::string")); + REQUIRE_THAT( + src, IsClassTemplate("A", "T,std::unique_ptr")); + REQUIRE_THAT(src, IsClassTemplate("A", "double,T")); + // TODO: Figure out how to handle the same templates with different + // template + // parameter names + // REQUIRE_THAT(puml, !IsClassTemplate("A", "long,U")); + REQUIRE_THAT(src, IsClassTemplate("A", "long,T")); + REQUIRE_THAT(src, IsClassTemplate("A", "long,bool")); + REQUIRE_THAT(src, IsClassTemplate("A", "double,bool")); + REQUIRE_THAT(src, IsClassTemplate("A", "long,float")); + REQUIRE_THAT(src, IsClassTemplate("A", "double,float")); + REQUIRE_THAT(src, IsClassTemplate("A", "bool,std::string")); + REQUIRE_THAT(src, IsClassTemplate("A", "std::string,std::string")); + REQUIRE_THAT(src, IsClassTemplate("A", "char,std::string")); + REQUIRE_THAT(src, IsClass(_A("B"))); + REQUIRE_THAT(src, IsClassTemplate("R", "T")); - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); + REQUIRE_THAT(src, IsField("bapair", "PairPairBA")); + REQUIRE_THAT(src, IsField("abool", "APtr")); + REQUIRE_THAT(src, IsField("aboolfloat", + "AAPtr")); REQUIRE_THAT(src, IsField("afloat", + "ASharedPtr")); REQUIRE_THAT( src, IsField("boolstring", + "A")); REQUIRE_THAT(src, IsField("floatstring", + "AStringPtr")); REQUIRE_THAT(src, IsField("atfloat", + "AAPtr")); - mermaid::AliasMatcher _A(src); - using mermaid::IsField; + REQUIRE_THAT(src, IsField("intstring", "AIntString")); + REQUIRE_THAT(src, IsField("stringstring", + "AStringString")); REQUIRE_THAT(src, IsField("bstringstring", + "BStringString")); - REQUIRE_THAT(src, !Contains("type-parameter-")); + REQUIRE_THAT(src, IsField("bs", "BVector")); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A>"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - // TODO: Figure out how to handle the same templates with different - // template - // parameter names - // REQUIRE_THAT(puml, !IsClass("A", "long,U")); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("R"))); + REQUIRE_THAT(src, IsField("cb", + "SimpleCallback")); #if LLVM_VERSION_MAJOR >= 16 REQUIRE_THAT( + src, IsField("gcb", "GenericCallback")); + #else + REQUIRE_THAT( + src, IsField("gcb", + "GenericCallback")); #endif REQUIRE_THAT(src, + IsField("vcb", "VoidCallback")); - REQUIRE_THAT(src, IsField("bapair", "PairPairBA")); - REQUIRE_THAT(src, IsField("abool", "APtr")); - REQUIRE_THAT(src, IsField("aboolfloat", "AAPtr")); - REQUIRE_THAT(src, IsField("afloat", "ASharedPtr")); - REQUIRE_THAT( - src, IsField("boolstring", "A")); - REQUIRE_THAT(src, IsField("floatstring", "AStringPtr")); - REQUIRE_THAT(src, IsField("atfloat", "AAPtr")); + REQUIRE_THAT( + src, !IsClassTemplate("std::std::function", + "void(T...,int),int)")); - REQUIRE_THAT(src, IsField("intstring", "AIntString")); - REQUIRE_THAT(src, IsField("stringstring", "AStringString")); - REQUIRE_THAT(src, IsField("bstringstring", "BStringString")); + REQUIRE_THAT( + src, IsInstantiation(_A("A"), _A("A"))); + REQUIRE_THAT( + src, IsInstantiation(_A("A"), _A("A"))); + REQUIRE_THAT(src, IsInstantiation(_A("A"), + _A("A"))); - REQUIRE_THAT(src, IsField("bs", "BVector")); + REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); + // REQUIRE_THAT(puml, !IsInstantiation(_A("A"), + // _A("A"))); + REQUIRE_THAT( + src, IsInstantiation(_A("A"), _A("A"))); + REQUIRE_THAT( + src, IsInstantiation(_A("A"), _A("A"))); + REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); + REQUIRE_THAT( + src, IsInstantiation(_A("A"), _A("A"))); + REQUIRE_THAT(src, + IsInstantiation(_A("A"), + _A("A"))); REQUIRE_THAT(src, + IsInstantiation(_A("A"), + _A("A"))); REQUIRE_THAT(src, IsInstantiation( + _A("A"), _A("A"))); - REQUIRE_THAT(src, IsField("cb", "SimpleCallback")); -#if LLVM_VERSION_MAJOR >= 16 - REQUIRE_THAT( - src, IsField("gcb", "GenericCallback")); -#else - REQUIRE_THAT( - src, IsField("gcb", "GenericCallback")); -#endif - REQUIRE_THAT(src, IsField("vcb", "VoidCallback")); + REQUIRE_THAT(src, + IsInstantiation(_A("A>"), + _A("A>"))); + REQUIRE_THAT(src, + IsInstantiation( + _A("A"), _A("A>"))); - REQUIRE_THAT( - src, !IsClassTemplate("std::std::function", "void(T...,int),int)")); + REQUIRE_THAT(src, IsAggregation(_A("R"), _A("B"), "+vps")); + REQUIRE_THAT(src, IsAggregation(_A("R"), _A("B"), "-bapair")); + REQUIRE_THAT( + src, IsAggregation(_A("R"), _A("A"), + "-aboolfloat")); REQUIRE_THAT( src, IsAggregation(_A("R"), + _A("A"), "-bapair")); REQUIRE_THAT(src, IsAggregation(_A("R"), + _A("A"), "-aboolfloat")); REQUIRE_THAT( src, + IsAggregation(_A("R"), _A("A"), "-atfloat")); REQUIRE_THAT( + src, IsAggregation(_A("R"), _A("A"), + "-atfloat")); REQUIRE_THAT( src, IsAssociation(_A("R"), + _A("A"), "-afloat")); REQUIRE_THAT(src, IsAggregation( + _A("R"), _A("A"), "-boolstring")); + REQUIRE_THAT(src, + IsAggregation(_A("R"), + _A("A>"), + "-floatstring")); REQUIRE_THAT(src, IsDependency(_A("R"), + _A("A"))); REQUIRE_THAT( src, IsDependency(_A("R"), + _A("A"))); - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } + { + auto j = generate_class_json(diagram, *model); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - // REQUIRE_THAT(puml, !IsInstantiation(_A("A"), - // _A("A"))); - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, - IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, - IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, - IsInstantiation( - _A("A"), _A("A"))); + using namespace json; - REQUIRE_THAT(src, - IsInstantiation(_A("A>"), - _A("A>"))); - REQUIRE_THAT(src, - IsInstantiation( - _A("A"), _A("A>"))); + REQUIRE(json::IsClass(j, "A")); + REQUIRE(json::IsClass(j, "A")); + REQUIRE(json::IsClass(j, "A>")); + REQUIRE(json::IsClass(j, "A")); + REQUIRE(json::IsClass(j, "A")); + REQUIRE(json::IsClass(j, "A")); + REQUIRE(json::IsClass(j, "A")); + REQUIRE(json::IsClass(j, "A")); + REQUIRE(json::IsClass(j, "A")); + REQUIRE(json::IsClass(j, "A")); + REQUIRE(json::IsClass(j, "A")); + REQUIRE(json::IsClass(j, "A")); + REQUIRE(json::IsClass(j, "A")); + REQUIRE(json::IsClass(j, "B")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("B"), "+vps")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("B"), "-bapair")); - REQUIRE_THAT( - src, IsAggregation(_A("R"), _A("A"), "-aboolfloat")); - REQUIRE_THAT( - src, IsAggregation(_A("R"), _A("A"), "-bapair")); - REQUIRE_THAT(src, - IsAggregation(_A("R"), _A("A"), "-aboolfloat")); - REQUIRE_THAT( - src, IsAggregation(_A("R"), _A("A"), "-atfloat")); - REQUIRE_THAT( - src, IsAggregation(_A("R"), _A("A"), "-atfloat")); - REQUIRE_THAT( - src, IsAssociation(_A("R"), _A("A"), "-afloat")); - REQUIRE_THAT(src, - IsAggregation( - _A("R"), _A("A"), "-boolstring")); - REQUIRE_THAT(src, - IsAggregation(_A("R"), - _A("A>"), "-floatstring")); -#if !defined(__APPLE__) - // TODO(#176) - REQUIRE_THAT(src, IsDependency(_A("R"), _A("A"))); - REQUIRE_THAT( - src, IsDependency(_A("R"), _A("A"))); -#endif + save_json(config.output_directory(), diagram->name + ".json", j); + } + { + auto src = generate_class_mermaid(diagram, *model); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + mermaid::AliasMatcher _A(src); + using mermaid::IsField; + + REQUIRE_THAT(src, !Contains("type-parameter-")); + + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("A>"))); + REQUIRE_THAT(src, IsClass(_A("A"))); + // TODO: Figure out how to handle the same templates with different + // template + // parameter names + // REQUIRE_THAT(puml, !IsClass("A", "long,U")); + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("B"))); + REQUIRE_THAT(src, IsClass(_A("R"))); + + REQUIRE_THAT(src, IsField("bapair", "PairPairBA")); + REQUIRE_THAT(src, IsField("abool", "APtr")); + REQUIRE_THAT(src, IsField("aboolfloat", + "AAPtr")); REQUIRE_THAT(src, IsField("afloat", + "ASharedPtr")); REQUIRE_THAT( src, IsField("boolstring", + "A")); REQUIRE_THAT(src, IsField("floatstring", + "AStringPtr")); REQUIRE_THAT(src, IsField("atfloat", + "AAPtr")); + + REQUIRE_THAT(src, IsField("intstring", "AIntString")); + REQUIRE_THAT(src, IsField("stringstring", + "AStringString")); REQUIRE_THAT(src, IsField("bstringstring", + "BStringString")); + + REQUIRE_THAT(src, IsField("bs", "BVector")); + + REQUIRE_THAT(src, IsField("cb", + "SimpleCallback")); #if LLVM_VERSION_MAJOR >= 16 REQUIRE_THAT( + src, IsField("gcb", "GenericCallback")); + #else + REQUIRE_THAT( + src, IsField("gcb", + "GenericCallback")); #endif REQUIRE_THAT(src, + IsField("vcb", "VoidCallback")); + + REQUIRE_THAT( + src, !IsClassTemplate("std::std::function", + "void(T...,int),int)")); + + REQUIRE_THAT( + src, IsInstantiation(_A("A"), _A("A"))); + REQUIRE_THAT( + src, IsInstantiation(_A("A"), _A("A"))); + REQUIRE_THAT(src, IsInstantiation(_A("A"), + _A("A"))); + + REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); + // REQUIRE_THAT(puml, !IsInstantiation(_A("A"), + // _A("A"))); + REQUIRE_THAT( + src, IsInstantiation(_A("A"), _A("A"))); + REQUIRE_THAT( + src, IsInstantiation(_A("A"), _A("A"))); + REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); + REQUIRE_THAT( + src, IsInstantiation(_A("A"), _A("A"))); + REQUIRE_THAT(src, + IsInstantiation(_A("A"), + _A("A"))); REQUIRE_THAT(src, + IsInstantiation(_A("A"), + _A("A"))); REQUIRE_THAT(src, IsInstantiation( + _A("A"), _A("A"))); + + REQUIRE_THAT(src, + IsInstantiation(_A("A>"), + _A("A>"))); + REQUIRE_THAT(src, + IsInstantiation( + _A("A"), _A("A>"))); + + REQUIRE_THAT(src, IsAggregation(_A("R"), _A("B"), "+vps")); + REQUIRE_THAT(src, IsAggregation(_A("R"), _A("B"), "-bapair")); + REQUIRE_THAT( + src, IsAggregation(_A("R"), _A("A"), + "-aboolfloat")); REQUIRE_THAT( src, IsAggregation(_A("R"), + _A("A"), "-bapair")); REQUIRE_THAT(src, IsAggregation(_A("R"), + _A("A"), "-aboolfloat")); REQUIRE_THAT( src, + IsAggregation(_A("R"), _A("A"), "-atfloat")); REQUIRE_THAT( + src, IsAggregation(_A("R"), _A("A"), + "-atfloat")); REQUIRE_THAT( src, IsAssociation(_A("R"), + _A("A"), "-afloat")); REQUIRE_THAT(src, IsAggregation( + _A("R"), _A("A"), "-boolstring")); + REQUIRE_THAT(src, + IsAggregation(_A("R"), + _A("A>"), + "-floatstring")); #if !defined(__APPLE__) + // TODO(#176) + REQUIRE_THAT(src, IsDependency(_A("R"), + _A("A"))); REQUIRE_THAT( src, IsDependency(_A("R"), + _A("A"))); #endif + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + } + */ } \ No newline at end of file diff --git a/tests/t00015/test_case.h b/tests/t00015/test_case.h index 42752d54..9dd602f2 100644 --- a/tests/t00015/test_case.h +++ b/tests/t00015/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00015/test_case.cc + * tests/t00015/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00015", "[test-case][class]") +TEST_CASE("t00015") { + using namespace clanguml::test; + auto [config, db] = load_config("t00015"); auto diagram = config.diagrams["t00015_class"]; @@ -28,44 +30,11 @@ TEST_CASE("t00015", "[test-case][class]") REQUIRE(model->name() == "t00015_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsClass(_A("ns1::A"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns2_v0_9_0::A"))); - REQUIRE_THAT(src, IsClass(_A("ns1::Anon"))); - REQUIRE_THAT(src, IsClass(_A("ns3::ns1::ns2::Anon"))); - REQUIRE_THAT(src, IsClass(_A("ns3::B"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "ns1::A")); - REQUIRE(IsClass(j, "ns1::ns2_v0_9_0::A")); - REQUIRE(IsClass(j, "ns1::Anon")); - REQUIRE(IsClass(j, "ns3::ns1::ns2::Anon")); - REQUIRE(IsClass(j, "ns3::B")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - REQUIRE_THAT(src, IsClass(_A("ns1::A"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns2_v0_9_0::A"))); - REQUIRE_THAT(src, IsClass(_A("ns1::Anon"))); - REQUIRE_THAT(src, IsClass(_A("ns3::ns1::ns2::Anon"))); - REQUIRE_THAT(src, IsClass(_A("ns3::B"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "ns1::A")); + REQUIRE(IsClass(src, "ns1::ns2_v0_9_0::A")); + REQUIRE(IsClass(src, "ns1::Anon")); + REQUIRE(IsClass(src, "ns3::ns1::ns2::Anon")); + REQUIRE(IsClass(src, "ns3::B")); + }); } \ No newline at end of file diff --git a/tests/t00016/test_case.h b/tests/t00016/test_case.h index 5efdbe20..161597e8 100644 --- a/tests/t00016/test_case.h +++ b/tests/t00016/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00016/test_case.cc + * tests/t00016/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00016", "[test-case][class]") +TEST_CASE("t00016") { + using namespace clanguml::test; + auto [config, db] = load_config("t00016"); auto diagram = config.diagrams["t00016_class"]; @@ -28,69 +30,20 @@ TEST_CASE("t00016", "[test-case][class]") REQUIRE(model->name() == "t00016_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClassTemplate(src, "is_numeric")); + REQUIRE(IsClassTemplate(src, "is_numeric")); + REQUIRE(IsClassTemplate(src, "is_numeric")); + REQUIRE(IsClassTemplate(src, "is_numeric")); + REQUIRE(IsClassTemplate(src, "is_numeric")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsClassTemplate("is_numeric", "typename")); - REQUIRE_THAT(src, IsClassTemplate("is_numeric", "int")); - REQUIRE_THAT(src, IsClassTemplate("is_numeric", "bool")); - REQUIRE_THAT(src, IsClassTemplate("is_numeric", "char")); - REQUIRE_THAT(src, IsClassTemplate("is_numeric", "float")); - - REQUIRE_THAT(src, - IsInstantiation( - _A("is_numeric"), _A("is_numeric"), "up")); - REQUIRE_THAT(src, - IsInstantiation( - _A("is_numeric"), _A("is_numeric"), "up")); - REQUIRE_THAT(src, - IsInstantiation( - _A("is_numeric"), _A("is_numeric"), "up")); - REQUIRE_THAT(src, - IsInstantiation( - _A("is_numeric"), _A("is_numeric"), "up")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClassTemplate(j, "is_numeric")); - REQUIRE(IsClass(j, "is_numeric")); - REQUIRE(IsClass(j, "is_numeric")); - REQUIRE(IsClass(j, "is_numeric")); - REQUIRE(IsClass(j, "is_numeric")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - REQUIRE_THAT(src, IsClass(_A("is_numeric"))); - REQUIRE_THAT(src, IsClass(_A("is_numeric"))); - REQUIRE_THAT(src, IsClass(_A("is_numeric"))); - REQUIRE_THAT(src, IsClass(_A("is_numeric"))); - REQUIRE_THAT(src, IsClass(_A("is_numeric"))); - - REQUIRE_THAT(src, - IsInstantiation(_A("is_numeric"), _A("is_numeric"))); - REQUIRE_THAT(src, - IsInstantiation( - _A("is_numeric"), _A("is_numeric"))); - REQUIRE_THAT(src, - IsInstantiation( - _A("is_numeric"), _A("is_numeric"))); - REQUIRE_THAT(src, - IsInstantiation( - _A("is_numeric"), _A("is_numeric"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsInstantiation( + src, "is_numeric", "is_numeric", "up")); + REQUIRE(IsInstantiation( + src, "is_numeric", "is_numeric", "up")); + REQUIRE(IsInstantiation( + src, "is_numeric", "is_numeric", "up")); + REQUIRE(IsInstantiation( + src, "is_numeric", "is_numeric", "up")); + }); } \ No newline at end of file diff --git a/tests/t00017/test_case.h b/tests/t00017/test_case.h index 865764ba..644aebec 100644 --- a/tests/t00017/test_case.h +++ b/tests/t00017/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00017/test_case.cc + * tests/t00017/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00017", "[test-case][class]") +TEST_CASE("t00017") { + using namespace clanguml::test; + auto [config, db] = load_config("t00017"); auto diagram = config.diagrams["t00017_class"]; @@ -28,107 +30,47 @@ TEST_CASE("t00017", "[test-case][class]") REQUIRE(model->name() == "t00017_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM( + config, diagram, *model, + [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClass(src, "C")); + REQUIRE(IsClass(src, "D")); + REQUIRE(IsClass(src, "E")); + REQUIRE(IsClass(src, "F")); + REQUIRE(IsClass(src, "G")); + REQUIRE(IsClass(src, "H")); + REQUIRE(IsClass(src, "I")); + REQUIRE(IsClass(src, "J")); + REQUIRE(IsClass(src, "K")); + REQUIRE(IsClass(src, "R")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - REQUIRE_THAT(src, IsClass(_A("F"))); - REQUIRE_THAT(src, IsClass(_A("G"))); - REQUIRE_THAT(src, IsClass(_A("H"))); - REQUIRE_THAT(src, IsClass(_A("I"))); - REQUIRE_THAT(src, IsClass(_A("J"))); - REQUIRE_THAT(src, IsClass(_A("K"))); - REQUIRE_THAT(src, IsClass(_A("R"))); + REQUIRE(IsField(src, "R", "some_int", "int")); + REQUIRE((IsField(src, "R", "some_int_pointer", "int *"))); + REQUIRE((IsField( + src, "R", "some_int_pointer_pointer", "int **"))); - REQUIRE_THAT(src, (IsField("some_int", "int"))); - REQUIRE_THAT(src, (IsField("some_int_pointer", "int *"))); - REQUIRE_THAT( - src, (IsField("some_int_pointer_pointer", "int **"))); - - // Relationship members should not be rendered as part of this testcase - REQUIRE_THAT(src, !(IsField("a", _A("A")))); - REQUIRE_THAT(src, !(IsField("b", _A("B")))); - - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("A"), "-a")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("B"), "-b")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("C"), "-c")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("D"), "-d")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("E"), "-e")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("F"), "-f")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("G"), "-g")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("H"), "-h")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("I"), "-i")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("J"), "-j")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("K"), "-k")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - REQUIRE(IsClass(j, "C")); - REQUIRE(IsClass(j, "D")); - REQUIRE(IsClass(j, "E")); - REQUIRE(IsClass(j, "F")); - REQUIRE(IsClass(j, "G")); - REQUIRE(IsClass(j, "H")); - REQUIRE(IsClass(j, "I")); - REQUIRE(IsClass(j, "J")); - REQUIRE(IsClass(j, "K")); - REQUIRE(IsClass(j, "R")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - mermaid::AliasMatcher _A(src); - using mermaid::IsField; - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - REQUIRE_THAT(src, IsClass(_A("F"))); - REQUIRE_THAT(src, IsClass(_A("G"))); - REQUIRE_THAT(src, IsClass(_A("H"))); - REQUIRE_THAT(src, IsClass(_A("I"))); - REQUIRE_THAT(src, IsClass(_A("J"))); - REQUIRE_THAT(src, IsClass(_A("K"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - - REQUIRE_THAT(src, (IsField("some_int", "int"))); - REQUIRE_THAT(src, (IsField("some_int_pointer", "int *"))); - REQUIRE_THAT( - src, (IsField("some_int_pointer_pointer", "int **"))); - - // Relationship members should not be rendered as part of this testcase - REQUIRE_THAT(src, !(IsField("a", _A("A")))); - REQUIRE_THAT(src, !(IsField("b", _A("B")))); - - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("A"), "-a")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("B"), "-b")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("C"), "-c")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("D"), "-d")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("E"), "-e")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("F"), "-f")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("G"), "-g")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("H"), "-h")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("I"), "-i")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("J"), "-j")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("K"), "-k")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsAggregation(src, "R", "A", "a")); + REQUIRE(IsAssociation(src, "R", "B", "b")); + REQUIRE(IsAssociation(src, "R", "C", "c")); + REQUIRE(IsAssociation(src, "R", "D", "d")); + REQUIRE(IsAssociation(src, "R", "E", "e")); + REQUIRE(IsAggregation(src, "R", "F", "f")); + REQUIRE(IsAssociation(src, "R", "G", "g")); + REQUIRE(IsAssociation(src, "R", "H", "h")); + REQUIRE(IsAssociation(src, "R", "I", "i")); + REQUIRE(IsAssociation(src, "R", "J", "j")); + REQUIRE(IsAssociation(src, "R", "K", "k")); + }, + [](const plantuml_t &src) { + // Relationship members should not be rendered as part of this + // testcase + REQUIRE(!IsField(src, "R", "a", "A")); + REQUIRE(!IsField(src, "R", "b", "B")); + }, + [](const mermaid_t &src) { + REQUIRE(!IsField(src, "R", "a", "A")); + REQUIRE(!IsField(src, "R", "b", "B")); + }); } \ No newline at end of file diff --git a/tests/t00018/test_case.h b/tests/t00018/test_case.h index 8ca24e0b..7424462f 100644 --- a/tests/t00018/test_case.h +++ b/tests/t00018/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00018/test_case.cc + * tests/t00018/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00018", "[test-case][class]") +TEST_CASE("t00018") { + using namespace clanguml::test; + auto [config, db] = load_config("t00018"); auto diagram = config.diagrams["t00018_class"]; @@ -28,45 +30,13 @@ TEST_CASE("t00018", "[test-case][class]") REQUIRE(model->name() == "t00018_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "widget")); + REQUIRE(IsClass(src, "impl::widget")); + REQUIRE(IsDependency(src, "impl::widget", "widget")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsClass(_A("widget"))); - REQUIRE_THAT(src, IsClass(_A("impl::widget"))); - - REQUIRE_THAT( - src, IsAggregation(_A("widget"), _A("impl::widget"), "-pImpl")); - REQUIRE_THAT(src, IsDependency(_A("impl::widget"), _A("widget"))); - REQUIRE_THAT(src, !IsDependency(_A("widget"), _A("widget"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "widget")); - REQUIRE(IsClass(j, "impl::widget")); - REQUIRE(IsDependency(j, "impl::widget", "widget")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - mermaid::AliasMatcher _A(src); - - REQUIRE_THAT(src, IsClass(_A("widget"))); - REQUIRE_THAT(src, IsClass(_A("impl::widget"))); - - REQUIRE_THAT( - src, IsAggregation(_A("widget"), _A("impl::widget"), "-pImpl")); - REQUIRE_THAT(src, IsDependency(_A("impl::widget"), _A("widget"))); - REQUIRE_THAT(src, !IsDependency(_A("widget"), _A("widget"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsAggregation(src, "widget", "impl::widget", "pImpl")); + REQUIRE(IsDependency(src, "impl::widget", "widget")); + REQUIRE(!IsDependency(src, "widget", "widget")); + }); } \ No newline at end of file diff --git a/tests/t00019/test_case.h b/tests/t00019/test_case.h index d7bdb746..7d17aa32 100644 --- a/tests/t00019/test_case.h +++ b/tests/t00019/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00019/test_case.cc + * tests/t00019/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00019", "[test-case][class]") +TEST_CASE("t00019") { + using namespace clanguml::test; + auto [config, db] = load_config("t00019"); auto diagram = config.diagrams["t00019_class"]; @@ -28,101 +30,33 @@ TEST_CASE("t00019", "[test-case][class]") REQUIRE(model->name() == "t00019_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "Base")); + REQUIRE(IsClassTemplate(src, "Layer1")); + REQUIRE(IsClassTemplate(src, "Layer2")); + REQUIRE(IsClassTemplate(src, "Layer3")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsClass(_A("Base"))); - REQUIRE_THAT(src, IsClassTemplate("Layer1", "LowerLayer")); - REQUIRE_THAT(src, IsClassTemplate("Layer2", "LowerLayer")); - REQUIRE_THAT(src, IsClassTemplate("Layer3", "LowerLayer")); + REQUIRE(IsBaseClass(src, "Base", "Layer3")); + REQUIRE(!IsDependency(src, "Base", "Layer3")); - REQUIRE_THAT(src, IsBaseClass(_A("Base"), _A("Layer3"))); - REQUIRE_THAT(src, !IsDependency(_A("Base"), _A("Layer3"))); + REQUIRE(IsBaseClass(src, "Layer3", "Layer2>")); + REQUIRE(!IsDependency(src, "Layer3", "Layer2>")); - REQUIRE_THAT( - src, IsBaseClass(_A("Layer3"), _A("Layer2>"))); - REQUIRE_THAT( - src, !IsDependency(_A("Layer3"), _A("Layer2>"))); + REQUIRE(IsBaseClass( + src, "Layer2>", "Layer1>>")); - REQUIRE_THAT(src, - IsBaseClass(_A("Layer2>"), - _A("Layer1>>"))); + REQUIRE(!IsDependency( + src, "Layer2>", "Layer1>>")); - REQUIRE_THAT(src, - !IsDependency(_A("Layer2>"), - _A("Layer1>>"))); + REQUIRE(IsAggregation( + src, "A", "Layer1>>", "layers")); + REQUIRE(!IsDependency(src, "A", "Layer1>>")); - REQUIRE_THAT(src, - IsAggregation( - _A("A"), _A("Layer1>>"), "+layers")); - REQUIRE_THAT( - src, !IsDependency(_A("A"), _A("Layer1>>"))); + REQUIRE( + !IsAggregation(src, "A", "Layer2>", "layers")); - REQUIRE_THAT(src, - !IsAggregation(_A("A"), _A("Layer2>"), "+layers")); + REQUIRE(!IsAggregation(src, "A", "Layer3", "layers")); - REQUIRE_THAT( - src, !IsAggregation(_A("A"), _A("Layer3"), "+layers")); - - REQUIRE_THAT(src, !IsAggregation(_A("A"), _A("Base"), "+layers")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "Base")); - REQUIRE(IsClassTemplate(j, "Layer1")); - REQUIRE(IsClassTemplate(j, "Layer2")); - REQUIRE(IsClassTemplate(j, "Layer3")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - REQUIRE_THAT(src, IsClass(_A("Base"))); - REQUIRE_THAT(src, IsClass(_A("Layer1"))); - REQUIRE_THAT(src, IsClass(_A("Layer2"))); - REQUIRE_THAT(src, IsClass(_A("Layer3"))); - - REQUIRE_THAT(src, IsBaseClass(_A("Base"), _A("Layer3"))); - REQUIRE_THAT(src, !IsDependency(_A("Base"), _A("Layer3"))); - - REQUIRE_THAT( - src, IsBaseClass(_A("Layer3"), _A("Layer2>"))); - REQUIRE_THAT( - src, !IsDependency(_A("Layer3"), _A("Layer2>"))); - - REQUIRE_THAT(src, - IsBaseClass(_A("Layer2>"), - _A("Layer1>>"))); - - REQUIRE_THAT(src, - !IsDependency(_A("Layer2>"), - _A("Layer1>>"))); - - REQUIRE_THAT(src, - IsAggregation( - _A("A"), _A("Layer1>>"), "+layers")); - REQUIRE_THAT( - src, !IsDependency(_A("A"), _A("Layer1>>"))); - - REQUIRE_THAT(src, - !IsAggregation(_A("A"), _A("Layer2>"), "+layers")); - - REQUIRE_THAT( - src, !IsAggregation(_A("A"), _A("Layer3"), "+layers")); - - REQUIRE_THAT(src, !IsAggregation(_A("A"), _A("Base"), "+layers")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(!IsAggregation(src, "A", "Base", "layers")); + }); } \ No newline at end of file diff --git a/tests/t00020/test_case.h b/tests/t00020/test_case.h index d959b04c..6657869d 100644 --- a/tests/t00020/test_case.h +++ b/tests/t00020/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00020/test_case.cc + * tests/t00020/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00020", "[test-case][class]") +TEST_CASE("t00020") { + using namespace clanguml::test; + auto [config, db] = load_config("t00020"); auto diagram = config.diagrams["t00020_class"]; @@ -28,53 +30,66 @@ TEST_CASE("t00020", "[test-case][class]") REQUIRE(model->name() == "t00020_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsAbstractClass(src, "AbstractFactory")); + REQUIRE(IsAbstractClass(src, "ProductA")); + REQUIRE(IsAbstractClass(src, "ProductB")); + REQUIRE(IsClass(src, "ProductA1")); + REQUIRE(IsClass(src, "ProductA2")); + REQUIRE(IsClass(src, "ProductB1")); + REQUIRE(IsClass(src, "ProductB2")); + REQUIRE(IsClass(src, "Factory1")); + REQUIRE(IsClass(src, "Factory2")); + }); + /* + { + auto src = generate_class_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsAbstractClass(_A("ProductA"))); - REQUIRE_THAT(src, IsAbstractClass(_A("ProductB"))); - REQUIRE_THAT(src, IsClass(_A("ProductA1"))); - REQUIRE_THAT(src, IsClass(_A("ProductA2"))); - REQUIRE_THAT(src, IsClass(_A("ProductB1"))); - REQUIRE_THAT(src, IsClass(_A("ProductB2"))); - REQUIRE_THAT(src, IsAbstractClass(_A("AbstractFactory"))); - REQUIRE_THAT(src, IsClass(_A("Factory1"))); - REQUIRE_THAT(src, IsClass(_A("Factory2"))); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE_THAT(src, IsAbstractClass(_A("ProductA"))); + REQUIRE_THAT(src, IsAbstractClass(_A("ProductB"))); + REQUIRE_THAT(src, IsClass(_A("ProductA1"))); + REQUIRE_THAT(src, IsClass(_A("ProductA2"))); + REQUIRE_THAT(src, IsClass(_A("ProductB1"))); + REQUIRE_THAT(src, IsClass(_A("ProductB2"))); + REQUIRE_THAT(src, IsAbstractClass(_A("AbstractFactory"))); + REQUIRE_THAT(src, IsClass(_A("Factory1"))); + REQUIRE_THAT(src, IsClass(_A("Factory2"))); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } + { + auto j = generate_class_json(diagram, *model); - using namespace json; + using namespace json; - REQUIRE(IsClass(j, "ProductA1")); - REQUIRE(IsClass(j, "ProductA2")); - REQUIRE(IsClass(j, "ProductB1")); - REQUIRE(IsClass(j, "ProductB2")); - REQUIRE(IsAbstractClass(j, "AbstractFactory")); + REQUIRE(IsClass(j, "ProductA1")); + REQUIRE(IsClass(j, "ProductA2")); + REQUIRE(IsClass(j, "ProductB1")); + REQUIRE(IsClass(j, "ProductB2")); + REQUIRE(IsAbstractClass(j, "AbstractFactory")); - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); + save_json(config.output_directory(), diagram->name + ".json", j); + } + { + auto src = generate_class_mermaid(diagram, *model); - mermaid::AliasMatcher _A(src); - using mermaid::IsAbstractClass; + mermaid::AliasMatcher _A(src); + using mermaid::IsAbstractClass; - REQUIRE_THAT(src, IsAbstractClass(_A("ProductA"))); - REQUIRE_THAT(src, IsAbstractClass(_A("ProductB"))); - REQUIRE_THAT(src, IsClass(_A("ProductA1"))); - REQUIRE_THAT(src, IsClass(_A("ProductA2"))); - REQUIRE_THAT(src, IsClass(_A("ProductB1"))); - REQUIRE_THAT(src, IsClass(_A("ProductB2"))); - REQUIRE_THAT(src, IsAbstractClass(_A("AbstractFactory"))); - REQUIRE_THAT(src, IsClass(_A("Factory1"))); - REQUIRE_THAT(src, IsClass(_A("Factory2"))); + REQUIRE_THAT(src, IsAbstractClass(_A("ProductA"))); + REQUIRE_THAT(src, IsAbstractClass(_A("ProductB"))); + REQUIRE_THAT(src, IsClass(_A("ProductA1"))); + REQUIRE_THAT(src, IsClass(_A("ProductA2"))); + REQUIRE_THAT(src, IsClass(_A("ProductB1"))); + REQUIRE_THAT(src, IsClass(_A("ProductB2"))); + REQUIRE_THAT(src, IsAbstractClass(_A("AbstractFactory"))); + REQUIRE_THAT(src, IsClass(_A("Factory1"))); + REQUIRE_THAT(src, IsClass(_A("Factory2"))); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t00021/test_case.h b/tests/t00021/test_case.h index f916adf3..a9c511b6 100644 --- a/tests/t00021/test_case.h +++ b/tests/t00021/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00021/test_case.cc + * tests/t00021/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00021", "[test-case][class]") +TEST_CASE("t00021") { + using namespace clanguml::test; + auto [config, db] = load_config("t00021"); auto diagram = config.diagrams["t00021_class"]; @@ -28,47 +30,14 @@ TEST_CASE("t00021", "[test-case][class]") REQUIRE(model->name() == "t00021_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsAbstractClass(src, "Item")); + REQUIRE(IsAbstractClass(src, "Visitor")); + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsAbstractClass(_A("Item"))); - REQUIRE_THAT(src, IsAbstractClass(_A("Visitor"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("Visitor1"))); - REQUIRE_THAT(src, IsClass(_A("Visitor2"))); - REQUIRE_THAT(src, IsClass(_A("Visitor3"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "Visitor1")); - REQUIRE(IsClass(j, "Visitor2")); - REQUIRE(IsAbstractClass(j, "Item")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsAbstractClass; - - REQUIRE_THAT(src, IsAbstractClass(_A("Item"))); - REQUIRE_THAT(src, IsAbstractClass(_A("Visitor"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("Visitor1"))); - REQUIRE_THAT(src, IsClass(_A("Visitor2"))); - REQUIRE_THAT(src, IsClass(_A("Visitor3"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsClass(src, "Visitor1")); + REQUIRE(IsClass(src, "Visitor2")); + REQUIRE(IsClass(src, "Visitor3")); + }); } \ No newline at end of file diff --git a/tests/t00022/test_case.h b/tests/t00022/test_case.h index ab38da8c..af819cb7 100644 --- a/tests/t00022/test_case.h +++ b/tests/t00022/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00022/test_case.cc + * tests/t00022/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00022", "[test-case][class]") +TEST_CASE("t00022") { + using namespace clanguml::test; + auto [config, db] = load_config("t00022"); auto diagram = config.diagrams["t00022_class"]; @@ -28,38 +30,9 @@ TEST_CASE("t00022", "[test-case][class]") REQUIRE(model->name() == "t00022_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsAbstractClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A1"))); - REQUIRE_THAT(src, IsClass(_A("A2"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A1")); - REQUIRE(IsClass(j, "A2")); - REQUIRE(IsAbstractClass(j, "A")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - mermaid::AliasMatcher _A(src); - using mermaid::IsAbstractClass; - - REQUIRE_THAT(src, IsAbstractClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A1"))); - REQUIRE_THAT(src, IsClass(_A("A2"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A1")); + REQUIRE(IsClass(src, "A2")); + REQUIRE(IsAbstractClass(src, "A")); + }); } diff --git a/tests/t00023/test_case.h b/tests/t00023/test_case.h index a0c74506..0e49a4fb 100644 --- a/tests/t00023/test_case.h +++ b/tests/t00023/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00023/test_case.cc + * tests/t00023/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00023", "[test-case][class]") +TEST_CASE("t00023") { + using namespace clanguml::test; + auto [config, db] = load_config("t00023"); auto diagram = config.diagrams["t00023_class"]; @@ -28,39 +30,9 @@ TEST_CASE("t00023", "[test-case][class]") REQUIRE(model->name() == "t00023_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsAbstractClass(_A("Strategy"))); - REQUIRE_THAT(src, IsClass(_A("StrategyA"))); - REQUIRE_THAT(src, IsClass(_A("StrategyB"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "StrategyA")); - REQUIRE(IsClass(j, "StrategyB")); - REQUIRE(IsAbstractClass(j, "Strategy")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsAbstractClass; - - REQUIRE_THAT(src, IsAbstractClass(_A("Strategy"))); - REQUIRE_THAT(src, IsClass(_A("StrategyA"))); - REQUIRE_THAT(src, IsClass(_A("StrategyB"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsAbstractClass(src, "Strategy")); + REQUIRE(IsClass(src, "StrategyA")); + REQUIRE(IsClass(src, "StrategyB")); + }); } \ No newline at end of file diff --git a/tests/t00024/test_case.h b/tests/t00024/test_case.h index 7ede8607..7ecd61c1 100644 --- a/tests/t00024/test_case.h +++ b/tests/t00024/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00024/test_case.cc + * tests/t00024/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00024", "[test-case][class]") +TEST_CASE("t00024") { + using namespace clanguml::test; + auto [config, db] = load_config("t00024"); auto diagram = config.diagrams["t00024_class"]; @@ -28,50 +30,13 @@ TEST_CASE("t00024", "[test-case][class]") REQUIRE(model->name() == "t00024_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsAbstractClass(_A("Target"))); - REQUIRE_THAT(src, IsClass(_A("Target1"))); - REQUIRE_THAT(src, IsClass(_A("Target2"))); - REQUIRE_THAT(src, IsClass(_A("Proxy"))); - REQUIRE_THAT(src, IsBaseClass(_A("Target"), _A("Target1"))); - REQUIRE_THAT(src, IsBaseClass(_A("Target"), _A("Target2"))); - REQUIRE_THAT(src, IsBaseClass(_A("Target"), _A("Proxy"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "Target1")); - REQUIRE(IsClass(j, "Target2")); - REQUIRE(IsAbstractClass(j, "Target")); - REQUIRE(IsBaseClass(j, "Target", "Target1")); - REQUIRE(IsBaseClass(j, "Target", "Target2")); - REQUIRE(IsBaseClass(j, "Target", "Proxy")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsAbstractClass; - - REQUIRE_THAT(src, IsAbstractClass(_A("Target"))); - REQUIRE_THAT(src, IsClass(_A("Target1"))); - REQUIRE_THAT(src, IsClass(_A("Target2"))); - REQUIRE_THAT(src, IsClass(_A("Proxy"))); - REQUIRE_THAT(src, IsBaseClass(_A("Target"), _A("Target1"))); - REQUIRE_THAT(src, IsBaseClass(_A("Target"), _A("Target2"))); - REQUIRE_THAT(src, IsBaseClass(_A("Target"), _A("Proxy"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "Target1")); + REQUIRE(IsClass(src, "Target2")); + REQUIRE(IsClass(src, "Proxy")); + REQUIRE(IsAbstractClass(src, "Target")); + REQUIRE(IsBaseClass(src, "Target", "Target1")); + REQUIRE(IsBaseClass(src, "Target", "Target2")); + REQUIRE(IsBaseClass(src, "Target", "Proxy")); + }); } \ No newline at end of file diff --git a/tests/t00025/test_case.h b/tests/t00025/test_case.h index c15ba9e9..dbe33d13 100644 --- a/tests/t00025/test_case.h +++ b/tests/t00025/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00025/test_case.cc + * tests/t00025/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00025", "[test-case][class]") +TEST_CASE("t00025") { + using namespace clanguml::test; + auto [config, db] = load_config("t00025"); auto diagram = config.diagrams["t00025_class"]; @@ -28,68 +30,22 @@ TEST_CASE("t00025", "[test-case][class]") REQUIRE(model->name() == "t00025_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "Target1")); + REQUIRE(IsClass(src, "Target2")); + REQUIRE(IsClassTemplate(src, "Proxy")); + REQUIRE(IsDependency(src, "Proxy", "Target1")); + REQUIRE(IsDependency(src, "Proxy", "Target2")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsClass(_A("Target1"))); - REQUIRE_THAT(src, IsClass(_A("Target2"))); - REQUIRE_THAT(src, IsClassTemplate("Proxy", "T")); - REQUIRE_THAT( - src, IsInstantiation(_A("Proxy"), _A("Proxy"))); - REQUIRE_THAT( - src, IsInstantiation(_A("Proxy"), _A("Proxy"))); - REQUIRE_THAT(src, - IsAggregation(_A("ProxyHolder"), _A("Proxy"), "+proxy1")); - REQUIRE_THAT(src, - IsAggregation(_A("ProxyHolder"), _A("Proxy"), "+proxy2")); - REQUIRE_THAT( - src, !IsAggregation(_A("ProxyHolder"), _A("Target1"), "+proxy1")); - REQUIRE_THAT( - src, !IsAggregation(_A("ProxyHolder"), _A("Target2"), "+proxy2")); - REQUIRE_THAT(src, IsDependency(_A("Proxy"), _A("Target1"))); - REQUIRE_THAT(src, IsDependency(_A("Proxy"), _A("Target2"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "Target1")); - REQUIRE(IsClass(j, "Target2")); - REQUIRE(IsClassTemplate(j, "Proxy")); - REQUIRE(IsDependency(j, "Proxy", "Target1")); - REQUIRE(IsDependency(j, "Proxy", "Target2")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - REQUIRE_THAT(src, IsClass(_A("Target1"))); - REQUIRE_THAT(src, IsClass(_A("Target2"))); - REQUIRE_THAT(src, IsClass(_A("Proxy"))); - REQUIRE_THAT( - src, IsInstantiation(_A("Proxy"), _A("Proxy"))); - REQUIRE_THAT( - src, IsInstantiation(_A("Proxy"), _A("Proxy"))); - REQUIRE_THAT(src, - IsAggregation(_A("ProxyHolder"), _A("Proxy"), "+proxy1")); - REQUIRE_THAT(src, - IsAggregation(_A("ProxyHolder"), _A("Proxy"), "+proxy2")); - REQUIRE_THAT( - src, !IsAggregation(_A("ProxyHolder"), _A("Target1"), "+proxy1")); - REQUIRE_THAT( - src, !IsAggregation(_A("ProxyHolder"), _A("Target2"), "+proxy2")); - REQUIRE_THAT(src, IsDependency(_A("Proxy"), _A("Target1"))); - REQUIRE_THAT(src, IsDependency(_A("Proxy"), _A("Target2"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsInstantiation(src, "Proxy", "Proxy")); + REQUIRE(IsInstantiation(src, "Proxy", "Proxy")); + REQUIRE(IsAggregation( + src, "ProxyHolder", "Proxy", "proxy1")); + REQUIRE(IsAggregation( + src, "ProxyHolder", "Proxy", "proxy2")); + REQUIRE( + !IsAggregation(src, "ProxyHolder", "Target1", "proxy1")); + REQUIRE( + !IsAggregation(src, "ProxyHolder", "Target2", "proxy2")); + }); } \ No newline at end of file diff --git a/tests/t00026/test_case.h b/tests/t00026/test_case.h index 3de355c2..90ecca47 100644 --- a/tests/t00026/test_case.h +++ b/tests/t00026/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00026/test_case.cc + * tests/t00026/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00026", "[test-case][class]") +TEST_CASE("t00026") { + using namespace clanguml::test; + auto [config, db] = load_config("t00026"); auto diagram = config.diagrams["t00026_class"]; @@ -28,48 +30,15 @@ TEST_CASE("t00026", "[test-case][class]") REQUIRE(model->name() == "t00026_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClassTemplate(src, "Memento")); + REQUIRE(IsClassTemplate(src, "Originator")); + REQUIRE(IsClassTemplate(src, "Caretaker")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsClassTemplate("Memento", "T")); - REQUIRE_THAT(src, IsClassTemplate("Originator", "T")); - REQUIRE_THAT(src, IsClassTemplate("Caretaker", "T")); - REQUIRE_THAT(src, - IsInstantiation( - _A("Originator"), _A("Originator"))); - REQUIRE_THAT(src, - IsInstantiation(_A("Caretaker"), _A("Caretaker"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClassTemplate(j, "Memento")); - REQUIRE(IsClassTemplate(j, "Originator")); - REQUIRE(IsInstantiation(j, "Originator", "Originator")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - REQUIRE_THAT(src, IsClass(_A("Memento"))); - REQUIRE_THAT(src, IsClass(_A("Originator"))); - REQUIRE_THAT(src, IsClass(_A("Caretaker"))); - REQUIRE_THAT(src, - IsInstantiation( - _A("Originator"), _A("Originator"))); - REQUIRE_THAT(src, - IsInstantiation(_A("Caretaker"), _A("Caretaker"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE( + IsInstantiation(src, "Originator", "Originator")); + REQUIRE( + IsInstantiation(src, "Originator", "Originator")); + REQUIRE(IsInstantiation(src, "Caretaker", "Caretaker")); + }); } \ No newline at end of file diff --git a/tests/t00027/test_case.h b/tests/t00027/test_case.h index e9cd07a8..afc9133f 100644 --- a/tests/t00027/test_case.h +++ b/tests/t00027/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00027", "[test-case][class]") +TEST_CASE("t00027") { + using namespace clanguml::test; + auto [config, db] = load_config("t00027"); auto diagram = config.diagrams["t00027_class"]; @@ -28,6 +30,29 @@ TEST_CASE("t00027", "[test-case][class]") REQUIRE(model->name() == "t00027_class"); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsAbstractClass(src, "Shape")); + REQUIRE(IsAbstractClass(src, "ShapeDecorator")); + + REQUIRE(IsClassTemplate(src, "Line...>")); + REQUIRE(IsInstantiation(src, "Line...>", "Line")); + REQUIRE(IsInstantiation(src, "Line...>", "Line")); + REQUIRE(IsAggregation(src, "Window", "Text", "description")); + + REQUIRE(IsInstantiation(src, "Line...>", "Line")); + REQUIRE(IsInstantiation(src, "Line...>", "Line")); + REQUIRE(IsInstantiation(src, "Text...>", "Text")); + REQUIRE(IsInstantiation(src, "Text...>", "Text")); + + REQUIRE(IsAggregation( + src, "Window", "Line", "border")); + REQUIRE(IsAggregation(src, "Window", "Line", "divider")); + REQUIRE(IsAggregation( + src, "Window", "Text", "title")); + REQUIRE( + IsAggregation(src, "Window", "Text", "description")); + }); +/* { auto src = generate_class_puml(diagram, *model); AliasMatcher _A(src); @@ -102,5 +127,5 @@ TEST_CASE("t00027", "[test-case][class]") IsAggregation(_A("Window"), _A("Text"), "+description")); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } \ No newline at end of file diff --git a/tests/t00028/test_case.h b/tests/t00028/test_case.h index 77b8df35..3598f279 100644 --- a/tests/t00028/test_case.h +++ b/tests/t00028/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00028/test_case.cc + * tests/t00028/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00028", "[test-case][class]") +TEST_CASE("t00028") { + using namespace clanguml::test; + auto [config, db] = load_config("t00028"); auto diagram = config.diagrams["t00028_class"]; @@ -28,78 +30,105 @@ TEST_CASE("t00028", "[test-case][class]") REQUIRE(model->name() == "t00028_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClassTemplate("E", "T")); - REQUIRE_THAT(src, IsEnum(_A("F"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - REQUIRE_THAT(src, HasNote(_A("A"), "top", "A class note.")); - REQUIRE_THAT(src, HasNote(_A("B"), "left", "B class note.")); - REQUIRE_THAT(src, HasNote(_A("C"), "bottom", "C class note.")); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClass(src, "C")); + REQUIRE(IsClass(src, "D")); + REQUIRE(IsClassTemplate(src, "E")); + REQUIRE(IsEnum(src, "F")); + REQUIRE(IsClass(src, "R")); + REQUIRE(HasNote(src, "A", "top", "A class note.")); + REQUIRE(HasNote(src, "B", "left", "B class note.")); + REQUIRE(HasNote(src, "C", "bottom", "C class note.")); const auto d_note = R"( D class note.)"; - REQUIRE_THAT(src, HasNote(_A("D"), "left", d_note)); - REQUIRE_THAT( - src, HasNote(_A("E"), "left", "E template class note.")); - REQUIRE_THAT(src, HasNote(_A("F"), "bottom", "F enum note.")); - REQUIRE_THAT(src, !HasNote(_A("G"), "left", "G class note.")); - REQUIRE_THAT(src, HasNote(_A("R"), "right", "R class note.")); - REQUIRE_THAT(src, - HasMemberNote( - _A("R"), "aaa", "left", "R contains an instance of A.")); - REQUIRE_THAT( - src, !HasMemberNote(_A("R"), "bbb", "right", "R class note.")); - REQUIRE_THAT( - src, HasMemberNote(_A("R"), "ccc", "left", "Reference to C.")); + REQUIRE(HasNote(src, "D", "left", d_note)); + REQUIRE(HasNote(src, "E", "left", "E template class note.")); + REQUIRE(HasNote(src, "F", "bottom", "F enum note.")); + REQUIRE(!HasNote(src, "G", "left", "G class note.")); + REQUIRE(HasNote(src, "R", "right", "R class note.")); + REQUIRE(HasMemberNote( + src, "R", "aaa", "left", "R contains an instance of A.")); + REQUIRE(!HasMemberNote(src, "R", "bbb", "right", "R class note.")); + REQUIRE(HasMemberNote(src, "R", "ccc", "left", "Reference to C.")); + }); + /* + { + auto src = generate_class_puml(diagram, *model); + AliasMatcher _A(src); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - using namespace json; + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("B"))); + REQUIRE_THAT(src, IsClass(_A("C"))); + REQUIRE_THAT(src, IsClass(_A("D"))); + REQUIRE_THAT(src, IsClassTemplate("E", "T")); + REQUIRE_THAT(src, IsEnum(_A("F"))); + REQUIRE_THAT(src, IsClass(_A("R"))); + REQUIRE_THAT(src, HasNote(_A("A"), "top", "A class note.")); + REQUIRE_THAT(src, HasNote(_A("B"), "left", "B class note.")); + REQUIRE_THAT(src, HasNote(_A("C"), "bottom", "C class note.")); + const auto d_note = R"( + D + class + note.)"; + REQUIRE_THAT(src, HasNote(_A("D"), "left", d_note)); + REQUIRE_THAT( + src, HasNote(_A("E"), "left", "E template class note.")); + REQUIRE_THAT(src, HasNote(_A("F"), "bottom", "F enum note.")); + REQUIRE_THAT(src, !HasNote(_A("G"), "left", "G class note.")); + REQUIRE_THAT(src, HasNote(_A("R"), "right", "R class note.")); + REQUIRE_THAT(src, + HasMemberNote( + _A("R"), "aaa", "left", "R contains an instance of A.")); + REQUIRE_THAT( + src, !HasMemberNote(_A("R"), "bbb", "right", "R class note.")); + REQUIRE_THAT( + src, HasMemberNote(_A("R"), "ccc", "left", "Reference to C.")); - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } + { + auto j = generate_class_json(diagram, *model); - mermaid::AliasMatcher _A(src); - using mermaid::HasNote; - using mermaid::IsEnum; + using namespace json; - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - REQUIRE_THAT(src, IsEnum(_A("F"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - REQUIRE_THAT(src, HasNote(_A("A"), "top", "A class note.")); - REQUIRE_THAT(src, HasNote(_A("B"), "left", "B class note.")); - REQUIRE_THAT(src, HasNote(_A("C"), "bottom", "C class note.")); - const auto d_note = R"( -D -class -note.)"; - REQUIRE_THAT(src, HasNote(_A("D"), "left", d_note)); - REQUIRE_THAT( - src, HasNote(_A("E"), "left", "E template class note.")); - REQUIRE_THAT(src, HasNote(_A("F"), "bottom", "F enum note.")); - REQUIRE_THAT(src, !HasNote(_A("G"), "left", "G class note.")); - REQUIRE_THAT(src, HasNote(_A("R"), "right", "R class note.")); + save_json(config.output_directory(), diagram->name + ".json", j); + } + { + auto src = generate_class_mermaid(diagram, *model); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + mermaid::AliasMatcher _A(src); + using mermaid::HasNote; + using mermaid::IsEnum; + + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("B"))); + REQUIRE_THAT(src, IsClass(_A("C"))); + REQUIRE_THAT(src, IsClass(_A("D"))); + REQUIRE_THAT(src, IsClass(_A("E"))); + REQUIRE_THAT(src, IsEnum(_A("F"))); + REQUIRE_THAT(src, IsClass(_A("R"))); + REQUIRE_THAT(src, HasNote(_A("A"), "top", "A class note.")); + REQUIRE_THAT(src, HasNote(_A("B"), "left", "B class note.")); + REQUIRE_THAT(src, HasNote(_A("C"), "bottom", "C class note.")); + const auto d_note = R"( + D + class + note.)"; + REQUIRE_THAT(src, HasNote(_A("D"), "left", d_note)); + REQUIRE_THAT( + src, HasNote(_A("E"), "left", "E template class note.")); + REQUIRE_THAT(src, HasNote(_A("F"), "bottom", "F enum note.")); + REQUIRE_THAT(src, !HasNote(_A("G"), "left", "G class note.")); + REQUIRE_THAT(src, HasNote(_A("R"), "right", "R class note.")); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t00029/test_case.h b/tests/t00029/test_case.h index c5ed006b..4e70ae2d 100644 --- a/tests/t00029/test_case.h +++ b/tests/t00029/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00029", "[test-case][class]") +TEST_CASE("t00029") { + using namespace clanguml::test; + auto [config, db] = load_config("t00029"); auto diagram = config.diagrams["t00029_class"]; @@ -28,66 +30,23 @@ TEST_CASE("t00029", "[test-case][class]") REQUIRE(model->name() == "t00029_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(!IsClass(src, "B")); + REQUIRE(IsClassTemplate(src, "C")); + REQUIRE(!IsClassTemplate(src, "D")); + REQUIRE(IsEnum(src, "E")); + REQUIRE(!IsEnum(src, "F")); + REQUIRE(IsClass(src, "G1")); + REQUIRE(IsClass(src, "G2")); + REQUIRE(IsClass(src, "G3")); + REQUIRE(IsClass(src, "G4")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsClass(src, "R")); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, !IsClass(_A("B"))); - REQUIRE_THAT(src, IsClassTemplate("C", "T")); - REQUIRE_THAT(src, !IsClassTemplate("D", "T")); - REQUIRE_THAT(src, IsEnum(_A("E"))); - REQUIRE_THAT(src, !IsEnum(_A("F"))); - REQUIRE_THAT(src, IsClass(_A("G1"))); - REQUIRE_THAT(src, IsClass(_A("G2"))); - REQUIRE_THAT(src, IsClass(_A("G3"))); - REQUIRE_THAT(src, IsClass(_A("G4"))); - - REQUIRE_THAT(src, IsClass(_A("R"))); - - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("G1"), "+g1")); - REQUIRE_THAT(src, !IsAggregation(_A("R"), _A("G2"), "+g2")); - REQUIRE_THAT(src, !IsAggregation(_A("R"), _A("G3"), "+g3")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("G4"), "+g4")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsAggregation(j, "R", "G1", "g1")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsEnum; - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, !IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, !IsClass(_A("D"))); - REQUIRE_THAT(src, IsEnum(_A("E"))); - REQUIRE_THAT(src, !IsEnum(_A("F"))); - REQUIRE_THAT(src, IsClass(_A("G1"))); - REQUIRE_THAT(src, IsClass(_A("G2"))); - REQUIRE_THAT(src, IsClass(_A("G3"))); - REQUIRE_THAT(src, IsClass(_A("G4"))); - - REQUIRE_THAT(src, IsClass(_A("R"))); - - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("G1"), "+g1")); - REQUIRE_THAT(src, !IsAggregation(_A("R"), _A("G2"), "+g2")); - REQUIRE_THAT(src, !IsAggregation(_A("R"), _A("G3"), "+g3")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("G4"), "+g4")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsAggregation(src, "R", "G1", "g1")); + REQUIRE(!IsAggregation(src, "R", "G2", "g2")); + REQUIRE(!IsAggregation(src, "R", "G3", "g3")); + REQUIRE(IsAssociation(src, "R", "G4", "g4")); + }); } \ No newline at end of file diff --git a/tests/t00030/test_case.h b/tests/t00030/test_case.h index bd04683e..30a0a2f0 100644 --- a/tests/t00030/test_case.h +++ b/tests/t00030/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00030/test_case.cc + * tests/t00030/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00030", "[test-case][class]") +TEST_CASE("t00030") { + using namespace clanguml::test; + auto [config, db] = load_config("t00030"); auto diagram = config.diagrams["t00030_class"]; @@ -28,55 +30,16 @@ TEST_CASE("t00030", "[test-case][class]") REQUIRE(model->name() == "t00030_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClass(src, "C")); + REQUIRE(IsClass(src, "D")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("A"), "+aaa")); - REQUIRE_THAT( - src, IsComposition(_A("R"), _A("B"), "+bbb", "0..1", "1..*")); - REQUIRE_THAT( - src, IsAggregation(_A("R"), _A("C"), "+ccc", "0..1", "1..5")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("D"), "+ddd", "", "1")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("E"), "+eee", "", "1")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsAggregation(j, "R", "C", "ccc")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("A"), "+aaa")); - REQUIRE_THAT( - src, IsComposition(_A("R"), _A("B"), "+bbb", "0..1", "1..*")); - REQUIRE_THAT( - src, IsAggregation(_A("R"), _A("C"), "+ccc", "0..1", "1..5")); - REQUIRE_THAT(src, IsAssociation(_A("R"), _A("D"), "+ddd", "", "1")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("E"), "+eee", "", "1")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsAssociation(src, "R", "A", "aaa")); + REQUIRE(IsComposition(src, "R", "B", "bbb", "0..1", "1..*")); + REQUIRE(IsAggregation(src, "R", "C", "ccc", "0..1", "1..5")); + REQUIRE(IsAssociation(src, "R", "D", "ddd", "", "1")); + REQUIRE(IsAggregation(src, "R", "E", "eee", "", "1")); + }); } \ No newline at end of file diff --git a/tests/t30001/test_case.h b/tests/t30001/test_case.h index 4772e727..8b85fbe1 100644 --- a/tests/t30001/test_case.h +++ b/tests/t30001/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t30001/test_case.cc + * tests/t30001/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,11 @@ * limitations under the License. */ -TEST_CASE("t30001", "[test-case][package]") +TEST_CASE("t30001") { + using namespace clanguml::test; + using namespace std::string_literals; + auto [config, db] = load_config("t30001"); auto diagram = config.diagrams["t30001_package"]; @@ -28,104 +31,34 @@ TEST_CASE("t30001", "[test-case][package]") REQUIRE(model->name() == "t30001_package"); - { - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(HasTitle(src, "Basic package diagram example")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(!IsNamespacePackage(src, "clanguml"s)); + REQUIRE(!IsNamespacePackage(src, "t30001"s)); + REQUIRE(IsNamespacePackage(src, "A"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s, "AAA"s)); + REQUIRE(IsNamespacePackage(src, "B"s, "AA"s, "AAA"s)); + REQUIRE(IsNamespacePackage(src, "B"s, "AA"s, "BBB"s)); + REQUIRE(IsNamespacePackage(src, "B"s, "BB"s)); + REQUIRE(IsNamespacePackage(src, "B"s)); - REQUIRE_THAT(src, HasTitle("Basic package diagram example")); + REQUIRE( + HasNote(src, "AA", "top", "This is namespace AA in namespace A")); - REQUIRE_THAT(src, IsPackage("A")); - REQUIRE_THAT(src, IsPackage("AAA")); - REQUIRE_THAT(src, IsPackage("AAA")); + REQUIRE(HasLink(src, "AAA", + fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" + "t30001/t30001.cc#L6", + clanguml::util::get_git_commit()), + "AAA")); - // TODO: Fix _A() to handle fully qualified names, right - // now it only finds the first element with unqualified - // name match - REQUIRE_THAT(src, - HasNote(_A("AA"), "top", "This is namespace AA in namespace A")); + REQUIRE(HasLink(src, "BBB", + fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" + "t30001/t30001.cc#L8", + clanguml::util::get_git_commit()), + "BBB")); - REQUIRE_THAT(src, - HasLink(_A("AAA"), - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t30001/t30001.cc#L6", - clanguml::util::get_git_commit()), - "AAA")); - - REQUIRE_THAT(src, - HasLink(_A("BBB"), - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t30001/t30001.cc#L8", - clanguml::util::get_git_commit()), - "BBB")); - - REQUIRE_THAT(src, HasComment("t30001 test diagram of type package")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_package_json(diagram, *model); - - using namespace json; - using namespace std::string_literals; - - REQUIRE(HasTitle(j, "Basic package diagram example")); - - REQUIRE(!IsNamespacePackage(j, "clanguml"s)); - REQUIRE(!IsNamespacePackage(j, "t30001"s)); - REQUIRE(IsNamespacePackage(j, "A"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "AAA"s)); - REQUIRE(IsNamespacePackage(j, "B"s, "AA"s, "AAA"s)); - REQUIRE(IsNamespacePackage(j, "B"s, "AA"s, "BBB"s)); - REQUIRE(IsNamespacePackage(j, "B"s, "BB"s)); - REQUIRE(IsNamespacePackage(j, "B"s)); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_package_mermaid(diagram, *model); - mermaid::AliasMatcher _A(src); - - using mermaid::HasComment; - using mermaid::HasLink; - using mermaid::HasPackageNote; - using mermaid::HasTitle; - using mermaid::IsPackage; - - REQUIRE_THAT(src, HasTitle("Basic package diagram example")); - - REQUIRE_THAT(src, IsPackage(_A("A"))); - REQUIRE_THAT(src, IsPackage(_A("AAA"))); - REQUIRE_THAT(src, IsPackage(_A("AAA"))); - - // TODO: Fix _A() to handle fully qualified names, right - // now it only finds the first element with unqualified - // name match - REQUIRE_THAT(src, - HasPackageNote( - _A("AA"), "top", "This is namespace AA in namespace A")); - - REQUIRE_THAT(src, - HasLink(_A("AAA"), - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t30001/t30001.cc#L6", - clanguml::util::get_git_commit()), - "AAA")); - - REQUIRE_THAT(src, - HasLink(_A("BBB"), - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t30001/t30001.cc#L8", - clanguml::util::get_git_commit()), - "BBB")); - - REQUIRE_THAT(src, HasComment("t30001 test diagram of type package")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(HasComment(src, "t30001 test diagram of type package")); + }); } diff --git a/tests/t30002/test_case.h b/tests/t30002/test_case.h index 908402ae..8b5daa65 100644 --- a/tests/t30002/test_case.h +++ b/tests/t30002/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t30002/test_case.cc + * tests/t30002/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,11 @@ * limitations under the License. */ -TEST_CASE("t30002", "[test-case][package]") +TEST_CASE("t30002") { + using namespace clanguml::test; + using namespace std::string_literals; + auto [config, db] = load_config("t30002"); auto diagram = config.diagrams["t30002_package"]; @@ -28,146 +31,191 @@ TEST_CASE("t30002", "[test-case][package]") REQUIRE(model->name() == "t30002_package"); - { - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s, "A1"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s, "A2"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s, "A3"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s, "A4"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s, "A5"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s, "A6"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s, "A7"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s, "A8"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s, "A9"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s, "A10"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s, "A11"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s, "A12"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s, "A13"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s, "A14"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s, "A15"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s, "A16"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s, "A17"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s, "A18"s)); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsNamespacePackage(src, "B"s, "BB"s, "BBB"s)); - REQUIRE_THAT(src, IsPackage("A1")); - REQUIRE_THAT(src, IsPackage("A2")); - REQUIRE_THAT(src, IsPackage("A3")); - REQUIRE_THAT(src, IsPackage("A4")); - REQUIRE_THAT(src, IsPackage("A5")); - REQUIRE_THAT(src, IsPackage("A6")); - REQUIRE_THAT(src, IsPackage("A7")); - REQUIRE_THAT(src, IsPackage("A8")); - REQUIRE_THAT(src, IsPackage("A9")); - REQUIRE_THAT(src, IsPackage("A11")); - REQUIRE_THAT(src, IsPackage("A12")); - REQUIRE_THAT(src, IsPackage("A13")); - REQUIRE_THAT(src, IsPackage("A14")); - REQUIRE_THAT(src, IsPackage("A15")); - REQUIRE_THAT(src, IsPackage("A16")); - REQUIRE_THAT(src, IsPackage("A17")); - REQUIRE_THAT(src, IsPackage("A18")); + REQUIRE(IsDependency(src, "BBB", "A1")); + REQUIRE(IsDependency(src, "BBB", "A2")); + REQUIRE(IsDependency(src, "BBB", "A3")); + REQUIRE(IsDependency(src, "BBB", "A4")); + REQUIRE(IsDependency(src, "BBB", "A5")); + REQUIRE(IsDependency(src, "BBB", "A6")); + REQUIRE(IsDependency(src, "BBB", "A7")); + REQUIRE(IsDependency(src, "BBB", "A8")); + REQUIRE(IsDependency(src, "BBB", "A9")); + REQUIRE(IsDependency(src, "BBB", "A10")); + REQUIRE(IsDependency(src, "BBB", "A11")); + REQUIRE(IsDependency(src, "BBB", "A12")); + REQUIRE(IsDependency(src, "BBB", "A13")); + REQUIRE(IsDependency(src, "BBB", "A14")); + REQUIRE(IsDependency(src, "BBB", "A15")); + REQUIRE(IsDependency(src, "BBB", "A16")); + REQUIRE(IsDependency(src, "BBB", "A17")); + REQUIRE(IsDependency(src, "BBB", "A18")); + }); + /* + { + auto src = generate_package_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A1"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A2"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A3"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A4"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A5"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A6"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A7"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A8"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A9"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A10"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A11"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A12"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A13"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A14"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A15"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A16"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A17"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A18"))); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + REQUIRE_THAT(src, IsPackage("A1")); + REQUIRE_THAT(src, IsPackage("A2")); + REQUIRE_THAT(src, IsPackage("A3")); + REQUIRE_THAT(src, IsPackage("A4")); + REQUIRE_THAT(src, IsPackage("A5")); + REQUIRE_THAT(src, IsPackage("A6")); + REQUIRE_THAT(src, IsPackage("A7")); + REQUIRE_THAT(src, IsPackage("A8")); + REQUIRE_THAT(src, IsPackage("A9")); + REQUIRE_THAT(src, IsPackage("A11")); + REQUIRE_THAT(src, IsPackage("A12")); + REQUIRE_THAT(src, IsPackage("A13")); + REQUIRE_THAT(src, IsPackage("A14")); + REQUIRE_THAT(src, IsPackage("A15")); + REQUIRE_THAT(src, IsPackage("A16")); + REQUIRE_THAT(src, IsPackage("A17")); + REQUIRE_THAT(src, IsPackage("A18")); - { - auto j = generate_package_json(diagram, *model); + REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A1"))); + REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A2"))); + REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A3"))); + REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A4"))); + REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A5"))); + REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A6"))); + REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A7"))); + REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A8"))); + REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A9"))); + REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A10"))); + REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A11"))); + REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A12"))); + REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A13"))); + REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A14"))); + REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A15"))); + REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A16"))); + REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A17"))); + REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A18"))); - using namespace json; - using namespace std::string_literals; + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A1"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A2"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A3"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A4"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A5"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A6"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A7"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A8"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A9"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A10"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A11"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A12"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A13"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A14"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A15"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A16"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A17"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A18"s)); + { + auto j = generate_package_json(diagram, *model); - REQUIRE(IsNamespacePackage(j, "B"s, "BB"s, "BBB"s)); + using namespace json; + using namespace std::string_literals; - REQUIRE(IsDependency(j, "BBB", "A1")); - REQUIRE(IsDependency(j, "BBB", "A2")); - REQUIRE(IsDependency(j, "BBB", "A3")); - REQUIRE(IsDependency(j, "BBB", "A4")); - REQUIRE(IsDependency(j, "BBB", "A5")); - REQUIRE(IsDependency(j, "BBB", "A6")); - REQUIRE(IsDependency(j, "BBB", "A7")); - REQUIRE(IsDependency(j, "BBB", "A8")); - REQUIRE(IsDependency(j, "BBB", "A9")); - REQUIRE(IsDependency(j, "BBB", "A10")); - REQUIRE(IsDependency(j, "BBB", "A11")); - REQUIRE(IsDependency(j, "BBB", "A12")); - REQUIRE(IsDependency(j, "BBB", "A13")); - REQUIRE(IsDependency(j, "BBB", "A14")); - REQUIRE(IsDependency(j, "BBB", "A15")); - REQUIRE(IsDependency(j, "BBB", "A16")); - REQUIRE(IsDependency(j, "BBB", "A17")); - REQUIRE(IsDependency(j, "BBB", "A18")); + REQUIRE(IsNamespacePackage(j, "A"s, "AA"s)); + REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A1"s)); + REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A2"s)); + REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A3"s)); + REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A4"s)); + REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A5"s)); + REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A6"s)); + REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A7"s)); + REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A8"s)); + REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A9"s)); + REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A10"s)); + REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A11"s)); + REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A12"s)); + REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A13"s)); + REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A14"s)); + REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A15"s)); + REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A16"s)); + REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A17"s)); + REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A18"s)); - save_json(config.output_directory(), diagram->name + ".json", j); - } + REQUIRE(IsNamespacePackage(j, "B"s, "BB"s, "BBB"s)); - { - auto src = generate_package_mermaid(diagram, *model); - mermaid::AliasMatcher _A(src); - using mermaid::IsPackage; - using mermaid::IsPackageDependency; + REQUIRE(IsDependency(j, "BBB", "A1")); + REQUIRE(IsDependency(j, "BBB", "A2")); + REQUIRE(IsDependency(j, "BBB", "A3")); + REQUIRE(IsDependency(j, "BBB", "A4")); + REQUIRE(IsDependency(j, "BBB", "A5")); + REQUIRE(IsDependency(j, "BBB", "A6")); + REQUIRE(IsDependency(j, "BBB", "A7")); + REQUIRE(IsDependency(j, "BBB", "A8")); + REQUIRE(IsDependency(j, "BBB", "A9")); + REQUIRE(IsDependency(j, "BBB", "A10")); + REQUIRE(IsDependency(j, "BBB", "A11")); + REQUIRE(IsDependency(j, "BBB", "A12")); + REQUIRE(IsDependency(j, "BBB", "A13")); + REQUIRE(IsDependency(j, "BBB", "A14")); + REQUIRE(IsDependency(j, "BBB", "A15")); + REQUIRE(IsDependency(j, "BBB", "A16")); + REQUIRE(IsDependency(j, "BBB", "A17")); + REQUIRE(IsDependency(j, "BBB", "A18")); - REQUIRE_THAT(src, IsPackage(_A("A1"))); - REQUIRE_THAT(src, IsPackage(_A("A2"))); - REQUIRE_THAT(src, IsPackage(_A("A3"))); - REQUIRE_THAT(src, IsPackage(_A("A4"))); - REQUIRE_THAT(src, IsPackage(_A("A5"))); - REQUIRE_THAT(src, IsPackage(_A("A6"))); - REQUIRE_THAT(src, IsPackage(_A("A7"))); - REQUIRE_THAT(src, IsPackage(_A("A8"))); - REQUIRE_THAT(src, IsPackage(_A("A9"))); - REQUIRE_THAT(src, IsPackage(_A("A11"))); - REQUIRE_THAT(src, IsPackage(_A("A12"))); - REQUIRE_THAT(src, IsPackage(_A("A13"))); - REQUIRE_THAT(src, IsPackage(_A("A14"))); - REQUIRE_THAT(src, IsPackage(_A("A15"))); - REQUIRE_THAT(src, IsPackage(_A("A16"))); - REQUIRE_THAT(src, IsPackage(_A("A17"))); - REQUIRE_THAT(src, IsPackage(_A("A18"))); + save_json(config.output_directory(), diagram->name + ".json", j); + } - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A1"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A2"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A3"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A4"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A5"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A6"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A7"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A8"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A9"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A10"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A11"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A12"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A13"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A14"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A15"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A16"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A17"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A18"))); + { + auto src = generate_package_mermaid(diagram, *model); + mermaid::AliasMatcher _A(src); + using mermaid::IsPackage; + using mermaid::IsPackageDependency; - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE_THAT(src, IsPackage(_A("A1"))); + REQUIRE_THAT(src, IsPackage(_A("A2"))); + REQUIRE_THAT(src, IsPackage(_A("A3"))); + REQUIRE_THAT(src, IsPackage(_A("A4"))); + REQUIRE_THAT(src, IsPackage(_A("A5"))); + REQUIRE_THAT(src, IsPackage(_A("A6"))); + REQUIRE_THAT(src, IsPackage(_A("A7"))); + REQUIRE_THAT(src, IsPackage(_A("A8"))); + REQUIRE_THAT(src, IsPackage(_A("A9"))); + REQUIRE_THAT(src, IsPackage(_A("A11"))); + REQUIRE_THAT(src, IsPackage(_A("A12"))); + REQUIRE_THAT(src, IsPackage(_A("A13"))); + REQUIRE_THAT(src, IsPackage(_A("A14"))); + REQUIRE_THAT(src, IsPackage(_A("A15"))); + REQUIRE_THAT(src, IsPackage(_A("A16"))); + REQUIRE_THAT(src, IsPackage(_A("A17"))); + REQUIRE_THAT(src, IsPackage(_A("A18"))); + + REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A1"))); + REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A2"))); + REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A3"))); + REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A4"))); + REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A5"))); + REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A6"))); + REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A7"))); + REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A8"))); + REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A9"))); + REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A10"))); + REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A11"))); + REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A12"))); + REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A13"))); + REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A14"))); + REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A15"))); + REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A16"))); + REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A17"))); + REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A18"))); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + } + */ } diff --git a/tests/t30003/test_case.h b/tests/t30003/test_case.h index 4b9f5863..301bbb73 100644 --- a/tests/t30003/test_case.h +++ b/tests/t30003/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t30003/test_case.cc + * tests/t30003/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,11 @@ * limitations under the License. */ -TEST_CASE("t30003", "[test-case][package]") +TEST_CASE("t30003") { + using namespace clanguml::test; + using namespace std::string_literals; + auto [config, db] = load_config("t30003"); auto diagram = config.diagrams["t30003_package"]; @@ -27,58 +30,16 @@ TEST_CASE("t30003", "[test-case][package]") auto model = generate_package_diagram(*db, diagram); REQUIRE(model->name() == "t30003_package"); - { - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsNamespacePackage(src, "ns1"s)); + REQUIRE(IsNamespacePackage(src, "ns1"s, "ns2_v1_0_0"s)); + REQUIRE(IsNamespacePackage(src, "ns1"s, "ns2_v0_9_0"s)); + REQUIRE(IsNamespacePackage(src, "ns3"s)); + REQUIRE(IsNamespacePackage(src, "ns3"s, "ns1"s)); + REQUIRE(IsNamespacePackage(src, "ns3"s, "ns1"s, "ns2"s)); - REQUIRE_THAT(src, IsPackage("ns1")); - REQUIRE_THAT(src, IsPackage("ns2")); - REQUIRE_THAT(src, IsPackage("ns3")); - REQUIRE_THAT(src, IsPackage("ns2_v1_0_0")); - REQUIRE_THAT(src, IsPackage("ns2_v0_9_0")); - - REQUIRE_THAT(src, IsDeprecated(_A("ns2_v0_9_0"))); - REQUIRE_THAT(src, IsDeprecated(_A("ns3"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_package_json(diagram, *model); - - using namespace json; - using namespace std::string_literals; - - REQUIRE(IsNamespacePackage(j, "ns1"s)); - REQUIRE(IsNamespacePackage(j, "ns1"s, "ns2_v1_0_0"s)); - REQUIRE(IsNamespacePackage(j, "ns1"s, "ns2_v0_9_0"s)); - REQUIRE(IsNamespacePackage(j, "ns3"s)); - REQUIRE(IsNamespacePackage(j, "ns3"s, "ns1"s)); - REQUIRE(IsNamespacePackage(j, "ns3"s, "ns1"s, "ns2"s)); - - REQUIRE(IsDeprecated(j, "ns2_v0_9_0")); - REQUIRE(IsDeprecated(j, "ns3")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_package_mermaid(diagram, *model); - mermaid::AliasMatcher _A(src); - using mermaid::IsPackage; - - REQUIRE_THAT(src, IsPackage(_A("ns1"))); - REQUIRE_THAT(src, IsPackage(_A("ns2"))); - REQUIRE_THAT(src, IsPackage(_A("ns3"))); - REQUIRE_THAT(src, IsPackage(_A("ns2_v1_0_0"))); - REQUIRE_THAT(src, IsPackage(_A("ns2_v0_9_0"))); - - // REQUIRE_THAT(src, IsDeprecated(_A("ns2_v0_9_0"))); - // REQUIRE_THAT(src, IsDeprecated(_A("ns3"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + // REQUIRE(IsDeprecated(src, "ns2_v0_9_0")); + // REQUIRE(IsDeprecated(src, "ns3")); + }); } diff --git a/tests/t30004/test_case.h b/tests/t30004/test_case.h index bd66c760..4829f92a 100644 --- a/tests/t30004/test_case.h +++ b/tests/t30004/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t30004/test_case.cc + * tests/t30004/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,11 @@ * limitations under the License. */ -TEST_CASE("t30004", "[test-case][package]") +TEST_CASE("t30004") { + using namespace clanguml::test; + using namespace std::string_literals; + auto [config, db] = load_config("t30004"); auto diagram = config.diagrams["t30004_package"]; @@ -28,7 +31,15 @@ TEST_CASE("t30004", "[test-case][package]") REQUIRE(model->name() == "t30004_package"); - { + CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsNamespacePackage(src, "A"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AAA"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "BBB"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "CCC"s)); + REQUIRE(!IsNamespacePackage(src, "A"s, "DDD"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "EEE"s)); + }); + /*{ auto src = generate_package_puml(diagram, *model); AliasMatcher _A(src); @@ -72,5 +83,5 @@ TEST_CASE("t30004", "[test-case][package]") REQUIRE_THAT(src, IsPackage(_A("EEE"))); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } diff --git a/tests/t30005/test_case.h b/tests/t30005/test_case.h index 57248548..ef0098b3 100644 --- a/tests/t30005/test_case.h +++ b/tests/t30005/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t30005/test_case.cc + * tests/t30005/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,11 @@ * limitations under the License. */ -TEST_CASE("t30005", "[test-case][package]") +TEST_CASE("t30005") { + using namespace clanguml::test; + using namespace std::string_literals; + auto [config, db] = load_config("t30005"); auto diagram = config.diagrams["t30005_package"]; @@ -28,6 +31,21 @@ TEST_CASE("t30005", "[test-case][package]") REQUIRE(model->name() == "t30005_package"); + CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsNamespacePackage(src, "A"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s, "AAA"s)); + REQUIRE(IsNamespacePackage(src, "B"s)); + REQUIRE(IsNamespacePackage(src, "B"s, "BB"s)); + REQUIRE(IsNamespacePackage(src, "B"s, "BB"s, "BBB"s)); + REQUIRE(IsNamespacePackage(src, "C"s)); + REQUIRE(IsNamespacePackage(src, "C"s, "CC"s)); + REQUIRE(IsNamespacePackage(src, "C"s, "CC"s, "CCC"s)); + + REQUIRE(IsDependency(src, "BBB", "AAA")); + REQUIRE(IsDependency(src, "CCC", "AAA")); + }); +/* { auto src = generate_package_puml(diagram, *model); AliasMatcher _A(src); @@ -82,5 +100,5 @@ TEST_CASE("t30005", "[test-case][package]") REQUIRE_THAT(src, IsPackageDependency(_A("CCC"), _A("AAA"))); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } diff --git a/tests/t30006/test_case.h b/tests/t30006/test_case.h index 6201fa50..3e580e14 100644 --- a/tests/t30006/test_case.h +++ b/tests/t30006/test_case.h @@ -16,8 +16,11 @@ * limitations under the License. */ -TEST_CASE("t30006", "[test-case][package]") +TEST_CASE("t30006") { + using namespace clanguml::test; + using namespace std::string_literals; + auto [config, db] = load_config("t30006"); auto diagram = config.diagrams["t30006_package"]; @@ -28,6 +31,16 @@ TEST_CASE("t30006", "[test-case][package]") REQUIRE(model->name() == "t30006_package"); + CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsNamespacePackage(src, "A"s)); + REQUIRE(IsNamespacePackage(src, "B"s)); + REQUIRE(IsNamespacePackage(src, "C"s)); + + REQUIRE(IsDependency(src, "A", "B")); + REQUIRE(IsDependency(src, "A", "C")); + }); + + /* { auto src = generate_package_puml(diagram, *model); AliasMatcher _A(src); @@ -75,5 +88,5 @@ TEST_CASE("t30006", "[test-case][package]") REQUIRE_THAT(src, IsPackageDependency(_A("A"), _A("C"))); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } diff --git a/tests/t30007/test_case.h b/tests/t30007/test_case.h index 653212db..58fd9b39 100644 --- a/tests/t30007/test_case.h +++ b/tests/t30007/test_case.h @@ -16,8 +16,11 @@ * limitations under the License. */ -TEST_CASE("t30007", "[test-case][package]") +TEST_CASE("t30007") { + using namespace clanguml::test; + using namespace std::string_literals; + auto [config, db] = load_config("t30007"); auto diagram = config.diagrams["t30007_package"]; @@ -28,56 +31,68 @@ TEST_CASE("t30007", "[test-case][package]") REQUIRE(model->name() == "t30007_package"); - { - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsNamespacePackage(src, "A"s)); + REQUIRE(IsNamespacePackage(src, "A"s, "AA"s)); + REQUIRE(IsNamespacePackage(src, "B"s)); + REQUIRE(IsNamespacePackage(src, "C"s)); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsDependency(src, "AA", "B")); + REQUIRE(IsDependency(src, "AA", "C")); + }); + /* + { + auto src = generate_package_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE_THAT(src, IsPackage("A")); - REQUIRE_THAT(src, IsPackage("B")); - REQUIRE_THAT(src, IsPackage("C")); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsDependency(_A("AA"), _A("B"))); - REQUIRE_THAT(src, IsDependency(_A("AA"), _A("C"))); + REQUIRE_THAT(src, IsPackage("A")); + REQUIRE_THAT(src, IsPackage("B")); + REQUIRE_THAT(src, IsPackage("C")); - REQUIRE_THAT(src, IsLayoutHint(_A("C"), "up", _A("AA"))); - REQUIRE_THAT(src, IsLayoutHint(_A("C"), "left", _A("B"))); + REQUIRE_THAT(src, IsDependency(_A("AA"), _A("B"))); + REQUIRE_THAT(src, IsDependency(_A("AA"), _A("C"))); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + REQUIRE_THAT(src, IsLayoutHint(_A("C"), "up", _A("AA"))); + REQUIRE_THAT(src, IsLayoutHint(_A("C"), "left", _A("B"))); - { - auto j = generate_package_json(diagram, *model); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - using namespace json; - using namespace std::string_literals; + { + auto j = generate_package_json(diagram, *model); - REQUIRE(IsNamespacePackage(j, "A"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s)); - REQUIRE(IsNamespacePackage(j, "B"s)); - REQUIRE(IsNamespacePackage(j, "C"s)); + using namespace json; + using namespace std::string_literals; - REQUIRE(IsDependency(j, "AA", "B")); - REQUIRE(IsDependency(j, "AA", "C")); + REQUIRE(IsNamespacePackage(j, "A"s)); + REQUIRE(IsNamespacePackage(j, "A"s, "AA"s)); + REQUIRE(IsNamespacePackage(j, "B"s)); + REQUIRE(IsNamespacePackage(j, "C"s)); - save_json(config.output_directory(), diagram->name + ".json", j); - } + REQUIRE(IsDependency(j, "AA", "B")); + REQUIRE(IsDependency(j, "AA", "C")); - { - auto src = generate_package_mermaid(diagram, *model); - mermaid::AliasMatcher _A(src); - using mermaid::IsPackage; - using mermaid::IsPackageDependency; + save_json(config.output_directory(), diagram->name + ".json", j); + } - REQUIRE_THAT(src, IsPackage(_A("A"))); - REQUIRE_THAT(src, IsPackage(_A("B"))); - REQUIRE_THAT(src, IsPackage(_A("C"))); + { + auto src = generate_package_mermaid(diagram, *model); + mermaid::AliasMatcher _A(src); + using mermaid::IsPackage; + using mermaid::IsPackageDependency; - REQUIRE_THAT(src, IsPackageDependency(_A("AA"), _A("B"))); - REQUIRE_THAT(src, IsPackageDependency(_A("AA"), _A("C"))); + REQUIRE_THAT(src, IsPackage(_A("A"))); + REQUIRE_THAT(src, IsPackage(_A("B"))); + REQUIRE_THAT(src, IsPackage(_A("C"))); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE_THAT(src, IsPackageDependency(_A("AA"), _A("B"))); + REQUIRE_THAT(src, IsPackageDependency(_A("AA"), _A("C"))); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + } + */ } diff --git a/tests/t30008/test_case.h b/tests/t30008/test_case.h index 70f52d6a..9100a09e 100644 --- a/tests/t30008/test_case.h +++ b/tests/t30008/test_case.h @@ -16,8 +16,11 @@ * limitations under the License. */ -TEST_CASE("t30008", "[test-case][package]") +TEST_CASE("t30008") { + using namespace clanguml::test; + using namespace std::string_literals; + auto [config, db] = load_config("t30008"); auto diagram = config.diagrams["t30008_package"]; @@ -28,79 +31,98 @@ TEST_CASE("t30008", "[test-case][package]") REQUIRE(model->name() == "t30008_package"); - { - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsNamespacePackage(src, "dependants"s, "A"s)); + REQUIRE(IsNamespacePackage(src, "dependants"s, "B"s)); + REQUIRE(IsNamespacePackage(src, "dependants"s, "C"s)); + REQUIRE(!IsNamespacePackage(src, "dependants"s, "X"s)); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsDependency(src, "B", "A")); + REQUIRE(IsDependency(src, "C", "B")); - REQUIRE_THAT(src, IsPackage("A")); - REQUIRE_THAT(src, IsPackage("B")); - REQUIRE_THAT(src, IsPackage("C")); - REQUIRE_THAT(src, !IsPackage("X")); + REQUIRE(IsNamespacePackage(src, "dependencies"s, "D"s)); + REQUIRE(IsNamespacePackage(src, "dependencies"s, "E"s)); + REQUIRE(IsNamespacePackage(src, "dependencies"s, "F"s)); + REQUIRE(!IsNamespacePackage(src, "dependencies"s, "Y"s)); - REQUIRE_THAT(src, IsDependency(_A("B"), _A("A"))); - REQUIRE_THAT(src, IsDependency(_A("C"), _A("B"))); + REQUIRE(IsDependency(src, "E", "D")); + REQUIRE(IsDependency(src, "F", "E")); + }); + /* + { + auto src = generate_package_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE_THAT(src, IsPackage("D")); - REQUIRE_THAT(src, IsPackage("E")); - REQUIRE_THAT(src, IsPackage("F")); - REQUIRE_THAT(src, !IsPackage("Y")); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsDependency(_A("E"), _A("D"))); - REQUIRE_THAT(src, IsDependency(_A("F"), _A("E"))); + REQUIRE_THAT(src, IsPackage("A")); + REQUIRE_THAT(src, IsPackage("B")); + REQUIRE_THAT(src, IsPackage("C")); + REQUIRE_THAT(src, !IsPackage("X")); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + REQUIRE_THAT(src, IsDependency(_A("B"), _A("A"))); + REQUIRE_THAT(src, IsDependency(_A("C"), _A("B"))); - { - auto j = generate_package_json(diagram, *model); + REQUIRE_THAT(src, IsPackage("D")); + REQUIRE_THAT(src, IsPackage("E")); + REQUIRE_THAT(src, IsPackage("F")); + REQUIRE_THAT(src, !IsPackage("Y")); - using namespace json; - using namespace std::string_literals; + REQUIRE_THAT(src, IsDependency(_A("E"), _A("D"))); + REQUIRE_THAT(src, IsDependency(_A("F"), _A("E"))); - REQUIRE(IsNamespacePackage(j, "dependants"s, "A"s)); - REQUIRE(IsNamespacePackage(j, "dependants"s, "B"s)); - REQUIRE(IsNamespacePackage(j, "dependants"s, "C"s)); - REQUIRE(!IsNamespacePackage(j, "dependants"s, "X"s)); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - REQUIRE(IsDependency(j, "B", "A")); - REQUIRE(IsDependency(j, "C", "B")); + { + auto j = generate_package_json(diagram, *model); - REQUIRE(IsNamespacePackage(j, "dependencies"s, "D"s)); - REQUIRE(IsNamespacePackage(j, "dependencies"s, "E"s)); - REQUIRE(IsNamespacePackage(j, "dependencies"s, "F"s)); - REQUIRE(!IsNamespacePackage(j, "dependencies"s, "Y"s)); + using namespace json; + using namespace std::string_literals; - REQUIRE(IsDependency(j, "E", "D")); - REQUIRE(IsDependency(j, "F", "E")); + REQUIRE(IsNamespacePackage(j, "dependants"s, "A"s)); + REQUIRE(IsNamespacePackage(j, "dependants"s, "B"s)); + REQUIRE(IsNamespacePackage(j, "dependants"s, "C"s)); + REQUIRE(!IsNamespacePackage(j, "dependants"s, "X"s)); - save_json(config.output_directory(), diagram->name + ".json", j); - } + REQUIRE(IsDependency(j, "B", "A")); + REQUIRE(IsDependency(j, "C", "B")); - { - auto src = generate_package_mermaid(diagram, *model); - mermaid::AliasMatcher _A(src); - using mermaid::IsPackage; - using mermaid::IsPackageDependency; + REQUIRE(IsNamespacePackage(j, "dependencies"s, "D"s)); + REQUIRE(IsNamespacePackage(j, "dependencies"s, "E"s)); + REQUIRE(IsNamespacePackage(j, "dependencies"s, "F"s)); + REQUIRE(!IsNamespacePackage(j, "dependencies"s, "Y"s)); - REQUIRE_THAT(src, IsPackage(_A("A"))); - REQUIRE_THAT(src, IsPackage(_A("B"))); - REQUIRE_THAT(src, IsPackage(_A("C"))); - REQUIRE_THAT(src, !IsPackage(_A("X"))); + REQUIRE(IsDependency(j, "E", "D")); + REQUIRE(IsDependency(j, "F", "E")); - REQUIRE_THAT(src, IsPackageDependency(_A("B"), _A("A"))); - REQUIRE_THAT(src, IsPackageDependency(_A("C"), _A("B"))); + save_json(config.output_directory(), diagram->name + ".json", j); + } - REQUIRE_THAT(src, IsPackage(_A("D"))); - REQUIRE_THAT(src, IsPackage(_A("E"))); - REQUIRE_THAT(src, IsPackage(_A("F"))); - REQUIRE_THAT(src, !IsPackage(_A("Y"))); + { + auto src = generate_package_mermaid(diagram, *model); + mermaid::AliasMatcher _A(src); + using mermaid::IsPackage; + using mermaid::IsPackageDependency; - REQUIRE_THAT(src, IsPackageDependency(_A("E"), _A("D"))); - REQUIRE_THAT(src, IsPackageDependency(_A("F"), _A("E"))); + REQUIRE_THAT(src, IsPackage(_A("A"))); + REQUIRE_THAT(src, IsPackage(_A("B"))); + REQUIRE_THAT(src, IsPackage(_A("C"))); + REQUIRE_THAT(src, !IsPackage(_A("X"))); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE_THAT(src, IsPackageDependency(_A("B"), _A("A"))); + REQUIRE_THAT(src, IsPackageDependency(_A("C"), _A("B"))); + + REQUIRE_THAT(src, IsPackage(_A("D"))); + REQUIRE_THAT(src, IsPackage(_A("E"))); + REQUIRE_THAT(src, IsPackage(_A("F"))); + REQUIRE_THAT(src, !IsPackage(_A("Y"))); + + REQUIRE_THAT(src, IsPackageDependency(_A("E"), _A("D"))); + REQUIRE_THAT(src, IsPackageDependency(_A("F"), _A("E"))); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } diff --git a/tests/t30009/test_case.h b/tests/t30009/test_case.h index 84600695..8a2156b3 100644 --- a/tests/t30009/test_case.h +++ b/tests/t30009/test_case.h @@ -16,8 +16,11 @@ * limitations under the License. */ -TEST_CASE("t30009", "[test-case][package]") +TEST_CASE("t30009") { + using namespace clanguml::test; + using namespace std::string_literals; + auto [config, db] = load_config("t30009"); auto diagram = config.diagrams["t30009_package"]; @@ -28,56 +31,70 @@ TEST_CASE("t30009", "[test-case][package]") REQUIRE(model->name() == "t30009_package"); - { - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsNamespacePackage(src, "One"s)); + REQUIRE(IsNamespacePackage(src, "Two"s)); + REQUIRE(IsNamespacePackage(src, "One"s, "A"s)); + REQUIRE(IsNamespacePackage(src, "One"s, "B"s)); + REQUIRE(IsNamespacePackage(src, "One"s, "C"s)); + REQUIRE(IsNamespacePackage(src, "One"s, "D"s)); + REQUIRE(IsNamespacePackage(src, "Two"s, "A"s)); + REQUIRE(IsNamespacePackage(src, "Two"s, "B"s)); + REQUIRE(IsNamespacePackage(src, "Two"s, "C"s)); + REQUIRE(IsNamespacePackage(src, "Two"s, "D"s)); + }); + /* + { + auto src = generate_package_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - // Check if all packages exist - REQUIRE_THAT(src, IsPackage("One")); - REQUIRE_THAT(src, IsPackage("Two")); - REQUIRE_THAT(src, IsPackage("A")); - REQUIRE_THAT(src, IsPackage("B")); - REQUIRE_THAT(src, IsPackage("C")); - REQUIRE_THAT(src, IsPackage("D")); + // Check if all packages exist + REQUIRE_THAT(src, IsPackage("One")); + REQUIRE_THAT(src, IsPackage("Two")); + REQUIRE_THAT(src, IsPackage("A")); + REQUIRE_THAT(src, IsPackage("B")); + REQUIRE_THAT(src, IsPackage("C")); + REQUIRE_THAT(src, IsPackage("D")); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - { - auto j = generate_package_json(diagram, *model); + { + auto j = generate_package_json(diagram, *model); - using namespace json; - using namespace std::string_literals; + using namespace json; + using namespace std::string_literals; - REQUIRE(IsNamespacePackage(j, "One"s)); - REQUIRE(IsNamespacePackage(j, "Two"s)); - REQUIRE(IsNamespacePackage(j, "One"s, "A"s)); - REQUIRE(IsNamespacePackage(j, "One"s, "B"s)); - REQUIRE(IsNamespacePackage(j, "One"s, "C"s)); - REQUIRE(IsNamespacePackage(j, "One"s, "D"s)); - REQUIRE(IsNamespacePackage(j, "Two"s, "A"s)); - REQUIRE(IsNamespacePackage(j, "Two"s, "B"s)); - REQUIRE(IsNamespacePackage(j, "Two"s, "C"s)); - REQUIRE(IsNamespacePackage(j, "Two"s, "D"s)); + REQUIRE(IsNamespacePackage(j, "One"s)); + REQUIRE(IsNamespacePackage(j, "Two"s)); + REQUIRE(IsNamespacePackage(j, "One"s, "A"s)); + REQUIRE(IsNamespacePackage(j, "One"s, "B"s)); + REQUIRE(IsNamespacePackage(j, "One"s, "C"s)); + REQUIRE(IsNamespacePackage(j, "One"s, "D"s)); + REQUIRE(IsNamespacePackage(j, "Two"s, "A"s)); + REQUIRE(IsNamespacePackage(j, "Two"s, "B"s)); + REQUIRE(IsNamespacePackage(j, "Two"s, "C"s)); + REQUIRE(IsNamespacePackage(j, "Two"s, "D"s)); - save_json(config.output_directory(), diagram->name + ".json", j); - } + save_json(config.output_directory(), diagram->name + ".json", j); + } - { - auto src = generate_package_mermaid(diagram, *model); - mermaid::AliasMatcher _A(src); - using mermaid::IsPackage; + { + auto src = generate_package_mermaid(diagram, *model); + mermaid::AliasMatcher _A(src); + using mermaid::IsPackage; - REQUIRE_THAT(src, IsPackage(_A("One"))); - REQUIRE_THAT(src, IsPackage(_A("Two"))); - REQUIRE_THAT(src, IsPackage(_A("A"))); - REQUIRE_THAT(src, IsPackage(_A("B"))); - REQUIRE_THAT(src, IsPackage(_A("C"))); - REQUIRE_THAT(src, IsPackage(_A("D"))); + REQUIRE_THAT(src, IsPackage(_A("One"))); + REQUIRE_THAT(src, IsPackage(_A("Two"))); + REQUIRE_THAT(src, IsPackage(_A("A"))); + REQUIRE_THAT(src, IsPackage(_A("B"))); + REQUIRE_THAT(src, IsPackage(_A("C"))); + REQUIRE_THAT(src, IsPackage(_A("D"))); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t30010/test_case.h b/tests/t30010/test_case.h index 19d06edf..cab73e2b 100644 --- a/tests/t30010/test_case.h +++ b/tests/t30010/test_case.h @@ -16,8 +16,11 @@ * limitations under the License. */ -TEST_CASE("t30010", "[test-case][package]") +TEST_CASE("t30010") { + using namespace clanguml::test; + using namespace std::string_literals; + auto [config, db] = load_config("t30010"); auto diagram = config.diagrams["t30010_package"]; @@ -28,61 +31,75 @@ TEST_CASE("t30010", "[test-case][package]") REQUIRE(model->name() == "t30010_package"); - { - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsDirectoryPackage(src, "app"s)); + REQUIRE(IsDirectoryPackage(src, "libraries"s, "lib1"s)); + REQUIRE(IsDirectoryPackage(src, "libraries"s, "lib2"s)); + REQUIRE(IsDirectoryPackage(src, "libraries"s, "lib3"s)); + REQUIRE(IsDirectoryPackage(src, "libraries"s, "lib4"s)); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsDependency(src, "app", "lib1")); + REQUIRE(IsDependency(src, "app", "lib2")); + REQUIRE(IsDependency(src, "app", "lib3")); + REQUIRE(IsDependency(src, "app", "lib4")); + }); + /* + { + auto src = generate_package_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE_THAT(src, IsPackage("app")); - REQUIRE_THAT(src, IsPackage("libraries")); - REQUIRE_THAT(src, IsPackage("lib1")); - REQUIRE_THAT(src, IsPackage("lib2")); - REQUIRE_THAT(src, !IsPackage("library1")); - REQUIRE_THAT(src, !IsPackage("library2")); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib1"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib2"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib3"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib4"))); + REQUIRE_THAT(src, IsPackage("app")); + REQUIRE_THAT(src, IsPackage("libraries")); + REQUIRE_THAT(src, IsPackage("lib1")); + REQUIRE_THAT(src, IsPackage("lib2")); + REQUIRE_THAT(src, !IsPackage("library1")); + REQUIRE_THAT(src, !IsPackage("library2")); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib1"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib2"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib3"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib4"))); - { - auto j = generate_package_json(diagram, *model); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - using namespace json; - using namespace std::string_literals; + { + auto j = generate_package_json(diagram, *model); - REQUIRE(IsDirectoryPackage(j, "app"s)); - REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib1"s)); - REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib2"s)); - REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib3"s)); - REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib4"s)); + using namespace json; + using namespace std::string_literals; - save_json(config.output_directory(), diagram->name + ".json", j); - } + REQUIRE(IsDirectoryPackage(j, "app"s)); + REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib1"s)); + REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib2"s)); + REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib3"s)); + REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib4"s)); - { - auto src = generate_package_mermaid(diagram, *model); - mermaid::AliasMatcher _A(src); - using mermaid::IsPackage; - using mermaid::IsPackageDependency; + save_json(config.output_directory(), diagram->name + ".json", j); + } - REQUIRE_THAT(src, IsPackage(_A("app"))); - REQUIRE_THAT(src, IsPackage(_A("libraries"))); - REQUIRE_THAT(src, IsPackage(_A("lib1"))); - REQUIRE_THAT(src, IsPackage(_A("lib2"))); - REQUIRE_THAT(src, !IsPackage(_A("library1"))); - REQUIRE_THAT(src, !IsPackage(_A("library2"))); + { + auto src = generate_package_mermaid(diagram, *model); + mermaid::AliasMatcher _A(src); + using mermaid::IsPackage; + using mermaid::IsPackageDependency; - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib1"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib2"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib3"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib4"))); + REQUIRE_THAT(src, IsPackage(_A("app"))); + REQUIRE_THAT(src, IsPackage(_A("libraries"))); + REQUIRE_THAT(src, IsPackage(_A("lib1"))); + REQUIRE_THAT(src, IsPackage(_A("lib2"))); + REQUIRE_THAT(src, !IsPackage(_A("library1"))); + REQUIRE_THAT(src, !IsPackage(_A("library2"))); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib1"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib2"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib3"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib4"))); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t30011/test_case.h b/tests/t30011/test_case.h index a8adfd0a..949ab8b0 100644 --- a/tests/t30011/test_case.h +++ b/tests/t30011/test_case.h @@ -16,8 +16,11 @@ * limitations under the License. */ -TEST_CASE("t30011", "[test-case][package]") +TEST_CASE("t30011") { + using namespace clanguml::test; + using namespace std::string_literals; + auto [config, db] = load_config("t30011"); auto diagram = config.diagrams["t30011_package"]; @@ -28,66 +31,81 @@ TEST_CASE("t30011", "[test-case][package]") REQUIRE(model->name() == "t30011_package"); - { - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsDirectoryPackage(src, "app"s)); + REQUIRE(IsDirectoryPackage(src, "libraries"s, "lib1"s)); + REQUIRE(IsDirectoryPackage(src, "libraries"s, "lib2"s)); + REQUIRE(IsDirectoryPackage(src, "libraries"s, "lib3"s)); + REQUIRE(IsDirectoryPackage(src, "libraries"s, "lib4"s)); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsDependency(src, "app"s, "lib1"s)); + REQUIRE(IsDependency(src, "app"s, "lib2"s)); + REQUIRE(IsDependency(src, "app"s, "lib3"s)); + REQUIRE(IsDependency(src, "app"s, "lib4"s)); + }); + /* + { + auto src = generate_package_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE_THAT(src, IsPackage("app")); - REQUIRE_THAT(src, IsPackage("libraries")); - REQUIRE_THAT(src, IsPackage("lib1")); - REQUIRE_THAT(src, IsPackage("lib2")); - REQUIRE_THAT(src, !IsPackage("library1")); - REQUIRE_THAT(src, !IsPackage("library2")); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib1"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib2"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib3"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib4"))); + REQUIRE_THAT(src, IsPackage("app")); + REQUIRE_THAT(src, IsPackage("libraries")); + REQUIRE_THAT(src, IsPackage("lib1")); + REQUIRE_THAT(src, IsPackage("lib2")); + REQUIRE_THAT(src, !IsPackage("library1")); + REQUIRE_THAT(src, !IsPackage("library2")); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib1"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib2"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib3"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib4"))); - { - auto j = generate_package_json(diagram, *model); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - using namespace json; - using namespace std::string_literals; + { + auto j = generate_package_json(diagram, *model); - REQUIRE(IsDirectoryPackage(j, "app"s)); - REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib1"s)); - REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib2"s)); - REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib3"s)); - REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib4"s)); + using namespace json; + using namespace std::string_literals; - REQUIRE(IsDependency(j, "app"s, "lib1"s)); - REQUIRE(IsDependency(j, "app"s, "lib2"s)); - REQUIRE(IsDependency(j, "app"s, "lib3"s)); - REQUIRE(IsDependency(j, "app"s, "lib4"s)); + REQUIRE(IsDirectoryPackage(j, "app"s)); + REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib1"s)); + REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib2"s)); + REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib3"s)); + REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib4"s)); - save_json(config.output_directory(), diagram->name + ".json", j); - } + REQUIRE(IsDependency(j, "app"s, "lib1"s)); + REQUIRE(IsDependency(j, "app"s, "lib2"s)); + REQUIRE(IsDependency(j, "app"s, "lib3"s)); + REQUIRE(IsDependency(j, "app"s, "lib4"s)); - { - auto src = generate_package_mermaid(diagram, *model); - mermaid::AliasMatcher _A(src); - using mermaid::IsPackage; - using mermaid::IsPackageDependency; + save_json(config.output_directory(), diagram->name + ".json", j); + } - REQUIRE_THAT(src, IsPackage(_A("app"))); - REQUIRE_THAT(src, IsPackage(_A("libraries"))); - REQUIRE_THAT(src, IsPackage(_A("lib1"))); - REQUIRE_THAT(src, IsPackage(_A("lib2"))); - REQUIRE_THAT(src, !IsPackage(_A("library1"))); - REQUIRE_THAT(src, !IsPackage(_A("library2"))); + { + auto src = generate_package_mermaid(diagram, *model); + mermaid::AliasMatcher _A(src); + using mermaid::IsPackage; + using mermaid::IsPackageDependency; - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib1"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib2"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib3"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib4"))); + REQUIRE_THAT(src, IsPackage(_A("app"))); + REQUIRE_THAT(src, IsPackage(_A("libraries"))); + REQUIRE_THAT(src, IsPackage(_A("lib1"))); + REQUIRE_THAT(src, IsPackage(_A("lib2"))); + REQUIRE_THAT(src, !IsPackage(_A("library1"))); + REQUIRE_THAT(src, !IsPackage(_A("library2"))); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib1"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib2"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib3"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib4"))); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + } + */ } \ No newline at end of file diff --git a/tests/t30012/test_case.h b/tests/t30012/test_case.h index 1e841adb..8c4a6736 100644 --- a/tests/t30012/test_case.h +++ b/tests/t30012/test_case.h @@ -16,8 +16,11 @@ * limitations under the License. */ -TEST_CASE("t30012", "[test-case][package]") +TEST_CASE("t30012") { + using namespace clanguml::test; + using namespace std::string_literals; + auto [config, db] = load_config("t30012"); auto diagram = config.diagrams["t30012_package"]; @@ -28,6 +31,14 @@ TEST_CASE("t30012", "[test-case][package]") REQUIRE(model->name() == "t30012_package"); + CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsModulePackage(src, "app"s)); + REQUIRE(IsModulePackage(src, "app"s, "lib1"s)); + REQUIRE(IsModulePackage(src, "app"s, "lib1"s, "mod1"s)); + REQUIRE(IsModulePackage(src, "app"s, "lib1"s, "mod2"s)); + REQUIRE(IsModulePackage(src, "app"s, "lib2"s)); + }); +/* { auto src = generate_package_puml(diagram, *model); AliasMatcher _A(src); @@ -73,5 +84,5 @@ TEST_CASE("t30012", "[test-case][package]") REQUIRE_THAT(src, IsPackage(_A("mod2"))); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } \ No newline at end of file diff --git a/tests/t30013/test_case.h b/tests/t30013/test_case.h index 44b9024f..bfdf866e 100644 --- a/tests/t30013/test_case.h +++ b/tests/t30013/test_case.h @@ -16,8 +16,11 @@ * limitations under the License. */ -TEST_CASE("t30013", "[test-case][package]") +TEST_CASE("t30013") { + using namespace clanguml::test; + using namespace std::string_literals; + auto [config, db] = load_config("t30013"); auto diagram = config.diagrams["t30013_package"]; @@ -28,130 +31,173 @@ TEST_CASE("t30013", "[test-case][package]") REQUIRE(model->name() == "t30013_package"); - { - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsModulePackage(src, "app"s)); + REQUIRE(IsModulePackage(src, "mod1"s)); + REQUIRE(IsModulePackage(src, "mod2"s)); + REQUIRE(IsModulePackage(src, "mod3"s)); + REQUIRE(IsModulePackage(src, "mod4"s)); + REQUIRE(IsModulePackage(src, "mod5"s)); + REQUIRE(IsModulePackage(src, "mod6"s)); + REQUIRE(IsModulePackage(src, "mod7"s)); + REQUIRE(IsModulePackage(src, "mod8"s)); + REQUIRE(IsModulePackage(src, "mod9"s)); + REQUIRE(IsModulePackage(src, "mod10"s)); + REQUIRE(IsModulePackage(src, "mod11"s)); + REQUIRE(IsModulePackage(src, "mod12"s)); + REQUIRE(IsModulePackage(src, "mod13"s)); + REQUIRE(IsModulePackage(src, "mod14"s)); + REQUIRE(IsModulePackage(src, "mod15"s)); + REQUIRE(IsModulePackage(src, "mod16"s)); + REQUIRE(IsModulePackage(src, "mod17"s)); + REQUIRE(IsModulePackage(src, "mod18"s)); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsDependency(src, "app", "mod1")); + REQUIRE(IsDependency(src, "app", "mod2")); + REQUIRE(IsDependency(src, "app", "mod3")); + REQUIRE(IsDependency(src, "app", "mod4")); + REQUIRE(IsDependency(src, "app", "mod5")); + REQUIRE(IsDependency(src, "app", "mod6")); + REQUIRE(IsDependency(src, "app", "mod7")); + REQUIRE(IsDependency(src, "app", "mod8")); + REQUIRE(IsDependency(src, "app", "mod9")); + REQUIRE(IsDependency(src, "app", "mod10")); + REQUIRE(IsDependency(src, "app", "mod11")); + REQUIRE(IsDependency(src, "app", "mod12")); + REQUIRE(IsDependency(src, "app", "mod13")); + REQUIRE(IsDependency(src, "app", "mod14")); + REQUIRE(IsDependency(src, "app", "mod15")); + REQUIRE(IsDependency(src, "app", "mod16")); + REQUIRE(IsDependency(src, "app", "mod17")); + REQUIRE(IsDependency(src, "app", "mod18")); + }); + /* + { + auto src = generate_package_puml(diagram, *model); + AliasMatcher _A(src); - // Check if all packages exist - REQUIRE_THAT(src, IsPackage("app")); - REQUIRE_THAT(src, IsPackage("mod1")); - REQUIRE_THAT(src, IsPackage("mod2")); - REQUIRE_THAT(src, IsPackage("mod3")); - REQUIRE_THAT(src, IsPackage("mod4")); - REQUIRE_THAT(src, IsPackage("mod5")); - REQUIRE_THAT(src, IsPackage("mod6")); - REQUIRE_THAT(src, IsPackage("mod7")); - REQUIRE_THAT(src, IsPackage("mod8")); - REQUIRE_THAT(src, IsPackage("mod9")); - REQUIRE_THAT(src, IsPackage("mod10")); - REQUIRE_THAT(src, IsPackage("mod11")); - REQUIRE_THAT(src, IsPackage("mod12")); - REQUIRE_THAT(src, IsPackage("mod13")); - REQUIRE_THAT(src, IsPackage("mod14")); - REQUIRE_THAT(src, IsPackage("mod15")); - REQUIRE_THAT(src, IsPackage("mod16")); - REQUIRE_THAT(src, IsPackage("mod17")); - REQUIRE_THAT(src, IsPackage("mod18")); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod1"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod2"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod3"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod4"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod5"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod6"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod7"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod8"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod9"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod10"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod11"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod12"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod13"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod14"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod15"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod16"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod17"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod18"))); + // Check if all packages exist + REQUIRE_THAT(src, IsPackage("app")); + REQUIRE_THAT(src, IsPackage("mod1")); + REQUIRE_THAT(src, IsPackage("mod2")); + REQUIRE_THAT(src, IsPackage("mod3")); + REQUIRE_THAT(src, IsPackage("mod4")); + REQUIRE_THAT(src, IsPackage("mod5")); + REQUIRE_THAT(src, IsPackage("mod6")); + REQUIRE_THAT(src, IsPackage("mod7")); + REQUIRE_THAT(src, IsPackage("mod8")); + REQUIRE_THAT(src, IsPackage("mod9")); + REQUIRE_THAT(src, IsPackage("mod10")); + REQUIRE_THAT(src, IsPackage("mod11")); + REQUIRE_THAT(src, IsPackage("mod12")); + REQUIRE_THAT(src, IsPackage("mod13")); + REQUIRE_THAT(src, IsPackage("mod14")); + REQUIRE_THAT(src, IsPackage("mod15")); + REQUIRE_THAT(src, IsPackage("mod16")); + REQUIRE_THAT(src, IsPackage("mod17")); + REQUIRE_THAT(src, IsPackage("mod18")); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod1"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod2"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod3"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod4"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod5"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod6"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod7"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod8"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod9"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod10"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod11"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod12"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod13"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod14"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod15"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod16"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod17"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod18"))); - { - auto j = generate_package_json(diagram, *model); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - using namespace json; - using namespace std::string_literals; - REQUIRE(IsModulePackage(j, "app"s)); - REQUIRE(IsModulePackage(j, "mod1"s)); - REQUIRE(IsModulePackage(j, "mod2"s)); - REQUIRE(IsModulePackage(j, "mod3"s)); - REQUIRE(IsModulePackage(j, "mod4"s)); - REQUIRE(IsModulePackage(j, "mod5"s)); - REQUIRE(IsModulePackage(j, "mod6"s)); - REQUIRE(IsModulePackage(j, "mod7"s)); - REQUIRE(IsModulePackage(j, "mod8"s)); - REQUIRE(IsModulePackage(j, "mod9"s)); - REQUIRE(IsModulePackage(j, "mod10"s)); - REQUIRE(IsModulePackage(j, "mod11"s)); - REQUIRE(IsModulePackage(j, "mod12"s)); - REQUIRE(IsModulePackage(j, "mod13"s)); - REQUIRE(IsModulePackage(j, "mod14"s)); - REQUIRE(IsModulePackage(j, "mod15"s)); - REQUIRE(IsModulePackage(j, "mod16"s)); - REQUIRE(IsModulePackage(j, "mod17"s)); - REQUIRE(IsModulePackage(j, "mod18"s)); + { + auto j = generate_package_json(diagram, *model); - save_json(config.output_directory(), diagram->name + ".json", j); - } + using namespace json; + using namespace std::string_literals; + REQUIRE(IsModulePackage(j, "app"s)); + REQUIRE(IsModulePackage(j, "mod1"s)); + REQUIRE(IsModulePackage(j, "mod2"s)); + REQUIRE(IsModulePackage(j, "mod3"s)); + REQUIRE(IsModulePackage(j, "mod4"s)); + REQUIRE(IsModulePackage(j, "mod5"s)); + REQUIRE(IsModulePackage(j, "mod6"s)); + REQUIRE(IsModulePackage(j, "mod7"s)); + REQUIRE(IsModulePackage(j, "mod8"s)); + REQUIRE(IsModulePackage(j, "mod9"s)); + REQUIRE(IsModulePackage(j, "mod10"s)); + REQUIRE(IsModulePackage(j, "mod11"s)); + REQUIRE(IsModulePackage(j, "mod12"s)); + REQUIRE(IsModulePackage(j, "mod13"s)); + REQUIRE(IsModulePackage(j, "mod14"s)); + REQUIRE(IsModulePackage(j, "mod15"s)); + REQUIRE(IsModulePackage(j, "mod16"s)); + REQUIRE(IsModulePackage(j, "mod17"s)); + REQUIRE(IsModulePackage(j, "mod18"s)); - { - auto src = generate_package_mermaid(diagram, *model); + save_json(config.output_directory(), diagram->name + ".json", j); + } - mermaid::AliasMatcher _A(src); - using mermaid::IsPackage; - using mermaid::IsPackageDependency; + { + auto src = generate_package_mermaid(diagram, *model); - REQUIRE_THAT(src, IsPackage(_A("app"))); - REQUIRE_THAT(src, IsPackage(_A("mod1"))); - REQUIRE_THAT(src, IsPackage(_A("mod2"))); - REQUIRE_THAT(src, IsPackage(_A("mod3"))); - REQUIRE_THAT(src, IsPackage(_A("mod4"))); - REQUIRE_THAT(src, IsPackage(_A("mod5"))); - REQUIRE_THAT(src, IsPackage(_A("mod6"))); - REQUIRE_THAT(src, IsPackage(_A("mod7"))); - REQUIRE_THAT(src, IsPackage(_A("mod8"))); - REQUIRE_THAT(src, IsPackage(_A("mod9"))); - REQUIRE_THAT(src, IsPackage(_A("mod10"))); - REQUIRE_THAT(src, IsPackage(_A("mod11"))); - REQUIRE_THAT(src, IsPackage(_A("mod12"))); - REQUIRE_THAT(src, IsPackage(_A("mod13"))); - REQUIRE_THAT(src, IsPackage(_A("mod14"))); - REQUIRE_THAT(src, IsPackage(_A("mod15"))); - REQUIRE_THAT(src, IsPackage(_A("mod16"))); - REQUIRE_THAT(src, IsPackage(_A("mod17"))); - REQUIRE_THAT(src, IsPackage(_A("mod18"))); + mermaid::AliasMatcher _A(src); + using mermaid::IsPackage; + using mermaid::IsPackageDependency; - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod1"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod2"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod3"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod4"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod5"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod6"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod7"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod8"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod9"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod10"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod11"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod12"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod13"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod14"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod15"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod16"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod17"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod18"))); + REQUIRE_THAT(src, IsPackage(_A("app"))); + REQUIRE_THAT(src, IsPackage(_A("mod1"))); + REQUIRE_THAT(src, IsPackage(_A("mod2"))); + REQUIRE_THAT(src, IsPackage(_A("mod3"))); + REQUIRE_THAT(src, IsPackage(_A("mod4"))); + REQUIRE_THAT(src, IsPackage(_A("mod5"))); + REQUIRE_THAT(src, IsPackage(_A("mod6"))); + REQUIRE_THAT(src, IsPackage(_A("mod7"))); + REQUIRE_THAT(src, IsPackage(_A("mod8"))); + REQUIRE_THAT(src, IsPackage(_A("mod9"))); + REQUIRE_THAT(src, IsPackage(_A("mod10"))); + REQUIRE_THAT(src, IsPackage(_A("mod11"))); + REQUIRE_THAT(src, IsPackage(_A("mod12"))); + REQUIRE_THAT(src, IsPackage(_A("mod13"))); + REQUIRE_THAT(src, IsPackage(_A("mod14"))); + REQUIRE_THAT(src, IsPackage(_A("mod15"))); + REQUIRE_THAT(src, IsPackage(_A("mod16"))); + REQUIRE_THAT(src, IsPackage(_A("mod17"))); + REQUIRE_THAT(src, IsPackage(_A("mod18"))); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod1"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod2"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod3"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod4"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod5"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod6"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod7"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod8"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod9"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod10"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod11"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod12"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod13"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod14"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod15"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod16"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod17"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod18"))); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + } + */ } \ No newline at end of file diff --git a/tests/t30014/test_case.h b/tests/t30014/test_case.h index 06c30eed..63005d94 100644 --- a/tests/t30014/test_case.h +++ b/tests/t30014/test_case.h @@ -16,8 +16,11 @@ * limitations under the License. */ -TEST_CASE("t30014", "[test-case][package]") +TEST_CASE("t30014") { + using namespace clanguml::test; + using namespace std::string_literals; + auto [config, db] = load_config("t30014"); auto diagram = config.diagrams["t30014_package"]; @@ -28,6 +31,14 @@ TEST_CASE("t30014", "[test-case][package]") REQUIRE(model->name() == "t30014_package"); + CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsModulePackage(src, "app"s)); + REQUIRE(IsModulePackage(src, "app"s, ":lib1"s)); + REQUIRE(IsModulePackage(src, "app"s, ":lib2"s)); + REQUIRE(IsModulePackage(src, "app"s, ":lib1"s, "mod1"s)); + REQUIRE(!IsModulePackage(src, "app"s, ":lib1"s, "mod2"s)); + }); +/* { auto src = generate_package_puml(diagram, *model); AliasMatcher _A(src); @@ -72,5 +83,5 @@ TEST_CASE("t30014", "[test-case][package]") REQUIRE_THAT(src, IsPackage(_A("mod1"))); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } \ No newline at end of file diff --git a/tests/t30015/test_case.h b/tests/t30015/test_case.h index 85dc7eab..ee24f2df 100644 --- a/tests/t30015/test_case.h +++ b/tests/t30015/test_case.h @@ -16,8 +16,11 @@ * limitations under the License. */ -TEST_CASE("t30015", "[test-case][package]") +TEST_CASE("t30015") { + using namespace clanguml::test; + using namespace std::string_literals; + auto [config, db] = load_config("t30015"); auto diagram = config.diagrams["t30015_package"]; @@ -28,134 +31,178 @@ TEST_CASE("t30015", "[test-case][package]") REQUIRE(model->name() == "t30015_package"); - { - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsModulePackage(src, "app"s)); + REQUIRE(IsModulePackage(src, "lib1"s)); + REQUIRE(IsModulePackage(src, "lib1"s, ":mod1"s)); + REQUIRE(IsModulePackage(src, "lib1"s, ":mod2"s)); + REQUIRE(IsModulePackage(src, "lib1"s, ":mod3"s)); + REQUIRE(IsModulePackage(src, "lib1"s, ":mod4"s)); + REQUIRE(IsModulePackage(src, "lib1"s, ":mod5"s)); + REQUIRE(IsModulePackage(src, "lib1"s, ":mod6"s)); + REQUIRE(IsModulePackage(src, "lib1"s, ":mod7"s)); + REQUIRE(IsModulePackage(src, "lib1"s, ":mod8"s)); + REQUIRE(IsModulePackage(src, "lib1"s, ":mod9"s)); + REQUIRE(IsModulePackage(src, "lib1"s, ":mod10"s)); + REQUIRE(IsModulePackage(src, "lib1"s, ":mod11"s)); + REQUIRE(IsModulePackage(src, "lib1"s, ":mod12"s)); + REQUIRE(IsModulePackage(src, "lib1"s, ":mod13"s)); + REQUIRE(IsModulePackage(src, "lib1"s, ":mod14"s)); + REQUIRE(IsModulePackage(src, "lib1"s, ":mod15"s)); + REQUIRE(IsModulePackage(src, "lib1"s, ":mod16"s)); + REQUIRE(IsModulePackage(src, "lib1"s, ":mod17"s)); + REQUIRE(IsModulePackage(src, "lib1"s, ":mod18"s)); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsDependency(src, "app", ":mod1")); + REQUIRE(IsDependency(src, "app", ":mod2")); + REQUIRE(IsDependency(src, "app", ":mod3")); + REQUIRE(IsDependency(src, "app", ":mod4")); + REQUIRE(IsDependency(src, "app", ":mod5")); + REQUIRE(IsDependency(src, "app", ":mod6")); + REQUIRE(IsDependency(src, "app", ":mod7")); + REQUIRE(IsDependency(src, "app", ":mod8")); + REQUIRE(IsDependency(src, "app", ":mod9")); + REQUIRE(IsDependency(src, "app", ":mod10")); + REQUIRE(IsDependency(src, "app", ":mod11")); + REQUIRE(IsDependency(src, "app", ":mod12")); + REQUIRE(IsDependency(src, "app", ":mod13")); + REQUIRE(IsDependency(src, "app", ":mod14")); + REQUIRE(IsDependency(src, "app", ":mod15")); + REQUIRE(IsDependency(src, "app", ":mod16")); + REQUIRE(IsDependency(src, "app", ":mod17")); + REQUIRE(IsDependency(src, "app", ":mod18")); + }); + /* + { + auto src = generate_package_puml(diagram, *model); + AliasMatcher _A(src); - // Check if all packages exist - REQUIRE_THAT(src, IsPackage("app")); - REQUIRE_THAT(src, IsPackage("lib1")); - REQUIRE_THAT(src, IsPackage(":mod1")); - REQUIRE_THAT(src, IsPackage(":mod2")); - REQUIRE_THAT(src, IsPackage(":mod3")); - REQUIRE_THAT(src, IsPackage(":mod4")); - REQUIRE_THAT(src, IsPackage(":mod5")); - REQUIRE_THAT(src, IsPackage(":mod6")); - REQUIRE_THAT(src, IsPackage(":mod7")); - REQUIRE_THAT(src, IsPackage(":mod8")); - REQUIRE_THAT(src, IsPackage(":mod9")); - REQUIRE_THAT(src, IsPackage(":mod10")); - REQUIRE_THAT(src, IsPackage(":mod11")); - REQUIRE_THAT(src, IsPackage(":mod12")); - REQUIRE_THAT(src, IsPackage(":mod13")); - REQUIRE_THAT(src, IsPackage(":mod14")); - REQUIRE_THAT(src, IsPackage(":mod15")); - REQUIRE_THAT(src, IsPackage(":mod16")); - REQUIRE_THAT(src, IsPackage(":mod17")); - REQUIRE_THAT(src, IsPackage(":mod18")); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod1"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod2"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod3"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod4"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod5"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod6"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod7"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod8"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod9"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod10"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod11"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod12"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod13"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod14"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod15"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod16"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod17"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod18"))); + // Check if all packages exist + REQUIRE_THAT(src, IsPackage("app")); + REQUIRE_THAT(src, IsPackage("lib1")); + REQUIRE_THAT(src, IsPackage(":mod1")); + REQUIRE_THAT(src, IsPackage(":mod2")); + REQUIRE_THAT(src, IsPackage(":mod3")); + REQUIRE_THAT(src, IsPackage(":mod4")); + REQUIRE_THAT(src, IsPackage(":mod5")); + REQUIRE_THAT(src, IsPackage(":mod6")); + REQUIRE_THAT(src, IsPackage(":mod7")); + REQUIRE_THAT(src, IsPackage(":mod8")); + REQUIRE_THAT(src, IsPackage(":mod9")); + REQUIRE_THAT(src, IsPackage(":mod10")); + REQUIRE_THAT(src, IsPackage(":mod11")); + REQUIRE_THAT(src, IsPackage(":mod12")); + REQUIRE_THAT(src, IsPackage(":mod13")); + REQUIRE_THAT(src, IsPackage(":mod14")); + REQUIRE_THAT(src, IsPackage(":mod15")); + REQUIRE_THAT(src, IsPackage(":mod16")); + REQUIRE_THAT(src, IsPackage(":mod17")); + REQUIRE_THAT(src, IsPackage(":mod18")); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod1"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod2"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod3"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod4"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod5"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod6"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod7"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod8"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod9"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod10"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod11"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod12"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod13"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod14"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod15"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod16"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod17"))); + REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod18"))); - { - auto j = generate_package_json(diagram, *model); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - using namespace json; - using namespace std::string_literals; + { + auto j = generate_package_json(diagram, *model); - REQUIRE(IsModulePackage(j, "app"s)); - REQUIRE(IsModulePackage(j, "lib1"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod1"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod2"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod3"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod4"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod5"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod6"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod7"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod8"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod9"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod10"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod11"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod12"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod13"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod14"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod15"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod16"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod17"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod18"s)); + using namespace json; + using namespace std::string_literals; - save_json(config.output_directory(), diagram->name + ".json", j); - } + REQUIRE(IsModulePackage(j, "app"s)); + REQUIRE(IsModulePackage(j, "lib1"s)); + REQUIRE(IsModulePackage(j, "lib1"s, ":mod1"s)); + REQUIRE(IsModulePackage(j, "lib1"s, ":mod2"s)); + REQUIRE(IsModulePackage(j, "lib1"s, ":mod3"s)); + REQUIRE(IsModulePackage(j, "lib1"s, ":mod4"s)); + REQUIRE(IsModulePackage(j, "lib1"s, ":mod5"s)); + REQUIRE(IsModulePackage(j, "lib1"s, ":mod6"s)); + REQUIRE(IsModulePackage(j, "lib1"s, ":mod7"s)); + REQUIRE(IsModulePackage(j, "lib1"s, ":mod8"s)); + REQUIRE(IsModulePackage(j, "lib1"s, ":mod9"s)); + REQUIRE(IsModulePackage(j, "lib1"s, ":mod10"s)); + REQUIRE(IsModulePackage(j, "lib1"s, ":mod11"s)); + REQUIRE(IsModulePackage(j, "lib1"s, ":mod12"s)); + REQUIRE(IsModulePackage(j, "lib1"s, ":mod13"s)); + REQUIRE(IsModulePackage(j, "lib1"s, ":mod14"s)); + REQUIRE(IsModulePackage(j, "lib1"s, ":mod15"s)); + REQUIRE(IsModulePackage(j, "lib1"s, ":mod16"s)); + REQUIRE(IsModulePackage(j, "lib1"s, ":mod17"s)); + REQUIRE(IsModulePackage(j, "lib1"s, ":mod18"s)); - { - auto src = generate_package_mermaid(diagram, *model); + save_json(config.output_directory(), diagram->name + ".json", j); + } - mermaid::AliasMatcher _A(src); - using mermaid::IsPackage; - using mermaid::IsPackageDependency; + { + auto src = generate_package_mermaid(diagram, *model); - REQUIRE_THAT(src, IsPackage(_A("app"))); - REQUIRE_THAT(src, IsPackage(_A("lib1"))); - REQUIRE_THAT(src, IsPackage(_A(":mod1"))); - REQUIRE_THAT(src, IsPackage(_A(":mod2"))); - REQUIRE_THAT(src, IsPackage(_A(":mod3"))); - REQUIRE_THAT(src, IsPackage(_A(":mod4"))); - REQUIRE_THAT(src, IsPackage(_A(":mod5"))); - REQUIRE_THAT(src, IsPackage(_A(":mod6"))); - REQUIRE_THAT(src, IsPackage(_A(":mod7"))); - REQUIRE_THAT(src, IsPackage(_A(":mod8"))); - REQUIRE_THAT(src, IsPackage(_A(":mod9"))); - REQUIRE_THAT(src, IsPackage(_A(":mod10"))); - REQUIRE_THAT(src, IsPackage(_A(":mod11"))); - REQUIRE_THAT(src, IsPackage(_A(":mod12"))); - REQUIRE_THAT(src, IsPackage(_A(":mod13"))); - REQUIRE_THAT(src, IsPackage(_A(":mod14"))); - REQUIRE_THAT(src, IsPackage(_A(":mod15"))); - REQUIRE_THAT(src, IsPackage(_A(":mod16"))); - REQUIRE_THAT(src, IsPackage(_A(":mod17"))); - REQUIRE_THAT(src, IsPackage(_A(":mod18"))); + mermaid::AliasMatcher _A(src); + using mermaid::IsPackage; + using mermaid::IsPackageDependency; - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod1"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod2"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod3"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod4"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod5"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod6"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod7"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod8"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod9"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod10"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod11"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod12"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod13"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod14"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod15"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod16"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod17"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod18"))); + REQUIRE_THAT(src, IsPackage(_A("app"))); + REQUIRE_THAT(src, IsPackage(_A("lib1"))); + REQUIRE_THAT(src, IsPackage(_A(":mod1"))); + REQUIRE_THAT(src, IsPackage(_A(":mod2"))); + REQUIRE_THAT(src, IsPackage(_A(":mod3"))); + REQUIRE_THAT(src, IsPackage(_A(":mod4"))); + REQUIRE_THAT(src, IsPackage(_A(":mod5"))); + REQUIRE_THAT(src, IsPackage(_A(":mod6"))); + REQUIRE_THAT(src, IsPackage(_A(":mod7"))); + REQUIRE_THAT(src, IsPackage(_A(":mod8"))); + REQUIRE_THAT(src, IsPackage(_A(":mod9"))); + REQUIRE_THAT(src, IsPackage(_A(":mod10"))); + REQUIRE_THAT(src, IsPackage(_A(":mod11"))); + REQUIRE_THAT(src, IsPackage(_A(":mod12"))); + REQUIRE_THAT(src, IsPackage(_A(":mod13"))); + REQUIRE_THAT(src, IsPackage(_A(":mod14"))); + REQUIRE_THAT(src, IsPackage(_A(":mod15"))); + REQUIRE_THAT(src, IsPackage(_A(":mod16"))); + REQUIRE_THAT(src, IsPackage(_A(":mod17"))); + REQUIRE_THAT(src, IsPackage(_A(":mod18"))); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod1"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod2"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod3"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod4"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod5"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod6"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod7"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod8"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod9"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod10"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod11"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod12"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod13"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod14"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod15"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod16"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod17"))); + REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod18"))); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + } + */ } \ No newline at end of file diff --git a/tests/t40001/test_case.h b/tests/t40001/test_case.h index 1bdef77c..b972f298 100644 --- a/tests/t40001/test_case.h +++ b/tests/t40001/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t40001/test_case.cc + * tests/t40001/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t40001", "[test-case][include]") +TEST_CASE("t40001") { + using namespace clanguml::test; + auto [config, db] = load_config("t40001"); auto diagram = config.diagrams["t40001_include"]; @@ -28,89 +30,23 @@ TEST_CASE("t40001", "[test-case][include]") REQUIRE(model->name() == "t40001_include"); - { - auto src = generate_include_puml(diagram, *model); + CHECK_INCLUDE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(HasTitle(src, "Basic include diagram example")); - AliasMatcher _A(src); + REQUIRE(IsFolder(src, "include/lib1")); + REQUIRE(IsFile(src, "include/lib1/lib1.h")); + REQUIRE(IsFile(src, "src/t40001.cc")); + REQUIRE(IsFile(src, "include/t40001_include1.h")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, HasTitle("Basic include diagram example")); + REQUIRE(IsSystemHeader(src, "string")); + REQUIRE(IsSystemHeader(src, "yaml-cpp/yaml.h")); - REQUIRE_THAT(src, IsFolder("lib1")); - REQUIRE_THAT(src, IsFile("lib1.h")); - REQUIRE_THAT(src, IsFile("t40001.cc")); - REQUIRE_THAT(src, IsFile("t40001_include1.h")); + REQUIRE(IsHeaderDependency( + src, "src/t40001.cc", "include/t40001_include1.h")); + REQUIRE(IsHeaderDependency( + src, "include/t40001_include1.h", "include/lib1/lib1.h")); - REQUIRE_THAT(src, IsFile("string")); - REQUIRE_THAT(src, IsFile("yaml-cpp/yaml.h")); - - REQUIRE_THAT( - src, IsAssociation(_A("t40001.cc"), _A("t40001_include1.h"))); - REQUIRE_THAT(src, IsAssociation(_A("t40001_include1.h"), _A("lib1.h"))); - - REQUIRE_THAT(src, IsDependency(_A("t40001_include1.h"), _A("string"))); - - REQUIRE_THAT(src, HasComment("t40001 test diagram of type include")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_include_json(diagram, *model); - - using namespace json; - - REQUIRE(HasTitle(j, "Basic include diagram example")); - - REQUIRE(IsFolder(j, "include")); - REQUIRE(IsFolder(j, "include/lib1")); - REQUIRE(IsFolder(j, "src")); - - REQUIRE(IsHeader(j, "include/lib1/lib1.h")); - REQUIRE(IsHeader(j, "include/t40001_include1.h")); - REQUIRE(IsFile(j, "src/t40001.cc")); - REQUIRE(IsSystemHeader(j, "yaml-cpp/yaml.h")); - - REQUIRE(IsFile(j, "string")); - - REQUIRE(IsAssociation(j, "src/t40001.cc", "include/t40001_include1.h")); - REQUIRE(IsAssociation( - j, "include/t40001_include1.h", "include/lib1/lib1.h")); - REQUIRE(IsDependency(j, "include/t40001_include1.h", "string")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_include_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::HasComment; - using mermaid::HasTitle; - using mermaid::IsFile; - using mermaid::IsFolder; - using mermaid::IsIncludeDependency; - - REQUIRE_THAT(src, HasTitle("Basic include diagram example")); - - REQUIRE_THAT(src, IsFolder(_A("lib1"))); - REQUIRE_THAT(src, IsFile(_A("lib1.h"))); - REQUIRE_THAT(src, IsFile(_A("t40001.cc"))); - REQUIRE_THAT(src, IsFile(_A("t40001_include1.h"))); - - REQUIRE_THAT(src, IsFile(_A("string"))); - REQUIRE_THAT(src, IsFile(_A("yaml-cpp/yaml.h"))); - - REQUIRE_THAT( - src, IsAssociation(_A("t40001.cc"), _A("t40001_include1.h"))); - REQUIRE_THAT(src, IsAssociation(_A("t40001_include1.h"), _A("lib1.h"))); - - REQUIRE_THAT( - src, IsIncludeDependency(_A("t40001_include1.h"), _A("string"))); - - REQUIRE_THAT(src, HasComment("t40001 test diagram of type include")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsSystemHeaderDependency( + src, "include/t40001_include1.h", "string")); + }); } diff --git a/tests/t40002/test_case.h b/tests/t40002/test_case.h index bf09cb1d..52e7659c 100644 --- a/tests/t40002/test_case.h +++ b/tests/t40002/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t40002/test_case.cc + * tests/t40002/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t40002", "[test-case][include]") +TEST_CASE("t40002") { + using namespace clanguml::test; + auto [config, db] = load_config("t40002"); auto diagram = config.diagrams["t40002_include"]; @@ -28,141 +30,53 @@ TEST_CASE("t40002", "[test-case][include]") REQUIRE(model->name() == "t40002_include"); - { - auto src = generate_include_puml(diagram, *model); + CHECK_INCLUDE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsFolder(src, "include")); + REQUIRE(IsFolder(src, "include/lib1")); + REQUIRE(IsFolder(src, "include/lib2")); + REQUIRE(IsFolder(src, "src")); + REQUIRE(IsFolder(src, "src/lib1")); + REQUIRE(IsFolder(src, "src/lib2")); + REQUIRE(IsFile(src, "include/lib1/lib1.h")); + REQUIRE(IsFile(src, "include/lib2/lib2.h")); + REQUIRE(!IsFile(src, "include/lib2/lib2_detail.h")); + REQUIRE(IsFile(src, "src/lib1/lib1.cc")); + REQUIRE(IsFile(src, "src/lib2/lib2.cc")); + REQUIRE(IsFile(src, "src/t40002.cc")); - AliasMatcher _A(src); + REQUIRE(!IsFile(src, "string")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE( + IsHeaderDependency(src, "src/t40002.cc", "include/lib1/lib1.h")); + REQUIRE(IsHeaderDependency( + src, "include/lib1/lib1.h", "include/lib2/lib2.h")); + REQUIRE( + IsHeaderDependency(src, "src/lib1/lib1.cc", "include/lib1/lib1.h")); + REQUIRE( + IsHeaderDependency(src, "src/lib2/lib2.cc", "include/lib2/lib2.h")); - REQUIRE_THAT(src, IsFolder("lib1")); - REQUIRE_THAT(src, IsFolder("lib2")); - REQUIRE_THAT(src, IsFile("lib1.h")); - REQUIRE_THAT(src, IsFile("lib2.h")); - REQUIRE_THAT(src, !IsFile("lib2_detail.h")); - REQUIRE_THAT(src, IsFile("t40002.cc")); - REQUIRE_THAT(src, IsFile("lib1.cc")); - REQUIRE_THAT(src, IsFile("lib2.cc")); + REQUIRE(HasLink(src, "t40002.cc", + fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" + "t40002/src/t40002.cc#L0", + clanguml::util::get_git_commit()), + "t40002.cc")); - REQUIRE_THAT(src, !IsFile("string")); + REQUIRE(HasLink(src, "lib1.cc", + fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" + "t40002/src/lib1/lib1.cc#L0", + clanguml::util::get_git_commit()), + "lib1.cc")); - REQUIRE_THAT(src, IsAssociation(_A("t40002.cc"), _A("lib1.h"))); - REQUIRE_THAT(src, IsAssociation(_A("lib1.h"), _A("lib2.h"))); - REQUIRE_THAT(src, IsAssociation(_A("lib1.cc"), _A("lib1.h"))); - REQUIRE_THAT(src, IsAssociation(_A("lib2.cc"), _A("lib2.h"))); + REQUIRE(HasLink(src, "lib1.h", + fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" + "t40002/include/lib1/lib1.h#L0", + clanguml::util::get_git_commit()), + "lib1.h")); - REQUIRE_THAT(src, - HasLink(_A("t40002.cc"), - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t40002/src/t40002.cc#L0", - clanguml::util::get_git_commit()), - "t40002.cc")); - - REQUIRE_THAT(src, - HasLink(_A("lib1.cc"), - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t40002/src/lib1/lib1.cc#L0", - clanguml::util::get_git_commit()), - "lib1.cc")); - - REQUIRE_THAT(src, - HasLink(_A("lib1.h"), - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t40002/include/lib1/lib1.h#L0", - clanguml::util::get_git_commit()), - "lib1.h")); - - REQUIRE_THAT(src, - HasLink(_A("lib2.h"), - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t40002/include/lib2/lib2.h#L0", - clanguml::util::get_git_commit()), - "lib2.h")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_include_json(diagram, *model); - - using namespace json; - - REQUIRE(IsFolder(j, "include")); - REQUIRE(IsFolder(j, "include/lib1")); - REQUIRE(IsFolder(j, "include/lib2")); - REQUIRE(IsFolder(j, "src")); - REQUIRE(IsFolder(j, "src/lib1")); - REQUIRE(IsFolder(j, "src/lib2")); - REQUIRE(IsFile(j, "include/lib1/lib1.h")); - REQUIRE(IsFile(j, "include/lib2/lib2.h")); - REQUIRE(!IsFile(j, "include/lib2/lib2_detail.h")); - REQUIRE(IsFile(j, "src/lib1/lib1.cc")); - REQUIRE(IsFile(j, "src/lib2/lib2.cc")); - REQUIRE(IsFile(j, "src/t40002.cc")); - - REQUIRE(!IsFile(j, "string")); - - REQUIRE(IsAssociation(j, "src/t40002.cc", "include/lib1/lib1.h")); - REQUIRE(IsAssociation(j, "include/lib1/lib1.h", "include/lib2/lib2.h")); - REQUIRE(IsAssociation(j, "src/lib1/lib1.cc", "include/lib1/lib1.h")); - REQUIRE(IsAssociation(j, "src/lib2/lib2.cc", "include/lib2/lib2.h")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_include_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::HasLink; - using mermaid::IsFile; - using mermaid::IsFolder; - - REQUIRE_THAT(src, IsFolder(_A("lib1"))); - REQUIRE_THAT(src, IsFolder(_A("lib2"))); - REQUIRE_THAT(src, IsFile(_A("lib1.h"))); - REQUIRE_THAT(src, IsFile(_A("lib2.h"))); - REQUIRE_THAT(src, !IsFile(_A("lib2_detail.h"))); - REQUIRE_THAT(src, IsFile(_A("t40002.cc"))); - REQUIRE_THAT(src, IsFile(_A("lib1.cc"))); - REQUIRE_THAT(src, IsFile(_A("lib2.cc"))); - - REQUIRE_THAT(src, !IsFile(_A("string"))); - - REQUIRE_THAT(src, IsAssociation(_A("t40002.cc"), _A("lib1.h"))); - REQUIRE_THAT(src, IsAssociation(_A("lib1.h"), _A("lib2.h"))); - REQUIRE_THAT(src, IsAssociation(_A("lib1.cc"), _A("lib1.h"))); - REQUIRE_THAT(src, IsAssociation(_A("lib2.cc"), _A("lib2.h"))); - - REQUIRE_THAT(src, - HasLink(_A("t40002.cc"), - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t40002/src/t40002.cc#L0", - clanguml::util::get_git_commit()), - "t40002.cc")); - - REQUIRE_THAT(src, - HasLink(_A("lib1.cc"), - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t40002/src/lib1/lib1.cc#L0", - clanguml::util::get_git_commit()), - "lib1.cc")); - - REQUIRE_THAT(src, - HasLink(_A("lib1.h"), - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t40002/include/lib1/lib1.h#L0", - clanguml::util::get_git_commit()), - "lib1.h")); - - REQUIRE_THAT(src, - HasLink(_A("lib2.h"), - fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" - "t40002/include/lib2/lib2.h#L0", - clanguml::util::get_git_commit()), - "lib2.h")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(HasLink(src, "lib2.h", + fmt::format("https://github.com/bkryza/clang-uml/blob/{}/tests/" + "t40002/include/lib2/lib2.h#L0", + clanguml::util::get_git_commit()), + "lib2.h")); + }); } diff --git a/tests/t40003/test_case.h b/tests/t40003/test_case.h index 5b44ae41..9e76177d 100644 --- a/tests/t40003/test_case.h +++ b/tests/t40003/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t40003/test_case.cc + * tests/t40003/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t40003", "[test-case][include]") +TEST_CASE("t40003") { + using namespace clanguml::test; + auto [config, db] = load_config("t40003"); auto diagram = config.diagrams["t40003_include"]; @@ -28,72 +30,22 @@ TEST_CASE("t40003", "[test-case][include]") REQUIRE(model->name() == "t40003_include"); - { - auto src = generate_include_puml(diagram, *model); + CHECK_INCLUDE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsFolder(src, "include/dependants")); + REQUIRE(IsFolder(src, "include/dependencies")); + REQUIRE(IsFolder(src, "src/dependants")); + REQUIRE(IsFolder(src, "src/dependencies")); - AliasMatcher _A(src); + REQUIRE(IsFile(src, "include/dependants/t1.h")); + REQUIRE(IsFile(src, "include/dependants/t2.h")); + REQUIRE(IsFile(src, "include/dependants/t3.h")); + REQUIRE(!IsFile(src, "include/dependants/t4.h")); + REQUIRE(IsFile(src, "src/dependants/t1.cc")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsFolder("dependants")); - REQUIRE_THAT(src, IsFolder("dependencies")); - - REQUIRE_THAT(src, IsFile("t1.h")); - REQUIRE_THAT(src, IsFile("t2.h")); - REQUIRE_THAT(src, IsFile("t3.h")); - - REQUIRE_THAT(src, !IsFile("t4.h")); - REQUIRE_THAT(src, IsFile("t5.h")); - REQUIRE_THAT(src, !IsFile("t6.h")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_include_json(diagram, *model); - - using namespace json; - - REQUIRE(IsFolder(j, "include/dependants")); - REQUIRE(IsFolder(j, "include/dependencies")); - REQUIRE(IsFolder(j, "src/dependants")); - REQUIRE(IsFolder(j, "src/dependencies")); - - REQUIRE(IsFile(j, "include/dependants/t1.h")); - REQUIRE(IsFile(j, "include/dependants/t2.h")); - REQUIRE(IsFile(j, "include/dependants/t3.h")); - REQUIRE(!IsFile(j, "include/dependants/t4.h")); - REQUIRE(IsFile(j, "src/dependants/t1.cc")); - - REQUIRE(IsFile(j, "include/dependencies/t1.h")); - REQUIRE(IsFile(j, "include/dependencies/t2.h")); - REQUIRE(IsFile(j, "include/dependencies/t3.h")); - REQUIRE(!IsFile(j, "include/dependencies/t4.h")); - REQUIRE(IsFile(j, "src/dependencies/t2.cc")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_include_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::HasLink; - using mermaid::IsFile; - using mermaid::IsFolder; - - REQUIRE_THAT(src, IsFolder(_A("dependants"))); - REQUIRE_THAT(src, IsFolder(_A("dependencies"))); - - REQUIRE_THAT(src, IsFile(_A("t1.h"))); - REQUIRE_THAT(src, IsFile(_A("t2.h"))); - REQUIRE_THAT(src, IsFile(_A("t3.h"))); - - REQUIRE_THAT(src, !IsFile(_A("t4.h"))); - REQUIRE_THAT(src, IsFile(_A("t5.h"))); - REQUIRE_THAT(src, !IsFile(_A("t6.h"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsFile(src, "include/dependencies/t1.h")); + REQUIRE(IsFile(src, "include/dependencies/t2.h")); + REQUIRE(IsFile(src, "include/dependencies/t3.h")); + REQUIRE(!IsFile(src, "include/dependencies/t4.h")); + REQUIRE(IsFile(src, "src/dependencies/t2.cc")); + }); } diff --git a/tests/test_cases.cc b/tests/test_cases.cc index 524f994e..f4637578 100644 --- a/tests/test_cases.cc +++ b/tests/test_cases.cc @@ -74,6 +74,500 @@ load_config(const std::string &test_name) return res; } +namespace detail { +template +auto generate_diagram_impl(clanguml::common::compilation_database &db, + std::shared_ptr diagram) +{ + LOG_INFO("All paths will be evaluated relative to {}", + diagram->root_directory().string()); + + using diagram_config = DiagramConfig; + using diagram_model = + typename clanguml::common::generators::diagram_model_t< + diagram_config>::type; + using diagram_visitor = + typename clanguml::common::generators::diagram_visitor_t< + diagram_config>::type; + + inject_diagram_options(diagram); + + auto model = clanguml::common::generators::generate(db, diagram->name, + dynamic_cast(*diagram), + diagram->get_translation_units()); + + return model; +} + +template +auto render_diagram( + std::shared_ptr config, DiagramModel &model) +{ + using diagram_config = DiagramConfig; + using diagram_model = DiagramModel; + using diagram_generator = + typename clanguml::common::generators::diagram_generator_t< + DiagramConfig, typename GeneratorType::generator_tag>::type; + + std::stringstream ss; + + ss << diagram_generator(dynamic_cast(*config), model); + + if constexpr (std::is_same_v) { + return nlohmann::json::parse(ss.str()); + } + else { + return ss.str(); + } +} +// +// template +// auto generate_diagram_json( +// std::shared_ptr config, DiagramModel &model) +//{ +// using diagram_config = DiagramConfig; +// using diagram_model = DiagramModel; +// using diagram_generator = +// typename clanguml::common::generators::diagram_generator_t< +// DiagramConfig, +// clanguml::common::generators::json_generator_tag>::type; +// +// std::stringstream ss; +// +// ss << diagram_generator(dynamic_cast(*config), model); +// +// return nlohmann::json::parse(ss.str()); +//} +// +// template +// auto generate_diagram_mermaid( +// std::shared_ptr config, DiagramModel &model) +//{ +// using diagram_config = DiagramConfig; +// using diagram_model = DiagramModel; +// using diagram_generator = +// typename clanguml::common::generators::diagram_generator_t< +// DiagramConfig, +// clanguml::common::generators::mermaid_generator_tag>::type; +// +// std::stringstream ss; +// +// ss << diagram_generator(dynamic_cast(*config), model); +// +// return ss.str(); +//} +} // namespace detail + +/// +/// @defgroup Diagram generators +/// @{ +/// + +std::unique_ptr generate_class_diagram( + clanguml::common::compilation_database &db, + std::shared_ptr diagram) +{ + return detail::generate_diagram_impl( + db, diagram); +} + +std::unique_ptr +generate_sequence_diagram(clanguml::common::compilation_database &db, + std::shared_ptr diagram) +{ + return detail::generate_diagram_impl( + db, diagram); +} + +std::unique_ptr +generate_package_diagram(clanguml::common::compilation_database &db, + std::shared_ptr diagram) +{ + return detail::generate_diagram_impl( + db, diagram); +} + +std::unique_ptr +generate_include_diagram(clanguml::common::compilation_database &db, + std::shared_ptr diagram) +{ + return detail::generate_diagram_impl( + db, diagram); +} + +/// }@ + +/// +/// @defgroup Diagram renderers +/// @{ +/// +/* +template +std::string render_class_diagram( + std::shared_ptr config, + clanguml::class_diagram::model::diagram &model) +{ + return detail::generate_diagram(config, model); +} + +std::string render_sequence_diagram( + std::shared_ptr config, + clanguml::sequence_diagram::model::diagram &model) +{ + return detail::generate_diagram_puml( + config, model); +} + +std::string generate_package_puml( + std::shared_ptr config, + clanguml::package_diagram::model::diagram &model) +{ + return detail::generate_diagram_puml( + config, model); +} + +std::string generate_include_puml( + std::shared_ptr config, + clanguml::include_diagram::model::diagram &model) +{ + return detail::generate_diagram_puml( + config, model); +} + +nlohmann::json generate_class_json( + std::shared_ptr config, + clanguml::class_diagram::model::diagram &model) +{ + return detail::generate_diagram_json( + config, model); +} + +nlohmann::json generate_sequence_json( + std::shared_ptr config, + clanguml::sequence_diagram::model::diagram &model) +{ + return detail::generate_diagram_json( + config, model); +} + +nlohmann::json generate_package_json( + std::shared_ptr config, + clanguml::package_diagram::model::diagram &model) +{ + return detail::generate_diagram_json( + config, model); +} + +nlohmann::json generate_include_json( + std::shared_ptr config, + clanguml::include_diagram::model::diagram &model) +{ + return detail::generate_diagram_json( + config, model); +} + +std::string generate_class_mermaid( + std::shared_ptr config, + clanguml::class_diagram::model::diagram &model) +{ + return detail::generate_diagram_mermaid( + config, model); +} + +std::string generate_sequence_mermaid( + std::shared_ptr config, + clanguml::sequence_diagram::model::diagram &model) +{ + return detail::generate_diagram_mermaid( + config, model); +} + +std::string generate_package_mermaid( + std::shared_ptr config, + clanguml::package_diagram::model::diagram &model) +{ + return detail::generate_diagram_mermaid( + config, model); +} + +std::string generate_include_mermaid( + std::shared_ptr config, + clanguml::include_diagram::model::diagram &model) +{ + return detail::generate_diagram_mermaid( + config, model); +} +*/ + +template +void save_diagram(const std::filesystem::path &path, const T &diagram) +{ + static_assert( + std::is_same_v || std::is_same_v); + + std::filesystem::create_directories(path.parent_path()); + std::ofstream ofs; + ofs.open(path, std::ofstream::out | std::ofstream::trunc); + if constexpr (std::is_same_v) { + ofs << std::setw(2) << diagram; + } + else { + ofs << diagram; + } + + ofs.close(); +} + +void save_puml(const std::string &path, const std::string &filename, + const std::string &puml) +{ + std::filesystem::path p{path}; + p /= filename; + save_diagram(p, puml); +} + +void save_json(const std::string &path, const std::string &filename, + const nlohmann::json &j) +{ + std::filesystem::path p{path}; + p /= filename; + save_diagram(p, j); +} + +void save_mermaid(const std::string &path, const std::string &filename, + const std::string &mmd) +{ + std::filesystem::path p{path}; + p /= filename; + save_diagram(p, mmd); +} + +namespace clanguml::test { + +struct diagram_source_storage { + diagram_source_storage(plantuml_t &&p, json_t &&j, mermaid_t &&m) + : plantuml{std::move(p)} + , json{std::move(j)} + , mermaid{std::move(m)} + { + } + + template const T &get() const; + + plantuml_t plantuml; + json_t json; + mermaid_t mermaid; +}; + +template <> const plantuml_t &diagram_source_storage::get() const +{ + return plantuml; +} + +template <> const json_t &diagram_source_storage::get() const +{ + return json; +} + +template <> const mermaid_t &diagram_source_storage::get() const +{ + return mermaid; +} + +template +void try_run_test_case(const diagram_source_storage &diagrams, TC &&tc) +{ + if constexpr (std::is_invocable_v) { + try { + tc(diagrams.get()); + } + catch (doctest::TestFailureException &e) { + std::cout << "-----------------------------------------------------" + "--------------------------\n"; + std::cout << "Test case failed for diagram type " + << T::diagram_type_name << ": " << "\n"; + std::cout << diagrams.get().to_string() << "\n"; + + throw e; + } + } +} + +template +DiagramType render_class_diagram(std::shared_ptr c, + clanguml::class_diagram::model::diagram &model) +{ + return DiagramType{common::model::diagram_t::kClass, + detail::render_diagram( + c, model)}; +} + +template +DiagramType render_sequence_diagram( + std::shared_ptr c, + clanguml::sequence_diagram::model::diagram &model) +{ + return DiagramType{common::model::diagram_t::kSequence, + detail::render_diagram( + c, model)}; +} + +template +DiagramType render_package_diagram(std::shared_ptr c, + clanguml::package_diagram::model::diagram &model) +{ + return DiagramType{common::model::diagram_t::kPackage, + detail::render_diagram( + c, model)}; +} + +template +DiagramType render_include_diagram(std::shared_ptr c, + clanguml::include_diagram::model::diagram &model) +{ + return DiagramType{common::model::diagram_t::kInclude, + detail::render_diagram( + c, model)}; +} + +template +void CHECK_DIAGRAM_IMPL( + const diagram_source_storage &diagrams, TC &&tc, TCs &&...tcs) +{ + try_run_test_case(diagrams, tc); + try_run_test_case(diagrams, tc); + try_run_test_case(diagrams, tc); + + if constexpr (sizeof...(tcs) > 0) { + CHECK_DIAGRAM_IMPL(diagrams, std::forward(tcs)...); + } +} + +template +void CHECK_CLASS_DIAGRAM(const clanguml::config::config &config, + DiagramConfig diagram, DiagramModel &model, TCs &&...tcs) +{ + diagram_source_storage diagram_sources{ + render_class_diagram(diagram, model), + render_class_diagram(diagram, model), + render_class_diagram(diagram, model)}; + + CHECK_DIAGRAM_IMPL(diagram_sources, std::forward(tcs)...); + + save_puml(config.output_directory(), diagram->name + ".puml", + diagram_sources.plantuml.src); + save_json(config.output_directory(), diagram->name + ".json", + diagram_sources.json.src); + save_mermaid(config.output_directory(), diagram->name + ".mmd", + diagram_sources.mermaid.src); +} + +template +void CHECK_SEQUENCE_DIAGRAM(const clanguml::config::config &config, + DiagramConfig diagram, DiagramModel &model, TCs &&...tcs) +{ + diagram_source_storage diagram_sources{ + render_sequence_diagram(diagram, model), + render_sequence_diagram(diagram, model), + render_sequence_diagram(diagram, model)}; + + CHECK_DIAGRAM_IMPL(diagram_sources, std::forward(tcs)...); + + save_puml(config.output_directory(), diagram->name + ".puml", + diagram_sources.plantuml.src); + save_json(config.output_directory(), diagram->name + ".json", + diagram_sources.json.src); + save_mermaid(config.output_directory(), diagram->name + ".mmd", + diagram_sources.mermaid.src); +} + +template +void CHECK_PACKAGE_DIAGRAM(const clanguml::config::config &config, + DiagramConfig diagram, DiagramModel &model, TCs &&...tcs) +{ + diagram_source_storage diagram_sources{ + render_package_diagram(diagram, model), + render_package_diagram(diagram, model), + render_package_diagram(diagram, model)}; + + CHECK_DIAGRAM_IMPL(diagram_sources, std::forward(tcs)...); + + save_puml(config.output_directory(), diagram->name + ".puml", + diagram_sources.plantuml.src); + save_json(config.output_directory(), diagram->name + ".json", + diagram_sources.json.src); + save_mermaid(config.output_directory(), diagram->name + ".mmd", + diagram_sources.mermaid.src); +} + +template +void CHECK_INCLUDE_DIAGRAM(const clanguml::config::config &config, + DiagramConfig diagram, DiagramModel &model, TCs &&...tcs) +{ + diagram_source_storage diagram_sources{ + render_include_diagram(diagram, model), + render_include_diagram(diagram, model), + render_include_diagram(diagram, model)}; + + CHECK_DIAGRAM_IMPL(diagram_sources, std::forward(tcs)...); + + save_puml(config.output_directory(), diagram->name + ".puml", + diagram_sources.plantuml.src); + save_json(config.output_directory(), diagram->name + ".json", + diagram_sources.json.src); + save_mermaid(config.output_directory(), diagram->name + ".mmd", + diagram_sources.mermaid.src); +} + +} // namespace clanguml::test + +/* +template <> +plantuml_t render_class_diagram( + std::shared_ptr c, + clanguml::class_diagram::model::diagram &d) +{ + return detail::generate_diagram_puml(c, d); +} + +template <> +mermaid_t render_class_diagram( + std::shared_ptr c, + clanguml::class_diagram::model::diagram &d) +{ + return generate_class_mermaid(c, d); +} + +template <> +json_t render_class_diagram( + std::shared_ptr c, + clanguml::class_diagram::model::diagram &d) +{ + return generate_class_json(c, d); +} + +template <> +DiagramType render_sequence_diagram( + std::shared_ptr c, + clanguml::sequence_diagram::model::diagram &model); + +template +DiagramType render_package_diagram(std::shared_ptr c, + clanguml::package_diagram::model::diagram &model); + +template +DiagramType render_include_diagram(std::shared_ptr c, + clanguml::include_diagram::model::diagram &model); + +} +*/ +// using namespace clanguml::test::matchers; + +/* + + namespace detail { template auto generate_diagram_impl(clanguml::common::compilation_database &db, @@ -326,8 +820,198 @@ void save_mermaid(const std::string &path, const std::string &filename, save_diagram(p, mmd); } -using namespace clanguml::test::matchers; +namespace clanguml::test { +template struct test_traits; + +// function pointer +template +struct test_traits : public test_traits { }; + +template struct test_traits { + using return_type = R; + + static constexpr std::size_t arity = sizeof...(Args); + + template struct argument { + static_assert(N < arity, "error: invalid parameter index."); + using type = typename std::tuple_element>::type; + }; +}; + +struct diagram_source_storage { + diagram_source_storage(plantuml_t &&p, json_t &&j, mermaid_t &&m) + : plantuml{std::move(p)} + , json{std::move(j)} + , mermaid{std::move(m)} + { + } + + template const T &get() const; + + plantuml_t plantuml; + json_t json; + mermaid_t mermaid; +}; + +template <> const plantuml_t &diagram_source_storage::get() const +{ + return plantuml; +} + +template <> const json_t &diagram_source_storage::get() const +{ + return json; +} + +template <> const mermaid_t &diagram_source_storage::get() const +{ + return mermaid; +} + +template +void CHECK_CLASS_DIAGRAM_IMPL( + const diagram_source_storage &diagrams, TC &&tc, TCs &&...tcs) +{ + if constexpr (std::is_invocable_v) { + tc(diagrams.get()); + } + if constexpr (std::is_invocable_v) { + tc(diagrams.get()); + } + if constexpr (std::is_invocable_v) { + tc(diagrams.get()); + } + if constexpr (sizeof...(tcs) > 0) { + CHECK_CLASS_DIAGRAM_IMPL(diagrams, std::forward(tcs)...); + } +} + +template +void CHECK_CLASS_DIAGRAM( + DiagramConfig diagram, DiagramModel &model, TCs &&...tcs) +{ + diagram_source_storage diagram_sources{ + render_class_diagram(diagram, model), + render_class_diagram(diagram, model), + render_class_diagram(diagram, model)}; + + CHECK_CLASS_DIAGRAM_IMPL(diagram_sources, std::forward(tcs)...); +} + +// +// PlantUML test helpers +// +template <> +plantuml_t render_class_diagram( + std::shared_ptr c, + clanguml::class_diagram::model::diagram &d) +{ + return generate_class_puml(c, d); +} + +template <> bool IsClass(plantuml_t d, std::string name) +{ + return util::contains(d.src, fmt::format("class {}", name)); +} + +// +// MermaidJS test helpers +// +template <> +mermaid_t render_class_diagram( + std::shared_ptr c, + clanguml::class_diagram::model::diagram &d) +{ + return generate_class_mermaid(c, d); +} + +template <> bool IsClass(mermaid_t d, std::string name) +{ + return util::contains(d.src, fmt::format("class {}", name)); +} + +// +// JSON test helpers +// +struct File { + explicit File(const std::string &f) + : file{f} + { + } + + const std::string file; +}; + +std::optional get_element_by_id( + const nlohmann::json &j, const std::string &id) +{ + if (!j.contains("elements")) + return {}; + + for (const nlohmann::json &e : j["elements"]) { + if (e["id"] == id) + return {e}; + + if (e["type"] == "namespace" || e["type"] == "folder") { + auto maybe_e = get_element_by_id(e, id); + if (maybe_e) + return maybe_e; + } + } + + return {}; +} + +std::optional get_element( + const nlohmann::json &j, const std::string &name) +{ + if (!j.contains("elements")) + return {}; + + for (const nlohmann::json &e : j["elements"]) { + if (e["display_name"] == name) + return {e}; + + if (e["type"] == "namespace" || e["type"] == "folder" || + e["type"] == "directory" || e["type"] == "module") { + auto maybe_e = get_element(e, name); + if (maybe_e) + return maybe_e; + } + } + + return {}; +} + +std::optional get_element( + const json_t &src, const std::string &name) +{ + return get_element(src.src, name); +} + +std::string expand_name(const nlohmann::json &j, const std::string &name) +{ + return name; +} + +template <> +json_t render_class_diagram( + std::shared_ptr c, + clanguml::class_diagram::model::diagram &d) +{ + return generate_class_json(c, d); +} + +template <> bool IsClass(json_t d, std::string name) +{ + auto e = get_element(d.src, expand_name(d.src, name)); + return e && e->at("type") == "class"; +} +} +} + + */ /// /// Class diagram tests /// @@ -360,6 +1044,9 @@ using namespace clanguml::test::matchers; #include "t00028/test_case.h" #include "t00029/test_case.h" #include "t00030/test_case.h" + +/* + #include "t00031/test_case.h" #include "t00032/test_case.h" #include "t00033/test_case.h" @@ -483,6 +1170,7 @@ using namespace clanguml::test::matchers; #include "t20052/test_case.h" #include "t20053/test_case.h" +*/ /// /// Package diagram tests /// @@ -506,21 +1194,65 @@ using namespace clanguml::test::matchers; /// /// Include diagram tests /// + #include "t40001/test_case.h" #include "t40002/test_case.h" #include "t40003/test_case.h" +/* + /// /// Other tests (e.g. configuration file) /// #include "t90000/test_case.h" #include "t90001/test_case.h" +*/ /// /// Main test function /// int main(int argc, char *argv[]) { + doctest::Context context; + + // defaults + // context.addFilter("test-case-exclude", + // "*math*"); // exclude test cases with "math" in their name + context.setOption( + "abort-after", 5); // stop test execution after 5 failed assertions + context.setOption("order-by", "name"); // sort the test cases by their name + + context.applyCommandLine(argc, argv); + + // overrides + context.setOption( + "no-breaks", false); // don't break in the debugger when assertions fail + + clanguml::cli::cli_handler clih; + + std::vector argvv = { + "clang-uml", "--config", "./test_config_data/simple.yml"}; + + // if (debug_log) + // argvv.push_back("-vvv"); + // else + argvv.push_back("-q"); + + clih.handle_options(argvv.size(), argvv.data()); + + int res = context.run(); // run + + if (context.shouldExit()) // important - query flags (and --exit) rely on + // the user doing this + return res; // propagate the result of the tests + + int client_stuff_return_code = 0; + // your program - if the testing framework is integrated in your production + // code + + return res + client_stuff_return_code; // the result from doctest is + // propagated here as well + /* Catch::Session session; using namespace Catch::clara; @@ -547,4 +1279,5 @@ int main(int argc, char *argv[]) clih.handle_options(argvv.size(), argvv.data()); return session.run(); + */ } diff --git a/tests/test_cases.h b/tests/test_cases.h index b8e61102..0e84baa1 100644 --- a/tests/test_cases.h +++ b/tests/test_cases.h @@ -25,6 +25,7 @@ #include "class_diagram/visitor/translation_unit_visitor.h" #include "common/clang_utils.h" #include "common/compilation_database.h" +#include "common/generators/generators.h" #include "config/config.h" #include "include_diagram/generators/plantuml/include_diagram_generator.h" #include "include_diagram/visitor/translation_unit_visitor.h" @@ -34,10 +35,8 @@ #include "sequence_diagram/visitor/translation_unit_visitor.h" #include "util/util.h" -#define CATCH_CONFIG_RUNNER -#define CATCH_CONFIG_CONSOLE_WIDTH 512 - -#include "catch.h" +#define DOCTEST_CONFIG_IMPLEMENT +#include "doctest/doctest.h" #include #include @@ -47,28 +46,1802 @@ #include #include -using Catch::Matchers::Contains; -using Catch::Matchers::EndsWith; -using Catch::Matchers::Equals; -using Catch::Matchers::Matches; -using Catch::Matchers::StartsWith; -using Catch::Matchers::VectorContains; - using namespace clanguml::util; std::pair load_config(const std::string &test_name); -std::string generate_sequence_puml( - std::shared_ptr config, - clanguml::sequence_diagram::model::diagram &model); - -std::string generate_class_puml( - std::shared_ptr config, - clanguml::class_diagram::model::diagram &model); +// std::string generate_sequence_puml( +// std::shared_ptr config, +// clanguml::sequence_diagram::model::diagram &model); +// +// std::string generate_class_puml( +// std::shared_ptr config, +// clanguml::class_diagram::model::diagram &model); void save_puml(const std::string &path, const std::string &puml); +namespace clanguml::test { + +template constexpr bool has_type() noexcept +{ + return (std::is_same_v || ... || false); +} + +struct Public { }; + +struct Protected { }; + +struct Private { }; + +struct Abstract { }; + +struct Static { }; + +struct Const { }; + +struct Constexpr { }; + +struct Consteval { }; + +struct Coroutine { }; + +struct Noexcept { }; + +struct Default { }; + +struct Deleted { }; + +struct NamespacePackage { }; +struct ModulePackage { }; +struct DirectoryPackage { }; + +template std::string package_type_name(); + +template <> std::string package_type_name() +{ + return "namespace"; +} + +template <> std::string package_type_name() { return "module"; } + +template <> std::string package_type_name() +{ + return "directory"; +} + +template struct diagram_source_t { + diagram_source_t(clanguml::common::model::diagram_t dt, T &&s) + { + diagram_type = dt; + src = std::move(s); + } + + bool contains(std::string name) const; + + virtual std::string get_alias(std::string name) const + { + return "__INVALID_ALIAS__"; + } + + bool search(const std::string &pattern) const; + + std::string to_string() const; + + T src; + clanguml::common::model::diagram_t diagram_type; +}; + +struct plantuml_t : public diagram_source_t { + using diagram_source_t::diagram_source_t; + using source_type = std::string; + using generator_tag = clanguml::common::generators::plantuml_generator_tag; + + inline static const std::string diagram_type_name{"PlantUML"}; + + std::string get_alias(std::string name) const override + { + std::vector patterns; + + const std::string alias_regex("([A-Z]_[0-9]+)"); + + util::replace_all(name, "(", "\\("); + util::replace_all(name, ")", "\\)"); + util::replace_all(name, " ", "\\s"); + util::replace_all(name, "*", "\\*"); + util::replace_all(name, "[", "\\["); + util::replace_all(name, "]", "\\]"); + + patterns.push_back( + std::regex{"class\\s\"" + name + "\"\\sas\\s" + alias_regex}); + patterns.push_back( + std::regex{"abstract\\s\"" + name + "\"\\sas\\s" + alias_regex}); + patterns.push_back( + std::regex{"enum\\s\"" + name + "\"\\sas\\s" + alias_regex}); + patterns.push_back( + std::regex{"package\\s\"" + name + "\"\\sas\\s" + alias_regex}); + patterns.push_back( + std::regex{"package\\s\\[" + name + "\\]\\sas\\s" + alias_regex}); + patterns.push_back( + std::regex{"file\\s\"" + name + "\"\\sas\\s" + alias_regex}); + patterns.push_back( + std::regex{"folder\\s\"" + name + "\"\\sas\\s" + alias_regex}); + patterns.push_back( + std::regex{"participant\\s\"" + name + "\"\\sas\\s" + alias_regex}); + + std::smatch base_match; + + for (const auto &pattern : patterns) { + if (std::regex_search(src, base_match, pattern) && + base_match.size() == 2) { + std::ssub_match base_sub_match = base_match[1]; + std::string alias = base_sub_match.str(); + return trim(alias); + } + } + + return fmt::format("__INVALID__ALIAS__({})", name); + } +}; + +struct mermaid_t : public diagram_source_t { + using diagram_source_t::diagram_source_t; + using source_type = std::string; + using generator_tag = clanguml::common::generators::mermaid_generator_tag; + + inline static const std::string diagram_type_name{"MermaidJS"}; + + std::string get_alias(std::string name) const override + { + std::vector patterns; + + const std::string alias_regex("([A-Z]_[0-9]+)"); + + util::replace_all(name, "(", "("); + util::replace_all(name, ")", ")"); + util::replace_all(name, " ", "\\s"); + util::replace_all(name, "*", "\\*"); + util::replace_all(name, "[", "\\["); + util::replace_all(name, "]", "\\]"); + util::replace_all(name, "<", "<"); + util::replace_all(name, ">", ">"); + + patterns.push_back( + std::regex{"class\\s" + alias_regex + "\\[\"" + name + "\"\\]"}); + patterns.push_back( + std::regex{"subgraph\\s" + alias_regex + "\\[" + name + "\\]"}); + patterns.push_back( + std::regex{"\\s\\s" + alias_regex + "\\[" + name + "\\]"}); // file + + std::smatch base_match; + + for (const auto &pattern : patterns) { + if (std::regex_search(src, base_match, pattern) && + base_match.size() == 2) { + std::ssub_match base_sub_match = base_match[1]; + std::string alias = base_sub_match.str(); + return trim(alias); + } + } + + return fmt::format("__INVALID__ALIAS__({})", name); + } +}; + +struct json_t : public diagram_source_t { + using diagram_source_t::diagram_source_t; + using source_type = nlohmann::json; + using generator_tag = clanguml::common::generators::json_generator_tag; + + inline static const std::string diagram_type_name{"JSON"}; +}; + +std::optional get_element_by_id( + const nlohmann::json &j, const std::string &id) +{ + if (!j.contains("elements")) + return {}; + + for (const nlohmann::json &e : j["elements"]) { + if (e["id"] == id) + return {e}; + + if (e["type"] == "namespace" || e["type"] == "folder") { + auto maybe_e = get_element_by_id(e, id); + if (maybe_e) + return maybe_e; + } + } + + return {}; +} + +std::optional get_element( + const nlohmann::json &j, const std::string &name) +{ + if (!j.contains("elements")) + return {}; + + for (const nlohmann::json &e : j["elements"]) { + if (e["display_name"] == name) + return {e}; + + if (e["type"] == "namespace" || e["type"] == "folder" || + e["type"] == "directory" || e["type"] == "module") { + auto maybe_e = get_element(e, name); + if (maybe_e) + return maybe_e; + } + } + + return {}; +} + +std::optional get_element( + const json_t &src, const std::string &name) +{ + return get_element(src.src, name); +} + +std::optional get_participant( + const nlohmann::json &j, const std::string &name) +{ + if (!j.contains("participants")) + return {}; + + for (const nlohmann::json &e : j.at("participants")) { + if (e["display_name"] == name) + return {e}; + } + + return {}; +} + +auto get_relationship(const nlohmann::json &j, const nlohmann::json &from, + const nlohmann::json &to, const std::string &type, const std::string &label) +{ + return std::find_if(j["relationships"].begin(), j["relationships"].end(), + [&](const auto &it) { + auto match = (it["source"] == from) && (it["destination"] == to) && + (it["type"] == type); + + if (match && label.empty()) + return true; + + if (match && (label == it["label"])) + return true; + + return false; + }); +} + +auto get_relationship(const nlohmann::json &j, const std::string &from, + const std::string &to, const std::string &type, + const std::string &label = {}) +{ + auto source = get_element(j, from); + auto destination = get_element(j, to); + + if (!(source && destination)) + return j["relationships"].end(); + + return get_relationship( + j, source->at("id"), destination->at("id"), type, label); +} + +std::string expand_name(const nlohmann::json &j, const std::string &name) +{ + return name; +} + +template <> bool diagram_source_t::contains(std::string name) const +{ + return util::contains(src, name); +} + +template <> +bool diagram_source_t::search(const std::string &pattern) const +{ + std::regex pattern_regex{pattern}; + + std::smatch base_match; + return std::regex_search(src, base_match, pattern_regex); +} + +template <> +bool diagram_source_t::contains(std::string name) const +{ + return false; +} + +template <> std::string diagram_source_t::to_string() const +{ + return src; +} + +template <> std::string diagram_source_t::to_string() const +{ + return src.dump(2); +} + +/// +/// The following functions declarations define various checks on generated +/// diagrams. +/// They must be specialized for each diagram format (DiagramType) separately. +/// +/// @defgroup Test Cases diagram checks +/// @{ +/// + +// Check if generated diagram source starts with pattern +template +bool StartsWith(const DiagramType &d, std::string pattern); + +// Check if generated diagram source ends with pattern +template +bool EndsWith(const DiagramType &d, std::string pattern); + +template +bool HasTitle(const DiagramType &d, std::string const &str); + +// Check if generated diagram contains a specified enum +template +bool IsEnum(const DiagramType &d, std::string name); + +// Check if generated diagram contains a specified class +template +bool IsClass(const DiagramType &d, std::string name); + +// Check if generated diagram contains a specified class template +template +bool IsClassTemplate(const DiagramType &d, std::string name); + +// Check if generated diagram contains a specified abstract class +template +bool IsAbstractClass(const DiagramType &d, std::string name); + +// Check if generated diagram contains a specified class +template +bool IsBaseClass(const DiagramType &d, std::string base, std::string subclass); + +template +bool IsInnerClass( + const DiagramType &d, std::string const &parent, std::string const &inner); + +template +bool IsMethod(const DiagramType &d, const std::string &cls, + const std::string &name, const std::string &type = "void", + const std::string ¶ms = ""); + +template +bool IsField(const DiagramType &d, std::string const &cls, + std::string const &name, std::string type = "void"); + +template +bool IsAssociation(const DiagramType &d, std::string const &from, + std::string const &to, std::string const &label = "", + std::string multiplicity_source = "", std::string multiplicity_dest = "", + std::string style = ""); + +template +bool IsComposition(const DiagramType &d, std::string const &from, + std::string const &to, std::string const &label = "", + std::string multiplicity_source = "", std::string multiplicity_dest = "", + std::string style = ""); + +template +bool IsAggregation(const DiagramType &d, std::string const &from, + std::string const &to, std::string const &label = "", + std::string multiplicity_source = "", std::string multiplicity_dest = "", + std::string style = ""); + +template +bool IsInstantiation(const DiagramType &d, std::string const &from, + std::string const &to, std::string style = ""); + +template +bool IsDependency(const DiagramType &d, std::string const &from, + std::string const &to, std::string style = ""); + +template +bool IsFriend( + const DiagramType &d, std::string const &from, std::string const &to); + +template +bool IsPackageDependency( + const DiagramType &d, std::string const &from, std::string const &to); + +template +bool IsIncludeDependency( + const DiagramType &d, std::string const &from, std::string const &to); + +template +bool IsConstraint(const DiagramType &d, std::string const &from, + std::string const &to, std::string label = {}, std::string style = ""); + +template +bool IsConceptRequirement( + const DiagramType &d, std::string const &cpt, std::string requirement); + +template +bool IsLayoutHint(const DiagramType &d, std::string const &from, + std::string const &hint, std::string const &to); + +template +bool HasComment(const DiagramType &d, std::string const &comment); + +template +bool HasNote(const DiagramType &d, std::string const &cls, + std::string const &position, std::string const ¬e = ""); + +template +bool HasPackageNote(const DiagramType &d, std::string const &cls, + std::string const &position, std::string const ¬e = ""); + +template +bool HasMessageComment( + const DiagramType &d, std::string const &alias, std::string const ¬e); + +template +bool HasMemberNote(const DiagramType &d, std::string const &cls, + std::string const &member, std::string const &position, + std::string const ¬e = ""); + +template +bool HasLink(const DiagramType &d, std::string const &alias, + std::string const &link, std::string const &tooltip); + +template +bool HasMemberLink(const DiagramType &d, std::string const &method, + std::string const &link, std::string const &tooltip); + +template +bool IsFolder(const DiagramType &d, std::string const &path); + +template +bool IsFile(const DiagramType &d, std::string const &str); + +template +bool IsSystemHeader(const DiagramType &d, std::string const &str); + +template +bool IsHeaderDependency(const DiagramType &d, std::string const &from, + std::string const &to, std::string style = ""); + +template +bool IsSystemHeaderDependency(const DiagramType &d, std::string const &from, + std::string const &to, std::string style = ""); + +template +bool IsNamespacePackage(const DiagramType &d, Args... args); + +template +bool IsDirectoryPackage(const DiagramType &d, Args... args); + +template +bool IsModulePackage(const DiagramType &d, Args... args); + +template +bool IsDeprecated(const DiagramType &d, std::string const &str); + +/// +/// @} +/// + +template <> bool StartsWith(const plantuml_t &d, std::string pattern) +{ + return util::starts_with(d.src, pattern); +} + +template <> bool EndsWith(const plantuml_t &d, std::string pattern) +{ + return util::ends_with(d.src, pattern); +} + +template <> bool HasTitle(const plantuml_t &d, std::string const &str) +{ + return d.contains("title " + str); +} + +template <> bool IsEnum(const plantuml_t &d, std::string name) +{ + return d.contains(fmt::format("enum {}", d.get_alias(name))); +} + +template <> bool IsClass(const plantuml_t &d, std::string name) +{ + return d.contains(fmt::format("class {}", d.get_alias(name))); +} + +template <> bool IsClassTemplate(const plantuml_t &d, std::string name) +{ + return d.contains(fmt::format("class \"{}\"", name)); +} + +template <> bool IsAbstractClass(const plantuml_t &d, std::string name) +{ + return d.contains(fmt::format("abstract {}", d.get_alias(name))); +} + +template <> +bool IsBaseClass(const plantuml_t &d, std::string base, std::string subclass) +{ + return d.contains( + fmt::format("{} <|-- {}", d.get_alias(base), d.get_alias(subclass))); +} + +template <> +bool IsInnerClass( + const plantuml_t &d, std::string const &parent, std::string const &inner) +{ + return d.contains(d.get_alias(inner) + " --+ " + d.get_alias(parent)); +} + +template +bool IsMethod(const plantuml_t &d, std::string const &cls, + std::string const &name, std::string const &type = "void", + std::string const ¶ms = "") +{ + std::string pattern; + if constexpr (has_type()) + pattern += "{static} "; + + if constexpr (has_type()) + pattern += "{abstract} "; + + if constexpr (has_type()) + pattern = "+"; + else if constexpr (has_type()) + pattern = "#"; + else + pattern = "-"; + + pattern += name; + + pattern += "(" + params + ")"; + + if constexpr (has_type()) + pattern += " constexpr"; + + if constexpr (has_type()) + pattern += " consteval"; + + if constexpr (has_type()) + pattern += " const"; + + if constexpr (has_type()) + pattern += " = 0"; + + if constexpr (has_type()) + pattern += " = default"; + + if constexpr (has_type()) + pattern += " = deleted"; + + if constexpr (has_type()) + pattern += " [coroutine]"; + + pattern += " : " + type; + + return d.contains(pattern); +} + +template +bool IsField(const plantuml_t &d, std::string const &cls, + std::string const &name, std::string type) +{ + std::string pattern; + if constexpr (has_type()) + pattern += "{static} "; + + if constexpr (has_type()) + pattern = "+"; + else if constexpr (has_type()) + pattern = "#"; + else + pattern = "-"; + + pattern += name; + + return d.contains(pattern + " : " + type); +} + +template +bool IsAssociation(const plantuml_t &d, std::string const &from, + std::string const &to, std::string const &label = "", + std::string multiplicity_source = "", std::string multiplicity_dest = "", + std::string style = "") +{ + auto from_id = d.get_alias(from); + auto to_id = d.get_alias(to); + + std::string format_string = "{}"; + if (!multiplicity_source.empty()) + format_string += " \"" + multiplicity_source + "\""; + + format_string += fmt::format(" -{}->", style); + + if (!multiplicity_dest.empty()) + format_string += " \"" + multiplicity_dest + "\""; + + format_string += " {}"; + + if (!label.empty()) { + std::string label_prefix; + if constexpr (has_type()) + label_prefix = "+"; + else if constexpr (has_type()) + label_prefix = "#"; + else + label_prefix = "-"; + + format_string += " : {}{}"; + return d.contains(fmt::format( + fmt::runtime(format_string), from_id, to_id, label_prefix, label)); + } + + return d.contains(fmt::format(fmt::runtime(format_string), from_id, to_id)); +} + +template +bool IsComposition(const plantuml_t &d, std::string const &from, + std::string const &to, std::string const &label = "", + std::string multiplicity_source = "", std::string multiplicity_dest = "", + std::string style = "") +{ + std::string label_prefix; + if constexpr (has_type()) + label_prefix = "+"; + else if constexpr (has_type()) + label_prefix = "#"; + else + label_prefix = "-"; + + std::string format_string = "{}"; + if (!multiplicity_source.empty()) + format_string += " \"" + multiplicity_source + "\""; + + format_string += fmt::format(" *-{}-", style); + + if (!multiplicity_dest.empty()) + format_string += " \"" + multiplicity_dest + "\""; + + format_string += " {} : {}{}"; + + return d.contains(fmt::format(fmt::runtime(format_string), + d.get_alias(from), d.get_alias(to), label_prefix, label)); +} + +template +bool IsAggregation(const plantuml_t &d, std::string const &from, + std::string const &to, std::string const &label = "", + std::string multiplicity_source = "", std::string multiplicity_dest = "", + std::string style = "") +{ + std::string label_prefix; + if constexpr (has_type()) + label_prefix = "+"; + else if constexpr (has_type()) + label_prefix = "#"; + else + label_prefix = "-"; + + std::string format_string = "{}"; + if (!multiplicity_source.empty()) + format_string += " \"" + multiplicity_source + "\""; + + format_string += fmt::format(" o-{}-", style); + + if (!multiplicity_dest.empty()) + format_string += " \"" + multiplicity_dest + "\""; + + format_string += " {} : {}{}"; + + return d.contains(fmt::format(fmt::runtime(format_string), + d.get_alias(from), d.get_alias(to), label_prefix, label)); +} + +template <> +bool IsInstantiation(const plantuml_t &d, std::string const &from, + std::string const &to, std::string style) +{ + return d.contains( + fmt::format("{} .{}.|> {}", d.get_alias(to), style, d.get_alias(from))); +} + +template <> +bool IsDependency(const plantuml_t &d, std::string const &from, + std::string const &to, std::string style) +{ + return d.contains( + fmt::format("{} .{}.> {}", d.get_alias(from), style, d.get_alias(to))); +} + +template +bool IsFriend( + const plantuml_t &d, std::string const &from, std::string const &to) +{ + std::string pattern; + + if constexpr (has_type()) + pattern = "+"; + else if constexpr (has_type()) + pattern = "#"; + else + pattern = "-"; + + return d.contains(fmt::format("{} <.. {} : {}<>", d.get_alias(from), + d.get_alias(to), pattern)); +} + +template <> +bool IsPackageDependency( + const plantuml_t &d, std::string const &from, std::string const &to) +{ + return d.contains( + fmt::format("{} .{}.> {}", d.get_alias(from), "", d.get_alias(to))); +} + +template <> +bool IsIncludeDependency( + const plantuml_t &d, std::string const &from, std::string const &to) +{ + return d.contains( + fmt::format("{} .{}.> {}", d.get_alias(from), "", d.get_alias(to))); +} + +template <> +bool IsConstraint(const plantuml_t &d, std::string const &from, + std::string const &to, std::string label, std::string style) +{ + if (label.empty()) + return d.contains(fmt::format( + "{} .{}.> {}", d.get_alias(from), style, d.get_alias(to))); + + return d.contains(fmt::format( + "{} .{}.> {} : {}", d.get_alias(from), style, d.get_alias(to), label)); +} + +template <> +bool IsConceptRequirement( + const plantuml_t &d, std::string const &cpt, std::string requirement) +{ + return d.contains(requirement); +} + +template <> +bool IsLayoutHint(const plantuml_t &d, std::string const &from, + std::string const &hint, std::string const &to) +{ + return d.contains(fmt::format( + "{} -[hidden]{}- {}", d.get_alias(from), hint, d.get_alias(to))); +} + +template <> bool HasComment(const plantuml_t &d, std::string const &comment) +{ + return d.contains(fmt::format("' {}", comment)); +} + +template <> +bool HasNote(const plantuml_t &d, std::string const &cls, + std::string const &position, std::string const ¬e) +{ + return d.contains(fmt::format("note {} of {}", position, d.get_alias(cls))); +} + +template <> +bool HasMessageComment(const plantuml_t &d, std::string const &participant, + std::string const ¬e) +{ + return d.contains(std::string("note over ") + d.get_alias(participant) + + "\\n" + note + "\\n" + "end note"); +} + +template <> +bool HasMemberNote(const plantuml_t &d, std::string const &cls, + std::string const &member, std::string const &position, + std::string const ¬e) +{ + return d.contains( + fmt::format("note {} of {}::{}", position, d.get_alias(cls), member)); +} + +template <> +bool HasPackageNote(const plantuml_t &d, std::string const &cls, + std::string const &position, std::string const ¬e) +{ + return d.contains(fmt::format("note {} of {}", position, d.get_alias(cls))); +} + +template <> +bool HasLink(const plantuml_t &d, std::string const &element, + std::string const &link, std::string const &tooltip) +{ + return d.contains( + fmt::format("{} [[{}{{{}}}]]", d.get_alias(element), link, tooltip)); +} + +template <> +bool HasMemberLink(const plantuml_t &d, std::string const &method, + std::string const &link, std::string const &tooltip) +{ + return d.contains(fmt::format("{} [[[{}{{{}}}]]]", method, link, tooltip)); +} + +template <> bool IsFolder(const plantuml_t &d, std::string const &path) +{ + return d.contains("folder \"" + util::split(path, "/").back() + "\""); +} + +template <> bool IsFile(const plantuml_t &d, std::string const &path) +{ + return d.contains("file \"" + util::split(path, "/").back() + "\""); +} + +template <> bool IsSystemHeader(const plantuml_t &d, std::string const &path) +{ + return d.contains("file \"" + path + "\""); +} + +template <> +bool IsHeaderDependency(const plantuml_t &d, std::string const &from, + std::string const &to, std::string style) +{ + assert(d.diagram_type == common::model::diagram_t::kInclude); + + return d.contains( + fmt::format("{} --> {}", d.get_alias(util::split(from, "/").back()), + d.get_alias(util::split(to, "/").back()))); +} + +template <> +bool IsSystemHeaderDependency(const plantuml_t &d, std::string const &from, + std::string const &to, std::string style) +{ + assert(d.diagram_type == common::model::diagram_t::kInclude); + + return d.contains( + fmt::format("{} ..> {}", d.get_alias(util::split(from, "/").back()), + d.get_alias(util::split(to, "/").back()))); +} + +template auto get_last(Args &&...args) +{ + return std::get(std::forward_as_tuple(args...)); +} + +template +bool IsNamespacePackage(const plantuml_t &d, Args... args) +{ + const auto &name = get_last(args...); + return d.contains("package [" + name + "]"); +} + +template +bool IsDirectoryPackage(const plantuml_t &d, Args... args) +{ + const auto &name = get_last(args...); + return d.contains("package [" + name + "]"); +} + +template +bool IsModulePackage(const plantuml_t &d, Args... args) +{ + const auto &name = get_last(args...); + return d.contains("package [" + name + "]"); +} + +template <> bool IsDeprecated(const plantuml_t &d, const std::string &name) +{ + return d.contains(d.get_alias(name) + " <> "); +} + +// +// MermaidJS test helpers +// + +template <> bool HasTitle(const mermaid_t &d, std::string const &str) +{ + return d.contains("title: " + str); +} + +template <> bool IsEnum(const mermaid_t &d, std::string name) +{ + return d.search(std::string("class ") + d.get_alias(name) + + " \\{\\n\\s+<>"); +} + +template <> bool IsClass(const mermaid_t &d, std::string name) +{ + return d.contains(fmt::format("class {}[\"{}\"]", d.get_alias(name), name)); +} + +template <> bool IsClassTemplate(const mermaid_t &d, std::string name) +{ + return d.contains(fmt::format("class {}", d.get_alias(name))); +} + +template <> bool IsAbstractClass(const mermaid_t &d, std::string name) +{ + return d.search( + std::string("class ") + d.get_alias(name) + " \\{\\n\\s+<>"); +} + +template <> +bool IsBaseClass(const mermaid_t &d, std::string base, std::string subclass) +{ + return d.contains( + fmt::format("{} <|-- {}", d.get_alias(base), d.get_alias(subclass))); +} + +template <> +bool IsInnerClass( + const mermaid_t &d, std::string const &parent, std::string const &inner) +{ + return d.contains(d.get_alias(parent) + " ()-- " + d.get_alias(inner)); +} + +template +bool IsMethod(const mermaid_t &d, std::string const &cls, + std::string const &name, std::string type = "void", + std::string const ¶ms = "") +{ + std::string pattern; + + if constexpr (has_type()) + pattern = "+"; + else if constexpr (has_type()) + pattern = "#"; + else + pattern = "-"; + + pattern += name; + + pattern += "(" + params + ")"; + + std::vector method_mods; + if constexpr (has_type()) + method_mods.push_back("default"); + if constexpr (has_type()) + method_mods.push_back("const"); + if constexpr (has_type()) + method_mods.push_back("constexpr"); + if constexpr (has_type()) + method_mods.push_back("consteval"); + if constexpr (has_type()) + method_mods.push_back("coroutine"); + + pattern += " : "; + + if (!method_mods.empty()) { + pattern += fmt::format("[{}] ", fmt::join(method_mods, ",")); + } + + util::replace_all(type, "<", "<"); + util::replace_all(type, ">", ">"); + util::replace_all(type, "(", "("); + util::replace_all(type, ")", ")"); + util::replace_all(type, "##", "::"); + util::replace_all(type, "{", "{"); + util::replace_all(type, "}", "}"); + + pattern += type; + + if constexpr (has_type()) + pattern += "*"; + + if constexpr (has_type()) + pattern += "$"; + + return d.contains(pattern); +} + +template +bool IsField(const mermaid_t &d, std::string const &cls, + std::string const &name, std::string type) +{ + std::string pattern; + if constexpr (has_type()) + pattern += "{static} "; + + if constexpr (has_type()) + pattern = "+"; + else if constexpr (has_type()) + pattern = "#"; + else + pattern = "-"; + + pattern += name; + + util::replace_all(type, "<", "<"); + util::replace_all(type, ">", ">"); + util::replace_all(type, "(", "("); + util::replace_all(type, ")", ")"); + util::replace_all(type, "##", "::"); + util::replace_all(type, "{", "{"); + util::replace_all(type, "}", "}"); + + return d.contains(pattern + " : " + type); +} + +template +bool IsAssociation(const mermaid_t &d, std::string const &from, + std::string const &to, std::string const &label = "", + std::string multiplicity_source = "", std::string multiplicity_dest = "", + std::string style = "") +{ + auto from_id = d.get_alias(from); + auto to_id = d.get_alias(to); + + std::string label_prefix; + if constexpr (has_type()) + label_prefix = "+"; + else if constexpr (has_type()) + label_prefix = "#"; + else + label_prefix = "-"; + + std::string format_string = "{}"; + if (!multiplicity_source.empty()) + format_string += " \"" + multiplicity_source + "\""; + + format_string += " -->"; + + if (!multiplicity_dest.empty()) + format_string += " \"" + multiplicity_dest + "\""; + + format_string += " {}"; + + if (!label.empty()) { + format_string += " : {}{}"; + return d.contains(fmt::format( + fmt::runtime(format_string), from_id, to_id, label_prefix, label)); + } + + return d.contains(fmt::format(fmt::runtime(format_string), from_id, to_id)); +} + +template +bool IsComposition(const mermaid_t &d, std::string const &from, + std::string const &to, std::string const &label = "", + std::string multiplicity_source = "", std::string multiplicity_dest = "", + std::string style = "") +{ + std::string label_prefix; + if constexpr (has_type()) + label_prefix = "+"; + else if constexpr (has_type()) + label_prefix = "#"; + else + label_prefix = "-"; + + std::string format_string = "{}"; + if (!multiplicity_source.empty()) + format_string += " \"" + multiplicity_source + "\""; + + format_string += fmt::format(" *-{}-", style); + + if (!multiplicity_dest.empty()) + format_string += " \"" + multiplicity_dest + "\""; + + format_string += " {} : {}{}"; + + return d.contains(fmt::format(fmt::runtime(format_string), + d.get_alias(from), d.get_alias(to), label_prefix, label)); +} + +template +bool IsAggregation(const mermaid_t &d, std::string const &from, + std::string const &to, std::string const &label = "", + std::string multiplicity_source = "", std::string multiplicity_dest = "", + std::string style = "") +{ + std::string label_prefix; + if constexpr (has_type()) + label_prefix = "+"; + else if constexpr (has_type()) + label_prefix = "#"; + else + label_prefix = "-"; + + std::string format_string = "{}"; + if (!multiplicity_source.empty()) + format_string += " \"" + multiplicity_source + "\""; + + format_string += " o--"; + + if (!multiplicity_dest.empty()) + format_string += " \"" + multiplicity_dest + "\""; + + format_string += " {} : {}{}"; + + return d.contains(fmt::format(fmt::runtime(format_string), + d.get_alias(from), d.get_alias(to), label_prefix, label)); +} + +template <> +bool IsInstantiation(const mermaid_t &d, std::string const &from, + std::string const &to, std::string style) +{ + return d.contains( + fmt::format("{} ..|> {}", d.get_alias(to), d.get_alias(from))); +} + +template <> +bool IsDependency(const mermaid_t &d, std::string const &from, + std::string const &to, std::string style) +{ + if (d.diagram_type == common::model::diagram_t::kClass) { + return d.contains( + fmt::format("{} ..> {}", d.get_alias(from), d.get_alias(to))); + } + + return d.contains( + fmt::format("{} -.-> {}", d.get_alias(from), d.get_alias(to))); +} + +template <> +bool IsHeaderDependency(const mermaid_t &d, std::string const &from, + std::string const &to, std::string style) +{ + assert(d.diagram_type == common::model::diagram_t::kInclude); + + return d.contains( + fmt::format("{} --> {}", d.get_alias(util::split(from, "/").back()), + d.get_alias(util::split(to, "/").back()))); +} + +template <> +bool IsSystemHeaderDependency(const mermaid_t &d, std::string const &from, + std::string const &to, std::string style) +{ + assert(d.diagram_type == common::model::diagram_t::kInclude); + + return d.contains( + fmt::format("{} -.-> {}", d.get_alias(util::split(from, "/").back()), + d.get_alias(util::split(to, "/").back()))); +} + +template +bool IsFriend( + const mermaid_t &d, std::string const &from, std::string const &to) +{ + std::string pattern; + + if constexpr (has_type()) + pattern = "+"; + else if constexpr (has_type()) + pattern = "#"; + else + pattern = "-"; + + return d.contains(fmt::format( + "{} <.. {} : {}[friend]", d.get_alias(from), d.get_alias(to), pattern)); +} + +template <> +bool IsPackageDependency( + const mermaid_t &d, std::string const &from, std::string const &to) +{ + return d.contains( + fmt::format("{} -.-> {}", d.get_alias(from), "", d.get_alias(to))); +} + +template <> +bool IsIncludeDependency( + const mermaid_t &d, std::string const &from, std::string const &to) +{ + return d.contains( + fmt::format("{} -.-> {}", d.get_alias(from), "", d.get_alias(to))); +} + +template <> +bool IsConstraint(const mermaid_t &d, std::string const &from, + std::string const &to, std::string label, std::string style) +{ + auto from_id = d.get_alias(from); + auto to_id = d.get_alias(to); + + if (label.empty()) + return d.contains(fmt::format("{} ..> {}", from_id, "", to_id)); + + util::replace_all(label, "<", "<"); + util::replace_all(label, ">", ">"); + util::replace_all(label, "(", "("); + util::replace_all(label, ")", ")"); + util::replace_all(label, "##", "::"); + util::replace_all(label, "{", "{"); + util::replace_all(label, "}", "}"); + + if (label.empty()) + return d.contains(fmt::format("{} ..> {}", from_id, to_id)); + + return d.contains(fmt::format("{} ..> {} : {}", from_id, to_id, label)); +} + +template <> +bool IsConceptRequirement( + const mermaid_t &d, std::string const &cpt, std::string requirement) +{ + util::replace_all(requirement, "<", "<"); + util::replace_all(requirement, ">", ">"); + util::replace_all(requirement, "(", "("); + util::replace_all(requirement, ")", ")"); + util::replace_all(requirement, "##", "::"); + util::replace_all(requirement, "{", "{"); + util::replace_all(requirement, "}", "}"); + + return d.contains(requirement); +} + +template <> +bool IsLayoutHint(const mermaid_t &d, std::string const &from, + std::string const &hint, std::string const &to) +{ + return true; +} + +template <> bool HasComment(const mermaid_t &d, std::string const &comment) +{ + return d.contains(fmt::format("%% {}", comment)); +} + +template <> +bool HasNote(const mermaid_t &d, std::string const &cls, + std::string const &position, std::string const ¬e) +{ + if (d.diagram_type == common::model::diagram_t::kPackage) { + return d.contains(fmt::format("-.- {}", d.get_alias(cls))); + } + + return d.contains(fmt::format("note for {}", d.get_alias(cls))); +} + +template <> +bool HasMessageComment( + const mermaid_t &d, std::string const &participant, std::string const ¬e) +{ + return d.contains( + std::string("note over ") + d.get_alias(participant) + ": " + note); +} + +template <> +bool HasMemberNote(const mermaid_t &d, std::string const &cls, + std::string const &member, std::string const &position, + std::string const ¬e) +{ + return d.contains( + fmt::format("note for {} \"{}\"", d.get_alias(cls), note)); +} + +template <> +bool HasPackageNote(const mermaid_t &d, std::string const &cls, + std::string const &position, std::string const ¬e) +{ + return d.contains(fmt::format("-.- {}", d.get_alias(cls))); +} + +template <> +bool HasLink(const mermaid_t &d, std::string const &element, + std::string const &link, std::string const &tooltip) +{ + return d.contains(fmt::format( + "click {} href \"{}\" \"{}\"", d.get_alias(element), link, tooltip)); +} + +template <> +bool HasMemberLink(const mermaid_t &d, std::string const &method, + std::string const &link, std::string const &tooltip) +{ + return true; +} + +template <> bool IsFolder(const mermaid_t &d, std::string const &path) +{ + return d.contains("subgraph " + d.get_alias(util::split(path, "/").back())); +} + +template <> bool IsFile(const mermaid_t &d, std::string const &path) +{ + return d.contains(d.get_alias(util::split(path, "/").back()) + "["); +} + +template <> bool IsSystemHeader(const mermaid_t &d, std::string const &path) +{ + return d.contains(d.get_alias(path) + "["); +} + +template +bool IsNamespacePackage(const mermaid_t &d, Args... args) +{ + const auto &name = get_last(args...); + return d.contains("subgraph " + d.get_alias(name)); +} + +template +bool IsDirectoryPackage(const mermaid_t &d, Args... args) +{ + const auto &name = get_last(args...); + return d.contains("subgraph " + d.get_alias(name)); +} + +template +bool IsModulePackage(const mermaid_t &d, Args... args) +{ + const auto &name = get_last(args...); + return d.contains("subgraph " + d.get_alias(name)); +} + +template <> bool IsDeprecated(const mermaid_t &d, const std::string &name) +{ + return d.contains(d.get_alias(name) + " <> "); +} + +// +// JSON test helpers +// +struct File { + explicit File(const std::string &f) + : file{f} + { + } + + const std::string file; +}; + +template <> bool HasTitle(const json_t &d, std::string const &str) +{ + return d.src.contains("title") && d.src["title"] == str; +} + +template <> bool IsAbstractClass(const json_t &d, std::string name) +{ + auto e = get_element(d.src, expand_name(d.src, name)); + return e && e->at("type") == "class" && e->at("is_abstract"); +} + +template <> bool IsEnum(const json_t &d, std::string name) +{ + auto e = get_element(d.src, expand_name(d.src, name)); + return e && e->at("type") == "enum"; +} + +template <> bool IsClass(const json_t &d, std::string name) +{ + auto e = get_element(d.src, expand_name(d.src, name)); + return e && e->at("type") == "class" && !e->at("is_abstract"); +} + +template <> bool IsClassTemplate(const json_t &d, std::string name) +{ + auto e = get_element(d.src, expand_name(d.src, name)); + return e && e->at("type") == "class"; +} + +template <> +bool IsBaseClass(const json_t &d, std::string base, std::string subclass) +{ + const auto &j = d.src; + auto base_el = get_element(j, expand_name(j, base)); + auto subclass_el = get_element(j, expand_name(j, subclass)); + + if (!base_el || !subclass_el) + return false; + + const nlohmann::json &bases = (*subclass_el)["bases"]; + + return std::find_if(bases.begin(), bases.end(), [&](const auto &it) { + return it["id"] == base_el.value()["id"]; + }) != bases.end(); +} + +template <> +bool IsInnerClass( + const json_t &d, std::string const &parent, std::string const &inner) +{ + const auto &j = d.src; + + auto rel = get_relationship( + j, expand_name(j, inner), expand_name(j, parent), "containment"); + + return rel != j["relationships"].end(); +} + +template +bool IsMethod(const json_t &d, const std::string &cls, std::string const &name, + std::string type = "void", std::string const ¶ms = "") +{ + const auto &j = d.src; + auto sc = get_element(j, expand_name(j, cls)); + + if (!sc) + return false; + + const nlohmann::json &methods = (*sc)["methods"]; + + return std::find_if(methods.begin(), methods.end(), [&](const auto &it) { + return it["name"] == name; + }) != methods.end(); +} + +template +bool IsField(const json_t &d, std::string const &cls, std::string const &name, + std::string type) +{ + const auto &j = d.src; + + auto sc = get_element(j, expand_name(j, cls)); + + if (!sc) + return false; + + const nlohmann::json &members = (*sc)["members"]; + + return std::find_if(members.begin(), members.end(), [&](const auto &it) { + return it["name"] == name && it["type"] == type; + }) != members.end(); +} + +template +bool IsAssociation(const json_t &d, std::string const &from, + std::string const &to, std::string const &label = "", + std::string multiplicity_source = "", std::string multiplicity_dest = "", + std::string style = "") +{ + const auto &j = d.src; + + auto rel = get_relationship( + j, expand_name(j, from), expand_name(j, to), "association", label); + + if (rel == j["relationships"].end()) + return false; + + if (!label.empty() && (label != rel->at("label"))) + return false; + + std::string access; + if constexpr (has_type()) + access = "public"; + else if constexpr (has_type()) + access = "protected"; + else + access = "private"; + + if (access != rel->at("access")) + return false; + + return true; +} + +template +bool IsComposition(const json_t &d, std::string const &from, + std::string const &to, std::string const &label = "", + std::string multiplicity_source = "", std::string multiplicity_dest = "", + std::string style = "") +{ + const auto &j = d.src; + + auto rel = get_relationship( + j, expand_name(j, to), expand_name(j, from), "composition", label); + + if (rel == j["relationships"].end()) + return false; + + if (!label.empty() && label != rel->at("label")) + return false; + + std::string access; + if constexpr (has_type()) + access = "public"; + else if constexpr (has_type()) + access = "protected"; + else + access = "private"; + + if (access != rel->at("access")) + return false; + + return true; +} + +template +bool IsAggregation(const json_t &d, std::string const &from, + std::string const &to, std::string const &label = "", + std::string multiplicity_source = "", std::string multiplicity_dest = "", + std::string style = "") +{ + const auto &j = d.src; + + auto rel = get_relationship( + j, expand_name(j, from), expand_name(j, to), "aggregation", label); + + if (rel == j["relationships"].end()) + return false; + + if (!label.empty() && label != rel->at("label")) + return false; + + std::string access; + if constexpr (has_type()) + access = "public"; + else if constexpr (has_type()) + access = "protected"; + else + access = "private"; + + if (access != rel->at("access")) + return false; + + return true; +} + +template <> +bool IsInstantiation(const json_t &d, std::string const &from, + std::string const &to, std::string style) +{ + const auto &j = d.src; + + auto rel = get_relationship( + j, expand_name(j, to), expand_name(j, from), "instantiation"); + + if (rel == j["relationships"].end()) + return false; + + return true; +} + +template <> +bool IsDependency(const json_t &d, std::string const &from, + std::string const &to, std::string style) +{ + const auto &j = d.src; + + auto rel = get_relationship( + j, expand_name(j, from), expand_name(j, to), "dependency"); + + if (rel == j["relationships"].end()) + return false; + + return true; +} + +template +bool IsFriend(const json_t &d, std::string const &from, std::string const &to) +{ + std::string access; + + if constexpr (has_type()) + access = "public"; + else if constexpr (has_type()) + access = "protected"; + else + access = "private"; + + const auto &j = d.src; + + auto rel = get_relationship( + j, expand_name(j, from), expand_name(j, to), "friendship"); + + return rel != j["relationships"].end() && rel->at("access") == access; +} + +template <> +bool IsPackageDependency( + const json_t &d, std::string const &from, std::string const &to) +{ + const auto &j = d.src; + + auto rel = get_relationship( + j, expand_name(j, from), expand_name(j, to), "dependency"); + + if (rel == j["relationships"].end()) + return false; + + return true; +} + +template <> +bool IsIncludeDependency( + const json_t &d, std::string const &from, std::string const &to) +{ + const auto &j = d.src; + + auto rel = get_relationship( + j, expand_name(j, from), expand_name(j, to), "dependency"); + + if (rel == j["relationships"].end()) + return false; + + return true; +} + +template <> +bool IsConstraint(const json_t &d, std::string const &from, + std::string const &to, std::string label, std::string style) +{ + return false; +} + +template <> +bool IsConceptRequirement( + const json_t &d, std::string const &cpt, std::string requirement) +{ + return false; +} + +template <> +bool IsLayoutHint(const json_t &d, std::string const &from, + std::string const &hint, std::string const &to) +{ + return true; +} + +template <> bool HasComment(const json_t &d, std::string const &comment) +{ + // Comments are not included in JSON + return true; +} + +template <> +bool HasNote(const json_t &d, std::string const &cls, + std::string const &position, std::string const ¬e) +{ + const auto &j = d.src; + + auto sc = get_element(j, expand_name(j, cls)); + + if (!sc) + return false; + + std::string formatted = (*sc)["comment"]["formatted"]; + + return util::contains(formatted, note); +} + +template <> +bool HasPackageNote(const json_t &d, std::string const &cls, + std::string const &position, std::string const ¬e) +{ + return true; +} + +template <> +bool HasMessageComment( + const json_t &d, std::string const &alias, std::string const ¬e) +{ + return true; +} + +template <> +bool HasMemberNote(const json_t &d, std::string const &cls, + std::string const &member, std::string const &position, + std::string const ¬e) +{ + return true; +} + +template <> +bool HasLink(const json_t &d, std::string const &alias, std::string const &link, + std::string const &tooltip) +{ + return true; +} + +template <> +bool HasMemberLink(const json_t &d, std::string const &method, + std::string const &link, std::string const &tooltip) +{ + return true; +} + +template <> bool IsFolder(const json_t &d, std::string const &path) +{ + const auto &j = d.src; + + auto e = get_element(j, path); + return e && e->at("type") == "folder"; +} + +template <> bool IsFile(const json_t &d, std::string const &path) +{ + const auto &j = d.src; + + auto e = get_element(j, path); + return e && e->at("type") == "file"; +} + +template <> bool IsSystemHeader(const json_t &d, std::string const &path) +{ + const auto &j = d.src; + + auto e = get_element(j, path); + return e && e->at("type") == "file" && e->at("file_kind") == "header" && + e->at("is_system"); +} + +template <> +bool IsHeaderDependency(const json_t &d, std::string const &from, + std::string const &to, std::string style) +{ + assert(d.diagram_type == common::model::diagram_t::kInclude); + const auto &j = d.src; + + auto rel = get_relationship( + j, expand_name(j, from), expand_name(j, to), "association"); + + if (rel == j["relationships"].end()) + return false; + + return true; +} + +template <> +bool IsSystemHeaderDependency(const json_t &d, std::string const &from, + std::string const &to, std::string style) +{ + assert(d.diagram_type == common::model::diagram_t::kInclude); + const auto &j = d.src; + + auto rel = get_relationship( + j, expand_name(j, from), expand_name(j, to), "dependency"); + + if (rel == j["relationships"].end()) + return false; + + return true; +} + +template +bool IsPackagePath( + const nlohmann::json &j, const std::string &head, Args... args) +{ + if constexpr (sizeof...(Args) == 0) { + auto e = get_element(j, expand_name(j, head)); + + return e && e->at("type") == package_type_name(); + } + else { + auto e = get_element(j, head); + if (!e.has_value()) + return false; + + return IsPackagePath(*e, args...); + } +} + +template +bool IsNamespacePackage(const json_t &d, Args... args) +{ + const auto &j = d.src; + + return IsPackagePath(j, std::forward(args)...); +} + +template +bool IsDirectoryPackage(const json_t &d, Args... args) +{ + const auto &j = d.src; + + return IsPackagePath(j, std::forward(args)...); +} + +template bool IsModulePackage(const json_t &d, Args... args) +{ + const auto &j = d.src; + + return IsPackagePath(j, std::forward(args)...); +} + +template <> bool IsDeprecated(const json_t &d, const std::string &name) +{ + const auto &j = d.src; + + auto e = get_element(j, expand_name(j, name)); + return e && e->at("is_deprecated") == true; +} +} + +/* namespace clanguml { namespace test { namespace matchers { @@ -78,6 +1851,13 @@ using Catch::Matchers::StdString::CasedString; using Catch::Matchers::StdString::ContainsMatcher; using Catch::Matchers::StdString::RegexMatcher; +using Catch::Matchers::Contains; +using Catch::Matchers::EndsWith; +using Catch::Matchers::Equals; +using Catch::Matchers::Matches; +using Catch::Matchers::StartsWith; +using Catch::Matchers::VectorContains; + struct JsonMatcherBase : Catch::MatcherBase { JsonMatcherBase( std::string const &operation, CasedString const &comparator); @@ -757,7 +2537,7 @@ ContainsMatcher IsConstraint(std::string const &from, std::string const &to, util::replace_all(label, "<", "<"); util::replace_all(label, ">", ">"); util::replace_all(label, "(", "("); - util::replace_all(label, ")", ")"); + util::replace_all(label, ")", ") util::replace_all(label, "##", "::"); util::replace_all(label, "{", "{"); util::replace_all(label, "}", "}"); @@ -1690,3 +3470,4 @@ bool HasMessageChain( } } } +*/ \ No newline at end of file diff --git a/tests/test_thread_pool_executor.cc b/tests/test_thread_pool_executor.cc index 369b70a6..0285e49d 100644 --- a/tests/test_thread_pool_executor.cc +++ b/tests/test_thread_pool_executor.cc @@ -15,13 +15,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#define CATCH_CONFIG_MAIN +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN -#include "catch.h" +#include "doctest/doctest.h" #include "util/thread_pool_executor.h" -TEST_CASE("Test thread_pool_executor", "[unit-test]") +TEST_CASE("Test thread_pool_executor") { using clanguml::util::thread_pool_executor; diff --git a/tests/test_util.cc b/tests/test_util.cc index 0442e4c9..98145004 100644 --- a/tests/test_util.cc +++ b/tests/test_util.cc @@ -15,16 +15,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#define CATCH_CONFIG_MAIN +#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN #include "util/util.h" #include + #include -#include "catch.h" +#include "doctest/doctest.h" -TEST_CASE("Test split", "[unit-test]") +TEST_CASE("Test split") { using C = std::vector; using namespace clanguml::util; @@ -45,7 +46,7 @@ TEST_CASE("Test split", "[unit-test]") CHECK(split("std::vector::detail::", "::") == C{"std", "vector", "detail"}); } -TEST_CASE("Test abbreviate", "[unit-test]") +TEST_CASE("Test abbreviate") { using namespace clanguml::util; @@ -55,7 +56,7 @@ TEST_CASE("Test abbreviate", "[unit-test]") CHECK(abbreviate("abcdefg", 5) == "ab..."); } -TEST_CASE("Test starts_with", "[unit-test]") +TEST_CASE("Test starts_with") { using clanguml::util::starts_with; using std::filesystem::path; @@ -73,7 +74,7 @@ TEST_CASE("Test starts_with", "[unit-test]") CHECK_FALSE(starts_with(path{"c/file1.h"}, path{"c/file2.h"})); } -TEST_CASE("Test replace_all", "[unit-test]") +TEST_CASE("Test replace_all") { using namespace clanguml::util; @@ -95,7 +96,7 @@ TEST_CASE("Test replace_all", "[unit-test]") CHECK(text == orig); } -TEST_CASE("Test extract_template_parameter_index", "[unit-test]") +TEST_CASE("Test extract_template_parameter_index") { using namespace clanguml::common; @@ -124,7 +125,7 @@ TEST_CASE("Test extract_template_parameter_index", "[unit-test]") } } -TEST_CASE("Test parse_unexposed_template_params", "[unit-test]") +TEST_CASE("Test parse_unexposed_template_params") { using namespace clanguml::common; @@ -200,7 +201,7 @@ TEST_CASE("Test parse_unexposed_template_params", "[unit-test]") CHECK(declaration_template[2].type().value() == "Tail"); } -TEST_CASE("Test remove_prefix", "[unit-test]") +TEST_CASE("Test remove_prefix") { using namespace clanguml::util; @@ -224,7 +225,7 @@ TEST_CASE("Test remove_prefix", "[unit-test]") CHECK(collection.empty()); } -TEST_CASE("Test path_to_url", "[unit-test]") +TEST_CASE("Test path_to_url") { namespace fs = std::filesystem; using namespace clanguml::util; @@ -258,7 +259,7 @@ TEST_CASE("Test path_to_url", "[unit-test]") #endif } -TEST_CASE("Test ensure_path_is_absolute", "[unit-test]") +TEST_CASE("Test ensure_path_is_absolute") { using namespace clanguml::util; @@ -278,7 +279,7 @@ TEST_CASE("Test ensure_path_is_absolute", "[unit-test]") path{"/"}.make_preferred()); } -TEST_CASE("Test hash_seed", "[unit-test]") +TEST_CASE("Test hash_seed") { using namespace clanguml::util; @@ -287,7 +288,7 @@ TEST_CASE("Test hash_seed", "[unit-test]") CHECK(hash_seed(1) != hash_seed(2)); } -TEST_CASE("Test tokenize_unexposed_template_parameter", "[unit-test]") +TEST_CASE("Test tokenize_unexposed_template_parameter") { using namespace clanguml::common; @@ -398,7 +399,7 @@ TEST_CASE("Test tokenize_unexposed_template_parameter", "[unit-test]") } } -TEST_CASE("Test format_message_comment", "[unit-test]") +TEST_CASE("Test format_message_comment") { using namespace clanguml::util; @@ -419,7 +420,7 @@ TEST_CASE("Test format_message_comment", "[unit-test]") 15) == "This is a url:\nhttp://example.com/test/12345"); } -TEST_CASE("Test is_relative_to", "[unit-test]") +TEST_CASE("Test is_relative_to") { using std::filesystem::path; using namespace clanguml::util; @@ -432,7 +433,7 @@ TEST_CASE("Test is_relative_to", "[unit-test]") CHECK_FALSE(is_relative_to(child, base2)); } -TEST_CASE("Test parse_source_location", "[unit-test]") +TEST_CASE("Test parse_source_location") { using namespace clanguml::common; From eeae5caef5adafcc38967b75e329ea00627b1efd Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Mon, 13 May 2024 15:51:45 +0200 Subject: [PATCH 03/15] WIP --- .../json/class_diagram_generator.cc | 21 +- .../mermaid/class_diagram_generator.cc | 3 +- src/class_diagram/model/class_method.cc | 20 + src/class_diagram/model/class_method.h | 13 + .../visitor/translation_unit_visitor.cc | 13 +- src/common/model/diagram.cc | 5 + tests/CMakeLists.txt | 2 +- tests/t00028/test_case.h | 52 ++- tests/t00031/test_case.h | 71 +--- tests/t00032/test_case.h | 101 +---- tests/t00033/test_case.h | 83 +--- tests/t00034/test_case.h | 62 +-- tests/t00035/test_case.h | 62 +-- tests/t00036/test_case.h | 80 +--- tests/t00037/test_case.h | 59 +-- tests/t00038/test_case.h | 188 ++------ tests/t00039/test_case.h | 121 ++---- tests/t00040/test_case.h | 61 +-- tests/t00041/test_case.h | 117 ++--- tests/t00042/test_case.h | 45 +- tests/t00043/test_case.h | 129 ++---- tests/t00044/test_case.h | 102 +---- tests/t00045/test_case.h | 114 ++--- tests/t00046/test_case.h | 63 +-- tests/t00047/test_case.h | 54 +-- tests/t00048/test_case.h | 68 +-- tests/t00049/test_case.h | 88 +--- tests/t00050/test_case.h | 98 ++--- tests/t00051/test_case.h | 35 +- tests/t00052/test_case.h | 16 +- tests/t00053/test_case.h | 146 ++++--- tests/t00054/test_case.h | 28 +- tests/t00055/test_case.h | 29 +- tests/t00056/test_case.h | 401 ++++++++++-------- tests/t00057/test_case.h | 168 ++++---- tests/t00058/.clang-uml | 3 + tests/t00058/test_case.h | 182 ++++---- tests/t00059/test_case.h | 268 +++++++----- tests/t00060/test_case.h | 103 +++-- tests/t00061/test_case.h | 67 +-- tests/t00062/test_case.h | 55 ++- tests/t00063/test_case.h | 66 +-- tests/t00064/test_case.h | 44 +- tests/t00065/test_case.h | 86 ++-- tests/t00066/test_case.h | 180 ++++---- tests/t00067/test_case.h | 16 +- tests/t00068/test_case.h | 176 ++------ tests/t00069/test_case.h | 112 +++-- tests/t00070/test_case.h | 91 ++-- tests/t00071/test_case.h | 82 ++-- tests/t00072/test_case.h | 26 +- tests/t00073/test_case.h | 123 +++--- tests/t00074/test_case.h | 19 +- tests/t00075/test_case.h | 23 +- tests/t30011/test_case.h | 8 +- tests/test_cases.cc | 38 +- tests/test_cases.h | 234 +++++++--- 57 files changed, 2240 insertions(+), 2480 deletions(-) diff --git a/src/class_diagram/generators/json/class_diagram_generator.cc b/src/class_diagram/generators/json/class_diagram_generator.cc index 22aae5ac..340065ee 100644 --- a/src/class_diagram/generators/json/class_diagram_generator.cc +++ b/src/class_diagram/generators/json/class_diagram_generator.cc @@ -76,6 +76,8 @@ void to_json(nlohmann::json &j, const class_method &c) j["is_move_assignment"] = c.is_move_assignment(); j["is_copy_assignment"] = c.is_copy_assignment(); j["is_operator"] = c.is_operator(); + j["template_parameters"] = c.template_params(); + j["display_name"] = c.display_name(); j["parameters"] = c.parameters(); } @@ -156,7 +158,10 @@ void generator::generate_top_level_elements(nlohmann::json &parent) const { for (const auto &p : model()) { if (auto *pkg = dynamic_cast(p.get()); pkg) { - if (!pkg->is_empty()) + if (!pkg->is_empty() && + !pkg->all_of([this](const common::model::element &e) { + return !model().should_include(e); + })) generate(*pkg, parent); } else if (auto *cls = dynamic_cast(p.get()); cls) { @@ -198,7 +203,10 @@ void generator::generate(const package &p, nlohmann::json &parent) const for (const auto &subpackage : p) { if (dynamic_cast(subpackage.get()) != nullptr) { const auto &sp = dynamic_cast(*subpackage); - if (!sp.is_empty()) { + if (!sp.is_empty() && + !sp.all_of([this](const common::model::element &e) { + return !model().should_include(e); + })) { if (config().generate_packages()) generate(sp, package_object); else @@ -282,6 +290,9 @@ void generator::generate_relationships( const class_ &c, nlohmann::json &parent) const { for (const auto &r : c.relationships()) { + if (!model().should_include(r)) + continue; + auto target_element = model().get(r.destination()); if (!target_element.has_value()) { LOG_DBG("Skipping {} relation from {} to {} due " @@ -310,6 +321,9 @@ void generator::generate_relationships( const enum_ &c, nlohmann::json &parent) const { for (const auto &r : c.relationships()) { + if (!model().should_include(r)) + continue; + auto target_element = model().get(r.destination()); if (!target_element.has_value()) { LOG_DBG("Skipping {} relation from {} to {} due " @@ -328,6 +342,9 @@ void generator::generate_relationships( const concept_ &c, nlohmann::json &parent) const { for (const auto &r : c.relationships()) { + if (!model().should_include(r)) + continue; + auto target_element = model().get(r.destination()); if (!target_element.has_value()) { LOG_DBG("Skipping {} relation from {} to {} due " diff --git a/src/class_diagram/generators/mermaid/class_diagram_generator.cc b/src/class_diagram/generators/mermaid/class_diagram_generator.cc index 416e0ae8..f5bbb17d 100644 --- a/src/class_diagram/generators/mermaid/class_diagram_generator.cc +++ b/src/class_diagram/generators/mermaid/class_diagram_generator.cc @@ -281,8 +281,7 @@ void generator::generate_member( void generator::generate(const concept_ &c, std::ostream &ostr) const { - ostr << indent(1) << "class" - << " " << c.alias(); + ostr << indent(1) << "class" << " " << c.alias(); ostr << " {" << '\n'; ostr << indent(2) << "<>\n"; diff --git a/src/class_diagram/model/class_method.cc b/src/class_diagram/model/class_method.cc index 9d2052ea..7daf4c47 100644 --- a/src/class_diagram/model/class_method.cc +++ b/src/class_diagram/model/class_method.cc @@ -26,6 +26,26 @@ class_method::class_method(common::model::access_t access, { } +void class_method::update(const common::model::namespace_ &un) +{ + if (template_params().empty()) { + set_display_name(name()); + } + else { + std::stringstream template_params_str; + render_template_params(template_params_str, un, true); + set_display_name( + fmt::format("{}{}", name(), template_params_str.str())); + } +} + +std::string class_method::display_name() const { return display_name_; } + +void class_method::set_display_name(const std::string &display_name) +{ + display_name_ = display_name; +} + bool class_method::is_pure_virtual() const { return is_pure_virtual_; } void class_method::is_pure_virtual(bool is_pure_virtual) diff --git a/src/class_diagram/model/class_method.h b/src/class_diagram/model/class_method.h index 4cf4344b..da8fe5fa 100644 --- a/src/class_diagram/model/class_method.h +++ b/src/class_diagram/model/class_method.h @@ -46,6 +46,17 @@ public: ~class_method() override = default; + void update(const common::model::namespace_& un); + + /** + * @brief Method name including template parameters/arguments if any + * + * @return String representation of the methods display name + */ + std::string display_name() const; + + void set_display_name(const std::string &display_name); + /** * @brief Whether the method is pure virtual. * @@ -282,5 +293,7 @@ private: bool is_move_assignment_{false}; bool is_copy_assignment_{false}; bool is_operator_{false}; + + std::string display_name_; }; } // namespace clanguml::class_diagram::model diff --git a/src/class_diagram/visitor/translation_unit_visitor.cc b/src/class_diagram/visitor/translation_unit_visitor.cc index fef69cd3..6b05d751 100644 --- a/src/class_diagram/visitor/translation_unit_visitor.cc +++ b/src/class_diagram/visitor/translation_unit_visitor.cc @@ -1187,7 +1187,8 @@ void translation_unit_visitor::process_method( } class_method method{common::access_specifier_to_access_t(mf.getAccess()), - util::trim(method_name), method_return_type}; + util::trim(method_name), + config().simplify_template_type(method_return_type)}; process_method_properties(mf, c, method_name, method); @@ -1266,6 +1267,8 @@ void translation_unit_visitor::process_method( process_function_parameter_find_relationships_in_autotype(c, atsp); } + method.update(config().using_namespace()); + if (diagram().should_include(method)) { LOG_DBG("Adding method: {}", method.name()); @@ -1390,6 +1393,8 @@ void translation_unit_visitor::process_template_method( process_function_parameter(*param, method, c); } + method.update(config().using_namespace()); + if (diagram().should_include(method)) { LOG_DBG("Adding method: {}", method.name()); @@ -1678,7 +1683,9 @@ void translation_unit_visitor::process_static_field( class_member field{ common::access_specifier_to_access_t(field_declaration.getAccess()), - field_declaration.getNameAsString(), type_name}; + field_declaration.getNameAsString(), + config().simplify_template_type(type_name)}; + field.is_static(true); process_comment(field_declaration, field); @@ -1769,7 +1776,7 @@ void translation_unit_visitor::process_field( class_member field{ common::access_specifier_to_access_t(field_declaration.getAccess()), - field_name, field_type_str}; + field_name, config().simplify_template_type(field_type_str)}; // Parse the field comment process_comment(field_declaration, field); diff --git a/src/common/model/diagram.cc b/src/common/model/diagram.cc index b551792d..39168e27 100644 --- a/src/common/model/diagram.cc +++ b/src/common/model/diagram.cc @@ -78,6 +78,11 @@ bool diagram::should_include(const namespace_ &ns) const return filter_->should_include(ns); } +bool diagram::should_include(relationship r) const +{ + return should_include(r.type()); +} + bool diagram::should_include(const relationship_t r) const { if (filter_.get() == nullptr) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index dec53b5c..3ce15f5f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -102,7 +102,7 @@ foreach(TEST_NAME ${TEST_NAMES}) target_sources(${TEST_NAME} PUBLIC FILE_SET CXX_MODULES FILES ${TEST_CASE_MODULE_SOURCES}) endif(ENABLE_CXX_MODULES_TEST_CASES) - target_sources(${TEST_NAME} PUBLIC ${TEST_NAME}.cc test_cases_checks.h + target_sources(${TEST_NAME} PUBLIC ${TEST_NAME}.cc ${TEST_CASE_SOURCES} catch.h) else() target_sources(${TEST_NAME} PUBLIC ${TEST_NAME}.cc catch.h) diff --git a/tests/t00028/test_case.h b/tests/t00028/test_case.h index 3598f279..6a1980ad 100644 --- a/tests/t00028/test_case.h +++ b/tests/t00028/test_case.h @@ -30,31 +30,39 @@ TEST_CASE("t00028") REQUIRE(model->name() == "t00028_class"); - CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { - REQUIRE(IsClass(src, "A")); - REQUIRE(IsClass(src, "B")); - REQUIRE(IsClass(src, "C")); - REQUIRE(IsClass(src, "D")); - REQUIRE(IsClassTemplate(src, "E")); - REQUIRE(IsEnum(src, "F")); - REQUIRE(IsClass(src, "R")); - REQUIRE(HasNote(src, "A", "top", "A class note.")); - REQUIRE(HasNote(src, "B", "left", "B class note.")); - REQUIRE(HasNote(src, "C", "bottom", "C class note.")); - const auto d_note = R"( + CHECK_CLASS_DIAGRAM( + config, diagram, *model, + [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClass(src, "C")); + REQUIRE(IsClass(src, "D")); + REQUIRE(IsClassTemplate(src, "E")); + REQUIRE(IsEnum(src, "F")); + REQUIRE(IsClass(src, "R")); + REQUIRE(HasNote(src, "A", "top", "A class note.")); + REQUIRE(HasNote(src, "B", "left", "B class note.")); + REQUIRE(HasNote(src, "C", "bottom", "C class note.")); + const auto d_note = R"( D class note.)"; - REQUIRE(HasNote(src, "D", "left", d_note)); - REQUIRE(HasNote(src, "E", "left", "E template class note.")); - REQUIRE(HasNote(src, "F", "bottom", "F enum note.")); - REQUIRE(!HasNote(src, "G", "left", "G class note.")); - REQUIRE(HasNote(src, "R", "right", "R class note.")); - REQUIRE(HasMemberNote( - src, "R", "aaa", "left", "R contains an instance of A.")); - REQUIRE(!HasMemberNote(src, "R", "bbb", "right", "R class note.")); - REQUIRE(HasMemberNote(src, "R", "ccc", "left", "Reference to C.")); - }); + REQUIRE(HasNote(src, "D", "left", d_note)); + REQUIRE(HasNote(src, "E", "left", "E template class note.")); + REQUIRE(HasNote(src, "F", "bottom", "F enum note.")); + REQUIRE(HasNote(src, "R", "right", "R class note.")); + }, + [](const plantuml_t &src) { + REQUIRE(HasMemberNote(src, "R", "ccc", "left", "Reference to C.")); + REQUIRE(!HasMemberNote(src, "R", "bbb", "right", "R class note.")); + REQUIRE(HasMemberNote( + src, "R", "aaa", "left", "R contains an instance of A.")); + REQUIRE(!HasNote(src, "G", "left", "G class note.")); + }, + [](const mermaid_t &src) { + REQUIRE(HasNote(src, "R", "left", "R contains an instance of A.")); + REQUIRE(!HasNote(src, "G", "left", "G class note.")); + }); /* { auto src = generate_class_puml(diagram, *model); diff --git a/tests/t00031/test_case.h b/tests/t00031/test_case.h index d4ab8482..c0c7bb90 100644 --- a/tests/t00031/test_case.h +++ b/tests/t00031/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00031/test_case.cc + * tests/t00031/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00031", "[test-case][class]") +TEST_CASE("t00031") { + using namespace clanguml::test; + auto [config, db] = load_config("t00031"); auto diagram = config.diagrams["t00031_class"]; @@ -28,55 +30,20 @@ TEST_CASE("t00031", "[test-case][class]") REQUIRE(model->name() == "t00031_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsEnum(src, "B")); + REQUIRE(IsClass(src, "D")); + REQUIRE(IsClassTemplate(src, "C")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsEnum(_A("B"))); - REQUIRE_THAT(src, IsClassTemplate("C", "T")); - REQUIRE_THAT(src, IsClass(_A("D"))); - - REQUIRE_THAT(src, - IsAssociation( - _A("R"), _A("A"), "+aaa", "", "", "[#red,dashed,thickness=2]")); - REQUIRE_THAT(src, - IsComposition(_A("R"), _A("B"), "+bbb", "", "", - "[#green,dashed,thickness=4]")); - REQUIRE_THAT(src, IsDependency(_A("R"), _A("B"))); - REQUIRE_THAT(src, - IsAggregation(_A("R"), _A("C"), "+ccc", "", "", - "[#blue,dotted,thickness=8]")); - REQUIRE_THAT(src, - IsAssociation(_A("R"), _A("D"), "+ddd", "", "", - "[#blue,plain,thickness=16]")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClassTemplate(j, "C")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsEnum; - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsEnum(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsAssociation( + src, "R", "A", "aaa", "", "", "[#red,dashed,thickness=2]")); + REQUIRE(IsComposition( + src, "R", "B", "bbb", "", "", "[#green,dashed,thickness=4]")); + REQUIRE(IsDependency(src, "R", "B")); + REQUIRE(IsAggregation( + src, "R", "C", "ccc", "", "", "[#blue,dotted,thickness=8]")); + REQUIRE(IsAssociation( + src, "R", "D", "ddd", "", "", "[#blue,plain,thickness=16]")); + }); } \ No newline at end of file diff --git a/tests/t00032/test_case.h b/tests/t00032/test_case.h index 09dad790..1277d186 100644 --- a/tests/t00032/test_case.h +++ b/tests/t00032/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00032/test_case.cc + * tests/t00032/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00032", "[test-case][class]") +TEST_CASE("t00032") { + using namespace clanguml::test; + auto [config, db] = load_config("t00032"); auto diagram = config.diagrams["t00032_class"]; @@ -28,83 +30,24 @@ TEST_CASE("t00032", "[test-case][class]") REQUIRE(model->name() == "t00032_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "Base")); + REQUIRE(IsClass(src, "TBase")); + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClass(src, "C")); + REQUIRE(IsClass(src, "R")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsClassTemplate(src, "Overload")); - REQUIRE_THAT(src, IsClass(_A("Base"))); - REQUIRE_THAT(src, IsClass(_A("TBase"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - - REQUIRE_THAT(src, IsClassTemplate("Overload", "T,L,Ts...")); - - REQUIRE_THAT(src, IsBaseClass(_A("Base"), _A("Overload"))); - REQUIRE_THAT( - src, IsBaseClass(_A("TBase"), _A("Overload"))); - REQUIRE_THAT( - src, IsBaseClass(_A("A"), _A("Overload"))); - REQUIRE_THAT( - src, IsBaseClass(_A("B"), _A("Overload"))); - REQUIRE_THAT( - src, IsBaseClass(_A("C"), _A("Overload"))); - REQUIRE_THAT( - src, !IsDependency(_A("Overload"), _A("TBase"))); - REQUIRE_THAT( - src, !IsDependency(_A("Overload"), _A("A"))); - REQUIRE_THAT( - src, !IsDependency(_A("Overload"), _A("B"))); - REQUIRE_THAT( - src, !IsDependency(_A("Overload"), _A("C"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsBaseClass(j, "A", "Overload")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - REQUIRE_THAT(src, IsClass(_A("Base"))); - REQUIRE_THAT(src, IsClass(_A("TBase"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - - REQUIRE_THAT(src, IsClass(_A("Overload"))); - - REQUIRE_THAT(src, IsBaseClass(_A("Base"), _A("Overload"))); - REQUIRE_THAT( - src, IsBaseClass(_A("TBase"), _A("Overload"))); - REQUIRE_THAT( - src, IsBaseClass(_A("A"), _A("Overload"))); - REQUIRE_THAT( - src, IsBaseClass(_A("B"), _A("Overload"))); - REQUIRE_THAT( - src, IsBaseClass(_A("C"), _A("Overload"))); - REQUIRE_THAT( - src, !IsDependency(_A("Overload"), _A("TBase"))); - REQUIRE_THAT( - src, !IsDependency(_A("Overload"), _A("A"))); - REQUIRE_THAT( - src, !IsDependency(_A("Overload"), _A("B"))); - REQUIRE_THAT( - src, !IsDependency(_A("Overload"), _A("C"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsBaseClass(src, "Base", "Overload")); + REQUIRE(IsBaseClass(src, "TBase", "Overload")); + REQUIRE(IsBaseClass(src, "A", "Overload")); + REQUIRE(IsBaseClass(src, "B", "Overload")); + REQUIRE(IsBaseClass(src, "C", "Overload")); + REQUIRE(!IsDependency(src, "Overload", "TBase")); + REQUIRE(!IsDependency(src, "Overload", "A")); + REQUIRE(!IsDependency(src, "Overload", "B")); + REQUIRE(!IsDependency(src, "Overload", "C")); + }); } \ No newline at end of file diff --git a/tests/t00033/test_case.h b/tests/t00033/test_case.h index d5fdd3e7..40290923 100644 --- a/tests/t00033/test_case.h +++ b/tests/t00033/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00033/test_case.cc + * tests/t00033/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00033", "[test-case][class]") +TEST_CASE("t00033") { + using namespace clanguml::test; + auto [config, db] = load_config("t00033"); auto diagram = config.diagrams["t00033_class"]; @@ -28,70 +30,21 @@ TEST_CASE("t00033", "[test-case][class]") REQUIRE(model->name() == "t00033_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "B")); + REQUIRE(IsClassTemplate(src, "C")); + REQUIRE(IsClass(src, "D")); + REQUIRE(IsClass(src, "R")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsClassTemplate("A", "T")); - REQUIRE_THAT(src, IsClassTemplate("B", "T")); - REQUIRE_THAT(src, IsClassTemplate("C", "T")); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - - REQUIRE_THAT(src, - IsDependency(_A("A>>>"), - _A("B>>"))); - REQUIRE_THAT( - src, IsDependency(_A("B>>"), _A("C"))); - REQUIRE_THAT(src, IsDependency(_A("C"), _A("D"))); - - REQUIRE_THAT(src, IsInstantiation(_A("C"), _A("C"), "up")); - REQUIRE_THAT(src, - IsInstantiation(_A("B"), _A("B>>"), "up")); - REQUIRE_THAT(src, - IsInstantiation( - _A("A"), _A("A>>>"), "up")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A>>>")); REQUIRE(IsDependency( - j, "A>>>", "B>>")); + src, "A>>>", "B>>")); + REQUIRE(IsDependency(src, "B>>", "C")); + REQUIRE(IsDependency(src, "C", "D")); - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - - REQUIRE_THAT(src, - IsDependency(_A("A>>>"), - _A("B>>"))); - REQUIRE_THAT( - src, IsDependency(_A("B>>"), _A("C"))); - REQUIRE_THAT(src, IsDependency(_A("C"), _A("D"))); - - REQUIRE_THAT(src, IsInstantiation(_A("C"), _A("C"))); - REQUIRE_THAT( - src, IsInstantiation(_A("B"), _A("B>>"))); - REQUIRE_THAT(src, - IsInstantiation(_A("A"), _A("A>>>"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsInstantiation(src, "C", "C", "up")); + REQUIRE(IsInstantiation(src, "B", "B>>", "up")); + REQUIRE( + IsInstantiation(src, "A", "A>>>", "up")); + }); } \ No newline at end of file diff --git a/tests/t00034/test_case.h b/tests/t00034/test_case.h index 8a6858f7..6a65ac59 100644 --- a/tests/t00034/test_case.h +++ b/tests/t00034/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00034/test_case.cc + * tests/t00034/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00034", "[test-case][class]") +TEST_CASE("t00034") { + using namespace clanguml::test; + auto [config, db] = load_config("t00034"); auto diagram = config.diagrams["t00034_class"]; @@ -28,52 +30,14 @@ TEST_CASE("t00034", "[test-case][class]") REQUIRE(model->name() == "t00034_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClassTemplate(src, "lift_void")); + REQUIRE(IsClassTemplate(src, "drop_void")); + REQUIRE(IsClass(src, "Void")); + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "R")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsClassTemplate("lift_void", "T")); - REQUIRE_THAT(src, IsClassTemplate("drop_void", "T")); - REQUIRE_THAT(src, IsClass(_A("Void"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - - REQUIRE_THAT( - src, IsInstantiation(_A("lift_void"), _A("lift_void"))); - REQUIRE_THAT( - src, IsInstantiation(_A("drop_void"), _A("drop_void"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClassTemplate(j, "lift_void")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - REQUIRE_THAT(src, IsClass(_A("lift_void"))); - REQUIRE_THAT(src, IsClass(_A("drop_void"))); - REQUIRE_THAT(src, IsClass(_A("Void"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - - REQUIRE_THAT( - src, IsInstantiation(_A("lift_void"), _A("lift_void"))); - REQUIRE_THAT( - src, IsInstantiation(_A("drop_void"), _A("drop_void"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsInstantiation(src, "lift_void", "lift_void")); + REQUIRE(IsInstantiation(src, "drop_void", "drop_void")); + }); } \ No newline at end of file diff --git a/tests/t00035/test_case.h b/tests/t00035/test_case.h index 51018e78..95b0d2bf 100644 --- a/tests/t00035/test_case.h +++ b/tests/t00035/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00035/test_case.cc + * tests/t00035/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00035", "[test-case][class]") +TEST_CASE("t00035") { + using namespace clanguml::test; + auto [config, db] = load_config("t00035"); auto diagram = config.diagrams["t00035_class"]; @@ -28,50 +30,16 @@ TEST_CASE("t00035", "[test-case][class]") REQUIRE(model->name() == "t00035_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "Top")); + REQUIRE(IsClass(src, "Bottom")); + REQUIRE(IsClass(src, "Center")); + REQUIRE(IsClass(src, "Left")); + REQUIRE(IsClass(src, "Right")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsClass(_A("Top"))); - REQUIRE_THAT(src, IsClass(_A("Bottom"))); - REQUIRE_THAT(src, IsClass(_A("Center"))); - REQUIRE_THAT(src, IsClass(_A("Left"))); - REQUIRE_THAT(src, IsClass(_A("Right"))); - - REQUIRE_THAT(src, IsLayoutHint(_A("Center"), "up", _A("Top"))); - REQUIRE_THAT(src, IsLayoutHint(_A("Center"), "left", _A("Left"))); - REQUIRE_THAT(src, IsLayoutHint(_A("Center"), "right", _A("Right"))); - REQUIRE_THAT(src, IsLayoutHint(_A("Center"), "down", _A("Bottom"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "Top")); - REQUIRE(IsClass(j, "Bottom")); - REQUIRE(IsClass(j, "Center")); - REQUIRE(IsClass(j, "Left")); - REQUIRE(IsClass(j, "Right")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - REQUIRE_THAT(src, IsClass(_A("Top"))); - REQUIRE_THAT(src, IsClass(_A("Bottom"))); - REQUIRE_THAT(src, IsClass(_A("Center"))); - REQUIRE_THAT(src, IsClass(_A("Left"))); - REQUIRE_THAT(src, IsClass(_A("Right"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsLayoutHint(src, "Center", "up", "Top")); + REQUIRE(IsLayoutHint(src, "Center", "left", "Left")); + REQUIRE(IsLayoutHint(src, "Center", "right", "Right")); + REQUIRE(IsLayoutHint(src, "Center", "down", "Bottom")); + }); } \ No newline at end of file diff --git a/tests/t00036/test_case.h b/tests/t00036/test_case.h index 12c58572..16c5fe68 100644 --- a/tests/t00036/test_case.h +++ b/tests/t00036/test_case.h @@ -16,8 +16,11 @@ * limitations under the License. */ -TEST_CASE("t00036", "[test-case][class]") +TEST_CASE("t00036") { + using namespace clanguml::test; + using namespace std::string_literals; + auto [config, db] = load_config("t00036"); auto diagram = config.diagrams["t00036_class"]; @@ -29,66 +32,23 @@ TEST_CASE("t00036", "[test-case][class]") REQUIRE(model->name() == "t00036_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClassTemplate(src, {"ns1::ns11", "A"})); + REQUIRE(IsClassTemplate(src, {"ns1::ns11", "A"})); + REQUIRE(IsClass(src, {"ns1::ns11::ns111", "B"})); + REQUIRE(IsClass(src, {"ns2::ns22", "C"})); + REQUIRE(IsEnum(src, {"ns1", "E"})); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(!IsClass(src, "DImpl")); - REQUIRE_THAT(src, IsClassTemplate("A", "T")); - REQUIRE_THAT(src, IsClassTemplate("A", "int")); - REQUIRE_THAT(src, IsEnum(_A("E"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, !IsClass(_A("DImpl"))); - REQUIRE_THAT(src, IsPackage("ns111")); - REQUIRE_THAT(src, IsPackage("ns22")); - REQUIRE_THAT(src, !IsPackage("ns3")); - REQUIRE_THAT(src, !IsPackage("ns33")); + REQUIRE(IsNamespacePackage(src, "ns1"s)); + REQUIRE(IsNamespacePackage(src, "ns1"s, "ns11"s)); + REQUIRE(IsNamespacePackage(src, "ns1"s, "ns11"s, "ns111"s)); + REQUIRE(IsNamespacePackage(src, "ns2"s)); + REQUIRE(IsNamespacePackage(src, "ns2"s, "ns22"s)); - REQUIRE_THAT(src, IsAggregation(_A("B"), _A("A"), "+a_int")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - using namespace std::string_literals; - - REQUIRE(IsClass(j, "ns1::ns11::A")); - REQUIRE(IsClass(j, "ns1::ns11::A")); - REQUIRE(IsClass(j, "ns1::ns11::ns111::B")); - REQUIRE(IsClass(j, "ns2::ns22::C")); - REQUIRE(IsEnum(j, "ns1::E")); - REQUIRE(IsNamespacePackage(j, "ns1"s)); - REQUIRE(IsNamespacePackage(j, "ns1"s, "ns11"s)); - REQUIRE(IsNamespacePackage(j, "ns1"s, "ns11"s, "ns111"s)); - REQUIRE(IsNamespacePackage(j, "ns2"s)); - REQUIRE(IsNamespacePackage(j, "ns2"s, "ns22"s)); - REQUIRE(IsNamespacePackage(j, "ns3"s)); - REQUIRE(IsNamespacePackage(j, "ns3"s, "ns33"s)); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsEnum; - - REQUIRE_THAT(src, IsClass(_A("ns1::ns11::A"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns11::A"))); - REQUIRE_THAT(src, IsEnum(_A("ns1::E"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns11::ns111::B"))); - REQUIRE_THAT(src, IsClass(_A("ns2::ns22::C"))); - REQUIRE_THAT(src, !IsClass(_A("DImpl"))); - - REQUIRE_THAT(src, - IsAggregation( - _A("ns1::ns11::ns111::B"), _A("ns1::ns11::A"), "+a_int")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(!IsNamespacePackage(src, "ns3"s)); + REQUIRE(!IsNamespacePackage(src, "ns33"s)); + REQUIRE(!IsNamespacePackage(src, "ns3"s, "ns33"s)); + }); } \ No newline at end of file diff --git a/tests/t00037/test_case.h b/tests/t00037/test_case.h index e5e62d0f..6ad47529 100644 --- a/tests/t00037/test_case.h +++ b/tests/t00037/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00037/test_case.cc + * tests/t00037/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00037", "[test-case][class]") +TEST_CASE("t00037") { + using namespace clanguml::test; + auto [config, db] = load_config("t00037"); auto diagram = config.diagrams["t00037_class"]; @@ -29,49 +31,14 @@ TEST_CASE("t00037", "[test-case][class]") REQUIRE(model->name() == "t00037_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "ST")); + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "ST::(units)")); + REQUIRE(IsClass(src, "ST::(dimensions)")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsClass(_A("ST"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("ST::(units)"))); - REQUIRE_THAT(src, IsClass(_A("ST::(dimensions)"))); - REQUIRE_THAT(src, - IsAggregation(_A("ST"), _A("ST::(dimensions)"), "+dimensions")); - REQUIRE_THAT(src, IsAggregation(_A("ST"), _A("ST::(units)"), "-units")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "ST")); - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "ST::(units)")); - REQUIRE(IsClass(j, "ST::(dimensions)")); - REQUIRE(IsAggregation(j, "ST", "ST::(dimensions)", "dimensions")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - REQUIRE_THAT(src, IsClass(_A("ST"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("ST::(units)"))); - REQUIRE_THAT(src, IsClass(_A("ST::(dimensions)"))); - REQUIRE_THAT(src, - IsAggregation(_A("ST"), _A("ST::(dimensions)"), "+dimensions")); - REQUIRE_THAT(src, IsAggregation(_A("ST"), _A("ST::(units)"), "-units")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE( + IsAggregation(src, "ST", "ST::(dimensions)", "dimensions")); + REQUIRE(IsAggregation(src, "ST", "ST::(units)", "units")); + }); } \ No newline at end of file diff --git a/tests/t00038/test_case.h b/tests/t00038/test_case.h index 38363ddc..5b16987d 100644 --- a/tests/t00038/test_case.h +++ b/tests/t00038/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00038/test_case.cc + * tests/t00038/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00038", "[test-case][class]") +TEST_CASE("t00038") { + using namespace clanguml::test; + auto [config, db] = load_config("t00038"); auto diagram = config.diagrams["t00038_class"]; @@ -29,152 +31,56 @@ TEST_CASE("t00038", "[test-case][class]") REQUIRE(model->name() == "t00038_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClass(src, "C")); + REQUIRE(IsClass(src, "thirdparty::ns1::E")); + REQUIRE(IsClass(src, "key_t")); + REQUIRE(IsClassTemplate(src, "map")); + REQUIRE(IsClassTemplate(src, + "map>")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsClassTemplate(src, + "map>>")); + REQUIRE(IsClassTemplate(src, + "map>>>")); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("thirdparty::ns1::E"))); - REQUIRE_THAT(src, IsClass(_A("key_t"))); - REQUIRE_THAT(src, IsClassTemplate("map", "T")); - REQUIRE_THAT(src, - IsClassTemplate("map", - "std::integral_constant")); - REQUIRE_THAT(src, - IsClassTemplate("map", - "std::vector>")); - REQUIRE_THAT(src, - IsClassTemplate("map", - "std::map>>")); + REQUIRE(IsEnum(src, "property_t")); - REQUIRE_THAT(src, IsEnum(_A("property_t"))); + REQUIRE(IsInstantiation(src, "map", + "map>>>")); - REQUIRE_THAT(src, - IsInstantiation(_A("map"), - _A("map>>>"))); + REQUIRE(IsDependency(src, + "map>", + "property_t")); - REQUIRE_THAT(src, - IsDependency(_A("map>"), - _A("property_t"))); + REQUIRE(IsDependency(src, + "map<" + "std::vector>>", + "property_t")); - REQUIRE_THAT(src, - IsDependency(_A("map<" - "std::vector>>"), - _A("property_t"))); + REQUIRE(IsDependency(src, + "map>>>", + "property_t")); - REQUIRE_THAT(src, - IsDependency( - _A("map>>>"), - _A("property_t"))); + REQUIRE(IsDependency(src, + "map>>>", + "key_t")); - REQUIRE_THAT(src, - IsDependency( - _A("map>>>"), - _A("key_t"))); + REQUIRE(IsDependency(src, + "map>", + "thirdparty::ns1::color_t")); - REQUIRE_THAT(src, - IsDependency( - _A("map>"), - _A("thirdparty::ns1::color_t"))); - - REQUIRE_THAT(src, - IsBaseClass(_A("thirdparty::ns1::E"), - _A("map>"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - REQUIRE(IsClass(j, "C")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsEnum; - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("thirdparty::ns1::E"))); - REQUIRE_THAT(src, IsClass(_A("key_t"))); - REQUIRE_THAT(src, IsClass(_A("map"))); - REQUIRE_THAT(src, - IsClass(_A("map>"))); - REQUIRE_THAT(src, - IsClass(_A( - "map>>"))); - REQUIRE_THAT(src, - IsClass(_A("map>>>"))); - - REQUIRE_THAT(src, IsEnum(_A("property_t"))); - - REQUIRE_THAT(src, - IsInstantiation(_A("map"), - _A("map>>>"))); - - REQUIRE_THAT(src, - IsDependency(_A("map>"), - _A("property_t"))); - - REQUIRE_THAT(src, - IsDependency(_A("map<" - "std::vector>>"), - _A("property_t"))); - - REQUIRE_THAT(src, - IsDependency( - _A("map>>>"), - _A("property_t"))); - - REQUIRE_THAT(src, - IsDependency( - _A("map>>>"), - _A("key_t"))); - - REQUIRE_THAT(src, - IsDependency( - _A("map>"), - _A("thirdparty::ns1::color_t"))); - - REQUIRE_THAT(src, - IsBaseClass(_A("thirdparty::ns1::E"), - _A("map>"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsBaseClass(src, "thirdparty::ns1::E", + "map>")); + }); } \ No newline at end of file diff --git a/tests/t00039/test_case.h b/tests/t00039/test_case.h index 9e4c562b..36788d3f 100644 --- a/tests/t00039/test_case.h +++ b/tests/t00039/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00039/test_case.cc + * tests/t00039/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00039", "[test-case][class]") +TEST_CASE("t00039") { + using namespace clanguml::test; + auto [config, db] = load_config("t00039"); auto diagram = config.diagrams["t00039_class"]; @@ -28,96 +30,33 @@ TEST_CASE("t00039", "[test-case][class]") REQUIRE(model->name() == "t00039_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "AA")); + REQUIRE(IsClass(src, "AAA")); + REQUIRE(IsClass(src, "ns2::AAAA")); + REQUIRE(IsBaseClass(src, "A", "AA")); + REQUIRE(IsBaseClass(src, "AA", "AAA")); + REQUIRE(IsBaseClass(src, "AAA", "ns2::AAAA")); + REQUIRE(!IsClass(src, "detail::AA")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(!IsClass(src, "B")); + REQUIRE(!IsClass(src, "ns1::BB")); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("AA"))); - REQUIRE_THAT(src, IsClass(_A("AAA"))); - REQUIRE_THAT(src, IsClass(_A("ns2::AAAA"))); - REQUIRE_THAT(src, IsBaseClass(_A("A"), _A("AA"))); - REQUIRE_THAT(src, IsBaseClass(_A("AA"), _A("AAA"))); - REQUIRE_THAT(src, IsBaseClass(_A("AAA"), _A("ns2::AAAA"))); - REQUIRE_THAT(src, !IsClass(_A("detail::AA"))); + REQUIRE(IsClass(src, "C")); + REQUIRE(IsClass(src, "D")); + REQUIRE(IsClass(src, "E")); + REQUIRE(IsBaseClass(src, "C", "CD")); + REQUIRE(IsBaseClass(src, "D", "CD")); + REQUIRE(IsBaseClass(src, "D", "DE")); + REQUIRE(IsBaseClass(src, "E", "DE")); + REQUIRE(IsBaseClass(src, "C", "CDE")); + REQUIRE(IsBaseClass(src, "D", "CDE")); + REQUIRE(IsBaseClass(src, "E", "CDE")); - REQUIRE_THAT(src, !IsClass(_A("B"))); - REQUIRE_THAT(src, !IsClass(_A("ns1::BB"))); - - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - REQUIRE_THAT(src, IsBaseClass(_A("C"), _A("CD"))); - REQUIRE_THAT(src, IsBaseClass(_A("D"), _A("CD"))); - REQUIRE_THAT(src, IsBaseClass(_A("D"), _A("DE"))); - REQUIRE_THAT(src, IsBaseClass(_A("E"), _A("DE"))); - REQUIRE_THAT(src, IsBaseClass(_A("C"), _A("CDE"))); - REQUIRE_THAT(src, IsBaseClass(_A("D"), _A("CDE"))); - REQUIRE_THAT(src, IsBaseClass(_A("E"), _A("CDE"))); - - REQUIRE_THAT(src, IsClassTemplate("ns3::F", "T")); - REQUIRE_THAT(src, IsClassTemplate("ns3::FF", "T,M")); - REQUIRE_THAT(src, IsClassTemplate("ns3::FE", "T,M")); - REQUIRE_THAT(src, IsClassTemplate("ns3::FFF", "T,M,N")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "AA")); - REQUIRE(IsClass(j, "AAA")); - REQUIRE(IsBaseClass(j, "C", "CD")); - REQUIRE(IsBaseClass(j, "D", "CD")); - REQUIRE(IsBaseClass(j, "E", "DE")); - REQUIRE(IsBaseClass(j, "D", "DE")); - REQUIRE(IsBaseClass(j, "C", "CDE")); - REQUIRE(IsBaseClass(j, "D", "CDE")); - REQUIRE(IsBaseClass(j, "E", "CDE")); - - REQUIRE(IsClassTemplate(j, "ns3::F")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("AA"))); - REQUIRE_THAT(src, IsClass(_A("AAA"))); - REQUIRE_THAT(src, IsClass(_A("ns2::AAAA"))); - REQUIRE_THAT(src, IsBaseClass(_A("A"), _A("AA"))); - REQUIRE_THAT(src, IsBaseClass(_A("AA"), _A("AAA"))); - REQUIRE_THAT(src, IsBaseClass(_A("AAA"), _A("ns2::AAAA"))); - REQUIRE_THAT(src, !IsClass(_A("detail::AA"))); - - REQUIRE_THAT(src, !IsClass(_A("B"))); - REQUIRE_THAT(src, !IsClass(_A("ns1::BB"))); - - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - REQUIRE_THAT(src, IsBaseClass(_A("C"), _A("CD"))); - REQUIRE_THAT(src, IsBaseClass(_A("D"), _A("CD"))); - REQUIRE_THAT(src, IsBaseClass(_A("D"), _A("DE"))); - REQUIRE_THAT(src, IsBaseClass(_A("E"), _A("DE"))); - REQUIRE_THAT(src, IsBaseClass(_A("C"), _A("CDE"))); - REQUIRE_THAT(src, IsBaseClass(_A("D"), _A("CDE"))); - REQUIRE_THAT(src, IsBaseClass(_A("E"), _A("CDE"))); - - REQUIRE_THAT(src, IsClass(_A("ns3::F"))); - REQUIRE_THAT(src, IsClass(_A("ns3::FF"))); - REQUIRE_THAT(src, IsClass(_A("ns3::FE"))); - REQUIRE_THAT(src, IsClass(_A("ns3::FFF"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsClassTemplate(src, "ns3::F")); + REQUIRE(IsClassTemplate(src, "ns3::FF")); + REQUIRE(IsClassTemplate(src, "ns3::FE")); + REQUIRE(IsClassTemplate(src, "ns3::FFF")); + }); } diff --git a/tests/t00040/test_case.h b/tests/t00040/test_case.h index ec8b0181..8b21ef25 100644 --- a/tests/t00040/test_case.h +++ b/tests/t00040/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00040/test_case.cc + * tests/t00040/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00040", "[test-case][class]") +TEST_CASE("t00040") { + using namespace clanguml::test; + auto [config, db] = load_config("t00040"); auto diagram = config.diagrams["t00040_class"]; @@ -28,51 +30,14 @@ TEST_CASE("t00040", "[test-case][class]") auto model = generate_class_diagram(*db, diagram); REQUIRE(model->name() == "t00040_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("AA"))); - REQUIRE_THAT(src, IsClass(_A("AAA"))); - REQUIRE_THAT(src, IsBaseClass(_A("A"), _A("AA"))); - REQUIRE_THAT(src, IsBaseClass(_A("AA"), _A("AAA"))); - - REQUIRE_THAT(src, !IsClass(_A("B"))); - - REQUIRE_THAT(src, !IsDependency(_A("R"), _A("A"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "AA")); - REQUIRE(IsClass(j, "AAA")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("AA"))); - REQUIRE_THAT(src, IsClass(_A("AAA"))); - REQUIRE_THAT(src, IsBaseClass(_A("A"), _A("AA"))); - REQUIRE_THAT(src, IsBaseClass(_A("AA"), _A("AAA"))); - - REQUIRE_THAT(src, !IsClass(_A("B"))); - - REQUIRE_THAT(src, !IsDependency(_A("R"), _A("A"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "AA")); + REQUIRE(IsClass(src, "AAA")); + REQUIRE(IsBaseClass(src, "A", "AA")); + REQUIRE(IsBaseClass(src, "AA", "AAA")); + REQUIRE(!IsClass(src, "B")); + REQUIRE(!IsDependency(src, "R", "A")); + }); } \ No newline at end of file diff --git a/tests/t00041/test_case.h b/tests/t00041/test_case.h index 28fc90e3..5b262bdd 100644 --- a/tests/t00041/test_case.h +++ b/tests/t00041/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00041/test_case.cc + * tests/t00041/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00041", "[test-case][class]") +TEST_CASE("t00041") { + using namespace clanguml::test; + auto [config, db] = load_config("t00041"); auto diagram = config.diagrams["t00041_class"]; @@ -29,95 +31,34 @@ TEST_CASE("t00041", "[test-case][class]") REQUIRE(model->name() == "t00041_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(!IsClass(src, "A")); + REQUIRE(!IsClass(src, "AA")); + REQUIRE(!IsClass(src, "AAA")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(!IsClass(src, "B")); - REQUIRE_THAT(src, !IsClass(_A("A"))); - REQUIRE_THAT(src, !IsClass(_A("AA"))); - REQUIRE_THAT(src, !IsClass(_A("AAA"))); + REQUIRE(IsClass(src, "D")); + REQUIRE(IsClass(src, "E")); + REQUIRE(IsClass(src, "F")); + REQUIRE(IsClass(src, "R")); + REQUIRE(IsClass(src, "RR")); + REQUIRE(IsClass(src, "RRR")); + REQUIRE(!IsClass(src, "detail::G")); + REQUIRE(!IsClass(src, "H")); - REQUIRE_THAT(src, !IsClass(_A("B"))); + REQUIRE(IsBaseClass(src, "R", "RR")); + REQUIRE(IsBaseClass(src, "RR", "RRR")); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - REQUIRE_THAT(src, IsClass(_A("F"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - REQUIRE_THAT(src, IsClass(_A("RR"))); - REQUIRE_THAT(src, IsClass(_A("RRR"))); - REQUIRE_THAT(src, !IsClass(_A("detail::G"))); - REQUIRE_THAT(src, !IsClass(_A("H"))); + REQUIRE(IsAssociation(src, "D", "RR", "rr")); + REQUIRE(IsAssociation(src, "RR", "E", "e")); + REQUIRE(IsAssociation(src, "RR", "F", "f")); + REQUIRE(!IsDependency(src, "RR", "H")); - REQUIRE_THAT(src, IsBaseClass(_A("R"), _A("RR"))); - REQUIRE_THAT(src, IsBaseClass(_A("RR"), _A("RRR"))); - - REQUIRE_THAT(src, IsAssociation(_A("D"), _A("RR"), "+rr")); - REQUIRE_THAT(src, IsAssociation(_A("RR"), _A("E"), "+e")); - REQUIRE_THAT(src, IsAssociation(_A("RR"), _A("F"), "+f")); - REQUIRE_THAT(src, !IsDependency(_A("RR"), _A("H"))); - - REQUIRE_THAT(src, IsClass(_A("ns1::N"))); - REQUIRE_THAT(src, IsClass(_A("ns1::NN"))); - REQUIRE_THAT(src, IsClass(_A("ns1::NM"))); - REQUIRE_THAT(src, IsBaseClass(_A("ns1::N"), _A("ns1::NN"))); - REQUIRE_THAT(src, IsBaseClass(_A("ns1::N"), _A("ns1::NM"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(!IsClass(j, "A")); - REQUIRE(!IsClass(j, "AA")); - REQUIRE(!IsClass(j, "AAA")); - REQUIRE(IsClass(j, "D")); - REQUIRE(IsClass(j, "E")); - REQUIRE(IsClass(j, "F")); - REQUIRE(IsClass(j, "R")); - - REQUIRE(IsAssociation(j, "D", "RR", "rr")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - REQUIRE_THAT(src, !IsClass(_A("A"))); - REQUIRE_THAT(src, !IsClass(_A("AA"))); - REQUIRE_THAT(src, !IsClass(_A("AAA"))); - - REQUIRE_THAT(src, !IsClass(_A("B"))); - - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - REQUIRE_THAT(src, IsClass(_A("F"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - REQUIRE_THAT(src, IsClass(_A("RR"))); - REQUIRE_THAT(src, IsClass(_A("RRR"))); - REQUIRE_THAT(src, !IsClass(_A("detail::G"))); - REQUIRE_THAT(src, !IsClass(_A("H"))); - - REQUIRE_THAT(src, IsBaseClass(_A("R"), _A("RR"))); - REQUIRE_THAT(src, IsBaseClass(_A("RR"), _A("RRR"))); - - REQUIRE_THAT(src, IsAssociation(_A("D"), _A("RR"), "+rr")); - REQUIRE_THAT(src, IsAssociation(_A("RR"), _A("E"), "+e")); - REQUIRE_THAT(src, IsAssociation(_A("RR"), _A("F"), "+f")); - REQUIRE_THAT(src, !IsDependency(_A("RR"), _A("H"))); - - REQUIRE_THAT(src, IsClass(_A("ns1::N"))); - REQUIRE_THAT(src, IsClass(_A("ns1::NN"))); - REQUIRE_THAT(src, IsClass(_A("ns1::NM"))); - REQUIRE_THAT(src, IsBaseClass(_A("ns1::N"), _A("ns1::NN"))); - REQUIRE_THAT(src, IsBaseClass(_A("ns1::N"), _A("ns1::NM"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsClass(src, {"ns1", "N"})); + REQUIRE(IsClass(src, {"ns1", "NN"})); + REQUIRE(IsClass(src, {"ns1", "NM"})); + REQUIRE(IsBaseClass(src, "ns1::N", "ns1::NN")); + REQUIRE(IsBaseClass(src, "ns1::N", "ns1::NM")); + }); } \ No newline at end of file diff --git a/tests/t00042/test_case.h b/tests/t00042/test_case.h index 795220eb..b3e11df5 100644 --- a/tests/t00042/test_case.h +++ b/tests/t00042/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00042/test_case.cc + * tests/t00042/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00042", "[test-case][class]") +TEST_CASE("t00042") { + using namespace clanguml::test; + auto [config, db] = load_config("t00042"); auto diagram = config.diagrams["t00042_class"]; @@ -29,38 +31,9 @@ TEST_CASE("t00042", "[test-case][class]") REQUIRE(model->name() == "t00042_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsClassTemplate("A", "T")); - REQUIRE_THAT(src, IsClassTemplate("B", "T,K")); - REQUIRE_THAT(src, !IsClassTemplate("C", "T")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClassTemplate(j, "A")); - REQUIRE(IsClassTemplate(j, "B")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, !IsClass(_A("C"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "B")); + REQUIRE(!IsClassTemplate(src, "C")); + }); } \ No newline at end of file diff --git a/tests/t00043/test_case.h b/tests/t00043/test_case.h index abc539de..ce65f719 100644 --- a/tests/t00043/test_case.h +++ b/tests/t00043/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00043/test_case.cc + * tests/t00043/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00043", "[test-case][class]") +TEST_CASE("t00043") { + using namespace clanguml::test; + auto [config, db] = load_config("t00043"); auto diagram = config.diagrams["t00043_class"]; @@ -29,104 +31,31 @@ TEST_CASE("t00043", "[test-case][class]") REQUIRE(model->name() == "t00043_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, {"dependants", "A"})); + REQUIRE(IsClass(src, {"dependants", "B"})); + REQUIRE(IsClass(src, {"dependants", "C"})); + REQUIRE(IsClass(src, {"dependants", "D"})); + REQUIRE(IsClass(src, {"dependants", "BB"})); + REQUIRE(IsClass(src, {"dependants", "E"})); + REQUIRE(IsDependency(src, {"dependants", "B"}, {"dependants", "A"})); + REQUIRE(IsDependency(src, {"dependants", "BB"}, {"dependants", "A"})); + REQUIRE(IsDependency(src, {"dependants", "C"}, {"dependants", "B"})); + REQUIRE(IsDependency(src, {"dependants", "D"}, {"dependants", "C"})); + REQUIRE(IsDependency(src, {"dependants", "E"}, {"dependants", "D"})); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsClass(src, {"dependencies", "G"})); + REQUIRE(IsClass(src, {"dependencies", "GG"})); + REQUIRE(IsClass(src, {"dependencies", "H"})); + REQUIRE(!IsClass(src, {"dependencies", "HH"})); - // Check dependants filter - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("BB"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - REQUIRE_THAT(src, !IsClass(_A("F"))); - - REQUIRE_THAT(src, IsDependency(_A("B"), _A("A"))); - REQUIRE_THAT(src, IsDependency(_A("BB"), _A("A"))); - REQUIRE_THAT(src, IsDependency(_A("C"), _A("B"))); - REQUIRE_THAT(src, IsDependency(_A("D"), _A("C"))); - REQUIRE_THAT(src, IsDependency(_A("E"), _A("D"))); - - // Check dependencies filter - REQUIRE_THAT(src, IsClass(_A("G"))); - REQUIRE_THAT(src, IsClass(_A("GG"))); - REQUIRE_THAT(src, IsClass(_A("H"))); - REQUIRE_THAT(src, !IsClass(_A("HH"))); - REQUIRE_THAT(src, IsClass(_A("I"))); - REQUIRE_THAT(src, IsClass(_A("J"))); - - REQUIRE_THAT(src, IsDependency(_A("H"), _A("G"))); - REQUIRE_THAT(src, IsDependency(_A("H"), _A("GG"))); - REQUIRE_THAT(src, IsDependency(_A("I"), _A("H"))); - REQUIRE_THAT(src, IsDependency(_A("J"), _A("I"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "dependants::A")); - REQUIRE(IsClass(j, "dependants::B")); - REQUIRE(IsClass(j, "dependants::C")); - REQUIRE(IsClass(j, "dependants::D")); - REQUIRE(IsClass(j, "dependants::BB")); - REQUIRE(IsClass(j, "dependants::E")); - REQUIRE(IsDependency(j, "dependants::B", "dependants::A")); - - REQUIRE(IsClass(j, "dependencies::G")); - REQUIRE(IsClass(j, "dependencies::GG")); - REQUIRE(IsClass(j, "dependencies::H")); - REQUIRE(IsDependency(j, "dependencies::J", "dependencies::I")); - REQUIRE(IsDependency(j, "dependencies::H", "dependencies::G")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - // Check dependants filter - REQUIRE_THAT(src, IsClass(_A("dependants::A"))); - REQUIRE_THAT(src, IsClass(_A("dependants::B"))); - REQUIRE_THAT(src, IsClass(_A("dependants::BB"))); - REQUIRE_THAT(src, IsClass(_A("dependants::D"))); - REQUIRE_THAT(src, IsClass(_A("dependants::E"))); - REQUIRE_THAT(src, !IsClass(_A("dependants::F"))); - - REQUIRE_THAT( - src, IsDependency(_A("dependants::B"), _A("dependants::A"))); - REQUIRE_THAT( - src, IsDependency(_A("dependants::BB"), _A("dependants::A"))); - REQUIRE_THAT( - src, IsDependency(_A("dependants::C"), _A("dependants::B"))); - REQUIRE_THAT( - src, IsDependency(_A("dependants::D"), _A("dependants::C"))); - REQUIRE_THAT( - src, IsDependency(_A("dependants::E"), _A("dependants::D"))); - - // Check dependencies filter - REQUIRE_THAT(src, IsClass(_A("dependencies::G"))); - REQUIRE_THAT(src, IsClass(_A("dependencies::GG"))); - REQUIRE_THAT(src, IsClass(_A("dependencies::H"))); - REQUIRE_THAT(src, !IsClass(_A("dependencies::HH"))); - REQUIRE_THAT(src, IsClass(_A("dependencies::I"))); - REQUIRE_THAT(src, IsClass(_A("dependencies::J"))); - - REQUIRE_THAT( - src, IsDependency(_A("dependencies::H"), _A("dependencies::G"))); - REQUIRE_THAT( - src, IsDependency(_A("dependencies::H"), _A("dependencies::GG"))); - REQUIRE_THAT( - src, IsDependency(_A("dependencies::I"), _A("dependencies::H"))); - REQUIRE_THAT( - src, IsDependency(_A("dependencies::J"), _A("dependencies::I"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE( + IsDependency(src, {"dependencies", "J"}, {"dependencies", "I"})); + REQUIRE( + IsDependency(src, {"dependencies", "H"}, {"dependencies", "G"})); + REQUIRE( + IsDependency(src, {"dependencies", "I"}, {"dependencies", "H"})); + REQUIRE( + IsDependency(src, {"dependencies", "H"}, {"dependencies", "GG"})); + }); } \ No newline at end of file diff --git a/tests/t00044/test_case.h b/tests/t00044/test_case.h index 3f04d11d..18955892 100644 --- a/tests/t00044/test_case.h +++ b/tests/t00044/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00044/test_case.cc + * tests/t00044/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00044", "[test-case][class]") +TEST_CASE("t00044") { + using namespace clanguml::test; + auto [config, db] = load_config("t00044"); auto diagram = config.diagrams["t00044_class"]; @@ -29,90 +31,28 @@ TEST_CASE("t00044", "[test-case][class]") REQUIRE(model->name() == "t00044_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(!src.contains("type-parameter-")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsClassTemplate(src, "sink")); + REQUIRE(IsClassTemplate(src, "signal_handler")); - REQUIRE_THAT(src, !Contains("type-parameter-")); + REQUIRE(IsClassTemplate(src, "signal_handler")); + REQUIRE(IsClassTemplate(src, "signal_handler")); - REQUIRE_THAT(src, IsClassTemplate("sink", "T")); - REQUIRE_THAT(src, IsClassTemplate("signal_handler", "T,A")); + REQUIRE(IsClassTemplate(src, "sink>")); - REQUIRE_THAT(src, IsClassTemplate("signal_handler", "Ret(Args...),A")); - REQUIRE_THAT(src, IsClassTemplate("signal_handler", "void(int),bool")); + REQUIRE(IsInstantiation( + src, "sink", "sink>")); - REQUIRE_THAT( - src, IsClassTemplate("sink", "signal_handler")); + REQUIRE(IsInstantiation(src, "sink>", + "sink>")); - REQUIRE_THAT(src, - IsInstantiation( - _A("sink"), _A("sink>"))); + REQUIRE(IsClassTemplate(src, "signal_handler")); + REQUIRE(IsInstantiation( + src, "signal_handler", "signal_handler")); - REQUIRE_THAT(src, - IsInstantiation(_A("sink>"), - _A("sink>"))); - - REQUIRE_THAT(src, IsClassTemplate("signal_handler", "T,A")); - REQUIRE_THAT(src, - IsInstantiation(_A("signal_handler"), - _A("signal_handler"))); - - REQUIRE_THAT(src, - IsInstantiation(_A("signal_handler"), - _A("signal_handler"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClassTemplate(j, "sink")); - REQUIRE(IsClassTemplate(j, "signal_handler")); - REQUIRE(IsClassTemplate(j, "signal_handler")); - REQUIRE(IsStruct(j, "signal_handler")); - REQUIRE(IsClassTemplate(j, "signal_handler")); - REQUIRE(IsClassTemplate(j, "sink>")); - REQUIRE(IsStruct(j, "R")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - REQUIRE_THAT(src, !Contains("type-parameter-")); - - REQUIRE_THAT(src, IsClass(_A("sink"))); - REQUIRE_THAT(src, IsClass(_A("signal_handler"))); - - REQUIRE_THAT(src, IsClass(_A("signal_handler"))); - REQUIRE_THAT(src, IsClass(_A("signal_handler"))); - - REQUIRE_THAT(src, IsClass(_A("sink>"))); - - REQUIRE_THAT(src, - IsInstantiation( - _A("sink"), _A("sink>"))); - - REQUIRE_THAT(src, - IsInstantiation(_A("sink>"), - _A("sink>"))); - - REQUIRE_THAT(src, IsClass(_A("signal_handler"))); - REQUIRE_THAT(src, - IsInstantiation(_A("signal_handler"), - _A("signal_handler"))); - - REQUIRE_THAT(src, - IsInstantiation(_A("signal_handler"), - _A("signal_handler"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsInstantiation(src, "signal_handler", + "signal_handler")); + }); } \ No newline at end of file diff --git a/tests/t00045/test_case.h b/tests/t00045/test_case.h index 604308b4..a70c4da9 100644 --- a/tests/t00045/test_case.h +++ b/tests/t00045/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00045", "[test-case][class]") +TEST_CASE("t00045") { + using namespace clanguml::test; + auto [config, db] = load_config("t00045"); auto diagram = config.diagrams["t00045_class"]; @@ -28,97 +30,33 @@ TEST_CASE("t00045", "[test-case][class]") REQUIRE(model->name() == "t00045_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, {"ns1", "A"})); + REQUIRE(IsClass(src, {"ns1::ns2", "A"})); + REQUIRE(IsClass(src, {"ns1::ns2", "B"})); + REQUIRE(IsClass(src, {"ns1::ns2", "C"})); + REQUIRE(IsClass(src, {"ns1::ns2", "D"})); + REQUIRE(IsClass(src, {"ns1::ns2", "E"})); + REQUIRE(IsClass(src, {"ns1::ns2", "R"})); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("ns1::A"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns2::A"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns2::B"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns2::C"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns2::D"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns2::E"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns2::R"))); + REQUIRE(IsBaseClass(src, {"ns1::ns2", "A"}, {"ns1::ns2", "B"})); + REQUIRE(IsBaseClass(src, {"ns1", "A"}, {"ns1::ns2", "C"})); + REQUIRE(IsBaseClass(src, {"ns1::ns2", "A"}, {"ns1::ns2", "D"})); + REQUIRE(IsBaseClass(src, "A", {"ns1::ns2", "E"})); - REQUIRE_THAT(src, IsBaseClass(_A("ns1::ns2::A"), _A("ns1::ns2::B"))); - REQUIRE_THAT(src, IsBaseClass(_A("ns1::A"), _A("ns1::ns2::C"))); - REQUIRE_THAT(src, IsBaseClass(_A("ns1::ns2::A"), _A("ns1::ns2::D"))); - REQUIRE_THAT(src, IsBaseClass(_A("A"), _A("ns1::ns2::E"))); + REQUIRE(IsAssociation(src, "ns1::ns2::R", "ns1::ns2::A", "a")); + REQUIRE(IsAssociation(src, "ns1::ns2::R", "ns1::A", "ns1_a")); + REQUIRE(IsAssociation( + src, "ns1::ns2::R", "ns1::ns2::A", "ns1_ns2_a")); + REQUIRE(IsAssociation(src, "ns1::ns2::R", "A", "root_a")); - REQUIRE_THAT( - src, IsAssociation(_A("ns1::ns2::R"), _A("ns1::ns2::A"), "+a")); - REQUIRE_THAT( - src, IsAssociation(_A("ns1::ns2::R"), _A("ns1::A"), "+ns1_a")); - REQUIRE_THAT(src, - IsAssociation(_A("ns1::ns2::R"), _A("ns1::ns2::A"), "+ns1_ns2_a")); - REQUIRE_THAT(src, IsAssociation(_A("ns1::ns2::R"), _A("A"), "+root_a")); + REQUIRE(IsDependency(src, "ns1::ns2::R", "AA")); - REQUIRE_THAT(src, IsDependency(_A("ns1::ns2::R"), _A("AA"))); - - REQUIRE_THAT(src, IsFriend(_A("ns1::ns2::R"), _A("AAA"))); - REQUIRE_THAT( - src, !IsFriend(_A("ns1::ns2::R"), _A("ns1::ns2::AAA"))); + REQUIRE(IsFriend(src, "ns1::ns2::R", "AAA")); + REQUIRE(!IsFriend(src, "ns1::ns2::R", "ns1::ns2::AAA")); // TODO: - // REQUIRE_THAT(puml, IsFriend(_A("ns1::ns2::R"), + // REQUIRE(puml, IsFriend(src, "ns1::ns2::R"), // _A("AAAA"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "ns1::A")); - REQUIRE(IsClass(j, "ns1::ns2::A")); - REQUIRE(IsClass(j, "ns1::ns2::B")); - REQUIRE(IsClass(j, "ns1::ns2::C")); - REQUIRE(IsClass(j, "ns1::ns2::D")); - REQUIRE(IsClass(j, "ns1::ns2::E")); - REQUIRE(IsClass(j, "ns1::ns2::R")); - - REQUIRE(IsBaseClass(j, "ns1::ns2::A", "ns1::ns2::B")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsFriend; - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("ns1::A"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns2::A"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns2::B"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns2::C"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns2::D"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns2::E"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns2::R"))); - - REQUIRE_THAT(src, IsBaseClass(_A("ns1::ns2::A"), _A("ns1::ns2::B"))); - REQUIRE_THAT(src, IsBaseClass(_A("ns1::A"), _A("ns1::ns2::C"))); - REQUIRE_THAT(src, IsBaseClass(_A("ns1::ns2::A"), _A("ns1::ns2::D"))); - REQUIRE_THAT(src, IsBaseClass(_A("A"), _A("ns1::ns2::E"))); - - REQUIRE_THAT( - src, IsAssociation(_A("ns1::ns2::R"), _A("ns1::ns2::A"), "+a")); - REQUIRE_THAT( - src, IsAssociation(_A("ns1::ns2::R"), _A("ns1::A"), "+ns1_a")); - REQUIRE_THAT(src, - IsAssociation(_A("ns1::ns2::R"), _A("ns1::ns2::A"), "+ns1_ns2_a")); - REQUIRE_THAT(src, IsAssociation(_A("ns1::ns2::R"), _A("A"), "+root_a")); - - REQUIRE_THAT(src, IsDependency(_A("ns1::ns2::R"), _A("AA"))); - - REQUIRE_THAT(src, IsFriend(_A("ns1::ns2::R"), _A("AAA"))); - REQUIRE_THAT( - src, !IsFriend(_A("ns1::ns2::R"), _A("ns1::ns2::AAA"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }); } \ No newline at end of file diff --git a/tests/t00046/test_case.h b/tests/t00046/test_case.h index 1352f8b5..35285e25 100644 --- a/tests/t00046/test_case.h +++ b/tests/t00046/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t00046/test_case.cc + * tests/t00046/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00046", "[test-case][class]") +TEST_CASE("t00046") { + using namespace clanguml::test; + auto [config, db] = load_config("t00046"); auto diagram = config.diagrams["t00046_class"]; @@ -28,51 +30,16 @@ TEST_CASE("t00046", "[test-case][class]") REQUIRE(model->name() == "t00046_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "AA")); + REQUIRE(IsClass(src, {"ns1::ns2", "B"})); + REQUIRE(IsClass(src, {"ns1::ns2", "C"})); + REQUIRE(IsClass(src, {"ns1::ns2", "D"})); + REQUIRE(IsClass(src, {"ns1::ns2", "E"})); + REQUIRE(IsClass(src, {"ns1::ns2", "R"})); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - - REQUIRE_THAT(src, IsField("i", "std::vector")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(get_element(j, "A").value()["type"] == "class"); - REQUIRE(get_element(j, "AA").value()["type"] == "class"); - REQUIRE(get_element(j, "ns1::A").value()["type"] == "class"); - REQUIRE(get_element(j, "ns1::ns2::D").value()["type"] == "class"); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsField; - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("AA"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns2::B"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns2::C"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns2::D"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns2::E"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns2::R"))); - - REQUIRE_THAT(src, IsField("i", "std::vector")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsField( + src, "ns1::ns2::R", "i", "std::vector")); + }); } \ No newline at end of file diff --git a/tests/t00047/test_case.h b/tests/t00047/test_case.h index 19854832..07a3b334 100644 --- a/tests/t00047/test_case.h +++ b/tests/t00047/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00047", "[test-case][class]") +TEST_CASE("t00047") { + using namespace clanguml::test; + auto [config, db] = load_config("t00047"); auto diagram = config.diagrams["t00047_class"]; @@ -28,48 +30,10 @@ TEST_CASE("t00047", "[test-case][class]") REQUIRE(model->name() == "t00047_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if class templates exist - REQUIRE_THAT(src, IsClassTemplate("conditional_t", "Ts...")); - REQUIRE_THAT(src, IsClassTemplate("conditional_t", "Else")); - REQUIRE_THAT(src, - IsClassTemplate("conditional_t", "std::true_type,Result,Tail...")); - REQUIRE_THAT(src, - IsClassTemplate("conditional_t", "std::false_type,Result,Tail...")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClassTemplate(j, "conditional_t")); - REQUIRE(IsClass(j, "conditional_t")); - REQUIRE(IsClass(j, "conditional_t")); - REQUIRE(IsClass(j, "conditional_t")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - // Check if class templates exist - REQUIRE_THAT(src, IsClass(_A("conditional_t"))); - REQUIRE_THAT(src, IsClass(_A("conditional_t"))); - REQUIRE_THAT( - src, IsClass(_A("conditional_t"))); - REQUIRE_THAT( - src, IsClass(_A("conditional_t"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClassTemplate(src, "conditional_t")); + REQUIRE(IsClass(src, "conditional_t")); + REQUIRE(IsClass(src, "conditional_t")); + REQUIRE(IsClass(src, "conditional_t")); + }); } \ No newline at end of file diff --git a/tests/t00048/test_case.h b/tests/t00048/test_case.h index 38ecc80b..69b726a3 100644 --- a/tests/t00048/test_case.h +++ b/tests/t00048/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00048", "[test-case][class]") +TEST_CASE("t00048") { + using namespace clanguml::test; + auto [config, db] = load_config("t00048"); auto diagram = config.diagrams["t00048_class"]; @@ -28,63 +30,19 @@ TEST_CASE("t00048", "[test-case][class]") REQUIRE(model->name() == "t00048_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { // Check if all classes exist - REQUIRE_THAT(src, IsAbstractClass(_A("Base"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); + REQUIRE(IsAbstractClass(src, "Base")); + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); // Check if class templates exist - REQUIRE_THAT(src, IsAbstractClassTemplate("BaseTemplate", "T")); - REQUIRE_THAT(src, IsClassTemplate("ATemplate", "T")); - REQUIRE_THAT(src, IsClassTemplate("BTemplate", "T")); + REQUIRE(IsAbstractClassTemplate(src, "BaseTemplate")); + REQUIRE(IsClassTemplate(src, "ATemplate")); + REQUIRE(IsClassTemplate(src, "BTemplate")); // Check if all inheritance relationships exist - REQUIRE_THAT(src, IsBaseClass(_A("Base"), _A("A"))); - REQUIRE_THAT(src, IsBaseClass(_A("Base"), _A("B"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - REQUIRE(IsClass(j, "ATemplate")); - REQUIRE(IsClass(j, "BTemplate")); - REQUIRE(IsBaseClass(j, "Base", "A")); - REQUIRE(IsBaseClass(j, "Base", "B")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsAbstractClass; - - // Check if all classes exist - REQUIRE_THAT(src, IsAbstractClass(_A("Base"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - - // Check if class templates exist - REQUIRE_THAT(src, IsAbstractClass(_A("BaseTemplate"))); - REQUIRE_THAT(src, IsClass(_A("ATemplate"))); - REQUIRE_THAT(src, IsClass(_A("BTemplate"))); - - // Check if all inheritance relationships exist - REQUIRE_THAT(src, IsBaseClass(_A("Base"), _A("A"))); - REQUIRE_THAT(src, IsBaseClass(_A("Base"), _A("B"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsBaseClass(src, "Base", "A")); + REQUIRE(IsBaseClass(src, "Base", "B")); + }); } \ No newline at end of file diff --git a/tests/t00049/test_case.h b/tests/t00049/test_case.h index 01494fc3..4272f408 100644 --- a/tests/t00049/test_case.h +++ b/tests/t00049/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00049", "[test-case][class]") +TEST_CASE("t00049") { + using namespace clanguml::test; + auto [config, db] = load_config("t00049"); auto diagram = config.diagrams["t00049_class"]; @@ -27,78 +29,22 @@ TEST_CASE("t00049", "[test-case][class]") auto model = generate_class_diagram(*db, diagram); REQUIRE(model->name() == "t00049_class"); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "R")); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + REQUIRE(IsClassTemplate(src, "A")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsMethod(src, "R", "get_int_map", "A")); + REQUIRE(IsMethod( + src, "R", "set_int_map", "void", "A && int_map")); - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("R"))); + REQUIRE(IsField(src, "R", "a_string", "A")); + REQUIRE( + IsField(src, "R", "a_vector_string", "A")); + REQUIRE(IsField(src, "R", "a_int_map", "A")); - // Check if class templates exist - REQUIRE_THAT(src, IsClassTemplate("A", "T")); - - // Check if all methods exist - REQUIRE_THAT(src, (IsMethod("get_int_map", "A"))); - REQUIRE_THAT(src, - (IsMethod("set_int_map", "void", "A && int_map"))); - - // Check if all fields exist - REQUIRE_THAT(src, (IsField("a_string", "A"))); - REQUIRE_THAT( - src, (IsField("a_vector_string", "A"))); - REQUIRE_THAT(src, (IsField("a_int_map", "A"))); - - // Check if all relationships exist - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "R")); - REQUIRE(IsClassTemplate(j, "A")); - REQUIRE(IsInstantiation(j, "A", "A")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsField; - using mermaid::IsMethod; - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("R"))); - - // Check if class templates exist - REQUIRE_THAT(src, IsClass(_A("A"))); - - // Check if all methods exist - REQUIRE_THAT(src, (IsMethod("get_int_map", "A"))); - REQUIRE_THAT(src, - (IsMethod("set_int_map", "void", "A && int_map"))); - - // Check if all fields exist - REQUIRE_THAT(src, (IsField("a_string", "A"))); - REQUIRE_THAT( - src, (IsField("a_vector_string", "A"))); - REQUIRE_THAT(src, (IsField("a_int_map", "A"))); - - // Check if all relationships exist - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsInstantiation(src, "A", "A")); + REQUIRE(IsInstantiation(src, "A", "A")); + REQUIRE(IsInstantiation(src, "A", "A")); + }); } \ No newline at end of file diff --git a/tests/t00050/test_case.h b/tests/t00050/test_case.h index 6a3c50dd..9363db62 100644 --- a/tests/t00050/test_case.h +++ b/tests/t00050/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00050", "[test-case][class]") +TEST_CASE("t00050") { + using namespace clanguml::test; + auto [config, db] = load_config("t00050"); auto diagram = config.diagrams["t00050_class"]; @@ -28,73 +30,31 @@ TEST_CASE("t00050", "[test-case][class]") REQUIRE(model->name() == "t00050_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM( + config, diagram, *model, + [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClass(src, "C")); + REQUIRE(IsClass(src, {"utils", "D"})); + REQUIRE(IsEnum(src, "E")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("utils::D"))); - REQUIRE_THAT(src, IsEnum(_A("E"))); - - REQUIRE_THAT(src, HasNote(_A("A"), "left")); - REQUIRE_THAT(src, HasNote(_A("A"), "right")); - REQUIRE_THAT(src, HasNote(_A("B"), "top")); - REQUIRE_THAT(src, HasNote(_A("C"), "top")); - REQUIRE_THAT(src, HasNote(_A("utils::D"), "top")); - REQUIRE_THAT(src, !HasNote(_A("E"), "bottom")); - REQUIRE_THAT(src, !HasNote(_A("NoComment"), "top")); - REQUIRE_THAT(src, HasNote(_A("F"), "top")); - REQUIRE_THAT(src, HasNote(_A("G"), "top")); - REQUIRE_THAT(src, HasNote(_A("G"), "bottom")); - REQUIRE_THAT(src, HasNote(_A("G"), "right")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - REQUIRE(IsClass(j, "C")); - REQUIRE(IsClass(j, "utils::D")); - REQUIRE(IsEnum(j, "E")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::HasNote; - using mermaid::IsEnum; - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("utils::D"))); - REQUIRE_THAT(src, IsEnum(_A("E"))); - - REQUIRE_THAT(src, HasNote(_A("A"), "left")); - REQUIRE_THAT(src, HasNote(_A("A"), "right")); - REQUIRE_THAT(src, HasNote(_A("B"), "top")); - REQUIRE_THAT(src, HasNote(_A("C"), "top")); - REQUIRE_THAT(src, HasNote(_A("utils::D"), "top")); - REQUIRE_THAT(src, !HasNote(_A("E"), "bottom")); - REQUIRE_THAT(src, !HasNote(_A("NoComment"), "top")); - REQUIRE_THAT(src, HasNote(_A("F"), "top")); - REQUIRE_THAT(src, HasNote(_A("G"), "top")); - REQUIRE_THAT(src, HasNote(_A("G"), "bottom")); - REQUIRE_THAT(src, HasNote(_A("G"), "right")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(HasNote(src, "A", "left")); + REQUIRE(HasNote(src, "A", "right")); + REQUIRE(HasNote(src, "B", "top")); + REQUIRE(HasNote(src, "C", "top")); + REQUIRE(HasNote(src, "utils::D", "top")); + REQUIRE(HasNote(src, "F", "top")); + REQUIRE(HasNote(src, "G", "top")); + REQUIRE(HasNote(src, "G", "bottom")); + REQUIRE(HasNote(src, "G", "right")); + }, + [](const plantuml_t &src) { + REQUIRE(!HasNote(src, "E", "bottom")); + REQUIRE(!HasNote(src, "NoComment", "top")); + }, + [](const mermaid_t &src) { + REQUIRE(!HasNote(src, "E", "bottom")); + REQUIRE(!HasNote(src, "NoComment", "top")); + }); } \ No newline at end of file diff --git a/tests/t00051/test_case.h b/tests/t00051/test_case.h index c2302184..cfcebade 100644 --- a/tests/t00051/test_case.h +++ b/tests/t00051/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00051", "[test-case][class]") +TEST_CASE("t00051") { + using namespace clanguml::test; + auto [config, db] = load_config("t00051"); auto diagram = config.diagrams["t00051_class"]; @@ -28,6 +30,36 @@ TEST_CASE("t00051", "[test-case][class]") REQUIRE(model->name() == "t00051_class"); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsInnerClass(src, "A", "A::custom_thread1")); + REQUIRE(IsInnerClass(src, "A", "A::custom_thread2")); + + REQUIRE(IsMethod(src, "A::custom_thread1", + "custom_thread1", "void", + "Function && f, Args &&... args")); + REQUIRE(IsMethod(src, "A::custom_thread2", "thread", "void", + "(lambda at t00051.cc:59:27) &&")); + REQUIRE(IsMethod(src, "A", "start_thread3", + "B<(lambda at t00051.cc:43:18),(lambda at " + "t00051.cc:43:27)>")); + REQUIRE(IsMethod( + src, "A", "get_function", "(lambda at t00051.cc:48:16)")); + + REQUIRE(IsClassTemplate(src, "B")); + REQUIRE(IsMethod(src, "B", "f", "void")); + REQUIRE(IsMethod(src, "B", "ff", "void")); + + REQUIRE(IsClassTemplate( + src, "B<(lambda at t00051.cc:43:18),(lambda at t00051.cc:43:27)>")); + + REQUIRE(IsInstantiation(src, "B", + "B<(lambda at t00051.cc:43:18),(lambda at t00051.cc:43:27)>")); + + REQUIRE(IsDependency(src, "A", + "B<(lambda at t00051.cc:43:18),(lambda at t00051.cc:43:27)>")); + }); + /* { auto src = generate_class_puml(diagram, *model); AliasMatcher _A(src); @@ -128,4 +160,5 @@ TEST_CASE("t00051", "[test-case][class]") save_mermaid(config.output_directory(), diagram->name + ".mmd", src); } + */ } \ No newline at end of file diff --git a/tests/t00052/test_case.h b/tests/t00052/test_case.h index 32319443..ee2dce46 100644 --- a/tests/t00052/test_case.h +++ b/tests/t00052/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00052", "[test-case][class]") +TEST_CASE("t00052") { + using namespace clanguml::test; + auto [config, db] = load_config("t00052"); auto diagram = config.diagrams["t00052_class"]; @@ -28,6 +30,17 @@ TEST_CASE("t00052", "[test-case][class]") REQUIRE(model->name() == "t00052_class"); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + + REQUIRE(IsClassTemplate(src, "B")); + + REQUIRE(IsMethod(src, "A", "a", "T", "T p")); + REQUIRE(IsMethod(src, "A", "aa", "void", "F && f, Q q")); + REQUIRE(IsMethod(src, "B", "b", "T", "T t")); + REQUIRE(IsMethod(src, "B", "bb", "T", "F && f, T t")); + }); + /* { auto src = generate_class_puml(diagram, *model); AliasMatcher _A(src); @@ -79,4 +92,5 @@ TEST_CASE("t00052", "[test-case][class]") save_mermaid(config.output_directory(), diagram->name + ".mmd", src); } + */ } \ No newline at end of file diff --git a/tests/t00053/test_case.h b/tests/t00053/test_case.h index 5cd14eb6..badae765 100644 --- a/tests/t00053/test_case.h +++ b/tests/t00053/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00053", "[test-case][class]") +TEST_CASE("t00053") { + using namespace clanguml::test; + auto [config, db] = load_config("t00053"); auto diagram = config.diagrams["t00053_class"]; @@ -28,78 +30,98 @@ TEST_CASE("t00053", "[test-case][class]") REQUIRE(model->name() == "t00053_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "a")); + REQUIRE(IsClass(src, "b")); + REQUIRE(IsClass(src, "c")); + REQUIRE(IsClass(src, "d")); + REQUIRE(IsClass(src, "e")); + REQUIRE(IsClass(src, "f")); + REQUIRE(IsClass(src, "g")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClass(src, "C")); + REQUIRE(IsClass(src, "D")); + REQUIRE(IsClass(src, "E")); + REQUIRE(IsClass(src, "F")); + REQUIRE(IsClass(src, "G")); + }); + /* + { + auto src = generate_class_puml(diagram, *model); + AliasMatcher _A(src); - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("a"))); - REQUIRE_THAT(src, IsClass(_A("b"))); - REQUIRE_THAT(src, IsClass(_A("c"))); - REQUIRE_THAT(src, IsClass(_A("d"))); - REQUIRE_THAT(src, IsClass(_A("e"))); - REQUIRE_THAT(src, IsClass(_A("f"))); - REQUIRE_THAT(src, IsClass(_A("g"))); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - REQUIRE_THAT(src, IsClass(_A("F"))); - REQUIRE_THAT(src, IsClass(_A("G"))); + // Check if all classes exist + REQUIRE_THAT(src, IsClass(_A("a"))); + REQUIRE_THAT(src, IsClass(_A("b"))); + REQUIRE_THAT(src, IsClass(_A("c"))); + REQUIRE_THAT(src, IsClass(_A("d"))); + REQUIRE_THAT(src, IsClass(_A("e"))); + REQUIRE_THAT(src, IsClass(_A("f"))); + REQUIRE_THAT(src, IsClass(_A("g"))); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("B"))); + REQUIRE_THAT(src, IsClass(_A("C"))); + REQUIRE_THAT(src, IsClass(_A("D"))); + REQUIRE_THAT(src, IsClass(_A("E"))); + REQUIRE_THAT(src, IsClass(_A("F"))); + REQUIRE_THAT(src, IsClass(_A("G"))); - { - auto j = generate_class_json(diagram, *model); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - using namespace json; + { + auto j = generate_class_json(diagram, *model); - REQUIRE(IsClass(j, "a")); - REQUIRE(IsClass(j, "b")); - REQUIRE(IsClass(j, "c")); - REQUIRE(IsClass(j, "d")); - REQUIRE(IsClass(j, "e")); - REQUIRE(IsClass(j, "f")); - REQUIRE(IsClass(j, "g")); + using namespace json; - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - REQUIRE(IsClass(j, "C")); - REQUIRE(IsClass(j, "D")); - REQUIRE(IsClass(j, "E")); - REQUIRE(IsClass(j, "F")); - REQUIRE(IsClass(j, "G")); + REQUIRE(IsClass(j, "a")); + REQUIRE(IsClass(j, "b")); + REQUIRE(IsClass(j, "c")); + REQUIRE(IsClass(j, "d")); + REQUIRE(IsClass(j, "e")); + REQUIRE(IsClass(j, "f")); + REQUIRE(IsClass(j, "g")); - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); + REQUIRE(IsClass(j, "A")); + REQUIRE(IsClass(j, "B")); + REQUIRE(IsClass(j, "C")); + REQUIRE(IsClass(j, "D")); + REQUIRE(IsClass(j, "E")); + REQUIRE(IsClass(j, "F")); + REQUIRE(IsClass(j, "G")); - mermaid::AliasMatcher _A(src); + save_json(config.output_directory(), diagram->name + ".json", j); + } + { + auto src = generate_class_mermaid(diagram, *model); - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("a"))); - REQUIRE_THAT(src, IsClass(_A("b"))); - REQUIRE_THAT(src, IsClass(_A("c"))); - REQUIRE_THAT(src, IsClass(_A("d"))); - REQUIRE_THAT(src, IsClass(_A("e"))); - REQUIRE_THAT(src, IsClass(_A("f"))); - REQUIRE_THAT(src, IsClass(_A("g"))); + mermaid::AliasMatcher _A(src); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - REQUIRE_THAT(src, IsClass(_A("F"))); - REQUIRE_THAT(src, IsClass(_A("G"))); + // Check if all classes exist + REQUIRE_THAT(src, IsClass(_A("a"))); + REQUIRE_THAT(src, IsClass(_A("b"))); + REQUIRE_THAT(src, IsClass(_A("c"))); + REQUIRE_THAT(src, IsClass(_A("d"))); + REQUIRE_THAT(src, IsClass(_A("e"))); + REQUIRE_THAT(src, IsClass(_A("f"))); + REQUIRE_THAT(src, IsClass(_A("g"))); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("B"))); + REQUIRE_THAT(src, IsClass(_A("C"))); + REQUIRE_THAT(src, IsClass(_A("D"))); + REQUIRE_THAT(src, IsClass(_A("E"))); + REQUIRE_THAT(src, IsClass(_A("F"))); + REQUIRE_THAT(src, IsClass(_A("G"))); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + } + */ } \ No newline at end of file diff --git a/tests/t00054/test_case.h b/tests/t00054/test_case.h index 7fcf352a..2f53b3ec 100644 --- a/tests/t00054/test_case.h +++ b/tests/t00054/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00054", "[test-case][class]") +TEST_CASE("t00054") { + using namespace clanguml::test; + auto [config, db] = load_config("t00054"); auto diagram = config.diagrams["t00054_class"]; @@ -28,6 +30,28 @@ TEST_CASE("t00054", "[test-case][class]") REQUIRE(model->name() == "t00054_class"); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "a")); + REQUIRE(IsClass(src, "b")); + REQUIRE(IsClass(src, {"detail", "c"})); + REQUIRE(IsClass(src, {"detail", "d"})); + REQUIRE(IsClass(src, {"detail", "e"})); + REQUIRE(IsClass(src, "f")); + REQUIRE(IsClass(src, "g")); + + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClass(src, {"detail2", "C"})); + REQUIRE(IsClass(src, {"detail2::detail3", "D"})); + REQUIRE(IsClass(src, {"detail2::detail3", "E"})); + REQUIRE(IsClass(src, {"detail2", "F"})); + REQUIRE(IsClass(src, "G")); + + REQUIRE(IsEnum(src, {"detail4", "i"})); + REQUIRE(IsEnum(src, {"detail4", "h"})); + REQUIRE(IsEnum(src, {"detail4", "j"})); + }); + /* { auto src = generate_class_puml(diagram, *model); AliasMatcher _A(src); @@ -114,5 +138,5 @@ TEST_CASE("t00054", "[test-case][class]") REQUIRE_THAT(src, IsEnum(_A("detail4::j"))); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } \ No newline at end of file diff --git a/tests/t00055/test_case.h b/tests/t00055/test_case.h index f349d5bf..6dc4056c 100644 --- a/tests/t00055/test_case.h +++ b/tests/t00055/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00055", "[test-case][class]") +TEST_CASE("t00055") { + using namespace clanguml::test; + auto [config, db] = load_config("t00055"); auto diagram = config.diagrams["t00055_class"]; @@ -28,6 +30,29 @@ TEST_CASE("t00055", "[test-case][class]") REQUIRE(model->name() == "t00055_class"); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClass(src, "C")); + REQUIRE(IsClass(src, "D")); + REQUIRE(IsClass(src, "E")); + REQUIRE(IsClass(src, "F")); + REQUIRE(IsClass(src, "G")); + REQUIRE(IsClass(src, "H")); + REQUIRE(IsClass(src, "I")); + REQUIRE(IsClass(src, "J")); + + REQUIRE(IsLayoutHint(src, "A", "right", "C")); + REQUIRE(IsLayoutHint(src, "C", "right", "E")); + REQUIRE(IsLayoutHint(src, "E", "right", "G")); + REQUIRE(IsLayoutHint(src, "G", "right", "I")); + + REQUIRE(IsLayoutHint(src, "B", "down", "D")); + REQUIRE(IsLayoutHint(src, "D", "down", "F")); + REQUIRE(IsLayoutHint(src, "F", "down", "H")); + REQUIRE(IsLayoutHint(src, "H", "down", "J")); + }); + /* { auto src = generate_class_puml(diagram, *model); AliasMatcher _A(src); @@ -96,5 +121,5 @@ TEST_CASE("t00055", "[test-case][class]") REQUIRE_THAT(src, IsClass(_A("J"))); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } \ No newline at end of file diff --git a/tests/t00056/test_case.h b/tests/t00056/test_case.h index 8d6efee1..238175b9 100644 --- a/tests/t00056/test_case.h +++ b/tests/t00056/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00056", "[test-case][class]") +TEST_CASE("t00056") { + using namespace clanguml::test; + auto [config, db] = load_config("t00056"); auto diagram = config.diagrams["t00056_class"]; @@ -28,200 +30,267 @@ TEST_CASE("t00056", "[test-case][class]") REQUIRE(model->name() == "t00056_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsConcept(src, "greater_than_simple")); + REQUIRE(IsConcept(src, "greater_than_with_requires")); + REQUIRE(IsConcept(src, "max_four_bytes")); + REQUIRE(IsConcept(src, "iterable")); + REQUIRE(IsConcept(src, "has_value_type")); + REQUIRE(IsConcept(src, "convertible_to_string")); + REQUIRE(IsConcept(src, "iterable_with_value_type")); + REQUIRE(IsConcept(src, "iterable_or_small_value_type")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsConceptRequirement( + src, "greater_than_with_requires", "sizeof (l) > sizeof (r)")); - // Check if all classes exist - REQUIRE_THAT(src, IsConcept(_A("greater_than_simple"))); - REQUIRE_THAT(src, IsConcept(_A("greater_than_with_requires"))); - REQUIRE_THAT(src, IsConcept(_A("max_four_bytes"))); - REQUIRE_THAT(src, IsConcept(_A("iterable"))); - REQUIRE_THAT(src, IsConcept(_A("has_value_type"))); - REQUIRE_THAT(src, IsConcept(_A("convertible_to_string"))); - REQUIRE_THAT(src, IsConcept(_A("iterable_with_value_type"))); - REQUIRE_THAT(src, IsConcept(_A("iterable_or_small_value_type"))); - - REQUIRE_THAT(src, - IsConceptRequirement(_A("greater_than_with_requires"), - "sizeof (l) > sizeof (r)")); - - REQUIRE_THAT( - src, IsConceptRequirement(_A("iterable"), "container.begin()")); - REQUIRE_THAT( - src, IsConceptRequirement(_A("iterable"), "container.end()")); + REQUIRE(IsConceptRequirement(src, "iterable", "container.begin()")); + REQUIRE(IsConceptRequirement(src, "iterable", "container.end()")); #if (LLVM_VERSION_MAJOR == 13) || (LLVM_VERSION_MAJOR == 14) - REQUIRE_THAT(src, - IsConceptRequirement( - _A("convertible_to_string"), "std::string({s})")); + REQUIRE(IsConceptRequirement( + src, "convertible_to_string", "std::string({s})")); #else - REQUIRE_THAT(src, + REQUIRE( IsConceptRequirement( - _A("convertible_to_string"), "std::string{s}")); + src,"convertible_to_string", "std::string{s}")); #endif - REQUIRE_THAT(src, - IsConceptRequirement(_A("convertible_to_string"), - "{std::to_string(s)} noexcept")); - REQUIRE_THAT(src, - IsConceptRequirement(_A("convertible_to_string"), - "{std::to_string(s)} -> std::same_as")); + REQUIRE(IsConceptRequirement( + src, "convertible_to_string", "{std::to_string(s)} noexcept")); + REQUIRE(IsConceptRequirement(src, "convertible_to_string", + "{std::to_string(s)} -> std::same_as")); - // Check if class templates exist - REQUIRE_THAT(src, IsClassTemplate("A", "max_four_bytes T")); - REQUIRE_THAT(src, IsClassTemplate("B", "T")); - REQUIRE_THAT(src, IsClassTemplate("C", "convertible_to_string T")); - REQUIRE_THAT( - src, IsClassTemplate("D", "iterable T1,T2,iterable T3,T4,T5")); - REQUIRE_THAT(src, IsClassTemplate("E", "T1,T2,T3")); - REQUIRE_THAT(src, IsClassTemplate("F", "T1,T2,T3")); + REQUIRE(IsClassTemplate(src, "A")); - // Check if all relationships exist - REQUIRE_THAT(src, - IsConstraint( - _A("A"), _A("max_four_bytes"), "T")); + REQUIRE(IsClassTemplate(src, "B")); + REQUIRE(IsClassTemplate(src, "C")); + REQUIRE(IsClassTemplate(src, "D")); + REQUIRE(IsClassTemplate(src, "E")); + REQUIRE(IsClassTemplate(src, "F")); - REQUIRE_THAT(src, - IsConstraint(_A("D"), - _A("max_four_bytes"), "T2")); - REQUIRE_THAT(src, - IsConstraint(_A("D"), - _A("max_four_bytes"), "T5")); - REQUIRE_THAT(src, - IsConstraint(_A("D"), - _A("iterable"), "T1")); - REQUIRE_THAT(src, - IsConstraint(_A("D"), - _A("iterable"), "T3")); + REQUIRE( + IsConstraint(src, "A", "max_four_bytes", "T")); - REQUIRE_THAT(src, - IsConstraint(_A("iterable_with_value_type"), - _A("has_value_type"), "T")); + REQUIRE(IsConstraint(src, "D", + "max_four_bytes", "T2")); + REQUIRE(IsConstraint(src, "D", + "max_four_bytes", "T5")); + REQUIRE(IsConstraint( + src, "D", "iterable", "T1")); + REQUIRE(IsConstraint( + src, "D", "iterable", "T3")); - REQUIRE_THAT(src, - IsConstraint(_A("iterable_or_small_value_type"), - _A("max_four_bytes"), "T")); - REQUIRE_THAT(src, - IsConstraint(_A("iterable_or_small_value_type"), - _A("iterable_with_value_type"), "T")); + REQUIRE(IsConstraint( + src, "iterable_with_value_type", "has_value_type", "T")); - REQUIRE_THAT(src, - IsConstraint(_A("E"), - _A("greater_than_with_requires"), "T1,T3")); + REQUIRE(IsConstraint( + src, "iterable_or_small_value_type", "max_four_bytes", "T")); + REQUIRE(IsConstraint(src, "iterable_or_small_value_type", + "iterable_with_value_type", "T")); - REQUIRE_THAT(src, - IsConstraint( - _A("F"), _A("greater_than_simple"), "T1,T3")); + REQUIRE(IsConstraint( + src, "E", "greater_than_with_requires", "T1,T3")); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); + REQUIRE(IsConstraint( + src, "F", "greater_than_simple", "T1,T3")); + }); + /* + { + auto src = generate_class_puml(diagram, *model); + AliasMatcher _A(src); - using namespace json; + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE(IsConcept(j, "greater_than_simple")); - REQUIRE(IsConcept(j, "greater_than_with_requires")); - REQUIRE(IsConcept(j, "max_four_bytes")); - REQUIRE(IsConcept(j, "iterable")); - REQUIRE(IsConcept(j, "has_value_type")); - REQUIRE(IsConcept(j, "convertible_to_string")); - REQUIRE(IsConcept(j, "iterable_with_value_type")); - REQUIRE(IsConcept(j, "iterable_or_small_value_type")); + // Check if all classes exist + REQUIRE_THAT(src, IsConcept(_A("greater_than_simple"))); + REQUIRE_THAT(src, IsConcept(_A("greater_than_with_requires"))); + REQUIRE_THAT(src, IsConcept(_A("max_four_bytes"))); + REQUIRE_THAT(src, IsConcept(_A("iterable"))); + REQUIRE_THAT(src, IsConcept(_A("has_value_type"))); + REQUIRE_THAT(src, IsConcept(_A("convertible_to_string"))); + REQUIRE_THAT(src, IsConcept(_A("iterable_with_value_type"))); + REQUIRE_THAT(src, IsConcept(_A("iterable_or_small_value_type"))); - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); + REQUIRE_THAT(src, + IsConceptRequirement(_A("greater_than_with_requires"), + "sizeof (l) > sizeof (r)")); - mermaid::AliasMatcher _A(src); - using mermaid::IsConcept; - using mermaid::IsConceptRequirement; - using mermaid::IsConstraint; + REQUIRE_THAT( + src, IsConceptRequirement(_A("iterable"), + "container.begin()")); REQUIRE_THAT( src, + IsConceptRequirement(_A("iterable"), "container.end()")); - // Check if all classes exist - REQUIRE_THAT(src, IsConcept(_A("greater_than_simple"))); - REQUIRE_THAT(src, IsConcept(_A("greater_than_with_requires"))); - REQUIRE_THAT(src, IsConcept(_A("max_four_bytes"))); - REQUIRE_THAT(src, IsConcept(_A("iterable"))); - REQUIRE_THAT(src, IsConcept(_A("has_value_type"))); - REQUIRE_THAT(src, IsConcept(_A("convertible_to_string"))); - REQUIRE_THAT(src, IsConcept(_A("iterable_with_value_type"))); - REQUIRE_THAT(src, IsConcept(_A("iterable_or_small_value_type"))); + #if (LLVM_VERSION_MAJOR == 13) || (LLVM_VERSION_MAJOR == 14) + REQUIRE_THAT(src, + IsConceptRequirement( + _A("convertible_to_string"), "std::string({s})")); + #else + REQUIRE_THAT(src, + IsConceptRequirement( + _A("convertible_to_string"), "std::string{s}")); + #endif + REQUIRE_THAT(src, + IsConceptRequirement(_A("convertible_to_string"), + "{std::to_string(s)} noexcept")); + REQUIRE_THAT(src, + IsConceptRequirement(_A("convertible_to_string"), + "{std::to_string(s)} -> std::same_as")); - REQUIRE_THAT(src, - IsConceptRequirement(_A("greater_than_with_requires"), - "sizeof (l) > sizeof (r)")); + // Check if class templates exist + REQUIRE_THAT(src, IsClassTemplate("A", "max_four_bytes T")); + REQUIRE_THAT(src, IsClassTemplate("B", "T")); + REQUIRE_THAT(src, IsClassTemplate("C", "convertible_to_string T")); + REQUIRE_THAT( + src, IsClassTemplate("D", "iterable T1,T2,iterable T3,T4,T5")); + REQUIRE_THAT(src, IsClassTemplate("E", "T1,T2,T3")); + REQUIRE_THAT(src, IsClassTemplate("F", "T1,T2,T3")); - REQUIRE_THAT( - src, IsConceptRequirement(_A("iterable"), "container.begin()")); - REQUIRE_THAT( - src, IsConceptRequirement(_A("iterable"), "container.end()")); + // Check if all relationships exist + REQUIRE_THAT(src, + IsConstraint( + _A("A"), _A("max_four_bytes"), "T")); -#if (LLVM_VERSION_MAJOR == 13) || (LLVM_VERSION_MAJOR == 14) - REQUIRE_THAT(src, - IsConceptRequirement( - _A("convertible_to_string"), "std::string({s})")); -#else - REQUIRE_THAT(src, - IsConceptRequirement( - _A("convertible_to_string"), "std::string{s}")); -#endif - REQUIRE_THAT(src, - IsConceptRequirement(_A("convertible_to_string"), - "{std::to_string(s)} noexcept")); - REQUIRE_THAT(src, - IsConceptRequirement(_A("convertible_to_string"), - "{std::to_string(s)} -> std::same_as")); + REQUIRE_THAT(src, + IsConstraint(_A("D"), + _A("max_four_bytes"), "T2")); + REQUIRE_THAT(src, + IsConstraint(_A("D"), + _A("max_four_bytes"), "T5")); + REQUIRE_THAT(src, + IsConstraint(_A("D"), + _A("iterable"), "T1")); + REQUIRE_THAT(src, + IsConstraint(_A("D"), + _A("iterable"), "T3")); - // Check if class templates exist - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - REQUIRE_THAT(src, IsClass(_A("F"))); + REQUIRE_THAT(src, + IsConstraint(_A("iterable_with_value_type"), + _A("has_value_type"), "T")); - // Check if all relationships exist - REQUIRE_THAT(src, - IsConstraint( - _A("A"), _A("max_four_bytes"), "T")); + REQUIRE_THAT(src, + IsConstraint(_A("iterable_or_small_value_type"), + _A("max_four_bytes"), "T")); + REQUIRE_THAT(src, + IsConstraint(_A("iterable_or_small_value_type"), + _A("iterable_with_value_type"), "T")); - REQUIRE_THAT(src, - IsConstraint(_A("D"), - _A("max_four_bytes"), "T2")); - REQUIRE_THAT(src, - IsConstraint(_A("D"), - _A("max_four_bytes"), "T5")); - REQUIRE_THAT(src, - IsConstraint(_A("D"), - _A("iterable"), "T1")); - REQUIRE_THAT(src, - IsConstraint(_A("D"), - _A("iterable"), "T3")); + REQUIRE_THAT(src, + IsConstraint(_A("E"), + _A("greater_than_with_requires"), "T1,T3")); - REQUIRE_THAT(src, - IsConstraint(_A("iterable_with_value_type"), - _A("has_value_type"), "T")); + REQUIRE_THAT(src, + IsConstraint( + _A("F"), _A("greater_than_simple"), + "T1,T3")); - REQUIRE_THAT(src, - IsConstraint(_A("iterable_or_small_value_type"), - _A("max_four_bytes"), "T")); - REQUIRE_THAT(src, - IsConstraint(_A("iterable_or_small_value_type"), - _A("iterable_with_value_type"), "T")); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } + { + auto j = generate_class_json(diagram, *model); - REQUIRE_THAT(src, - IsConstraint(_A("E"), - _A("greater_than_with_requires"), "T1,T3")); + using namespace json; - REQUIRE_THAT(src, - IsConstraint( - _A("F"), _A("greater_than_simple"), "T1,T3")); + REQUIRE(IsConcept(j, "greater_than_simple")); + REQUIRE(IsConcept(j, "greater_than_with_requires")); + REQUIRE(IsConcept(j, "max_four_bytes")); + REQUIRE(IsConcept(j, "iterable")); + REQUIRE(IsConcept(j, "has_value_type")); + REQUIRE(IsConcept(j, "convertible_to_string")); + REQUIRE(IsConcept(j, "iterable_with_value_type")); + REQUIRE(IsConcept(j, "iterable_or_small_value_type")); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_json(config.output_directory(), diagram->name + ".json", j); + } + { + auto src = generate_class_mermaid(diagram, *model); + + mermaid::AliasMatcher _A(src); + using mermaid::IsConcept; + using mermaid::IsConceptRequirement; + using mermaid::IsConstraint; + + // Check if all classes exist + REQUIRE_THAT(src, IsConcept(_A("greater_than_simple"))); + REQUIRE_THAT(src, IsConcept(_A("greater_than_with_requires"))); + REQUIRE_THAT(src, IsConcept(_A("max_four_bytes"))); + REQUIRE_THAT(src, IsConcept(_A("iterable"))); + REQUIRE_THAT(src, IsConcept(_A("has_value_type"))); + REQUIRE_THAT(src, IsConcept(_A("convertible_to_string"))); + REQUIRE_THAT(src, IsConcept(_A("iterable_with_value_type"))); + REQUIRE_THAT(src, IsConcept(_A("iterable_or_small_value_type"))); + + REQUIRE_THAT(src, + IsConceptRequirement(_A("greater_than_with_requires"), + "sizeof (l) > sizeof (r)")); + + REQUIRE_THAT( + src, IsConceptRequirement(_A("iterable"), + "container.begin()")); REQUIRE_THAT( src, + IsConceptRequirement(_A("iterable"), "container.end()")); + + #if (LLVM_VERSION_MAJOR == 13) || (LLVM_VERSION_MAJOR == 14) + REQUIRE_THAT(src, + IsConceptRequirement( + _A("convertible_to_string"), "std::string({s})")); + #else + REQUIRE_THAT(src, + IsConceptRequirement( + _A("convertible_to_string"), "std::string{s}")); + #endif + REQUIRE_THAT(src, + IsConceptRequirement(_A("convertible_to_string"), + "{std::to_string(s)} noexcept")); + REQUIRE_THAT(src, + IsConceptRequirement(_A("convertible_to_string"), + "{std::to_string(s)} -> std::same_as")); + + // Check if class templates exist + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("B"))); + REQUIRE_THAT(src, IsClass(_A("C"))); + REQUIRE_THAT(src, IsClass(_A("D"))); REQUIRE_THAT(src, IsClass(_A("E"))); + REQUIRE_THAT(src, IsClass(_A("F"))); + + // Check if all relationships exist + REQUIRE_THAT(src, + IsConstraint( + _A("A"), _A("max_four_bytes"), "T")); + + REQUIRE_THAT(src, + IsConstraint(_A("D"), + _A("max_four_bytes"), "T2")); + REQUIRE_THAT(src, + IsConstraint(_A("D"), + _A("max_four_bytes"), "T5")); + REQUIRE_THAT(src, + IsConstraint(_A("D"), + _A("iterable"), "T1")); + REQUIRE_THAT(src, + IsConstraint(_A("D"), + _A("iterable"), "T3")); + + REQUIRE_THAT(src, + IsConstraint(_A("iterable_with_value_type"), + _A("has_value_type"), "T")); + + REQUIRE_THAT(src, + IsConstraint(_A("iterable_or_small_value_type"), + _A("max_four_bytes"), "T")); + REQUIRE_THAT(src, + IsConstraint(_A("iterable_or_small_value_type"), + _A("iterable_with_value_type"), "T")); + + REQUIRE_THAT(src, + IsConstraint(_A("E"), + _A("greater_than_with_requires"), "T1,T3")); + + REQUIRE_THAT(src, + IsConstraint( + _A("F"), _A("greater_than_simple"), + "T1,T3")); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t00057/test_case.h b/tests/t00057/test_case.h index 1a7331ea..fcbdfdcf 100644 --- a/tests/t00057/test_case.h +++ b/tests/t00057/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00057", "[test-case][class]") +TEST_CASE("t00057") { + using namespace clanguml::test; + auto [config, db] = load_config("t00057"); auto diagram = config.diagrams["t00057_class"]; @@ -28,86 +30,110 @@ TEST_CASE("t00057", "[test-case][class]") REQUIRE(model->name() == "t00057_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "t00057_A")); + REQUIRE(IsClass(src, "t00057_B")); + REQUIRE(IsClass(src, "t00057_C")); + REQUIRE(IsUnion(src, "t00057_D")); + REQUIRE(IsClass(src, "t00057_E")); + REQUIRE(IsClass(src, "t00057_F")); + REQUIRE(IsClass(src, "t00057_G")); + REQUIRE(!IsClass(src, "(anonymous)")); + REQUIRE(IsClass(src, "t00057_R")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsAggregation(src, "t00057_R", "t00057_A", "a")); + REQUIRE(IsAggregation(src, "t00057_R", "t00057_B", "b")); + REQUIRE(IsAssociation(src, "t00057_R", "t00057_C", "c")); + REQUIRE(IsAggregation(src, "t00057_R", "t00057_D", "d")); + REQUIRE(IsAssociation(src, "t00057_R", "t00057_E", "e")); + REQUIRE(IsAssociation(src, "t00057_R", "t00057_F", "f")); + REQUIRE(IsAggregation( + src, "t00057_E", "t00057_E::(coordinates)", "coordinates")); + REQUIRE(IsAggregation( + src, "t00057_E", "t00057_E::(height)", "height")); + }); - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("t00057_A"))); - REQUIRE_THAT(src, IsClass(_A("t00057_B"))); - REQUIRE_THAT(src, IsClass(_A("t00057_C"))); - REQUIRE_THAT(src, IsUnion(_A("t00057_D"))); - REQUIRE_THAT(src, IsClass(_A("t00057_E"))); - REQUIRE_THAT(src, IsClass(_A("t00057_F"))); - REQUIRE_THAT(src, IsClass(_A("t00057_G"))); - REQUIRE_THAT(src, !IsClass(_A("(anonymous)"))); - REQUIRE_THAT(src, IsClass(_A("t00057_R"))); + /* + { + auto src = generate_class_puml(diagram, *model); + AliasMatcher _A(src); - // Check if all relationships exist - REQUIRE_THAT(src, IsAggregation(_A("t00057_R"), _A("t00057_A"), "+a")); - REQUIRE_THAT(src, IsAggregation(_A("t00057_R"), _A("t00057_B"), "+b")); - REQUIRE_THAT(src, IsAssociation(_A("t00057_R"), _A("t00057_C"), "+c")); - REQUIRE_THAT(src, IsAggregation(_A("t00057_R"), _A("t00057_D"), "+d")); - REQUIRE_THAT(src, IsAssociation(_A("t00057_R"), _A("t00057_E"), "+e")); - REQUIRE_THAT(src, IsAssociation(_A("t00057_R"), _A("t00057_F"), "+f")); - REQUIRE_THAT(src, - IsAggregation( - _A("t00057_E"), _A("t00057_E::(coordinates)"), "+coordinates")); - REQUIRE_THAT(src, - IsAggregation(_A("t00057_E"), _A("t00057_E::(height)"), "+height")); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + // Check if all classes exist + REQUIRE_THAT(src, IsClass(_A("t00057_A"))); + REQUIRE_THAT(src, IsClass(_A("t00057_B"))); + REQUIRE_THAT(src, IsClass(_A("t00057_C"))); + REQUIRE_THAT(src, IsUnion(_A("t00057_D"))); + REQUIRE_THAT(src, IsClass(_A("t00057_E"))); + REQUIRE_THAT(src, IsClass(_A("t00057_F"))); + REQUIRE_THAT(src, IsClass(_A("t00057_G"))); + REQUIRE_THAT(src, !IsClass(_A("(anonymous)"))); + REQUIRE_THAT(src, IsClass(_A("t00057_R"))); - { - auto j = generate_class_json(diagram, *model); + // Check if all relationships exist + REQUIRE_THAT(src, IsAggregation(_A("t00057_R"), _A("t00057_A"), + "+a")); REQUIRE_THAT(src, IsAggregation(_A("t00057_R"), _A("t00057_B"), + "+b")); REQUIRE_THAT(src, IsAssociation(_A("t00057_R"), _A("t00057_C"), + "+c")); REQUIRE_THAT(src, IsAggregation(_A("t00057_R"), _A("t00057_D"), + "+d")); REQUIRE_THAT(src, IsAssociation(_A("t00057_R"), _A("t00057_E"), + "+e")); REQUIRE_THAT(src, IsAssociation(_A("t00057_R"), _A("t00057_F"), + "+f")); REQUIRE_THAT(src, IsAggregation( _A("t00057_E"), + _A("t00057_E::(coordinates)"), "+coordinates")); REQUIRE_THAT(src, + IsAggregation(_A("t00057_E"), _A("t00057_E::(height)"), + "+height")); - using namespace json; + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - REQUIRE(get_element(j, "t00057_A").value()["type"] == "class"); - REQUIRE(get_element(j, "t00057_B").value()["type"] == "class"); - REQUIRE(get_element(j, "t00057_C").value()["type"] == "class"); - REQUIRE(get_element(j, "t00057_D").value()["type"] == "class"); - REQUIRE(get_element(j, "t00057_E").value()["type"] == "class"); - REQUIRE(get_element(j, "t00057_F").value()["type"] == "class"); - REQUIRE(get_element(j, "t00057_G").value()["type"] == "class"); - REQUIRE(get_element(j, "t00057_R").value()["type"] == "class"); + { + auto j = generate_class_json(diagram, *model); - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); + using namespace json; - mermaid::AliasMatcher _A(src); - using mermaid::IsUnion; + REQUIRE(get_element(j, "t00057_A").value()["type"] == "class"); + REQUIRE(get_element(j, "t00057_B").value()["type"] == "class"); + REQUIRE(get_element(j, "t00057_C").value()["type"] == "class"); + REQUIRE(get_element(j, "t00057_D").value()["type"] == "class"); + REQUIRE(get_element(j, "t00057_E").value()["type"] == "class"); + REQUIRE(get_element(j, "t00057_F").value()["type"] == "class"); + REQUIRE(get_element(j, "t00057_G").value()["type"] == "class"); + REQUIRE(get_element(j, "t00057_R").value()["type"] == "class"); - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("t00057_A"))); - REQUIRE_THAT(src, IsClass(_A("t00057_B"))); - REQUIRE_THAT(src, IsClass(_A("t00057_C"))); - REQUIRE_THAT(src, IsUnion(_A("t00057_D"))); - REQUIRE_THAT(src, IsClass(_A("t00057_E"))); - REQUIRE_THAT(src, IsClass(_A("t00057_F"))); - REQUIRE_THAT(src, IsClass(_A("t00057_G"))); - REQUIRE_THAT(src, !IsClass(_A("(anonymous)"))); - REQUIRE_THAT(src, IsClass(_A("t00057_R"))); + save_json(config.output_directory(), diagram->name + ".json", j); + } + { + auto src = generate_class_mermaid(diagram, *model); - // Check if all relationships exist - REQUIRE_THAT(src, IsAggregation(_A("t00057_R"), _A("t00057_A"), "+a")); - REQUIRE_THAT(src, IsAggregation(_A("t00057_R"), _A("t00057_B"), "+b")); - REQUIRE_THAT(src, IsAssociation(_A("t00057_R"), _A("t00057_C"), "+c")); - REQUIRE_THAT(src, IsAggregation(_A("t00057_R"), _A("t00057_D"), "+d")); - REQUIRE_THAT(src, IsAssociation(_A("t00057_R"), _A("t00057_E"), "+e")); - REQUIRE_THAT(src, IsAssociation(_A("t00057_R"), _A("t00057_F"), "+f")); - REQUIRE_THAT(src, - IsAggregation( - _A("t00057_E"), _A("t00057_E::(coordinates)"), "+coordinates")); - REQUIRE_THAT(src, - IsAggregation(_A("t00057_E"), _A("t00057_E::(height)"), "+height")); + mermaid::AliasMatcher _A(src); + using mermaid::IsUnion; - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + // Check if all classes exist + REQUIRE_THAT(src, IsClass(_A("t00057_A"))); + REQUIRE_THAT(src, IsClass(_A("t00057_B"))); + REQUIRE_THAT(src, IsClass(_A("t00057_C"))); + REQUIRE_THAT(src, IsUnion(_A("t00057_D"))); + REQUIRE_THAT(src, IsClass(_A("t00057_E"))); + REQUIRE_THAT(src, IsClass(_A("t00057_F"))); + REQUIRE_THAT(src, IsClass(_A("t00057_G"))); + REQUIRE_THAT(src, !IsClass(_A("(anonymous)"))); + REQUIRE_THAT(src, IsClass(_A("t00057_R"))); + + // Check if all relationships exist + REQUIRE_THAT(src, IsAggregation(_A("t00057_R"), _A("t00057_A"), + "+a")); REQUIRE_THAT(src, IsAggregation(_A("t00057_R"), _A("t00057_B"), + "+b")); REQUIRE_THAT(src, IsAssociation(_A("t00057_R"), _A("t00057_C"), + "+c")); REQUIRE_THAT(src, IsAggregation(_A("t00057_R"), _A("t00057_D"), + "+d")); REQUIRE_THAT(src, IsAssociation(_A("t00057_R"), _A("t00057_E"), + "+e")); REQUIRE_THAT(src, IsAssociation(_A("t00057_R"), _A("t00057_F"), + "+f")); REQUIRE_THAT(src, IsAggregation( _A("t00057_E"), + _A("t00057_E::(coordinates)"), "+coordinates")); REQUIRE_THAT(src, + IsAggregation(_A("t00057_E"), _A("t00057_E::(height)"), + "+height")); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + } + */ } \ No newline at end of file diff --git a/tests/t00058/.clang-uml b/tests/t00058/.clang-uml index a49be4ca..b238602e 100644 --- a/tests/t00058/.clang-uml +++ b/tests/t00058/.clang-uml @@ -8,5 +8,8 @@ diagrams: - clanguml::t00058 using_namespace: clanguml::t00058 plantuml: + after: + - '{{ alias("same_as_first_type") }} ..> {{ alias("first_type") }}' + mermaid: after: - '{{ alias("same_as_first_type") }} ..> {{ alias("first_type") }}' \ No newline at end of file diff --git a/tests/t00058/test_case.h b/tests/t00058/test_case.h index 1a31bb60..9a0581ae 100644 --- a/tests/t00058/test_case.h +++ b/tests/t00058/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00058", "[test-case][class]") +TEST_CASE("t00058") { + using namespace clanguml::test; + auto [config, db] = load_config("t00058"); auto diagram = config.diagrams["t00058_class"]; @@ -28,96 +30,134 @@ TEST_CASE("t00058", "[test-case][class]") REQUIRE(model->name() == "t00058_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM( + config, diagram, *model, + [](const auto &src) { + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate( + src, "B>")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsConcept(src, "same_as_first_type")); - REQUIRE_THAT(src, IsClassTemplate("A", "int,int,double,std::string")); - REQUIRE_THAT( - src, IsClassTemplate("B", "int,std::string,int,double,A")); + REQUIRE(IsConstraint(src, "A", + "same_as_first_type", "T,Args...")); - REQUIRE_THAT(src, IsConcept(_A("same_as_first_type"))); + REQUIRE(IsConstraint(src, "B", + "same_as_first_type", "T,Args...")); - REQUIRE_THAT(src, - IsConstraint(_A("A"), - _A("same_as_first_type"), "T,Args...")); + REQUIRE(IsAggregation( + src, "R", "A", "aa")); + REQUIRE(IsAggregation( + src, "R", "B>", "bb")); - REQUIRE_THAT(src, - IsConstraint(_A("B"), - _A("same_as_first_type"), "T,Args...")); + REQUIRE(IsInstantiation( + src, "A", "A")); + REQUIRE(IsInstantiation(src, "B", + "B>")); + }, + [](const plantuml_t &src) { + // TODO: This dependency has to be added manually in config file + // so it doesn't work in JSON + REQUIRE(IsDependency( + src, "same_as_first_type", "first_type")); + }, + [](const mermaid_t &src) { + // TODO: This dependency has to be added manually in config file + // so it doesn't work in JSON + REQUIRE(IsDependency( + src, "same_as_first_type", "first_type")); + }); - REQUIRE_THAT(src, - IsAggregation(_A("R"), _A("A"), "+aa")); - REQUIRE_THAT(src, - IsAggregation(_A("R"), - _A("B>"), "+bb")); + /* + { + auto src = generate_class_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE_THAT(src, - IsInstantiation( - _A("A"), _A("A"))); - REQUIRE_THAT(src, - IsInstantiation(_A("B"), - _A("B>"))); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, - IsDependency(_A("same_as_first_type"), - _A("first_type"))); + REQUIRE_THAT(src, IsClassTemplate("A", + "int,int,double,std::string")); REQUIRE_THAT( src, IsClassTemplate("B", + "int,std::string,int,double,A")); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + REQUIRE_THAT(src, IsConcept(_A("same_as_first_type"))); - { - auto j = generate_class_json(diagram, *model); + REQUIRE_THAT(src, + IsConstraint(_A("A"), + _A("same_as_first_type"), "T,Args...")); - using namespace json; + REQUIRE_THAT(src, + IsConstraint(_A("B"), + _A("same_as_first_type"), "T,Args...")); - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B>")); + REQUIRE_THAT(src, + IsAggregation(_A("R"), _A("A"), + "+aa")); REQUIRE_THAT(src, IsAggregation(_A("R"), + _A("B>"), "+bb")); - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); + REQUIRE_THAT(src, + IsInstantiation( + _A("A"), _A("A"))); + REQUIRE_THAT(src, + IsInstantiation(_A("B"), + _A("B>"))); - mermaid::AliasMatcher _A(src); - using mermaid::IsConcept; - using mermaid::IsConstraint; + REQUIRE_THAT(src, + IsDependency(_A("same_as_first_type"), + _A("first_type"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT( - src, IsClass(_A("B>"))); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - REQUIRE_THAT(src, IsConcept(_A("same_as_first_type"))); + { + auto j = generate_class_json(diagram, *model); - REQUIRE_THAT(src, - IsConstraint(_A("A"), - _A("same_as_first_type"), "T,Args...")); + using namespace json; - REQUIRE_THAT(src, - IsConstraint(_A("B"), - _A("same_as_first_type"), "T,Args...")); + REQUIRE(IsClass(j, "A")); + REQUIRE(IsClass(j, "B>")); - REQUIRE_THAT(src, - IsAggregation(_A("R"), _A("A"), "+aa")); - REQUIRE_THAT(src, - IsAggregation(_A("R"), - _A("B>"), "+bb")); + save_json(config.output_directory(), diagram->name + ".json", j); + } + { + auto src = generate_class_mermaid(diagram, *model); - REQUIRE_THAT(src, - IsInstantiation( - _A("A"), _A("A"))); - REQUIRE_THAT(src, - IsInstantiation(_A("B"), - _A("B>"))); + mermaid::AliasMatcher _A(src); + using mermaid::IsConcept; + using mermaid::IsConstraint; - // TODO - // REQUIRE_THAT(src, - // IsDependency(_A("same_as_first_type"), - // _A("first_type"))); + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT( + src, IsClass(_A("B>"))); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE_THAT(src, IsConcept(_A("same_as_first_type"))); + + REQUIRE_THAT(src, + IsConstraint(_A("A"), + _A("same_as_first_type"), "T,Args...")); + + REQUIRE_THAT(src, + IsConstraint(_A("B"), + _A("same_as_first_type"), "T,Args...")); + + REQUIRE_THAT(src, + IsAggregation(_A("R"), _A("A"), + "+aa")); REQUIRE_THAT(src, IsAggregation(_A("R"), + _A("B>"), "+bb")); + + REQUIRE_THAT(src, + IsInstantiation( + _A("A"), _A("A"))); + REQUIRE_THAT(src, + IsInstantiation(_A("B"), + _A("B>"))); + + // TODO + // REQUIRE_THAT(src, + // IsDependency(_A("same_as_first_type"), + // _A("first_type"))); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t00059/test_case.h b/tests/t00059/test_case.h index 851b1e87..435818db 100644 --- a/tests/t00059/test_case.h +++ b/tests/t00059/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00059", "[test-case][class]") +TEST_CASE("t00059") { + using namespace clanguml::test; + auto [config, db] = load_config("t00059"); auto diagram = config.diagrams["t00059_class"]; @@ -28,138 +30,186 @@ TEST_CASE("t00059", "[test-case][class]") REQUIRE(model->name() == "t00059_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsConcept(src, "fruit_c")); + REQUIRE(IsConcept(src, "apple_c")); + REQUIRE(IsConcept(src, "orange_c")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsConstraint(src, "apple_c", "fruit_c", "T", "up")); + REQUIRE(IsConstraint(src, "orange_c", "fruit_c", "T", "up")); - REQUIRE_THAT(src, IsConcept(_A("fruit_c"))); - REQUIRE_THAT(src, IsConcept(_A("apple_c"))); - REQUIRE_THAT(src, IsConcept(_A("orange_c"))); + REQUIRE(IsConceptRequirement(src, "apple_c", "t.get_sweetness()")); + REQUIRE(IsConceptRequirement(src, "apple_c", "t.get_bitterness()")); - REQUIRE_THAT( - src, IsConstraint(_A("apple_c"), _A("fruit_c"), "T", "up")); - REQUIRE_THAT( - src, IsConstraint(_A("orange_c"), _A("fruit_c"), "T", "up")); + REQUIRE(IsClass(src, "gala_apple")); + REQUIRE(IsClass(src, "empire_apple")); + REQUIRE(IsClass(src, "valencia_orange")); + REQUIRE(IsClass(src, "lima_orange")); + REQUIRE(IsClass(src, "R")); - REQUIRE_THAT( - src, IsConceptRequirement(_A("apple_c"), "t.get_sweetness()")); - REQUIRE_THAT( - src, IsConceptRequirement(_A("apple_c"), "t.get_bitterness()")); + REQUIRE(IsClassTemplate(src, "fruit_factory")); - REQUIRE_THAT(src, IsClass(_A("gala_apple"))); - REQUIRE_THAT(src, IsClass(_A("empire_apple"))); - REQUIRE_THAT(src, IsClass(_A("valencia_orange"))); - REQUIRE_THAT(src, IsClass(_A("lima_orange"))); - REQUIRE_THAT(src, IsClass(_A("R"))); + REQUIRE(IsDependency(src, "fruit_factory", + "gala_apple", "up")); + REQUIRE(IsDependency(src, "fruit_factory", + "valencia_orange", "up")); - REQUIRE_THAT( - src, IsClassTemplate("fruit_factory", "apple_c TA,orange_c TO")); + REQUIRE(IsDependency(src, "fruit_factory", + "empire_apple", "up")); + REQUIRE(IsDependency(src, "fruit_factory", + "lima_orange", "up")); - REQUIRE_THAT(src, - IsDependency(_A("fruit_factory"), - _A("gala_apple"), "up")); - REQUIRE_THAT(src, - IsDependency(_A("fruit_factory"), - _A("valencia_orange"), "up")); + REQUIRE(IsAggregation(src, "R", + "fruit_factory", "factory_1", "", "", + "up")); + REQUIRE(IsAggregation(src, "R", + "fruit_factory", "factory_2", "", "", + "up")); - REQUIRE_THAT(src, - IsDependency(_A("fruit_factory"), - _A("empire_apple"), "up")); - REQUIRE_THAT(src, - IsDependency(_A("fruit_factory"), - _A("lima_orange"), "up")); + REQUIRE(IsInstantiation(src, "fruit_factory", + "fruit_factory", "up")); + REQUIRE(IsInstantiation(src, "fruit_factory", + "fruit_factory", "up")); + }); + /* - REQUIRE_THAT(src, - IsAggregation(_A("R"), - _A("fruit_factory"), "+factory_1", - "", "", "up")); - REQUIRE_THAT(src, - IsAggregation(_A("R"), - _A("fruit_factory"), "+factory_2", "", - "", "up")); + { + auto src = generate_class_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE_THAT(src, - IsInstantiation(_A("fruit_factory"), - _A("fruit_factory"), "up")); - REQUIRE_THAT(src, - IsInstantiation(_A("fruit_factory"), - _A("fruit_factory"), "up")); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + REQUIRE_THAT(src, IsConcept(_A("fruit_c"))); + REQUIRE_THAT(src, IsConcept(_A("apple_c"))); + REQUIRE_THAT(src, IsConcept(_A("orange_c"))); - { - auto j = generate_class_json(diagram, *model); + REQUIRE_THAT( + src, IsConstraint(_A("apple_c"), _A("fruit_c"), "T", + "up")); REQUIRE_THAT( src, IsConstraint(_A("orange_c"), + _A("fruit_c"), "T", "up")); - using namespace json; + REQUIRE_THAT( + src, IsConceptRequirement(_A("apple_c"), + "t.get_sweetness()")); REQUIRE_THAT( src, + IsConceptRequirement(_A("apple_c"), "t.get_bitterness()")); - REQUIRE(IsConcept(j, "fruit_c")); - REQUIRE(IsConcept(j, "apple_c")); - REQUIRE(IsConcept(j, "orange_c")); + REQUIRE_THAT(src, IsClass(_A("gala_apple"))); + REQUIRE_THAT(src, IsClass(_A("empire_apple"))); + REQUIRE_THAT(src, IsClass(_A("valencia_orange"))); + REQUIRE_THAT(src, IsClass(_A("lima_orange"))); + REQUIRE_THAT(src, IsClass(_A("R"))); - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); + REQUIRE_THAT( + src, IsClassTemplate("fruit_factory", "apple_c TA,orange_c + TO")); - mermaid::AliasMatcher _A(src); - using mermaid::IsConcept; - using mermaid::IsConceptRequirement; - using mermaid::IsConstraint; + REQUIRE_THAT(src, + IsDependency(_A("fruit_factory"), + _A("gala_apple"), "up")); + REQUIRE_THAT(src, + IsDependency(_A("fruit_factory"), + _A("valencia_orange"), "up")); - REQUIRE_THAT(src, IsConcept(_A("fruit_c"))); - REQUIRE_THAT(src, IsConcept(_A("apple_c"))); - REQUIRE_THAT(src, IsConcept(_A("orange_c"))); + REQUIRE_THAT(src, + IsDependency(_A("fruit_factory"), + _A("empire_apple"), "up")); + REQUIRE_THAT(src, + IsDependency(_A("fruit_factory"), + _A("lima_orange"), "up")); - REQUIRE_THAT( - src, IsConstraint(_A("apple_c"), _A("fruit_c"), "T")); - REQUIRE_THAT( - src, IsConstraint(_A("orange_c"), _A("fruit_c"), "T")); + REQUIRE_THAT(src, + IsAggregation(_A("R"), + _A("fruit_factory"), + "+factory_1", + "", "", "up")); + REQUIRE_THAT(src, + IsAggregation(_A("R"), + _A("fruit_factory"), "+factory_2", + "", + "", "up")); - REQUIRE_THAT( - src, IsConceptRequirement(_A("apple_c"), "t.get_sweetness()")); - REQUIRE_THAT( - src, IsConceptRequirement(_A("apple_c"), "t.get_bitterness()")); + REQUIRE_THAT(src, + IsInstantiation(_A("fruit_factory"), + _A("fruit_factory"), "up")); + REQUIRE_THAT(src, + IsInstantiation(_A("fruit_factory"), + _A("fruit_factory"), "up")); - REQUIRE_THAT(src, IsClass(_A("gala_apple"))); - REQUIRE_THAT(src, IsClass(_A("empire_apple"))); - REQUIRE_THAT(src, IsClass(_A("valencia_orange"))); - REQUIRE_THAT(src, IsClass(_A("lima_orange"))); - REQUIRE_THAT(src, IsClass(_A("R"))); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - REQUIRE_THAT(src, IsClass(_A("fruit_factory"))); + { + auto j = generate_class_json(diagram, *model); - REQUIRE_THAT(src, - IsDependency(_A("fruit_factory"), - _A("gala_apple"))); - REQUIRE_THAT(src, - IsDependency(_A("fruit_factory"), - _A("valencia_orange"))); + using namespace json; - REQUIRE_THAT(src, - IsDependency(_A("fruit_factory"), - _A("empire_apple"))); - REQUIRE_THAT(src, - IsDependency(_A("fruit_factory"), - _A("lima_orange"))); + REQUIRE(IsConcept(j, "fruit_c")); + REQUIRE(IsConcept(j, "apple_c")); + REQUIRE(IsConcept(j, "orange_c")); - REQUIRE_THAT(src, - IsAggregation(_A("R"), - _A("fruit_factory"), "+factory_1")); - REQUIRE_THAT(src, - IsAggregation(_A("R"), - _A("fruit_factory"), "+factory_2")); + save_json(config.output_directory(), diagram->name + ".json", j); + } + { + auto src = generate_class_mermaid(diagram, *model); - REQUIRE_THAT(src, - IsInstantiation(_A("fruit_factory"), - _A("fruit_factory"))); - REQUIRE_THAT(src, - IsInstantiation(_A("fruit_factory"), - _A("fruit_factory"))); + mermaid::AliasMatcher _A(src); + using mermaid::IsConcept; + using mermaid::IsConceptRequirement; + using mermaid::IsConstraint; - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE_THAT(src, IsConcept(_A("fruit_c"))); + REQUIRE_THAT(src, IsConcept(_A("apple_c"))); + REQUIRE_THAT(src, IsConcept(_A("orange_c"))); + + REQUIRE_THAT( + src, IsConstraint(_A("apple_c"), _A("fruit_c"), "T")); + REQUIRE_THAT( + src, IsConstraint(_A("orange_c"), _A("fruit_c"), "T")); + + REQUIRE_THAT( + src, IsConceptRequirement(_A("apple_c"), + "t.get_sweetness()")); REQUIRE_THAT( src, + IsConceptRequirement(_A("apple_c"), "t.get_bitterness()")); + + REQUIRE_THAT(src, IsClass(_A("gala_apple"))); + REQUIRE_THAT(src, IsClass(_A("empire_apple"))); + REQUIRE_THAT(src, IsClass(_A("valencia_orange"))); + REQUIRE_THAT(src, IsClass(_A("lima_orange"))); + REQUIRE_THAT(src, IsClass(_A("R"))); + + REQUIRE_THAT(src, IsClass(_A("fruit_factory"))); + + REQUIRE_THAT(src, + IsDependency(_A("fruit_factory"), + _A("gala_apple"))); + REQUIRE_THAT(src, + IsDependency(_A("fruit_factory"), + _A("valencia_orange"))); + + REQUIRE_THAT(src, + IsDependency(_A("fruit_factory"), + _A("empire_apple"))); + REQUIRE_THAT(src, + IsDependency(_A("fruit_factory"), + _A("lima_orange"))); + + REQUIRE_THAT(src, + IsAggregation(_A("R"), + _A("fruit_factory"), + "+factory_1")); REQUIRE_THAT(src, IsAggregation(_A("R"), + _A("fruit_factory"), + "+factory_2")); + + REQUIRE_THAT(src, + IsInstantiation(_A("fruit_factory"), + _A("fruit_factory"))); + REQUIRE_THAT(src, + IsInstantiation(_A("fruit_factory"), + _A("fruit_factory"))); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t00060/test_case.h b/tests/t00060/test_case.h index 528bfcd4..87251cea 100644 --- a/tests/t00060/test_case.h +++ b/tests/t00060/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00060", "[test-case][class]") +TEST_CASE("t00060") { + using namespace clanguml::test; + auto [config, db] = load_config("t00060"); auto diagram = config.diagrams["t00060_class"]; @@ -28,59 +30,72 @@ TEST_CASE("t00060", "[test-case][class]") REQUIRE(model->name() == "t00060_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClass(src, "C")); + REQUIRE(IsClass(src, "D")); + REQUIRE(!IsClass(src, "E")); + REQUIRE(!IsClass(src, "F")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsClassTemplate(src, "G")); + REQUIRE(IsClassTemplate(src, "H")); + }); + /* +{ + auto src = generate_class_puml(diagram, *model); + AliasMatcher _A(src); - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, !IsClass(_A("E"))); - REQUIRE_THAT(src, !IsClass(_A("F"))); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - // Check if class templates exist - REQUIRE_THAT(src, IsClassTemplate("G", "T")); - REQUIRE_THAT(src, IsClassTemplate("H", "T,P")); + // Check if all classes exist + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("B"))); + REQUIRE_THAT(src, IsClass(_A("C"))); + REQUIRE_THAT(src, IsClass(_A("D"))); + REQUIRE_THAT(src, !IsClass(_A("E"))); + REQUIRE_THAT(src, !IsClass(_A("F"))); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + // Check if class templates exist + REQUIRE_THAT(src, IsClassTemplate("G", "T")); + REQUIRE_THAT(src, IsClassTemplate("H", "T,P")); - { - auto j = generate_class_json(diagram, *model); + save_puml(config.output_directory(), diagram->name + ".puml", src); +} - using namespace json; +{ + auto j = generate_class_json(diagram, *model); - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - REQUIRE(IsClass(j, "C")); - REQUIRE(IsClass(j, "D")); - REQUIRE(!IsClass(j, "E")); - REQUIRE(!IsClass(j, "F")); + using namespace json; - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); + REQUIRE(IsClass(j, "A")); + REQUIRE(IsClass(j, "B")); + REQUIRE(IsClass(j, "C")); + REQUIRE(IsClass(j, "D")); + REQUIRE(!IsClass(j, "E")); + REQUIRE(!IsClass(j, "F")); - mermaid::AliasMatcher _A(src); + save_json(config.output_directory(), diagram->name + ".json", j); +} +{ + auto src = generate_class_mermaid(diagram, *model); - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, !IsClass(_A("E"))); - REQUIRE_THAT(src, !IsClass(_A("F"))); + mermaid::AliasMatcher _A(src); - // Check if class templates exist - REQUIRE_THAT(src, IsClass(_A("G"))); - REQUIRE_THAT(src, IsClass(_A("H"))); + // Check if all classes exist + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("B"))); + REQUIRE_THAT(src, IsClass(_A("C"))); + REQUIRE_THAT(src, IsClass(_A("D"))); + REQUIRE_THAT(src, !IsClass(_A("E"))); + REQUIRE_THAT(src, !IsClass(_A("F"))); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + // Check if class templates exist + REQUIRE_THAT(src, IsClass(_A("G"))); + REQUIRE_THAT(src, IsClass(_A("H"))); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", src); +} + */ } \ No newline at end of file diff --git a/tests/t00061/test_case.h b/tests/t00061/test_case.h index 64b5fdb1..a2086cf8 100644 --- a/tests/t00061/test_case.h +++ b/tests/t00061/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00061", "[test-case][class]") +TEST_CASE("t00061") { + using namespace clanguml::test; + auto [config, db] = load_config("t00061"); auto diagram = config.diagrams["t00061_class"]; @@ -28,42 +30,49 @@ TEST_CASE("t00061", "[test-case][class]") REQUIRE(model->name() == "t00061_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(!IsClass(src, "B")); + REQUIRE(!IsClass(src, "C")); + }); + /* +{ + auto src = generate_class_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, !IsClass(_A("B"))); - REQUIRE_THAT(src, !IsClass(_A("C"))); + // Check if all classes exist + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, !IsClass(_A("B"))); + REQUIRE_THAT(src, !IsClass(_A("C"))); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + save_puml(config.output_directory(), diagram->name + ".puml", src); +} - { - auto j = generate_class_json(diagram, *model); +{ + auto j = generate_class_json(diagram, *model); - using namespace json; + using namespace json; - REQUIRE(IsClass(j, "A")); - REQUIRE(!IsClass(j, "B")); - REQUIRE(!IsClass(j, "C")); + REQUIRE(IsClass(j, "A")); + REQUIRE(!IsClass(j, "B")); + REQUIRE(!IsClass(j, "C")); - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); + save_json(config.output_directory(), diagram->name + ".json", j); +} +{ + auto src = generate_class_mermaid(diagram, *model); - mermaid::AliasMatcher _A(src); + mermaid::AliasMatcher _A(src); - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, !IsClass(_A("B"))); - REQUIRE_THAT(src, !IsClass(_A("C"))); + // Check if all classes exist + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, !IsClass(_A("B"))); + REQUIRE_THAT(src, !IsClass(_A("C"))); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", src); +} + */ } \ No newline at end of file diff --git a/tests/t00062/test_case.h b/tests/t00062/test_case.h index afa222c1..b266a93f 100644 --- a/tests/t00062/test_case.h +++ b/tests/t00062/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00062", "[test-case][class]") +TEST_CASE("t00062") { + using namespace clanguml::test; + auto [config, db] = load_config("t00062"); auto diagram = config.diagrams["t00062_class"]; @@ -28,6 +30,55 @@ TEST_CASE("t00062", "[test-case][class]") REQUIRE(model->name() == "t00062_class"); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(!src.contains("type-parameter-")); + + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A")); + + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A")); + + REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A>")); + REQUIRE(IsClassTemplate(src, "A>")); + + REQUIRE(IsField(src, "A", "u", "U &")); + REQUIRE(IsField(src, "A", "u", "U **")); + REQUIRE(IsField(src, "A", "u", "U ***")); + REQUIRE(IsField(src, "A", "u", "U &&")); + REQUIRE(IsField(src, "A", "u", "const U &")); + REQUIRE(IsField(src, "A", "c", "C &")); + REQUIRE(IsField(src, "A", "m", "M C::*")); + + REQUIRE(IsInstantiation(src, "A", "A")); + REQUIRE(IsInstantiation(src, "A", "A")); + REQUIRE(IsInstantiation(src, "A", "A")); + REQUIRE(IsInstantiation(src, "A", "A")); + + REQUIRE(IsInstantiation(src, "A", "A")); + REQUIRE( + IsInstantiation(src, "A", "A")); + + REQUIRE(IsInstantiation(src, "A", "A")); + REQUIRE(IsInstantiation(src, "A", "A")); + + REQUIRE(IsInstantiation(src, "A", "A")); + REQUIRE(IsInstantiation(src, "A", "A")); + REQUIRE(IsInstantiation(src, "A", "A>")); + REQUIRE(IsInstantiation(src, "A", "A>")); + }); + + /* { auto src = generate_class_puml(diagram, *model); AliasMatcher _A(src); @@ -148,5 +199,5 @@ TEST_CASE("t00062", "[test-case][class]") REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A>"))); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } \ No newline at end of file diff --git a/tests/t00063/test_case.h b/tests/t00063/test_case.h index 8eac17bc..8c87872f 100644 --- a/tests/t00063/test_case.h +++ b/tests/t00063/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00063", "[test-case][class]") +TEST_CASE("t00063") { + using namespace clanguml::test; + auto [config, db] = load_config("t00063"); auto diagram = config.diagrams["t00063_class"]; @@ -28,41 +30,49 @@ TEST_CASE("t00063", "[test-case][class]") REQUIRE(model->name() == "t00063_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(!IsEnum(src, "B")); + REQUIRE(!IsEnum(src, "C")); + }); + /* + { + auto src = generate_class_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, !IsEnum(_A("B"))); - REQUIRE_THAT(src, !IsEnum(_A("C"))); + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, !IsEnum(_A("B"))); + REQUIRE_THAT(src, !IsEnum(_A("C"))); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - { - auto j = generate_class_json(diagram, *model); + { + auto j = generate_class_json(diagram, *model); - using namespace json; + using namespace json; - REQUIRE(IsClass(j, "A")); - REQUIRE(!IsEnum(j, "B")); - REQUIRE(!IsEnum(j, "C")); + REQUIRE(IsClass(j, "A")); + REQUIRE(!IsEnum(j, "B")); + REQUIRE(!IsEnum(j, "C")); - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); + save_json(config.output_directory(), diagram->name + ".json", j); + } + { + auto src = generate_class_mermaid(diagram, *model); - mermaid::AliasMatcher _A(src); - using mermaid::IsEnum; + mermaid::AliasMatcher _A(src); + using mermaid::IsEnum; - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, !IsEnum(_A("B"))); - REQUIRE_THAT(src, !IsEnum(_A("C"))); + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, !IsEnum(_A("B"))); + REQUIRE_THAT(src, !IsEnum(_A("C"))); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + } + */ } \ No newline at end of file diff --git a/tests/t00064/test_case.h b/tests/t00064/test_case.h index c813798a..6089a397 100644 --- a/tests/t00064/test_case.h +++ b/tests/t00064/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00064", "[test-case][class]") +TEST_CASE("t00064") { + using namespace clanguml::test; + auto [config, db] = load_config("t00064"); auto diagram = config.diagrams["t00064_class"]; @@ -28,6 +30,45 @@ TEST_CASE("t00064", "[test-case][class]") REQUIRE(model->name() == "t00064_class"); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(!src.contains("type-parameter-")); + + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClass(src, "C")); + REQUIRE(IsClass(src, "R")); + + REQUIRE(IsClassTemplate(src, "type_list")); + REQUIRE(IsClassTemplate(src, "type_list")); + REQUIRE(IsClassTemplate(src, "type_list")); + + REQUIRE(IsClassTemplate(src, "head")); + REQUIRE(IsClassTemplate(src, "head>")); + REQUIRE(IsClassTemplate(src, "type_group_pair")); + REQUIRE(IsClassTemplate( + src, "type_group_pair,type_list>")); + REQUIRE(IsClassTemplate( + src, "type_group_pair,type_list>")); + + REQUIRE(IsClassTemplate(src, "optional_ref")); + + REQUIRE(IsClassTemplate(src, + "type_group_pair_it,type_list>")); + REQUIRE(IsMethod(src, "get", "ref_t", "unsigned int i")); +#if LLVM_VERSION_MAJOR < 16 + REQUIRE(IsMethod( + src, "getp", "value_type const*", "unsigned int i")); + REQUIRE(IsMethod( + src, "find", "unsigned int", "value_type const& v")); +#else + REQUIRE( + IsMethod(src, "getp", "const value_type *", "unsigned int i")); + REQUIRE( + IsMethod(src, + "find", "unsigned int", "const value_type & v")); +#endif + }); + /* { auto src = generate_class_puml(diagram, *model); AliasMatcher _A(src); @@ -137,4 +178,5 @@ TEST_CASE("t00064", "[test-case][class]") save_mermaid(config.output_directory(), diagram->name + ".mmd", src); } + */ } \ No newline at end of file diff --git a/tests/t00065/test_case.h b/tests/t00065/test_case.h index 51ccc4c5..7c127154 100644 --- a/tests/t00065/test_case.h +++ b/tests/t00065/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00065", "[test-case][class]") +TEST_CASE("t00065") { + using namespace clanguml::test; + auto [config, db] = load_config("t00065"); auto diagram = config.diagrams["t00065_class"]; @@ -28,48 +30,62 @@ TEST_CASE("t00065", "[test-case][class]") REQUIRE(model->name() == "t00065_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "R")); + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, {"detail", "AImpl"})); + REQUIRE(IsEnum(src, "XYZ")); + REQUIRE(IsEnum(src, "ABC")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsPackage("module1")); + REQUIRE(IsPackage("module2")); + REQUIRE(IsPackage("submodule1a")); + REQUIRE(IsPackage("concepts")); + }); + /* + { + auto src = generate_class_puml(diagram, *model); + AliasMatcher _A(src); - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("R"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("detail::AImpl"))); - REQUIRE_THAT(src, IsEnum(_A("XYZ"))); - REQUIRE_THAT(src, IsEnum(_A("ABC"))); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsPackage("module1")); - REQUIRE_THAT(src, IsPackage("module2")); - REQUIRE_THAT(src, IsPackage("submodule1a")); - REQUIRE_THAT(src, IsPackage("concepts")); + // Check if all classes exist + REQUIRE_THAT(src, IsClass(_A("R"))); + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("detail::AImpl"))); + REQUIRE_THAT(src, IsEnum(_A("XYZ"))); + REQUIRE_THAT(src, IsEnum(_A("ABC"))); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + REQUIRE_THAT(src, IsPackage("module1")); + REQUIRE_THAT(src, IsPackage("module2")); + REQUIRE_THAT(src, IsPackage("submodule1a")); + REQUIRE_THAT(src, IsPackage("concepts")); - { - auto j = generate_class_json(diagram, *model); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - using namespace json; + { + auto j = generate_class_json(diagram, *model); - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); + using namespace json; - mermaid::AliasMatcher _A(src); - using mermaid::IsEnum; + save_json(config.output_directory(), diagram->name + ".json", j); + } + { + auto src = generate_class_mermaid(diagram, *model); - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("R"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("detail::AImpl"))); - REQUIRE_THAT(src, IsEnum(_A("XYZ"))); - REQUIRE_THAT(src, IsEnum(_A("ABC"))); + mermaid::AliasMatcher _A(src); + using mermaid::IsEnum; - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + // Check if all classes exist + REQUIRE_THAT(src, IsClass(_A("R"))); + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("detail::AImpl"))); + REQUIRE_THAT(src, IsEnum(_A("XYZ"))); + REQUIRE_THAT(src, IsEnum(_A("ABC"))); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t00066/test_case.h b/tests/t00066/test_case.h index 37765b71..89959407 100644 --- a/tests/t00066/test_case.h +++ b/tests/t00066/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00066", "[test-case][class]") +TEST_CASE("t00066") { + using namespace clanguml::test; + auto [config, db] = load_config("t00066"); auto diagram = config.diagrams["t00066_class"]; @@ -28,98 +30,132 @@ TEST_CASE("t00066", "[test-case][class]") REQUIRE(model->name() == "t00066_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(!IsDependency(src, "A", "A")); - REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE(IsMethod(src,"A"))); + REQUIRE(IsMethod(src, "A", "void", "A &&")); + REQUIRE(IsMethod(src, "A", "void", "const A &")); - REQUIRE_THAT(src, !IsDependency(_A("A"), _A("A"))); + REQUIRE(IsMethod(src, "~A")); - REQUIRE_THAT(src, (IsMethod("A"))); - REQUIRE_THAT(src, (IsMethod("A", "void", "A &&"))); - REQUIRE_THAT( - src, (IsMethod("A", "void", "const A &"))); + REQUIRE(IsMethod(src,"basic_method"))); + REQUIRE(IsMethod(src,"static_method", "int"))); + REQUIRE(IsMethod(src,"const_method"))); + REQUIRE(IsMethod(src,"default_int", "int", "int i = 12"))); + REQUIRE(IsMethod(src, "default_string", "std::string", + "int i, std::string s = \"abc\"")); - REQUIRE_THAT(src, (IsMethod("~A"))); + REQUIRE(IsMethod(src, "size", "std::size_t")); - REQUIRE_THAT(src, (IsMethod("basic_method"))); - REQUIRE_THAT(src, (IsMethod("static_method", "int"))); - REQUIRE_THAT(src, (IsMethod("const_method"))); - REQUIRE_THAT( - src, (IsMethod("default_int", "int", "int i = 12"))); - REQUIRE_THAT(src, - (IsMethod("default_string", "std::string", - "int i, std::string s = \"abc\""))); + REQUIRE(IsMethod(src, "protected_method")); + REQUIRE(IsMethod(src, "private_method")); + REQUIRE(IsField(src, "public_member", "int")); + REQUIRE(IsField(src, "protected_member", "int")); + REQUIRE(IsField(src, "private_member", "int")); + REQUIRE( + (IsField(src,"auto_member", "const unsigned long")); - REQUIRE_THAT(src, (IsMethod("size", "std::size_t"))); + REQUIRE(IsField(src,"a_", "int")); + REQUIRE(IsField(src,"b_", "int")); + REQUIRE(IsField(src,"c_", "int")); + }); - REQUIRE_THAT(src, (IsMethod("protected_method"))); - REQUIRE_THAT(src, (IsMethod("private_method"))); - REQUIRE_THAT(src, (IsField("public_member", "int"))); - REQUIRE_THAT(src, (IsField("protected_member", "int"))); - REQUIRE_THAT(src, (IsField("private_member", "int"))); - REQUIRE_THAT(src, - (IsField("auto_member", "const unsigned long"))); + /* +{ + auto src = generate_class_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE_THAT(src, (IsField("a_", "int"))); - REQUIRE_THAT(src, (IsField("b_", "int"))); - REQUIRE_THAT(src, (IsField("c_", "int"))); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + REQUIRE_THAT(src, IsClass(_A("A"))); - { - auto j = generate_class_json(diagram, *model); + REQUIRE_THAT(src, !IsDependency(_A("A"), _A("A"))); - using namespace json; + REQUIRE_THAT(src, (IsMethod("A"))); + REQUIRE_THAT(src, (IsMethod("A", "void", "A &&"))); + REQUIRE_THAT( + src, (IsMethod("A", "void", "const A &"))); - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); + REQUIRE_THAT(src, (IsMethod("~A"))); - mermaid::AliasMatcher _A(src); - using mermaid::IsField; - using mermaid::IsMethod; + REQUIRE_THAT(src, (IsMethod("basic_method"))); + REQUIRE_THAT(src, (IsMethod("static_method", "int"))); + REQUIRE_THAT(src, (IsMethod("const_method"))); + REQUIRE_THAT( + src, (IsMethod("default_int", "int", "int i = 12"))); + REQUIRE_THAT(src, + (IsMethod("default_string", "std::string", + "int i, std::string s = \"abc\""))); - REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, (IsMethod("size", "std::size_t"))); - REQUIRE_THAT(src, !IsDependency(_A("A"), _A("A"))); + REQUIRE_THAT(src, (IsMethod("protected_method"))); + REQUIRE_THAT(src, (IsMethod("private_method"))); + REQUIRE_THAT(src, (IsField("public_member", "int"))); + REQUIRE_THAT(src, (IsField("protected_member", "int"))); + REQUIRE_THAT(src, (IsField("private_member", "int"))); + REQUIRE_THAT(src, + (IsField("auto_member", "const unsigned long"))); - REQUIRE_THAT(src, (IsMethod("A"))); - REQUIRE_THAT(src, (IsMethod("A", "void", "A &&"))); - REQUIRE_THAT( - src, (IsMethod("A", "void", "const A &"))); + REQUIRE_THAT(src, (IsField("a_", "int"))); + REQUIRE_THAT(src, (IsField("b_", "int"))); + REQUIRE_THAT(src, (IsField("c_", "int"))); - REQUIRE_THAT(src, (IsMethod("~A"))); + save_puml(config.output_directory(), diagram->name + ".puml", src); +} - REQUIRE_THAT(src, (IsMethod("basic_method"))); - REQUIRE_THAT(src, (IsMethod("static_method", "int"))); - REQUIRE_THAT(src, (IsMethod("const_method"))); - REQUIRE_THAT( - src, (IsMethod("default_int", "int", "int i = 12"))); - REQUIRE_THAT(src, - (IsMethod("default_string", "std::string", - "int i, std::string s = \"abc\""))); +{ + auto j = generate_class_json(diagram, *model); - REQUIRE_THAT(src, (IsMethod("size", "std::size_t"))); + using namespace json; - REQUIRE_THAT(src, (IsMethod("protected_method"))); - REQUIRE_THAT(src, (IsMethod("private_method"))); - REQUIRE_THAT(src, (IsField("public_member", "int"))); - REQUIRE_THAT(src, (IsField("protected_member", "int"))); - REQUIRE_THAT(src, (IsField("private_member", "int"))); - REQUIRE_THAT(src, - (IsField("auto_member", "const unsigned long"))); + save_json(config.output_directory(), diagram->name + ".json", j); +} +{ + auto src = generate_class_mermaid(diagram, *model); - REQUIRE_THAT(src, (IsField("a_", "int"))); - REQUIRE_THAT(src, (IsField("b_", "int"))); - REQUIRE_THAT(src, (IsField("c_", "int"))); + mermaid::AliasMatcher _A(src); + using mermaid::IsField; + using mermaid::IsMethod; - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE_THAT(src, IsClass(_A("A"))); + + REQUIRE_THAT(src, !IsDependency(_A("A"), _A("A"))); + + REQUIRE_THAT(src, (IsMethod("A"))); + REQUIRE_THAT(src, (IsMethod("A", "void", "A &&"))); + REQUIRE_THAT( + src, (IsMethod("A", "void", "const A &"))); + + REQUIRE_THAT(src, (IsMethod("~A"))); + + REQUIRE_THAT(src, (IsMethod("basic_method"))); + REQUIRE_THAT(src, (IsMethod("static_method", "int"))); + REQUIRE_THAT(src, (IsMethod("const_method"))); + REQUIRE_THAT( + src, (IsMethod("default_int", "int", "int i = 12"))); + REQUIRE_THAT(src, + (IsMethod("default_string", "std::string", + "int i, std::string s = \"abc\""))); + + REQUIRE_THAT(src, (IsMethod("size", "std::size_t"))); + + REQUIRE_THAT(src, (IsMethod("protected_method"))); + REQUIRE_THAT(src, (IsMethod("private_method"))); + REQUIRE_THAT(src, (IsField("public_member", "int"))); + REQUIRE_THAT(src, (IsField("protected_member", "int"))); + REQUIRE_THAT(src, (IsField("private_member", "int"))); + REQUIRE_THAT(src, + (IsField("auto_member", "const unsigned long"))); + + REQUIRE_THAT(src, (IsField("a_", "int"))); + REQUIRE_THAT(src, (IsField("b_", "int"))); + REQUIRE_THAT(src, (IsField("c_", "int"))); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", src); +}*/ } \ No newline at end of file diff --git a/tests/t00067/test_case.h b/tests/t00067/test_case.h index b1142a5b..62e8775b 100644 --- a/tests/t00067/test_case.h +++ b/tests/t00067/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00067", "[test-case][class]") +TEST_CASE("t00067") { + using namespace clanguml::test; + auto [config, db] = load_config("t00067"); auto diagram = config.diagrams["t00067_class"]; @@ -28,6 +30,16 @@ TEST_CASE("t00067", "[test-case][class]") REQUIRE(model->name() == "t00067_class"); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(!(IsMethod(src, "A"))); + REQUIRE(!(IsMethod(src, "A", "void", "A &&"))); + REQUIRE(!(IsMethod(src, "A", "void", "const A &"))); + + REQUIRE(!(IsMethod(src, "~A"))); + + REQUIRE(!(IsMethod(src, "~A"))); + }); + /* { auto src = generate_class_puml(diagram, *model); AliasMatcher _A(src); @@ -71,5 +83,5 @@ TEST_CASE("t00067", "[test-case][class]") REQUIRE_THAT(src, !(IsMethod("~A"))); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } \ No newline at end of file diff --git a/tests/t00068/test_case.h b/tests/t00068/test_case.h index 19836b1b..57b96ffb 100644 --- a/tests/t00068/test_case.h +++ b/tests/t00068/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00068_r0", "[test-case][class][t00068]") +TEST_CASE("t00068_r0") { + using namespace clanguml::test; + auto [config, db] = load_config("t00068"); auto diagram = config.diagrams["t00068_r0_class"]; @@ -26,61 +28,25 @@ TEST_CASE("t00068_r0", "[test-case][class][t00068]") REQUIRE(model->name() == "t00068_r0_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(!IsClass(src, "A")); + REQUIRE(!IsClass(src, "AA")); + REQUIRE(IsClass(src, "AAA")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(!IsClass(src, "B")); + REQUIRE(!IsClass(src, "BB")); - REQUIRE_THAT(src, !IsClass(_A("A"))); - REQUIRE_THAT(src, !IsClass(_A("AA"))); - REQUIRE_THAT(src, IsClass(_A("AAA"))); + REQUIRE(!IsClass(src, "R")); + REQUIRE(!IsClass(src, "RR")); - REQUIRE_THAT(src, !IsClass(_A("B"))); - REQUIRE_THAT(src, !IsClass(_A("BB"))); - - REQUIRE_THAT(src, !IsClass(_A("R"))); - REQUIRE_THAT(src, !IsClass(_A("RR"))); - - REQUIRE_THAT(src, !IsEnum(_A("AKind"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsClass; - using mermaid::IsEnum; - - REQUIRE_THAT(src, !IsClass(_A("A"))); - REQUIRE_THAT(src, !IsClass(_A("AA"))); - REQUIRE_THAT(src, IsClass(_A("AAA"))); - - REQUIRE_THAT(src, !IsClass(_A("B"))); - REQUIRE_THAT(src, !IsClass(_A("BB"))); - - REQUIRE_THAT(src, !IsClass(_A("R"))); - REQUIRE_THAT(src, !IsClass(_A("RR"))); - - REQUIRE_THAT(src, !IsEnum(_A("AKind"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(!IsEnum(src, "AKind")); + }); } -TEST_CASE("t00068_r1", "[test-case][class][t00068]") +TEST_CASE("t00068_r1") { + using namespace clanguml::test; + auto [config, db] = load_config("t00068"); auto diagram = config.diagrams["t00068_r1_class"]; @@ -88,53 +54,25 @@ TEST_CASE("t00068_r1", "[test-case][class][t00068]") auto model = generate_class_diagram(*db, diagram); REQUIRE(model->name() == "t00068_r1_class"); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(!IsClass(src, "A")); + REQUIRE(IsClass(src, "AA")); + REQUIRE(IsClass(src, "AAA")); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + REQUIRE(!IsClass(src, "B")); + REQUIRE(IsClass(src, "BB")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsClass(src, "R")); + REQUIRE(!IsClass(src, "RR")); - REQUIRE_THAT(src, !IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("AA"))); - REQUIRE_THAT(src, IsClass(_A("AAA"))); - - REQUIRE_THAT(src, !IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("BB"))); - - REQUIRE_THAT(src, IsClass(_A("R"))); - REQUIRE_THAT(src, !IsClass(_A("RR"))); - - REQUIRE_THAT(src, IsEnum(_A("AKind"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsClass; - - REQUIRE_THAT(src, !IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("AA"))); - REQUIRE_THAT(src, IsClass(_A("AAA"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsEnum(src, "AKind")); + }); } -TEST_CASE("t00068_r2", "[test-case][class][t00068]") +TEST_CASE("t00068_r2") { + using namespace clanguml::test; + auto [config, db] = load_config("t00068"); auto diagram = config.diagrams["t00068_r2_class"]; @@ -143,53 +81,17 @@ TEST_CASE("t00068_r2", "[test-case][class][t00068]") REQUIRE(model->name() == "t00068_r2_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "AA")); + REQUIRE(IsClass(src, "AAA")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClass(src, "BB")); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("AA"))); - REQUIRE_THAT(src, IsClass(_A("AAA"))); + REQUIRE(IsClass(src, "R")); + REQUIRE(IsClass(src, "RR")); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("BB"))); - - REQUIRE_THAT(src, IsClass(_A("R"))); - REQUIRE_THAT(src, IsClass(_A("RR"))); - - REQUIRE_THAT(src, IsEnum(_A("AKind"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsClass; - using mermaid::IsEnum; - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("AA"))); - REQUIRE_THAT(src, IsClass(_A("AAA"))); - - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("BB"))); - - REQUIRE_THAT(src, IsClass(_A("R"))); - REQUIRE_THAT(src, IsClass(_A("RR"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(IsEnum(src, "AKind")); + }); } \ No newline at end of file diff --git a/tests/t00069/test_case.h b/tests/t00069/test_case.h index 069803e2..b72232e3 100644 --- a/tests/t00069/test_case.h +++ b/tests/t00069/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00069", "[test-case][class]") +TEST_CASE("t00069") { + using namespace clanguml::test; + auto [config, db] = load_config("t00069"); auto diagram = config.diagrams["t00069_class"]; @@ -28,60 +30,82 @@ TEST_CASE("t00069", "[test-case][class]") REQUIRE(model->name() == "t00069_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsClassTemplate(src, "generator", "T")); - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE( + IsInnerClass(src,("generator", "generator::promise_type")); - // Check if class templates exist - REQUIRE_THAT(src, IsClassTemplate("generator", "T")); + REQUIRE( + IsMethod(src,"iota", "generator")); + REQUIRE( + IsMethod(src,"seed", "generator")); - // Check if all inner classes exist - REQUIRE_THAT(src, - IsInnerClass(_A("generator"), _A("generator::promise_type"))); - - // Check if all methods exist - REQUIRE_THAT(src, - (IsMethod("iota", "generator"))); - REQUIRE_THAT(src, - (IsMethod("seed", "generator"))); - - // Check if all relationships exist - REQUIRE_THAT( - src, IsDependency(_A("A"), _A("generator"))); - REQUIRE_THAT(src, + REQUIRE( + IsDependency(src,"A", "generator")); + REQUIRE( IsInstantiation( - _A("generator"), _A("generator"))); + src,"generator", "generator")); + }); + /* + { + auto src = generate_class_puml(diagram, *model); + AliasMatcher _A(src); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - { - auto j = generate_class_json(diagram, *model); + // Check if all classes exist + REQUIRE_THAT(src, IsClass(_A("A"))); - using namespace json; + // Check if class templates exist + REQUIRE_THAT(src, IsClassTemplate("generator", "T")); - save_json(config.output_directory(), diagram->name + ".json", j); - } + // Check if all inner classes exist + REQUIRE_THAT(src, + IsInnerClass(_A("generator"), + _A("generator::promise_type"))); - { - auto src = generate_class_mermaid(diagram, *model); + // Check if all methods exist + REQUIRE_THAT(src, + (IsMethod("iota", "generator"))); REQUIRE_THAT(src, (IsMethod("seed", + "generator"))); - mermaid::AliasMatcher _A(src); - using mermaid::IsClass; - using mermaid::IsMethod; + // Check if all relationships exist + REQUIRE_THAT( + src, IsDependency(_A("A"), _A("generator"))); + REQUIRE_THAT(src, + IsInstantiation( + _A("generator"), _A("generator"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, - (IsMethod("iota", "generator"))); - REQUIRE_THAT(src, - (IsMethod("seed", "generator"))); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + { + auto j = generate_class_json(diagram, *model); + + using namespace json; + + save_json(config.output_directory(), diagram->name + ".json", j); + } + + { + auto src = generate_class_mermaid(diagram, *model); + + mermaid::AliasMatcher _A(src); + using mermaid::IsClass; + using mermaid::IsMethod; + + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, + (IsMethod("iota", "generator"))); REQUIRE_THAT(src, (IsMethod("seed", + "generator"))); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t00070/test_case.h b/tests/t00070/test_case.h index 59227728..84d6644e 100644 --- a/tests/t00070/test_case.h +++ b/tests/t00070/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00070", "[test-case][class]") +TEST_CASE("t00070") { + using namespace clanguml::test; + auto [config, db] = load_config("t00070"); auto diagram = config.diagrams["t00070_class"]; @@ -28,62 +30,67 @@ TEST_CASE("t00070", "[test-case][class]") REQUIRE(model->name() == "t00070_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(!IsClass(src, "C")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsClassTemplate(src, "BB")); + REQUIRE(!IsClassTemplate(src, "CC")); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, !IsClass(_A("C"))); + REQUIRE(IsEnum(src, "BBB")); + REQUIRE(!IsClass(src, "BBBB")); + REQUIRE(!IsEnum(src, "CCC")); + }); - REQUIRE_THAT(src, IsClassTemplate("BB", "T")); - REQUIRE_THAT(src, !IsClassTemplate("CC", "T")); + /* + { + auto src = generate_class_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE_THAT(src, IsEnum(_A("BBB"))); - REQUIRE_THAT(src, !IsClass(_A("BBBB"))); - REQUIRE_THAT(src, !IsEnum(_A("CCC"))); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - using namespace json; + { + auto j = generate_class_json(diagram, *model); - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - REQUIRE(!IsClass(j, "C")); + using namespace json; - REQUIRE(InPublicModule(j, "A", "t00070")); - REQUIRE(InPublicModule(j, "B", "t00070.lib1")); + REQUIRE(IsClass(j, "A")); + REQUIRE(IsClass(j, "B")); + REQUIRE(!IsClass(j, "C")); - REQUIRE(!IsClass(j, "BBBB")); + REQUIRE(InPublicModule(j, "A", "t00070")); + REQUIRE(InPublicModule(j, "B", "t00070.lib1")); - save_json(config.output_directory(), diagram->name + ".json", j); - } + REQUIRE(!IsClass(j, "BBBB")); - { - auto src = generate_class_mermaid(diagram, *model); + save_json(config.output_directory(), diagram->name + ".json", j); + } - mermaid::AliasMatcher _A(src); - using mermaid::IsClass; - using mermaid::IsEnum; + { + auto src = generate_class_mermaid(diagram, *model); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, !IsClass(_A("C"))); + mermaid::AliasMatcher _A(src); + using mermaid::IsClass; + using mermaid::IsEnum; - REQUIRE_THAT(src, IsClass(_A("BB"))); - REQUIRE_THAT(src, !IsClass(_A("CC"))); + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("B"))); + REQUIRE_THAT(src, !IsClass(_A("C"))); - REQUIRE_THAT(src, IsEnum(_A("BBB"))); - REQUIRE_THAT(src, !IsClass(_A("BBBB"))); - REQUIRE_THAT(src, !IsEnum(_A("CCC"))); + REQUIRE_THAT(src, IsClass(_A("BB"))); + REQUIRE_THAT(src, !IsClass(_A("CC"))); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE_THAT(src, IsEnum(_A("BBB"))); + REQUIRE_THAT(src, !IsClass(_A("BBBB"))); + REQUIRE_THAT(src, !IsEnum(_A("CCC"))); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t00071/test_case.h b/tests/t00071/test_case.h index 21821d2d..485dd416 100644 --- a/tests/t00071/test_case.h +++ b/tests/t00071/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00071", "[test-case][class]") +TEST_CASE("t00071") { + using namespace clanguml::test; + auto [config, db] = load_config("t00071"); auto diagram = config.diagrams["t00071_class"]; @@ -28,49 +30,63 @@ TEST_CASE("t00071", "[test-case][class]") REQUIRE(model->name() == "t00071_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "R")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsEnum(src, {"detail", "BBB"})); + REQUIRE(IsEnum(src, {"detail", "CCC"})); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("R"))); + REQUIRE(IsModulePackage(src, "app"s)); + REQUIRE(IsModulePackage(src, "app"s, "lib1"s)); + REQUIRE(IsModulePackage(src, "app"s, "lib1"s, "mod1"s)); + REQUIRE(IsModulePackage(src, "app"s, "lib1"s, "mod2"s)); + }); + /* + { + auto src = generate_class_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE_THAT(src, IsEnum(_A("detail::BBB"))); - REQUIRE_THAT(src, IsEnum(_A("detail::CCC"))); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("R"))); - { - auto j = generate_class_json(diagram, *model); + REQUIRE_THAT(src, IsEnum(_A("detail::BBB"))); + REQUIRE_THAT(src, IsEnum(_A("detail::CCC"))); - using namespace json; - using namespace std::string_literals; + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - REQUIRE(IsModulePackage(j, "app"s)); - REQUIRE(IsModulePackage(j, "app"s, "lib1"s)); - REQUIRE(IsModulePackage(j, "app"s, "lib1"s, "mod1"s)); - REQUIRE(IsModulePackage(j, "app"s, "lib1"s, "mod2"s)); + { + auto j = generate_class_json(diagram, *model); - save_json(config.output_directory(), diagram->name + ".json", j); - } + using namespace json; + using namespace std::string_literals; - { - auto src = generate_class_mermaid(diagram, *model); + REQUIRE(IsModulePackage(j, "app"s)); + REQUIRE(IsModulePackage(j, "app"s, "lib1"s)); + REQUIRE(IsModulePackage(j, "app"s, "lib1"s, "mod1"s)); + REQUIRE(IsModulePackage(j, "app"s, "lib1"s, "mod2"s)); - mermaid::AliasMatcher _A(src); - using mermaid::IsClass; - using mermaid::IsEnum; + save_json(config.output_directory(), diagram->name + ".json", j); + } - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("R"))); + { + auto src = generate_class_mermaid(diagram, *model); - REQUIRE_THAT(src, IsEnum(_A("detail::BBB"))); - REQUIRE_THAT(src, IsEnum(_A("detail::CCC"))); + mermaid::AliasMatcher _A(src); + using mermaid::IsClass; + using mermaid::IsEnum; - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("R"))); + + REQUIRE_THAT(src, IsEnum(_A("detail::BBB"))); + REQUIRE_THAT(src, IsEnum(_A("detail::CCC"))); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t00072/test_case.h b/tests/t00072/test_case.h index 10252aed..d383d907 100644 --- a/tests/t00072/test_case.h +++ b/tests/t00072/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00072", "[test-case][class]") +TEST_CASE("t00072") { + using namespace clanguml::test; + auto [config, db] = load_config("t00072"); auto diagram = config.diagrams["t00072_class"]; @@ -28,6 +30,27 @@ TEST_CASE("t00072", "[test-case][class]") REQUIRE(model->name() == "t00072_class"); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsPackage(src, "app")); + REQUIRE(IsPackage(src, ":lib1")); + REQUIRE(IsPackage(src, ":lib2")); + REQUIRE(IsPackage(src, "mod1")); + REQUIRE(IsPackage(src, "mod2")); + + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "C")); + REQUIRE(IsClassTemplate(src, "CC")); + REQUIRE(IsEnum(src, {"detail", "CCC"})); + + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClassTemplate(src, "BB")); + REQUIRE(IsEnum(src, {"detail", "BBB"})); + + REQUIRE(IsClass(src, "D")); + REQUIRE(IsClass(src, "E")); + }); + /* + { auto src = generate_class_puml(diagram, *model); AliasMatcher _A(src); @@ -100,4 +123,5 @@ TEST_CASE("t00072", "[test-case][class]") save_mermaid(config.output_directory(), diagram->name + ".mmd", src); } + */ } \ No newline at end of file diff --git a/tests/t00073/test_case.h b/tests/t00073/test_case.h index 68af72fd..3168358f 100644 --- a/tests/t00073/test_case.h +++ b/tests/t00073/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00073", "[test-case][class]") +TEST_CASE("t00073") { + using namespace clanguml::test; + auto [config, db] = load_config("t00073"); auto diagram = config.diagrams["t00073_class"]; @@ -28,69 +30,84 @@ TEST_CASE("t00073", "[test-case][class]") REQUIRE(model->name() == "t00073_class"); - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClass(src, "AHandler")); + REQUIRE(IsClass(src, "BHandler")); + REQUIRE(IsClassTemplate(src, "Overload")); + REQUIRE(IsClassTemplate(src, "Overload")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(IsDependency(src, "AHandler", "A")); + REQUIRE(IsDependency(src, "BHandler", "B")); + REQUIRE(IsInstantiation( + src, "Overload", "Overload")); + REQUIRE(IsAggregation( + src, "R", "Overload", "dispatch")); + }); + /* + { + auto src = generate_class_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("AHandler"))); - REQUIRE_THAT(src, IsClass(_A("BHandler"))); - REQUIRE_THAT(src, IsClassTemplate("Overload", "Bases...")); - REQUIRE_THAT(src, IsClassTemplate("Overload", "AHandler,BHandler")); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsDependency(_A("AHandler"), _A("A"))); - REQUIRE_THAT(src, IsDependency(_A("BHandler"), _A("B"))); - REQUIRE_THAT(src, - IsInstantiation( - _A("Overload"), _A("Overload"))); - REQUIRE_THAT(src, - IsAggregation( - _A("R"), _A("Overload"), "+dispatch")); + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("B"))); + REQUIRE_THAT(src, IsClass(_A("AHandler"))); + REQUIRE_THAT(src, IsClass(_A("BHandler"))); + REQUIRE_THAT(src, IsClassTemplate("Overload", "Bases...")); + REQUIRE_THAT(src, IsClassTemplate("Overload", "AHandler,BHandler")); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + REQUIRE_THAT(src, IsDependency(_A("AHandler"), _A("A"))); + REQUIRE_THAT(src, IsDependency(_A("BHandler"), _A("B"))); + REQUIRE_THAT(src, + IsInstantiation( + _A("Overload"), + _A("Overload"))); REQUIRE_THAT(src, IsAggregation( + _A("R"), _A("Overload"), "+dispatch")); - { - auto j = generate_class_json(diagram, *model); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - using namespace json; + { + auto j = generate_class_json(diagram, *model); - REQUIRE(IsClassTemplate(j, "Overload")); - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - REQUIRE(IsClass(j, "AHandler")); - REQUIRE(IsClass(j, "BHandler")); - REQUIRE(IsClass(j, "Overload")); + using namespace json; - save_json(config.output_directory(), diagram->name + ".json", j); - } + REQUIRE(IsClassTemplate(j, "Overload")); + REQUIRE(IsClass(j, "A")); + REQUIRE(IsClass(j, "B")); + REQUIRE(IsClass(j, "AHandler")); + REQUIRE(IsClass(j, "BHandler")); + REQUIRE(IsClass(j, "Overload")); - { - auto src = generate_class_mermaid(diagram, *model); + save_json(config.output_directory(), diagram->name + ".json", j); + } - mermaid::AliasMatcher _A(src); - using mermaid::IsClass; + { + auto src = generate_class_mermaid(diagram, *model); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("AHandler"))); - REQUIRE_THAT(src, IsClass(_A("BHandler"))); - REQUIRE_THAT(src, IsClass(_A("Overload"))); - REQUIRE_THAT(src, IsClass(_A("Overload"))); + mermaid::AliasMatcher _A(src); + using mermaid::IsClass; - REQUIRE_THAT(src, IsDependency(_A("AHandler"), _A("A"))); - REQUIRE_THAT(src, IsDependency(_A("BHandler"), _A("B"))); - REQUIRE_THAT(src, - IsInstantiation( - _A("Overload"), _A("Overload"))); - REQUIRE_THAT(src, - IsAggregation( - _A("R"), _A("Overload"), "+dispatch")); + REQUIRE_THAT(src, IsClass(_A("A"))); + REQUIRE_THAT(src, IsClass(_A("B"))); + REQUIRE_THAT(src, IsClass(_A("AHandler"))); + REQUIRE_THAT(src, IsClass(_A("BHandler"))); + REQUIRE_THAT(src, IsClass(_A("Overload"))); + REQUIRE_THAT(src, IsClass(_A("Overload"))); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE_THAT(src, IsDependency(_A("AHandler"), _A("A"))); + REQUIRE_THAT(src, IsDependency(_A("BHandler"), _A("B"))); + REQUIRE_THAT(src, + IsInstantiation( + _A("Overload"), + _A("Overload"))); REQUIRE_THAT(src, IsAggregation( + _A("R"), _A("Overload"), "+dispatch")); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t00074/test_case.h b/tests/t00074/test_case.h index 3409091c..94d4b6c1 100644 --- a/tests/t00074/test_case.h +++ b/tests/t00074/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00074", "[test-case][class]") +TEST_CASE("t00074") { + using namespace clanguml::test; + auto [config, db] = load_config("t00074"); auto diagram = config.diagrams["t00074_class"]; @@ -28,6 +30,19 @@ TEST_CASE("t00074", "[test-case][class]") REQUIRE(model->name() == "t00074_class"); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsConcept(src, "fruit_c")); + REQUIRE(IsConcept(src, "apple_c")); + REQUIRE(IsConcept(src, "orange_c")); + + REQUIRE(IsConstraint(src, "apple_c", "fruit_c", "T")); + REQUIRE(IsConstraint(src, "orange_c", "fruit_c", "T")); + + REQUIRE(!IsConceptRequirement(src, "apple_c", "t.get_sweetness()")); + REQUIRE( + !IsConceptRequirement(src, "orange_c", "t.get_bitterness()")); + }); +/* { auto src = generate_class_puml(diagram, *model); AliasMatcher _A(src); @@ -87,5 +102,5 @@ TEST_CASE("t00074", "[test-case][class]") src, !IsConceptRequirement(_A("apple_c"), "t.get_bitterness()")); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } \ No newline at end of file diff --git a/tests/t00075/test_case.h b/tests/t00075/test_case.h index e1f4ac19..7170d6dc 100644 --- a/tests/t00075/test_case.h +++ b/tests/t00075/test_case.h @@ -16,8 +16,10 @@ * limitations under the License. */ -TEST_CASE("t00075", "[test-case][class]") +TEST_CASE("t00075") { + using namespace clanguml::test; + auto [config, db] = load_config("t00075"); auto diagram = config.diagrams["t00075_class"]; @@ -28,6 +30,25 @@ TEST_CASE("t00075", "[test-case][class]") REQUIRE(model->name() == "t00075_class"); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClassTemplate(src, "ABE")); + REQUIRE(IsClass(src, "R")); + + REQUIRE(IsEnum(src, "E")); + + REQUIRE(IsConcept(src, "C")); + + REQUIRE(IsConceptRequirement(src, "C", "T{}")); + REQUIRE(IsConceptRequirement(src, "C", "t.e()")); + REQUIRE(IsConceptRequirement(src, "C", "(T t)")); + REQUIRE(!IsConceptRequirement(src, "C", "(T ns1::ns2::t)")); + + REQUIRE(IsConstraint(src, "ABE", "C", "T", + "up[#green,dashed,thickness=2]")); + }); + { auto src = generate_class_puml(diagram, *model); AliasMatcher _A(src); diff --git a/tests/t30011/test_case.h b/tests/t30011/test_case.h index 949ab8b0..098ab003 100644 --- a/tests/t30011/test_case.h +++ b/tests/t30011/test_case.h @@ -38,10 +38,10 @@ TEST_CASE("t30011") REQUIRE(IsDirectoryPackage(src, "libraries"s, "lib3"s)); REQUIRE(IsDirectoryPackage(src, "libraries"s, "lib4"s)); - REQUIRE(IsDependency(src, "app"s, "lib1"s)); - REQUIRE(IsDependency(src, "app"s, "lib2"s)); - REQUIRE(IsDependency(src, "app"s, "lib3"s)); - REQUIRE(IsDependency(src, "app"s, "lib4"s)); + REQUIRE(IsDependency(src, "app", "lib1")); + REQUIRE(IsDependency(src, "app", "lib2")); + REQUIRE(IsDependency(src, "app", "lib3")); + REQUIRE(IsDependency(src, "app", "lib4")); }); /* { diff --git a/tests/test_cases.cc b/tests/test_cases.cc index f4637578..6ebd360c 100644 --- a/tests/test_cases.cc +++ b/tests/test_cases.cc @@ -387,7 +387,7 @@ void try_run_test_case(const diagram_source_storage &diagrams, TC &&tc) std::cout << "-----------------------------------------------------" "--------------------------\n"; std::cout << "Test case failed for diagram type " - << T::diagram_type_name << ": " << "\n"; + << T::diagram_type_name << ": " << "\n\n"; std::cout << diagrams.get().to_string() << "\n"; throw e; @@ -1044,9 +1044,6 @@ template <> bool IsClass(json_t d, std::string name) #include "t00028/test_case.h" #include "t00029/test_case.h" #include "t00030/test_case.h" - -/* - #include "t00031/test_case.h" #include "t00032/test_case.h" #include "t00033/test_case.h" @@ -1085,6 +1082,10 @@ template <> bool IsClass(json_t d, std::string name) #include "t00062/test_case.h" #include "t00063/test_case.h" #include "t00064/test_case.h" +/* + + + #if defined(ENABLE_CXX_STD_20_TEST_CASES) #include "t00065/test_case.h" #endif @@ -1215,43 +1216,24 @@ int main(int argc, char *argv[]) { doctest::Context context; - // defaults - // context.addFilter("test-case-exclude", - // "*math*"); // exclude test cases with "math" in their name - context.setOption( - "abort-after", 5); // stop test execution after 5 failed assertions - context.setOption("order-by", "name"); // sort the test cases by their name - context.applyCommandLine(argc, argv); - // overrides - context.setOption( - "no-breaks", false); // don't break in the debugger when assertions fail - clanguml::cli::cli_handler clih; std::vector argvv = { "clang-uml", "--config", "./test_config_data/simple.yml"}; - // if (debug_log) - // argvv.push_back("-vvv"); - // else - argvv.push_back("-q"); + argvv.push_back("-vvv"); clih.handle_options(argvv.size(), argvv.data()); - int res = context.run(); // run + int res = context.run(); - if (context.shouldExit()) // important - query flags (and --exit) rely on - // the user doing this - return res; // propagate the result of the tests + if (context.shouldExit()) + return res; - int client_stuff_return_code = 0; - // your program - if the testing framework is integrated in your production - // code + return res; - return res + client_stuff_return_code; // the result from doctest is - // propagated here as well /* Catch::Session session; using namespace Catch::clara; diff --git a/tests/test_cases.h b/tests/test_cases.h index 0e84baa1..d6d8a1cd 100644 --- a/tests/test_cases.h +++ b/tests/test_cases.h @@ -124,6 +124,11 @@ template struct diagram_source_t { return "__INVALID_ALIAS__"; } + virtual std::string get_alias(std::string ns, std::string name) const + { + return get_alias(fmt::format("{}::{}", ns, name)); + } + bool search(const std::string &pattern) const; std::string to_string() const; @@ -364,6 +369,43 @@ template <> std::string diagram_source_t::to_string() const return src.dump(2); } +struct QualifiedName { + QualifiedName(const char *n) + : name{n} + { + } + + QualifiedName(std::string_view n) + : name{n} + { + } + + QualifiedName(std::string_view ns_, std::string_view n) + : ns{ns_} + , name{n} + { + } + + QualifiedName(const char *ns_, const char *n) + : ns{ns_} + , name{n} + { + } + + operator std::string() const { return str(); } + + std::string str() const + { + if (ns) + return fmt::format("{}::{}", ns.value(), name); + + return name; + } + + std::optional ns; + std::string name; +}; + /// /// The following functions declarations define various checks on generated /// diagrams. @@ -386,23 +428,31 @@ bool HasTitle(const DiagramType &d, std::string const &str); // Check if generated diagram contains a specified enum template -bool IsEnum(const DiagramType &d, std::string name); +bool IsEnum(const DiagramType &d, QualifiedName name); + +// Check if generated diagram contains a specified union +template +bool IsUnion(const DiagramType &d, QualifiedName name); // Check if generated diagram contains a specified class template -bool IsClass(const DiagramType &d, std::string name); +bool IsClass(const DiagramType &d, QualifiedName name); // Check if generated diagram contains a specified class template template -bool IsClassTemplate(const DiagramType &d, std::string name); +bool IsClassTemplate(const DiagramType &d, QualifiedName name); + +template +bool IsAbstractClassTemplate(const DiagramType &d, QualifiedName name); // Check if generated diagram contains a specified abstract class template -bool IsAbstractClass(const DiagramType &d, std::string name); +bool IsAbstractClass(const DiagramType &d, QualifiedName name); // Check if generated diagram contains a specified class template -bool IsBaseClass(const DiagramType &d, std::string base, std::string subclass); +bool IsBaseClass( + const DiagramType &d, QualifiedName base, QualifiedName subclass); template bool IsInnerClass( @@ -440,8 +490,8 @@ bool IsInstantiation(const DiagramType &d, std::string const &from, std::string const &to, std::string style = ""); template -bool IsDependency(const DiagramType &d, std::string const &from, - std::string const &to, std::string style = ""); +bool IsDependency(const DiagramType &d, QualifiedName from, QualifiedName to, + std::string style = ""); template bool IsFriend( @@ -459,6 +509,9 @@ template bool IsConstraint(const DiagramType &d, std::string const &from, std::string const &to, std::string label = {}, std::string style = ""); +template +bool IsConcept(const DiagramType &d, std::string const &cpt); + template bool IsConceptRequirement( const DiagramType &d, std::string const &cpt, std::string requirement); @@ -543,28 +596,40 @@ template <> bool HasTitle(const plantuml_t &d, std::string const &str) return d.contains("title " + str); } -template <> bool IsEnum(const plantuml_t &d, std::string name) +template <> bool IsEnum(const plantuml_t &d, QualifiedName enm) { - return d.contains(fmt::format("enum {}", d.get_alias(name))); + return d.contains(fmt::format("enum {}", d.get_alias(enm.name))); } -template <> bool IsClass(const plantuml_t &d, std::string name) +template <> bool IsUnion(const plantuml_t &d, QualifiedName cls) { - return d.contains(fmt::format("class {}", d.get_alias(name))); + return d.contains(fmt::format("class {} <>", d.get_alias(cls))); } -template <> bool IsClassTemplate(const plantuml_t &d, std::string name) +template <> bool IsClass(const plantuml_t &d, QualifiedName cls) { - return d.contains(fmt::format("class \"{}\"", name)); + return d.contains(fmt::format("class {}", d.get_alias(cls.name))) || + d.contains(fmt::format("class {}", d.get_alias(cls.str()))); } -template <> bool IsAbstractClass(const plantuml_t &d, std::string name) +template <> bool IsClassTemplate(const plantuml_t &d, QualifiedName cls) { - return d.contains(fmt::format("abstract {}", d.get_alias(name))); + return d.contains(fmt::format("class \"{}\"", cls.name)); +} + +template <> bool IsAbstractClassTemplate(const plantuml_t &d, QualifiedName cls) +{ + return d.contains(fmt::format("abstract \"{}\"", cls.name)); +} + +template <> bool IsAbstractClass(const plantuml_t &d, QualifiedName cls) +{ + return d.contains(fmt::format("abstract {}", d.get_alias(cls.name))); } template <> -bool IsBaseClass(const plantuml_t &d, std::string base, std::string subclass) +bool IsBaseClass( + const plantuml_t &d, QualifiedName base, QualifiedName subclass) { return d.contains( fmt::format("{} <|-- {}", d.get_alias(base), d.get_alias(subclass))); @@ -750,11 +815,13 @@ bool IsInstantiation(const plantuml_t &d, std::string const &from, } template <> -bool IsDependency(const plantuml_t &d, std::string const &from, - std::string const &to, std::string style) +bool IsDependency(const plantuml_t &d, QualifiedName from, QualifiedName to, + std::string style) { - return d.contains( - fmt::format("{} .{}.> {}", d.get_alias(from), style, d.get_alias(to))); + return d.contains(fmt::format( + "{} .{}.> {}", d.get_alias(from), style, d.get_alias(to))) || + d.contains(fmt::format("{} .{}.> {}", d.get_alias(from.name), style, + d.get_alias(to.name))); } template @@ -802,6 +869,11 @@ bool IsConstraint(const plantuml_t &d, std::string const &from, "{} .{}.> {} : {}", d.get_alias(from), style, d.get_alias(to), label)); } +template <> bool IsConcept(const plantuml_t &d, std::string const &cpt) +{ + return d.contains("class " + d.get_alias(cpt) + " <>"); +} + template <> bool IsConceptRequirement( const plantuml_t &d, std::string const &cpt, std::string requirement) @@ -945,30 +1017,43 @@ template <> bool HasTitle(const mermaid_t &d, std::string const &str) return d.contains("title: " + str); } -template <> bool IsEnum(const mermaid_t &d, std::string name) +template <> bool IsEnum(const mermaid_t &d, QualifiedName enm) { - return d.search(std::string("class ") + d.get_alias(name) + + return d.search(std::string("class ") + d.get_alias(enm) + " \\{\\n\\s+<>"); } -template <> bool IsClass(const mermaid_t &d, std::string name) +template <> bool IsUnion(const mermaid_t &d, QualifiedName cls) { - return d.contains(fmt::format("class {}[\"{}\"]", d.get_alias(name), name)); + return d.search( + std::string("class ") + d.get_alias(cls) + " \\{\\n\\s+<>"); } -template <> bool IsClassTemplate(const mermaid_t &d, std::string name) +template <> bool IsClass(const mermaid_t &d, QualifiedName cls) { - return d.contains(fmt::format("class {}", d.get_alias(name))); + return d.contains(fmt::format("class {}", d.get_alias(cls))); } -template <> bool IsAbstractClass(const mermaid_t &d, std::string name) +template <> bool IsClassTemplate(const mermaid_t &d, QualifiedName cls) +{ + return d.contains(fmt::format("class {}", d.get_alias(cls))); +} + +template <> bool IsAbstractClassTemplate(const mermaid_t &d, QualifiedName cls) +{ + // return d.contains(fmt::format("class {}", d.get_alias(cls))); + return d.search( + std::string("class ") + d.get_alias(cls) + " \\{\\n\\s+<>"); +} + +template <> bool IsAbstractClass(const mermaid_t &d, QualifiedName name) { return d.search( std::string("class ") + d.get_alias(name) + " \\{\\n\\s+<>"); } template <> -bool IsBaseClass(const mermaid_t &d, std::string base, std::string subclass) +bool IsBaseClass(const mermaid_t &d, QualifiedName base, QualifiedName subclass) { return d.contains( fmt::format("{} <|-- {}", d.get_alias(base), d.get_alias(subclass))); @@ -1119,7 +1204,7 @@ bool IsComposition(const mermaid_t &d, std::string const &from, if (!multiplicity_source.empty()) format_string += " \"" + multiplicity_source + "\""; - format_string += fmt::format(" *-{}-", style); + format_string += fmt::format(" *--", style); if (!multiplicity_dest.empty()) format_string += " \"" + multiplicity_dest + "\""; @@ -1168,8 +1253,8 @@ bool IsInstantiation(const mermaid_t &d, std::string const &from, } template <> -bool IsDependency(const mermaid_t &d, std::string const &from, - std::string const &to, std::string style) +bool IsDependency( + const mermaid_t &d, QualifiedName from, QualifiedName to, std::string style) { if (d.diagram_type == common::model::diagram_t::kClass) { return d.contains( @@ -1259,6 +1344,12 @@ bool IsConstraint(const mermaid_t &d, std::string const &from, return d.contains(fmt::format("{} ..> {} : {}", from_id, to_id, label)); } +template <> bool IsConcept(const mermaid_t &d, std::string const &cpt) +{ + return d.search( + std::string("class ") + d.get_alias(cpt) + " \\{\\n\\s+<>"); +} + template <> bool IsConceptRequirement( const mermaid_t &d, std::string const &cpt, std::string requirement) @@ -1354,8 +1445,13 @@ template <> bool IsSystemHeader(const mermaid_t &d, std::string const &path) template bool IsNamespacePackage(const mermaid_t &d, Args... args) { + if (d.diagram_type == class_diagram::model::diagram_t::kClass) { + std::vector toks{{args...}}; + return d.contains(fmt::format("[\"{}", fmt::join(toks, "::"))); + } + const auto &name = get_last(args...); - return d.contains("subgraph " + d.get_alias(name)); + return d.contains(fmt::format("subgraph {}", d.get_alias(name))); } template @@ -1394,32 +1490,44 @@ template <> bool HasTitle(const json_t &d, std::string const &str) return d.src.contains("title") && d.src["title"] == str; } -template <> bool IsAbstractClass(const json_t &d, std::string name) +template <> bool IsAbstractClass(const json_t &d, QualifiedName cls) { - auto e = get_element(d.src, expand_name(d.src, name)); + auto e = get_element(d.src, expand_name(d.src, cls)); return e && e->at("type") == "class" && e->at("is_abstract"); } -template <> bool IsEnum(const json_t &d, std::string name) +template <> bool IsEnum(const json_t &d, QualifiedName enm) { - auto e = get_element(d.src, expand_name(d.src, name)); + auto e = get_element(d.src, expand_name(d.src, enm)); return e && e->at("type") == "enum"; } -template <> bool IsClass(const json_t &d, std::string name) +template <> bool IsUnion(const json_t &d, QualifiedName enm) { - auto e = get_element(d.src, expand_name(d.src, name)); + auto e = get_element(d.src, expand_name(d.src, enm)); + return e && e->at("type") == "class" && e->at("is_union"); +} + +template <> bool IsClass(const json_t &d, QualifiedName cls) +{ + auto e = get_element(d.src, expand_name(d.src, cls)); return e && e->at("type") == "class" && !e->at("is_abstract"); } -template <> bool IsClassTemplate(const json_t &d, std::string name) +template <> bool IsClassTemplate(const json_t &d, QualifiedName cls) { - auto e = get_element(d.src, expand_name(d.src, name)); + auto e = get_element(d.src, expand_name(d.src, cls)); return e && e->at("type") == "class"; } +template <> bool IsAbstractClassTemplate(const json_t &d, QualifiedName cls) +{ + auto e = get_element(d.src, expand_name(d.src, cls)); + return e && e->at("type") == "class" && e->at("is_abstract"); +} + template <> -bool IsBaseClass(const json_t &d, std::string base, std::string subclass) +bool IsBaseClass(const json_t &d, QualifiedName base, QualifiedName subclass) { const auto &j = d.src; auto base_el = get_element(j, expand_name(j, base)); @@ -1459,8 +1567,8 @@ bool IsMethod(const json_t &d, const std::string &cls, std::string const &name, const nlohmann::json &methods = (*sc)["methods"]; - return std::find_if(methods.begin(), methods.end(), [&](const auto &it) { - return it["name"] == name; + return std::find_if(methods.begin(), methods.end(), [name](const auto &it) { + return it["display_name"] == name; }) != methods.end(); } @@ -1522,7 +1630,7 @@ bool IsComposition(const json_t &d, std::string const &from, const auto &j = d.src; auto rel = get_relationship( - j, expand_name(j, to), expand_name(j, from), "composition", label); + j, expand_name(j, from), expand_name(j, to), "composition", label); if (rel == j["relationships"].end()) return false; @@ -1591,8 +1699,8 @@ bool IsInstantiation(const json_t &d, std::string const &from, } template <> -bool IsDependency(const json_t &d, std::string const &from, - std::string const &to, std::string style) +bool IsDependency( + const json_t &d, QualifiedName from, QualifiedName to, std::string style) { const auto &j = d.src; @@ -1655,18 +1763,48 @@ bool IsIncludeDependency( return true; } +template <> bool IsConcept(const json_t &d, std::string const &cpt) +{ + const auto &j = d.src; + + auto e = get_element(j, expand_name(j, cpt)); + return e && e->at("type") == "concept"; +} + template <> bool IsConstraint(const json_t &d, std::string const &from, std::string const &to, std::string label, std::string style) { - return false; + const auto &j = d.src; + + auto rel = get_relationship( + j, expand_name(j, from), expand_name(j, to), "constraint", label); + + if (rel == j["relationships"].end()) + return false; + + if ((*rel)["label"] != label) + return false; + + return true; } template <> bool IsConceptRequirement( const json_t &d, std::string const &cpt, std::string requirement) { - return false; + const auto &j = d.src; + + auto e = get_element(j, expand_name(j, cpt)); + + if (!e) + return false; + + const nlohmann::json &statements = (*e)["statements"]; + + return std::find_if(statements.begin(), statements.end(), + [requirement](const auto &it) { return it == requirement; }) != + statements.end(); } template <> From 27eaea5bbed8b2d43de6ba61a54eb62373408500 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Tue, 14 May 2024 11:39:07 +0200 Subject: [PATCH 04/15] Refactored class, package and include diagram test cases (#266) --- .../json/class_diagram_generator.cc | 15 + .../mermaid/class_diagram_generator.cc | 6 +- .../plantuml/class_diagram_generator.cc | 6 +- src/class_diagram/model/class_method.h | 2 +- src/common/generators/json/generator.cc | 29 +- src/common/generators/json/generator.h | 2 + src/common/generators/mermaid/generator.cc | 8 +- src/common/generators/mermaid/generator.h | 2 +- src/config/config.cc | 4 +- .../mermaid/package_diagram_generator.cc | 2 +- tests/t00002/test_case.h | 12 +- tests/t00003/test_case.h | 69 ++--- tests/t00004/test_case.h | 60 ++-- tests/t00005/test_case.h | 70 +++-- tests/t00006/test_case.h | 85 +++--- tests/t00007/test_case.h | 11 +- tests/t00008/test_case.h | 11 +- tests/t00009/test_case.h | 11 +- tests/t00010/test_case.h | 11 +- tests/t00011/test_case.h | 11 +- tests/t00012/test_case.h | 11 +- tests/t00013/test_case.h | 11 +- tests/t00014/test_case.h | 256 +----------------- tests/t00015/test_case.h | 11 +- tests/t00016/test_case.h | 11 +- tests/t00017/test_case.h | 11 +- tests/t00018/test_case.h | 11 +- tests/t00019/test_case.h | 11 +- tests/t00020/test_case.h | 62 +---- tests/t00021/test_case.h | 11 +- tests/t00022/test_case.h | 11 +- tests/t00023/test_case.h | 11 +- tests/t00024/test_case.h | 11 +- tests/t00025/test_case.h | 11 +- tests/t00026/test_case.h | 11 +- tests/t00027/test_case.h | 90 +----- tests/t00028/test_case.h | 87 +----- tests/t00029/test_case.h | 9 +- tests/t00030/test_case.h | 11 +- tests/t00031/test_case.h | 11 +- tests/t00032/test_case.h | 11 +- tests/t00033/test_case.h | 11 +- tests/t00034/test_case.h | 11 +- tests/t00035/test_case.h | 11 +- tests/t00036/test_case.h | 10 +- tests/t00037/test_case.h | 10 +- tests/t00038/test_case.h | 14 +- tests/t00039/test_case.h | 13 +- tests/t00040/test_case.h | 12 +- tests/t00041/test_case.h | 10 +- tests/t00042/test_case.h | 10 +- tests/t00043/test_case.h | 12 +- tests/t00044/test_case.h | 12 +- tests/t00045/test_case.h | 11 +- tests/t00046/test_case.h | 13 +- tests/t00047/test_case.h | 11 +- tests/t00048/test_case.h | 11 +- tests/t00049/test_case.h | 10 +- tests/t00050/test_case.h | 11 +- tests/t00051/test_case.h | 113 +------- tests/t00052/test_case.h | 64 +---- tests/t00053/test_case.h | 88 +----- tests/t00054/test_case.h | 99 +------ tests/t00055/test_case.h | 81 +----- tests/t00056/test_case.h | 214 +-------------- tests/t00057/test_case.h | 95 +------ tests/t00058/test_case.h | 104 +------ tests/t00059/test_case.h | 154 +---------- tests/t00060/test_case.h | 68 +---- tests/t00061/test_case.h | 51 +--- tests/t00062/test_case.h | 141 +--------- tests/t00063/test_case.h | 51 +--- tests/t00064/test_case.h | 142 +--------- tests/t00065/test_case.h | 66 +---- tests/t00066/test_case.h | 147 ++-------- tests/t00067/test_case.h | 66 +---- tests/t00068/test_case.h | 26 +- tests/t00069/test_case.h | 89 +----- tests/t00070/test_case.h | 62 +---- tests/t00071/test_case.h | 59 +--- tests/t00072/test_case.h | 97 +------ tests/t00073/test_case.h | 76 +----- tests/t00074/test_case.h | 104 ++----- tests/t00075/test_case.h | 93 +------ tests/t30001/test_case.h | 11 +- tests/t30002/test_case.h | 156 +---------- tests/t30003/test_case.h | 15 +- tests/t30004/test_case.h | 56 +--- tests/t30005/test_case.h | 67 +---- tests/t30006/test_case.h | 61 +---- tests/t30007/test_case.h | 69 +---- tests/t30008/test_case.h | 88 +----- tests/t30009/test_case.h | 65 +---- tests/t30010/test_case.h | 70 +---- tests/t30011/test_case.h | 76 +----- tests/t30012/test_case.h | 58 +--- tests/t30013/test_case.h | 140 +--------- tests/t30014/test_case.h | 57 +--- tests/t30015/test_case.h | 144 +--------- tests/t40001/test_case.h | 11 +- tests/t40002/test_case.h | 11 +- tests/t40003/test_case.h | 11 +- tests/test_cases.cc | 83 +++++- tests/test_cases.h | 177 ++++++++---- tests/test_util.cc | 1 - 105 files changed, 660 insertions(+), 4427 deletions(-) diff --git a/src/class_diagram/generators/json/class_diagram_generator.cc b/src/class_diagram/generators/json/class_diagram_generator.cc index 340065ee..7c6f3697 100644 --- a/src/class_diagram/generators/json/class_diagram_generator.cc +++ b/src/class_diagram/generators/json/class_diagram_generator.cc @@ -247,18 +247,33 @@ void generator::generate(const package &p, nlohmann::json &parent) const void generator::generate(const class_ &c, nlohmann::json &parent) const { nlohmann::json object = c; + + if (!config().generate_fully_qualified_name()) + object["display_name"] = + common::generators::json::render_name(c.full_name_no_ns()); + parent["elements"].push_back(std::move(object)); } void generator::generate(const enum_ &e, nlohmann::json &parent) const { nlohmann::json object = e; + + if (!config().generate_fully_qualified_name()) + object["display_name"] = + common::generators::json::render_name(e.full_name_no_ns()); + parent["elements"].push_back(std::move(object)); } void generator::generate(const concept_ &c, nlohmann::json &parent) const { nlohmann::json object = c; + + if (!config().generate_fully_qualified_name()) + object["display_name"] = + common::generators::json::render_name(c.full_name_no_ns()); + parent["elements"].push_back(std::move(object)); } diff --git a/src/class_diagram/generators/mermaid/class_diagram_generator.cc b/src/class_diagram/generators/mermaid/class_diagram_generator.cc index f5bbb17d..436d60b4 100644 --- a/src/class_diagram/generators/mermaid/class_diagram_generator.cc +++ b/src/class_diagram/generators/mermaid/class_diagram_generator.cc @@ -281,7 +281,8 @@ void generator::generate_member( void generator::generate(const concept_ &c, std::ostream &ostr) const { - ostr << indent(1) << "class" << " " << c.alias(); + ostr << indent(1) << "class" + << " " << c.alias(); ostr << " {" << '\n'; ostr << indent(2) << "<>\n"; @@ -299,7 +300,8 @@ void generator::generate(const concept_ &c, std::ostream &ostr) const << fmt::format("\"({})\"\n", fmt::join(parameters, ",")); for (const auto &req : c.requires_statements()) { - ostr << indent(2) << fmt::format("\"{}\"\n", render_name(req)); + ostr << indent(2) + << fmt::format("\"{}\"\n", render_name(req, false)); } } diff --git a/src/class_diagram/generators/plantuml/class_diagram_generator.cc b/src/class_diagram/generators/plantuml/class_diagram_generator.cc index 0a5b6fa8..67016667 100644 --- a/src/class_diagram/generators/plantuml/class_diagram_generator.cc +++ b/src/class_diagram/generators/plantuml/class_diagram_generator.cc @@ -67,7 +67,7 @@ void generator::generate_alias(const class_ &c, std::ostream &ostr) const class_type = "abstract"; std::string full_name; - if (config().generate_fully_qualified_name()) + if (!config().generate_fully_qualified_name()) full_name = c.full_name_no_ns(); else full_name = c.full_name(); @@ -89,7 +89,7 @@ void generator::generate_alias(const enum_ &e, std::ostream &ostr) const { print_debug(e, ostr); - if (config().generate_fully_qualified_name()) + if (!config().generate_fully_qualified_name()) ostr << "enum" << " \"" << e.name(); else @@ -106,7 +106,7 @@ void generator::generate_alias(const concept_ &c, std::ostream &ostr) const { print_debug(c, ostr); - if (config().generate_fully_qualified_name()) + if (!config().generate_fully_qualified_name()) ostr << "class" << " \"" << c.full_name_no_ns(); else diff --git a/src/class_diagram/model/class_method.h b/src/class_diagram/model/class_method.h index da8fe5fa..6c556d57 100644 --- a/src/class_diagram/model/class_method.h +++ b/src/class_diagram/model/class_method.h @@ -46,7 +46,7 @@ public: ~class_method() override = default; - void update(const common::model::namespace_& un); + void update(const common::model::namespace_ &un); /** * @brief Method name including template parameters/arguments if any diff --git a/src/common/generators/json/generator.cc b/src/common/generators/json/generator.cc index e1fa27c5..a9577f00 100644 --- a/src/common/generators/json/generator.cc +++ b/src/common/generators/json/generator.cc @@ -18,18 +18,10 @@ #include "generator.h" -namespace clanguml::common::model { +namespace clanguml::common { +namespace model { using nlohmann::json; -namespace detail { -std::string render_name(std::string name) -{ - util::replace_all(name, "##", "::"); - - return name; -} -} // namespace detail - void to_json(nlohmann::json &j, const source_location &sl) { j = json{{"file", sl.file_relative()}, @@ -40,9 +32,10 @@ void to_json(nlohmann::json &j, const source_location &sl) void to_json(nlohmann::json &j, const element &c) { j = json{{"id", std::to_string(c.id())}, - {"name", detail::render_name(c.name())}, + {"name", common::generators::json::render_name(c.name())}, {"namespace", c.get_namespace().to_string()}, {"type", c.type_name()}, - {"display_name", detail::render_name(c.full_name(true))}}; + {"display_name", + common::generators::json::render_name(c.full_name(true))}}; if (const auto &comment = c.comment(); comment) j["comment"] = comment.value(); @@ -81,4 +74,16 @@ void to_json(nlohmann::json &j, const relationship &c) if (const auto &comment = c.comment(); comment) j["comment"] = comment.value(); } +} // namespace model + +namespace generators::json { + +std::string render_name(std::string name) +{ + util::replace_all(name, "##", "::"); + + return name; +} + +} // namespace generators::json } // namespace clanguml::common::model diff --git a/src/common/generators/json/generator.h b/src/common/generators/json/generator.h index dea6b3d4..3554b8f5 100644 --- a/src/common/generators/json/generator.h +++ b/src/common/generators/json/generator.h @@ -51,6 +51,8 @@ using clanguml::common::model::element; using clanguml::common::model::message_t; using clanguml::common::model::relationship_t; +std::string render_name(std::string name); + /** * @brief Base class for diagram generators * diff --git a/src/common/generators/mermaid/generator.cc b/src/common/generators/mermaid/generator.cc index ba882f46..9ceb6877 100644 --- a/src/common/generators/mermaid/generator.cc +++ b/src/common/generators/mermaid/generator.cc @@ -78,12 +78,14 @@ std::string indent(const unsigned level) return std::string(level * kIndentWidth, ' '); // NOLINT } -std::string render_name(std::string name) +std::string render_name(std::string name, bool round_brackets) { util::replace_all(name, "<", "<"); util::replace_all(name, ">", ">"); - util::replace_all(name, "(", "("); - util::replace_all(name, ")", ")"); + if (round_brackets) { + util::replace_all(name, "(", "("); + util::replace_all(name, ")", ")"); + } util::replace_all(name, "##", "::"); util::replace_all(name, "{", "{"); util::replace_all(name, "}", "}"); diff --git a/src/common/generators/mermaid/generator.h b/src/common/generators/mermaid/generator.h index 9333d8b4..2fc67662 100644 --- a/src/common/generators/mermaid/generator.h +++ b/src/common/generators/mermaid/generator.h @@ -44,7 +44,7 @@ std::string to_mermaid(message_t r); std::string indent(unsigned level); -std::string render_name(std::string name); +std::string render_name(std::string name, bool round_brackets = true); /** * @brief Base class for diagram generators diff --git a/src/config/config.cc b/src/config/config.cc index 603cfb8b..03b472ab 100644 --- a/src/config/config.cc +++ b/src/config/config.cc @@ -268,8 +268,8 @@ std::string inheritable_diagram_options::simplify_template_type( bool inheritable_diagram_options::generate_fully_qualified_name() const { - return generate_packages() && - (package_type() == package_type_t::kNamespace); + return (package_type() == package_type_t::kNamespace) && + !generate_packages(); } std::vector diagram::get_translation_units() const diff --git a/src/package_diagram/generators/mermaid/package_diagram_generator.cc b/src/package_diagram/generators/mermaid/package_diagram_generator.cc index 1962d8c6..e2beff79 100644 --- a/src/package_diagram/generators/mermaid/package_diagram_generator.cc +++ b/src/package_diagram/generators/mermaid/package_diagram_generator.cc @@ -89,7 +89,7 @@ void generator::generate(const package &p, std::ostream &ostr) const << "]\n"; if (p.is_deprecated()) - ostr << indent(1) << "%% <>"; + ostr << indent(1) << "%% <>\n"; } for (const auto &subpackage : p) { diff --git a/tests/t00002/test_case.h b/tests/t00002/test_case.h index 463c0675..7a237d5f 100644 --- a/tests/t00002/test_case.h +++ b/tests/t00002/test_case.h @@ -21,20 +21,12 @@ TEST_CASE("t00002") using namespace clanguml::test; using namespace std::string_literals; - auto [config, db] = load_config("t00002"); - - auto diagram = config.diagrams["t00002_class"]; - - REQUIRE(diagram->name == "t00002_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00002", "t00002_class"); REQUIRE(diagram->include().namespaces.size() == 1); - REQUIRE(diagram->exclude().namespaces.size() == 0); - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00002_class"); - REQUIRE(model->should_include({"clanguml", "t00002"}, "A")); REQUIRE(!model->should_include({"std"}, "vector")); diff --git a/tests/t00003/test_case.h b/tests/t00003/test_case.h index 64f4eae0..b9e2897a 100644 --- a/tests/t00003/test_case.h +++ b/tests/t00003/test_case.h @@ -16,61 +16,48 @@ * limitations under the License. */ -// #include "../test_cases.h" - TEST_CASE("t00003") { using namespace clanguml::test; using namespace std::string_literals; - auto [config, db] = load_config("t00003"); - - auto diagram = config.diagrams["t00003_class"]; - - REQUIRE(diagram->name == "t00003_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00003", "t00003_class"); REQUIRE(diagram->include().namespaces.size() == 1); - REQUIRE(diagram->exclude().namespaces.size() == 0); - auto model = generate_class_diagram(*db, diagram); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); - REQUIRE(model->name() == "t00003_class"); + REQUIRE(!IsDependency(src, "A", "A")); - CHECK_CLASS_DIAGRAM(config, diagram, *model, - [](const auto &src) { - REQUIRE(IsClass(src, "A")); + REQUIRE(IsMethod(src, "A", "A")); + REQUIRE(IsMethod(src, "A", "A", "void", "A &&")); + REQUIRE(IsMethod(src, "A", "A", "void", "const A &")); - REQUIRE(!IsDependency(src, "A", "A")); + REQUIRE(IsMethod(src, "A", "~A")); - REQUIRE(IsMethod(src, "A", "A")); - REQUIRE(IsMethod(src, "A", "A", "void", "A &&")); - REQUIRE( - IsMethod(src, "A", "A", "void", "const A &")); + REQUIRE(IsMethod(src, "A", "basic_method")); + REQUIRE(IsMethod(src, "A", "static_method", "int")); + REQUIRE(IsMethod(src, "A", "const_method")); + REQUIRE(IsMethod(src, "A", "default_int", "int", "int i = 12")); + REQUIRE(IsMethod(src, "A", "default_string", "std::string", + "int i, std::string s = \"abc\"")); - REQUIRE(IsMethod(src, "A", "~A")); + REQUIRE(IsMethod( + src, "A", "size", "std::size_t")); - REQUIRE(IsMethod(src, "A", "basic_method")); - REQUIRE(IsMethod(src, "A", "static_method", "int")); - REQUIRE(IsMethod(src, "A", "const_method")); - REQUIRE( - IsMethod(src, "A", "default_int", "int", "int i = 12")); - REQUIRE(IsMethod(src, "A", "default_string", "std::string", - "int i, std::string s = \"abc\"")); + REQUIRE(IsMethod(src, "A", "protected_method")); + REQUIRE(IsMethod(src, "A", "private_method")); + REQUIRE(IsField(src, "A", "public_member", "int")); + REQUIRE(IsField(src, "A", "protected_member", "int")); + REQUIRE(IsField(src, "A", "private_member", "int")); + REQUIRE(IsField( + src, "A", "auto_member", "const unsigned long")); - REQUIRE(IsMethod( - src, "A", "size", "std::size_t")); - - REQUIRE(IsMethod(src, "A", "protected_method")); - REQUIRE(IsMethod(src, "A", "private_method")); - REQUIRE(IsField(src, "A", "public_member", "int")); - REQUIRE(IsField(src, "A", "protected_member", "int")); - REQUIRE(IsField(src, "A", "private_member", "int")); - REQUIRE(IsField( - src, "A", "auto_member", "const unsigned long")); - - REQUIRE(IsField(src, "A", "a_", "int")); - REQUIRE(IsField(src, "A", "b_", "int")); - REQUIRE(IsField(src, "A", "c_", "int")); - }); + REQUIRE(IsField(src, "A", "a_", "int")); + REQUIRE(IsField(src, "A", "b_", "int")); + REQUIRE(IsField(src, "A", "c_", "int")); + }); } \ No newline at end of file diff --git a/tests/t00004/test_case.h b/tests/t00004/test_case.h index 71a24a4a..f13bcf59 100644 --- a/tests/t00004/test_case.h +++ b/tests/t00004/test_case.h @@ -20,46 +20,38 @@ TEST_CASE("t00004") { using namespace clanguml::test; - auto [config, db] = load_config("t00004"); - - auto diagram = config.diagrams["t00004_class"]; - - REQUIRE(diagram->name == "t00004_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00004", "t00004_class"); REQUIRE(diagram->include().namespaces.size() == 1); REQUIRE(diagram->exclude().namespaces.size() == 0); - auto model = generate_class_diagram(*db, diagram); + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "A::AA")); + REQUIRE(IsClass(src, "A::AA::AAA")); + REQUIRE(IsEnum(src, "B::AA")); + REQUIRE(IsEnum(src, "A::AA::Lights")); + REQUIRE(IsInnerClass(src, "A", "A::AA")); + REQUIRE(IsInnerClass(src, "A::AA", "A::AA::AAA")); + REQUIRE(IsInnerClass(src, "A::AA", "A::AA::Lights")); - REQUIRE(model->name() == "t00004_class"); + REQUIRE(IsMethod(src, "A", "foo")); + REQUIRE(IsMethod(src, "A", "foo2")); - CHECK_CLASS_DIAGRAM(config, diagram, *model, - [](const auto &src) { - REQUIRE(IsClass(src, "A")); - REQUIRE(IsClass(src, "A::AA")); - REQUIRE(IsClass(src, "A::AA::AAA")); - REQUIRE(IsEnum(src, "B::AA")); - REQUIRE(IsEnum(src, "A::AA::Lights")); - REQUIRE(IsInnerClass(src, "A", "A::AA")); - REQUIRE(IsInnerClass(src, "A::AA", "A::AA::AAA")); - REQUIRE(IsInnerClass(src, "A::AA", "A::AA::Lights")); + REQUIRE(IsClassTemplate(src, "C")); + REQUIRE(IsInnerClass(src, "C", "C::AA")); + REQUIRE(IsInnerClass(src, "C::AA", "C::AA::AAA")); + REQUIRE(IsInnerClass(src, "C", "C::CC")); + REQUIRE(IsInnerClass(src, "C::AA", "C::AA::CCC")); - REQUIRE(IsMethod(src, "A", "foo")); - REQUIRE(IsMethod(src, "A", "foo2")); + REQUIRE(IsInnerClass(src, "C", "C::B")); + REQUIRE(IsAggregation(src, "C", "C::B", "b_int")); + REQUIRE(!IsInnerClass(src, "C", "C::B")); + REQUIRE(IsInstantiation(src, "C::B", "C::B")); - REQUIRE(IsClassTemplate(src, "C")); - REQUIRE(IsInnerClass(src, "C", "C::AA")); - REQUIRE(IsInnerClass(src, "C::AA", "C::AA::AAA")); - REQUIRE(IsInnerClass(src, "C", "C::CC")); - REQUIRE(IsInnerClass(src, "C::AA", "C::AA::CCC")); - - REQUIRE(IsInnerClass(src, "C", "C::B")); - REQUIRE(IsAggregation(src, "C", "C::B", "b_int")); - REQUIRE(!IsInnerClass(src, "C", "C::B")); - REQUIRE(IsInstantiation(src, "C::B", "C::B")); - - REQUIRE(IsClass(src, "detail::D")); - REQUIRE(IsClass(src, "detail::D::DD")); - REQUIRE(IsEnum(src, "detail::D::AA")); - }); + REQUIRE(IsClass(src, {"detail", "D"})); + REQUIRE(IsClass(src, {"detail", "D::DD"})); + REQUIRE(IsEnum(src, {"detail", "D::AA"})); + }); } \ No newline at end of file diff --git a/tests/t00005/test_case.h b/tests/t00005/test_case.h index 1a6a5aff..44e60a26 100644 --- a/tests/t00005/test_case.h +++ b/tests/t00005/test_case.h @@ -20,46 +20,38 @@ TEST_CASE("t00005") { using namespace clanguml::test; - auto [config, db] = load_config("t00005"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00005", "t00005_class"); - auto diagram = config.diagrams["t00005_class"]; + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClass(src, "C")); + REQUIRE(IsClass(src, "D")); + REQUIRE(IsClass(src, "E")); + REQUIRE(IsClass(src, "F")); + REQUIRE(IsClass(src, "G")); + REQUIRE(IsClass(src, "H")); + REQUIRE(IsClass(src, "I")); + REQUIRE(IsClass(src, "J")); + REQUIRE(IsClass(src, "K")); + REQUIRE(IsClass(src, "R")); - REQUIRE(diagram->name == "t00005_class"); + REQUIRE((IsField(src, "R", "some_int", "int"))); + REQUIRE((IsField(src, "R", "some_int_pointer", "int *"))); + REQUIRE( + (IsField(src, "R", "some_int_pointer_pointer", "int **"))); - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00005_class"); - - CHECK_CLASS_DIAGRAM(config, diagram, *model, - [](const auto &src) { - REQUIRE(IsClass(src, "A")); - REQUIRE(IsClass(src, "B")); - REQUIRE(IsClass(src, "C")); - REQUIRE(IsClass(src, "D")); - REQUIRE(IsClass(src, "E")); - REQUIRE(IsClass(src, "F")); - REQUIRE(IsClass(src, "G")); - REQUIRE(IsClass(src, "H")); - REQUIRE(IsClass(src, "I")); - REQUIRE(IsClass(src, "J")); - REQUIRE(IsClass(src, "K")); - REQUIRE(IsClass(src, "R")); - - REQUIRE((IsField(src, "R", "some_int", "int"))); - REQUIRE((IsField(src, "R", "some_int_pointer", "int *"))); - REQUIRE((IsField( - src, "R", "some_int_pointer_pointer", "int **"))); - - REQUIRE(IsAggregation(src, "R", "A", "a")); - REQUIRE(IsAssociation(src, "R", "B", "b")); - REQUIRE(IsAssociation(src, "R", "C", "c")); - REQUIRE(IsAssociation(src, "R", "D", "d")); - REQUIRE(IsAssociation(src, "R", "E", "e")); - REQUIRE(IsAggregation(src, "R", "F", "f")); - REQUIRE(IsAssociation(src, "R", "G", "g")); - REQUIRE(IsAssociation(src, "R", "H", "h")); - REQUIRE(IsAssociation(src, "R", "I", "i")); - REQUIRE(IsAssociation(src, "R", "J", "j")); - REQUIRE(IsAssociation(src, "R", "K", "k")); - }); + REQUIRE(IsAggregation(src, "R", "A", "a")); + REQUIRE(IsAssociation(src, "R", "B", "b")); + REQUIRE(IsAssociation(src, "R", "C", "c")); + REQUIRE(IsAssociation(src, "R", "D", "d")); + REQUIRE(IsAssociation(src, "R", "E", "e")); + REQUIRE(IsAggregation(src, "R", "F", "f")); + REQUIRE(IsAssociation(src, "R", "G", "g")); + REQUIRE(IsAssociation(src, "R", "H", "h")); + REQUIRE(IsAssociation(src, "R", "I", "i")); + REQUIRE(IsAssociation(src, "R", "J", "j")); + REQUIRE(IsAssociation(src, "R", "K", "k")); + }); } \ No newline at end of file diff --git a/tests/t00006/test_case.h b/tests/t00006/test_case.h index 15372092..e56e49ea 100644 --- a/tests/t00006/test_case.h +++ b/tests/t00006/test_case.h @@ -20,54 +20,45 @@ TEST_CASE("t00006") { using namespace clanguml::test; - auto [config, db] = load_config("t00006"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00006", "t00006_class"); - auto diagram = config.diagrams["t00006_class"]; + CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsClass(src, "A")); + REQUIRE(IsClass(src, "B")); + REQUIRE(IsClass(src, "C")); + REQUIRE(IsClass(src, "D")); + REQUIRE(IsClass(src, "E")); + REQUIRE(IsClass(src, "F")); + REQUIRE(IsClass(src, "G")); + REQUIRE(IsClass(src, "H")); + REQUIRE(IsClass(src, "I")); + REQUIRE(IsClass(src, "J")); + REQUIRE(IsClass(src, "K")); + REQUIRE(IsClass(src, "L")); + REQUIRE(IsClass(src, "M")); + REQUIRE(IsClass(src, "N")); + REQUIRE(IsClass(src, "NN")); + REQUIRE(IsClass(src, "NNN")); - REQUIRE(diagram->name == "t00006_class"); + REQUIRE( + IsInstantiation(src, "custom_container", "custom_container")); - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00006_class"); - - CHECK_CLASS_DIAGRAM(config, diagram, *model, - [](const auto &src) { - REQUIRE(IsClass(src, "A")); - REQUIRE(IsClass(src, "B")); - REQUIRE(IsClass(src, "C")); - REQUIRE(IsClass(src, "D")); - REQUIRE(IsClass(src, "E")); - REQUIRE(IsClass(src, "F")); - REQUIRE(IsClass(src, "G")); - REQUIRE(IsClass(src, "H")); - REQUIRE(IsClass(src, "I")); - REQUIRE(IsClass(src, "J")); - REQUIRE(IsClass(src, "K")); - REQUIRE(IsClass(src, "L")); - REQUIRE(IsClass(src, "M")); - REQUIRE(IsClass(src, "N")); - REQUIRE(IsClass(src, "NN")); - REQUIRE(IsClass(src, "NNN")); - - REQUIRE(IsInstantiation( - src, "custom_container", "custom_container")); - - REQUIRE(IsAggregation(src, "R", "A", "a")); - REQUIRE(IsAssociation(src, "R", "B", "b")); - REQUIRE(IsAggregation(src, "R", "C", "c")); - REQUIRE(IsAssociation(src, "R", "D", "d")); - REQUIRE( - IsAggregation(src, "R", "custom_container", "e")); - REQUIRE(IsAggregation(src, "R", "F", "f")); - REQUIRE(IsAssociation(src, "R", "G", "g")); - REQUIRE(IsAggregation(src, "R", "H", "h")); - REQUIRE(IsAssociation(src, "R", "I", "i")); - REQUIRE(IsAggregation(src, "R", "J", "j")); - REQUIRE(IsAssociation(src, "R", "K", "k")); - REQUIRE(IsAggregation(src, "R", "L", "lm")); - REQUIRE(IsAggregation(src, "R", "M", "lm")); - REQUIRE(IsAggregation(src, "R", "N", "ns")); - REQUIRE(IsAggregation(src, "R", "NN", "ns")); - REQUIRE(IsAggregation(src, "R", "NNN", "ns")); - }); + REQUIRE(IsAggregation(src, "R", "A", "a")); + REQUIRE(IsAssociation(src, "R", "B", "b")); + REQUIRE(IsAggregation(src, "R", "C", "c")); + REQUIRE(IsAssociation(src, "R", "D", "d")); + REQUIRE(IsAggregation(src, "R", "custom_container", "e")); + REQUIRE(IsAggregation(src, "R", "F", "f")); + REQUIRE(IsAssociation(src, "R", "G", "g")); + REQUIRE(IsAggregation(src, "R", "H", "h")); + REQUIRE(IsAssociation(src, "R", "I", "i")); + REQUIRE(IsAggregation(src, "R", "J", "j")); + REQUIRE(IsAssociation(src, "R", "K", "k")); + REQUIRE(IsAggregation(src, "R", "L", "lm")); + REQUIRE(IsAggregation(src, "R", "M", "lm")); + REQUIRE(IsAggregation(src, "R", "N", "ns")); + REQUIRE(IsAggregation(src, "R", "NN", "ns")); + REQUIRE(IsAggregation(src, "R", "NNN", "ns")); + }); } \ No newline at end of file diff --git a/tests/t00007/test_case.h b/tests/t00007/test_case.h index 7de1274d..a8bc596e 100644 --- a/tests/t00007/test_case.h +++ b/tests/t00007/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00007") { using namespace clanguml::test; - auto [config, db] = load_config("t00007"); - - auto diagram = config.diagrams["t00007_class"]; - - REQUIRE(diagram->name == "t00007_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00007_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00007", "t00007_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A")); diff --git a/tests/t00008/test_case.h b/tests/t00008/test_case.h index 6ca63719..fb90fdc3 100644 --- a/tests/t00008/test_case.h +++ b/tests/t00008/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00008") { using namespace clanguml::test; - auto [config, db] = load_config("t00008"); - - auto diagram = config.diagrams["t00008_class"]; - - REQUIRE(diagram->name == "t00008_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00008_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00008", "t00008_class"); CHECK_CLASS_DIAGRAM( config, diagram, *model, diff --git a/tests/t00009/test_case.h b/tests/t00009/test_case.h index 10667f94..9fdb667d 100644 --- a/tests/t00009/test_case.h +++ b/tests/t00009/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00009") { using namespace clanguml::test; - auto [config, db] = load_config("t00009"); - - auto diagram = config.diagrams["t00009_class"]; - - REQUIRE(diagram->name == "t00009_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00009_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00009", "t00009_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClassTemplate(src, "A")); diff --git a/tests/t00010/test_case.h b/tests/t00010/test_case.h index e1d15a9c..6dfb726e 100644 --- a/tests/t00010/test_case.h +++ b/tests/t00010/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00010") { using namespace clanguml::test; - auto [config, db] = load_config("t00010"); - - auto diagram = config.diagrams["t00010_class"]; - - REQUIRE(diagram->name == "t00010_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00010_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00010", "t00010_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClassTemplate(src, "A")); diff --git a/tests/t00011/test_case.h b/tests/t00011/test_case.h index 115c41e6..cd05c673 100644 --- a/tests/t00011/test_case.h +++ b/tests/t00011/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00011") { using namespace clanguml::test; - auto [config, db] = load_config("t00011"); - - auto diagram = config.diagrams["t00011_class"]; - - REQUIRE(diagram->name == "t00011_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00011_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00011", "t00011_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A")); diff --git a/tests/t00012/test_case.h b/tests/t00012/test_case.h index b2bba300..02a6af31 100644 --- a/tests/t00012/test_case.h +++ b/tests/t00012/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00012") { using namespace clanguml::test; - auto [config, db] = load_config("t00012"); - - auto diagram = config.diagrams["t00012_class"]; - - REQUIRE(diagram->name == "t00012_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00012_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00012", "t00012_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClassTemplate(src, "A")); diff --git a/tests/t00013/test_case.h b/tests/t00013/test_case.h index f97c1cb8..7f96873f 100644 --- a/tests/t00013/test_case.h +++ b/tests/t00013/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00013") { using namespace clanguml::test; - auto [config, db] = load_config("t00013"); - - auto diagram = config.diagrams["t00013_class"]; - - REQUIRE(diagram->name == "t00013_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00013_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00013", "t00013_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A")); diff --git a/tests/t00014/test_case.h b/tests/t00014/test_case.h index bc9c1f97..0829306f 100644 --- a/tests/t00014/test_case.h +++ b/tests/t00014/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00014") { using namespace clanguml::test; - auto [config, db] = load_config("t00014"); - - auto diagram = config.diagrams["t00014_class"]; - - REQUIRE(diagram->name == "t00014_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00014_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00014", "t00014_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(!src.contains("type-parameter-")); @@ -126,249 +119,4 @@ TEST_CASE("t00014") REQUIRE(IsDependency(src, "R", "A")); REQUIRE(IsDependency(src, "R", "A")); }); - /* - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, !Contains("type-parameter-")); - - REQUIRE_THAT(src, IsClassTemplate("A", "T,P")); - REQUIRE_THAT(src, IsClassTemplate("A", "T,std::string")); - REQUIRE_THAT( - src, IsClassTemplate("A", "T,std::unique_ptr")); - REQUIRE_THAT(src, IsClassTemplate("A", "double,T")); - // TODO: Figure out how to handle the same templates with different - // template - // parameter names - // REQUIRE_THAT(puml, !IsClassTemplate("A", "long,U")); - REQUIRE_THAT(src, IsClassTemplate("A", "long,T")); - REQUIRE_THAT(src, IsClassTemplate("A", "long,bool")); - REQUIRE_THAT(src, IsClassTemplate("A", "double,bool")); - REQUIRE_THAT(src, IsClassTemplate("A", "long,float")); - REQUIRE_THAT(src, IsClassTemplate("A", "double,float")); - REQUIRE_THAT(src, IsClassTemplate("A", "bool,std::string")); - REQUIRE_THAT(src, IsClassTemplate("A", "std::string,std::string")); - REQUIRE_THAT(src, IsClassTemplate("A", "char,std::string")); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClassTemplate("R", "T")); - - REQUIRE_THAT(src, IsField("bapair", "PairPairBA")); - REQUIRE_THAT(src, IsField("abool", "APtr")); - REQUIRE_THAT(src, IsField("aboolfloat", - "AAPtr")); REQUIRE_THAT(src, IsField("afloat", - "ASharedPtr")); REQUIRE_THAT( src, IsField("boolstring", - "A")); REQUIRE_THAT(src, IsField("floatstring", - "AStringPtr")); REQUIRE_THAT(src, IsField("atfloat", - "AAPtr")); - - REQUIRE_THAT(src, IsField("intstring", "AIntString")); - REQUIRE_THAT(src, IsField("stringstring", - "AStringString")); REQUIRE_THAT(src, IsField("bstringstring", - "BStringString")); - - REQUIRE_THAT(src, IsField("bs", "BVector")); - - REQUIRE_THAT(src, IsField("cb", - "SimpleCallback")); #if LLVM_VERSION_MAJOR >= 16 REQUIRE_THAT( - src, IsField("gcb", "GenericCallback")); - #else - REQUIRE_THAT( - src, IsField("gcb", - "GenericCallback")); #endif REQUIRE_THAT(src, - IsField("vcb", "VoidCallback")); - - REQUIRE_THAT( - src, !IsClassTemplate("std::std::function", - "void(T...,int),int)")); - - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), - _A("A"))); - - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - // REQUIRE_THAT(puml, !IsInstantiation(_A("A"), - // _A("A"))); - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, - IsInstantiation(_A("A"), - _A("A"))); REQUIRE_THAT(src, - IsInstantiation(_A("A"), - _A("A"))); REQUIRE_THAT(src, IsInstantiation( - _A("A"), _A("A"))); - - REQUIRE_THAT(src, - IsInstantiation(_A("A>"), - _A("A>"))); - REQUIRE_THAT(src, - IsInstantiation( - _A("A"), _A("A>"))); - - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("B"), "+vps")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("B"), "-bapair")); - REQUIRE_THAT( - src, IsAggregation(_A("R"), _A("A"), - "-aboolfloat")); REQUIRE_THAT( src, IsAggregation(_A("R"), - _A("A"), "-bapair")); REQUIRE_THAT(src, IsAggregation(_A("R"), - _A("A"), "-aboolfloat")); REQUIRE_THAT( src, - IsAggregation(_A("R"), _A("A"), "-atfloat")); REQUIRE_THAT( - src, IsAggregation(_A("R"), _A("A"), - "-atfloat")); REQUIRE_THAT( src, IsAssociation(_A("R"), - _A("A"), "-afloat")); REQUIRE_THAT(src, IsAggregation( - _A("R"), _A("A"), "-boolstring")); - REQUIRE_THAT(src, - IsAggregation(_A("R"), - _A("A>"), - "-floatstring")); REQUIRE_THAT(src, IsDependency(_A("R"), - _A("A"))); REQUIRE_THAT( src, IsDependency(_A("R"), - _A("A"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "A>")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "A")); - REQUIRE(json::IsClass(j, "B")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsField; - - REQUIRE_THAT(src, !Contains("type-parameter-")); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A>"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - // TODO: Figure out how to handle the same templates with different - // template - // parameter names - // REQUIRE_THAT(puml, !IsClass("A", "long,U")); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - - REQUIRE_THAT(src, IsField("bapair", "PairPairBA")); - REQUIRE_THAT(src, IsField("abool", "APtr")); - REQUIRE_THAT(src, IsField("aboolfloat", - "AAPtr")); REQUIRE_THAT(src, IsField("afloat", - "ASharedPtr")); REQUIRE_THAT( src, IsField("boolstring", - "A")); REQUIRE_THAT(src, IsField("floatstring", - "AStringPtr")); REQUIRE_THAT(src, IsField("atfloat", - "AAPtr")); - - REQUIRE_THAT(src, IsField("intstring", "AIntString")); - REQUIRE_THAT(src, IsField("stringstring", - "AStringString")); REQUIRE_THAT(src, IsField("bstringstring", - "BStringString")); - - REQUIRE_THAT(src, IsField("bs", "BVector")); - - REQUIRE_THAT(src, IsField("cb", - "SimpleCallback")); #if LLVM_VERSION_MAJOR >= 16 REQUIRE_THAT( - src, IsField("gcb", "GenericCallback")); - #else - REQUIRE_THAT( - src, IsField("gcb", - "GenericCallback")); #endif REQUIRE_THAT(src, - IsField("vcb", "VoidCallback")); - - REQUIRE_THAT( - src, !IsClassTemplate("std::std::function", - "void(T...,int),int)")); - - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), - _A("A"))); - - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - // REQUIRE_THAT(puml, !IsInstantiation(_A("A"), - // _A("A"))); - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, - IsInstantiation(_A("A"), - _A("A"))); REQUIRE_THAT(src, - IsInstantiation(_A("A"), - _A("A"))); REQUIRE_THAT(src, IsInstantiation( - _A("A"), _A("A"))); - - REQUIRE_THAT(src, - IsInstantiation(_A("A>"), - _A("A>"))); - REQUIRE_THAT(src, - IsInstantiation( - _A("A"), _A("A>"))); - - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("B"), "+vps")); - REQUIRE_THAT(src, IsAggregation(_A("R"), _A("B"), "-bapair")); - REQUIRE_THAT( - src, IsAggregation(_A("R"), _A("A"), - "-aboolfloat")); REQUIRE_THAT( src, IsAggregation(_A("R"), - _A("A"), "-bapair")); REQUIRE_THAT(src, IsAggregation(_A("R"), - _A("A"), "-aboolfloat")); REQUIRE_THAT( src, - IsAggregation(_A("R"), _A("A"), "-atfloat")); REQUIRE_THAT( - src, IsAggregation(_A("R"), _A("A"), - "-atfloat")); REQUIRE_THAT( src, IsAssociation(_A("R"), - _A("A"), "-afloat")); REQUIRE_THAT(src, IsAggregation( - _A("R"), _A("A"), "-boolstring")); - REQUIRE_THAT(src, - IsAggregation(_A("R"), - _A("A>"), - "-floatstring")); #if !defined(__APPLE__) - // TODO(#176) - REQUIRE_THAT(src, IsDependency(_A("R"), - _A("A"))); REQUIRE_THAT( src, IsDependency(_A("R"), - _A("A"))); #endif - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - } - */ } \ No newline at end of file diff --git a/tests/t00015/test_case.h b/tests/t00015/test_case.h index 9dd602f2..34f32410 100644 --- a/tests/t00015/test_case.h +++ b/tests/t00015/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00015") { using namespace clanguml::test; - auto [config, db] = load_config("t00015"); - - auto diagram = config.diagrams["t00015_class"]; - - REQUIRE(diagram->name == "t00015_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00015_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00015", "t00015_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "ns1::A")); diff --git a/tests/t00016/test_case.h b/tests/t00016/test_case.h index 161597e8..a4e0dfbc 100644 --- a/tests/t00016/test_case.h +++ b/tests/t00016/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00016") { using namespace clanguml::test; - auto [config, db] = load_config("t00016"); - - auto diagram = config.diagrams["t00016_class"]; - - REQUIRE(diagram->name == "t00016_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00016_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00016", "t00016_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClassTemplate(src, "is_numeric")); diff --git a/tests/t00017/test_case.h b/tests/t00017/test_case.h index 644aebec..bf61fb62 100644 --- a/tests/t00017/test_case.h +++ b/tests/t00017/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00017") { using namespace clanguml::test; - auto [config, db] = load_config("t00017"); - - auto diagram = config.diagrams["t00017_class"]; - - REQUIRE(diagram->name == "t00017_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00017_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00017", "t00017_class"); CHECK_CLASS_DIAGRAM( config, diagram, *model, diff --git a/tests/t00018/test_case.h b/tests/t00018/test_case.h index 7424462f..5ab46a7e 100644 --- a/tests/t00018/test_case.h +++ b/tests/t00018/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00018") { using namespace clanguml::test; - auto [config, db] = load_config("t00018"); - - auto diagram = config.diagrams["t00018_class"]; - - REQUIRE(diagram->name == "t00018_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00018_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00018", "t00018_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "widget")); diff --git a/tests/t00019/test_case.h b/tests/t00019/test_case.h index 7d17aa32..ceab5e62 100644 --- a/tests/t00019/test_case.h +++ b/tests/t00019/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00019") { using namespace clanguml::test; - auto [config, db] = load_config("t00019"); - - auto diagram = config.diagrams["t00019_class"]; - - REQUIRE(diagram->name == "t00019_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00019_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00019", "t00019_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "Base")); diff --git a/tests/t00020/test_case.h b/tests/t00020/test_case.h index 6657869d..bef7d8c8 100644 --- a/tests/t00020/test_case.h +++ b/tests/t00020/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00020") { using namespace clanguml::test; - auto [config, db] = load_config("t00020"); - - auto diagram = config.diagrams["t00020_class"]; - - REQUIRE(diagram->name == "t00020_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00020_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00020", "t00020_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsAbstractClass(src, "AbstractFactory")); @@ -41,55 +34,4 @@ TEST_CASE("t00020") REQUIRE(IsClass(src, "Factory1")); REQUIRE(IsClass(src, "Factory2")); }); - /* - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsAbstractClass(_A("ProductA"))); - REQUIRE_THAT(src, IsAbstractClass(_A("ProductB"))); - REQUIRE_THAT(src, IsClass(_A("ProductA1"))); - REQUIRE_THAT(src, IsClass(_A("ProductA2"))); - REQUIRE_THAT(src, IsClass(_A("ProductB1"))); - REQUIRE_THAT(src, IsClass(_A("ProductB2"))); - REQUIRE_THAT(src, IsAbstractClass(_A("AbstractFactory"))); - REQUIRE_THAT(src, IsClass(_A("Factory1"))); - REQUIRE_THAT(src, IsClass(_A("Factory2"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "ProductA1")); - REQUIRE(IsClass(j, "ProductA2")); - REQUIRE(IsClass(j, "ProductB1")); - REQUIRE(IsClass(j, "ProductB2")); - REQUIRE(IsAbstractClass(j, "AbstractFactory")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsAbstractClass; - - REQUIRE_THAT(src, IsAbstractClass(_A("ProductA"))); - REQUIRE_THAT(src, IsAbstractClass(_A("ProductB"))); - REQUIRE_THAT(src, IsClass(_A("ProductA1"))); - REQUIRE_THAT(src, IsClass(_A("ProductA2"))); - REQUIRE_THAT(src, IsClass(_A("ProductB1"))); - REQUIRE_THAT(src, IsClass(_A("ProductB2"))); - REQUIRE_THAT(src, IsAbstractClass(_A("AbstractFactory"))); - REQUIRE_THAT(src, IsClass(_A("Factory1"))); - REQUIRE_THAT(src, IsClass(_A("Factory2"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t00021/test_case.h b/tests/t00021/test_case.h index a9c511b6..8b99c173 100644 --- a/tests/t00021/test_case.h +++ b/tests/t00021/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00021") { using namespace clanguml::test; - auto [config, db] = load_config("t00021"); - - auto diagram = config.diagrams["t00021_class"]; - - REQUIRE(diagram->name == "t00021_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00021_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00021", "t00021_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsAbstractClass(src, "Item")); diff --git a/tests/t00022/test_case.h b/tests/t00022/test_case.h index af819cb7..cf060684 100644 --- a/tests/t00022/test_case.h +++ b/tests/t00022/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00022") { using namespace clanguml::test; - auto [config, db] = load_config("t00022"); - - auto diagram = config.diagrams["t00022_class"]; - - REQUIRE(diagram->name == "t00022_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00022_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00022", "t00022_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A1")); diff --git a/tests/t00023/test_case.h b/tests/t00023/test_case.h index 0e49a4fb..14da15a7 100644 --- a/tests/t00023/test_case.h +++ b/tests/t00023/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00023") { using namespace clanguml::test; - auto [config, db] = load_config("t00023"); - - auto diagram = config.diagrams["t00023_class"]; - - REQUIRE(diagram->name == "t00023_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00023_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00023", "t00023_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsAbstractClass(src, "Strategy")); diff --git a/tests/t00024/test_case.h b/tests/t00024/test_case.h index 7ecd61c1..c0f79c35 100644 --- a/tests/t00024/test_case.h +++ b/tests/t00024/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00024") { using namespace clanguml::test; - auto [config, db] = load_config("t00024"); - - auto diagram = config.diagrams["t00024_class"]; - - REQUIRE(diagram->name == "t00024_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00024_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00024", "t00024_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "Target1")); diff --git a/tests/t00025/test_case.h b/tests/t00025/test_case.h index dbe33d13..c6b466a6 100644 --- a/tests/t00025/test_case.h +++ b/tests/t00025/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00025") { using namespace clanguml::test; - auto [config, db] = load_config("t00025"); - - auto diagram = config.diagrams["t00025_class"]; - - REQUIRE(diagram->name == "t00025_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00025_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00025", "t00025_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "Target1")); diff --git a/tests/t00026/test_case.h b/tests/t00026/test_case.h index 90ecca47..92349753 100644 --- a/tests/t00026/test_case.h +++ b/tests/t00026/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00026") { using namespace clanguml::test; - auto [config, db] = load_config("t00026"); - - auto diagram = config.diagrams["t00026_class"]; - - REQUIRE(diagram->name == "t00026_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00026_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00026", "t00026_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClassTemplate(src, "Memento")); diff --git a/tests/t00027/test_case.h b/tests/t00027/test_case.h index afc9133f..71afe72e 100644 --- a/tests/t00027/test_case.h +++ b/tests/t00027/test_case.h @@ -19,16 +19,9 @@ TEST_CASE("t00027") { using namespace clanguml::test; - - auto [config, db] = load_config("t00027"); - auto diagram = config.diagrams["t00027_class"]; - - REQUIRE(diagram->name == "t00027_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00027_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00027", "t00027_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsAbstractClass(src, "Shape")); @@ -37,7 +30,8 @@ TEST_CASE("t00027") REQUIRE(IsClassTemplate(src, "Line...>")); REQUIRE(IsInstantiation(src, "Line...>", "Line")); REQUIRE(IsInstantiation(src, "Line...>", "Line")); - REQUIRE(IsAggregation(src, "Window", "Text", "description")); + REQUIRE( + IsAggregation(src, "Window", "Text", "description")); REQUIRE(IsInstantiation(src, "Line...>", "Line")); REQUIRE(IsInstantiation(src, "Line...>", "Line")); @@ -52,80 +46,4 @@ TEST_CASE("t00027") REQUIRE( IsAggregation(src, "Window", "Text", "description")); }); -/* - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, IsAbstractClass(_A("Shape"))); - REQUIRE_THAT(src, IsAbstractClass(_A("ShapeDecorator"))); - REQUIRE_THAT(src, IsClassTemplate("Line", "T<>...")); - REQUIRE_THAT(src, IsClassTemplate("Text", "T<>...")); - REQUIRE_THAT( - src, IsInstantiation(_A("Line...>"), _A("Line"))); - REQUIRE_THAT( - src, IsInstantiation(_A("Line...>"), _A("Line"))); - REQUIRE_THAT( - src, IsInstantiation(_A("Text...>"), _A("Text"))); - REQUIRE_THAT( - src, IsInstantiation(_A("Text...>"), _A("Text"))); - - REQUIRE_THAT(src, - IsAggregation(_A("Window"), _A("Line"), "+border")); - REQUIRE_THAT( - src, IsAggregation(_A("Window"), _A("Line"), "+divider")); - REQUIRE_THAT(src, - IsAggregation(_A("Window"), _A("Text"), "+title")); - REQUIRE_THAT(src, - IsAggregation(_A("Window"), _A("Text"), "+description")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsAbstractClass(j, "Shape")); - REQUIRE(IsAbstractClass(j, "ShapeDecorator")); - - REQUIRE(IsClassTemplate(j, "Line...>")); - REQUIRE(IsInstantiation(j, "Line...>", "Line")); - REQUIRE(IsInstantiation(j, "Line...>", "Line")); - REQUIRE(IsAggregation(j, "Window", "Text", "description")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsAbstractClass; - - REQUIRE_THAT(src, IsAbstractClass(_A("Shape"))); - REQUIRE_THAT(src, IsAbstractClass(_A("ShapeDecorator"))); - REQUIRE_THAT(src, IsClass(_A("Line...>"))); - REQUIRE_THAT(src, IsClass(_A("Text...>"))); - REQUIRE_THAT( - src, IsInstantiation(_A("Line...>"), _A("Line"))); - REQUIRE_THAT( - src, IsInstantiation(_A("Line...>"), _A("Line"))); - REQUIRE_THAT( - src, IsInstantiation(_A("Text...>"), _A("Text"))); - REQUIRE_THAT( - src, IsInstantiation(_A("Text...>"), _A("Text"))); - - REQUIRE_THAT(src, - IsAggregation(_A("Window"), _A("Line"), "+border")); - REQUIRE_THAT( - src, IsAggregation(_A("Window"), _A("Line"), "+divider")); - REQUIRE_THAT(src, - IsAggregation(_A("Window"), _A("Text"), "+title")); - REQUIRE_THAT(src, - IsAggregation(_A("Window"), _A("Text"), "+description")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } \ No newline at end of file diff --git a/tests/t00028/test_case.h b/tests/t00028/test_case.h index 6a1980ad..ad2860b0 100644 --- a/tests/t00028/test_case.h +++ b/tests/t00028/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00028") { using namespace clanguml::test; - auto [config, db] = load_config("t00028"); - - auto diagram = config.diagrams["t00028_class"]; - - REQUIRE(diagram->name == "t00028_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00028_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00028", "t00028_class"); CHECK_CLASS_DIAGRAM( config, diagram, *model, @@ -63,80 +56,4 @@ note.)"; REQUIRE(HasNote(src, "R", "left", "R contains an instance of A.")); REQUIRE(!HasNote(src, "G", "left", "G class note.")); }); - /* - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClassTemplate("E", "T")); - REQUIRE_THAT(src, IsEnum(_A("F"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - REQUIRE_THAT(src, HasNote(_A("A"), "top", "A class note.")); - REQUIRE_THAT(src, HasNote(_A("B"), "left", "B class note.")); - REQUIRE_THAT(src, HasNote(_A("C"), "bottom", "C class note.")); - const auto d_note = R"( - D - class - note.)"; - REQUIRE_THAT(src, HasNote(_A("D"), "left", d_note)); - REQUIRE_THAT( - src, HasNote(_A("E"), "left", "E template class note.")); - REQUIRE_THAT(src, HasNote(_A("F"), "bottom", "F enum note.")); - REQUIRE_THAT(src, !HasNote(_A("G"), "left", "G class note.")); - REQUIRE_THAT(src, HasNote(_A("R"), "right", "R class note.")); - REQUIRE_THAT(src, - HasMemberNote( - _A("R"), "aaa", "left", "R contains an instance of A.")); - REQUIRE_THAT( - src, !HasMemberNote(_A("R"), "bbb", "right", "R class note.")); - REQUIRE_THAT( - src, HasMemberNote(_A("R"), "ccc", "left", "Reference to C.")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::HasNote; - using mermaid::IsEnum; - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - REQUIRE_THAT(src, IsEnum(_A("F"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - REQUIRE_THAT(src, HasNote(_A("A"), "top", "A class note.")); - REQUIRE_THAT(src, HasNote(_A("B"), "left", "B class note.")); - REQUIRE_THAT(src, HasNote(_A("C"), "bottom", "C class note.")); - const auto d_note = R"( - D - class - note.)"; - REQUIRE_THAT(src, HasNote(_A("D"), "left", d_note)); - REQUIRE_THAT( - src, HasNote(_A("E"), "left", "E template class note.")); - REQUIRE_THAT(src, HasNote(_A("F"), "bottom", "F enum note.")); - REQUIRE_THAT(src, !HasNote(_A("G"), "left", "G class note.")); - REQUIRE_THAT(src, HasNote(_A("R"), "right", "R class note.")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t00029/test_case.h b/tests/t00029/test_case.h index 4e70ae2d..4d969d1d 100644 --- a/tests/t00029/test_case.h +++ b/tests/t00029/test_case.h @@ -20,13 +20,8 @@ TEST_CASE("t00029") { using namespace clanguml::test; - auto [config, db] = load_config("t00029"); - - auto diagram = config.diagrams["t00029_class"]; - - REQUIRE(diagram->name == "t00029_class"); - - auto model = generate_class_diagram(*db, diagram); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00029", "t00029_class"); REQUIRE(model->name() == "t00029_class"); diff --git a/tests/t00030/test_case.h b/tests/t00030/test_case.h index 30a0a2f0..f51dbd1c 100644 --- a/tests/t00030/test_case.h +++ b/tests/t00030/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00030") { using namespace clanguml::test; - auto [config, db] = load_config("t00030"); - - auto diagram = config.diagrams["t00030_class"]; - - REQUIRE(diagram->name == "t00030_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00030_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00030", "t00030_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A")); diff --git a/tests/t00031/test_case.h b/tests/t00031/test_case.h index c0c7bb90..c3f873dd 100644 --- a/tests/t00031/test_case.h +++ b/tests/t00031/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00031") { using namespace clanguml::test; - auto [config, db] = load_config("t00031"); - - auto diagram = config.diagrams["t00031_class"]; - - REQUIRE(diagram->name == "t00031_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00031_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00031", "t00031_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A")); diff --git a/tests/t00032/test_case.h b/tests/t00032/test_case.h index 1277d186..59582dfa 100644 --- a/tests/t00032/test_case.h +++ b/tests/t00032/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00032") { using namespace clanguml::test; - auto [config, db] = load_config("t00032"); - - auto diagram = config.diagrams["t00032_class"]; - - REQUIRE(diagram->name == "t00032_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00032_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00032", "t00032_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "Base")); diff --git a/tests/t00033/test_case.h b/tests/t00033/test_case.h index 40290923..b5cca187 100644 --- a/tests/t00033/test_case.h +++ b/tests/t00033/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00033") { using namespace clanguml::test; - auto [config, db] = load_config("t00033"); - - auto diagram = config.diagrams["t00033_class"]; - - REQUIRE(diagram->name == "t00033_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00033_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00033", "t00033_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClassTemplate(src, "A")); diff --git a/tests/t00034/test_case.h b/tests/t00034/test_case.h index 6a65ac59..45040d82 100644 --- a/tests/t00034/test_case.h +++ b/tests/t00034/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00034") { using namespace clanguml::test; - auto [config, db] = load_config("t00034"); - - auto diagram = config.diagrams["t00034_class"]; - - REQUIRE(diagram->name == "t00034_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00034_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00034", "t00034_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClassTemplate(src, "lift_void")); diff --git a/tests/t00035/test_case.h b/tests/t00035/test_case.h index 95b0d2bf..02d63311 100644 --- a/tests/t00035/test_case.h +++ b/tests/t00035/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00035") { using namespace clanguml::test; - auto [config, db] = load_config("t00035"); - - auto diagram = config.diagrams["t00035_class"]; - - REQUIRE(diagram->name == "t00035_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00035_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00035", "t00035_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "Top")); diff --git a/tests/t00036/test_case.h b/tests/t00036/test_case.h index 16c5fe68..6e44a5d9 100644 --- a/tests/t00036/test_case.h +++ b/tests/t00036/test_case.h @@ -21,17 +21,11 @@ TEST_CASE("t00036") using namespace clanguml::test; using namespace std::string_literals; - auto [config, db] = load_config("t00036"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00036", "t00036_class"); - auto diagram = config.diagrams["t00036_class"]; - - REQUIRE(diagram->name == "t00036_class"); REQUIRE(diagram->generate_packages() == true); - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00036_class"); - CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClassTemplate(src, {"ns1::ns11", "A"})); REQUIRE(IsClassTemplate(src, {"ns1::ns11", "A"})); diff --git a/tests/t00037/test_case.h b/tests/t00037/test_case.h index 6ad47529..662bccbc 100644 --- a/tests/t00037/test_case.h +++ b/tests/t00037/test_case.h @@ -20,17 +20,11 @@ TEST_CASE("t00037") { using namespace clanguml::test; - auto [config, db] = load_config("t00037"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00037", "t00037_class"); - auto diagram = config.diagrams["t00037_class"]; - - REQUIRE(diagram->name == "t00037_class"); REQUIRE(diagram->generate_packages() == true); - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00037_class"); - CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "ST")); REQUIRE(IsClass(src, "A")); diff --git a/tests/t00038/test_case.h b/tests/t00038/test_case.h index 5b16987d..ae900531 100644 --- a/tests/t00038/test_case.h +++ b/tests/t00038/test_case.h @@ -18,18 +18,10 @@ TEST_CASE("t00038") { - using namespace clanguml::test; + using namespace clanguml::test; - auto [config, db] = load_config("t00038"); - - auto diagram = config.diagrams["t00038_class"]; - - REQUIRE(diagram->name == "t00038_class"); - REQUIRE(diagram->generate_packages() == false); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00038_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00038", "t00038_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A")); diff --git a/tests/t00039/test_case.h b/tests/t00039/test_case.h index 36788d3f..1d722056 100644 --- a/tests/t00039/test_case.h +++ b/tests/t00039/test_case.h @@ -18,17 +18,10 @@ TEST_CASE("t00039") { - using namespace clanguml::test; + using namespace clanguml::test; - auto [config, db] = load_config("t00039"); - - auto diagram = config.diagrams["t00039_class"]; - - REQUIRE(diagram->name == "t00039_class"); - REQUIRE(diagram->generate_packages() == false); - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00039_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00039", "t00039_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A")); diff --git a/tests/t00040/test_case.h b/tests/t00040/test_case.h index 8b21ef25..d5915b71 100644 --- a/tests/t00040/test_case.h +++ b/tests/t00040/test_case.h @@ -20,16 +20,8 @@ TEST_CASE("t00040") { using namespace clanguml::test; - 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 [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00040", "t00040_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A")); diff --git a/tests/t00041/test_case.h b/tests/t00041/test_case.h index 5b262bdd..2fbfd147 100644 --- a/tests/t00041/test_case.h +++ b/tests/t00041/test_case.h @@ -20,17 +20,11 @@ TEST_CASE("t00041") { using namespace clanguml::test; - auto [config, db] = load_config("t00041"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00041", "t00041_class"); - auto diagram = config.diagrams["t00041_class"]; - - REQUIRE(diagram->name == "t00041_class"); REQUIRE(diagram->generate_packages() == false); - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00041_class"); - CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(!IsClass(src, "A")); REQUIRE(!IsClass(src, "AA")); diff --git a/tests/t00042/test_case.h b/tests/t00042/test_case.h index b3e11df5..b5c411ea 100644 --- a/tests/t00042/test_case.h +++ b/tests/t00042/test_case.h @@ -20,17 +20,11 @@ TEST_CASE("t00042") { using namespace clanguml::test; - auto [config, db] = load_config("t00042"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00042", "t00042_class"); - auto diagram = config.diagrams["t00042_class"]; - - REQUIRE(diagram->name == "t00042_class"); REQUIRE(diagram->generate_packages() == false); - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00042_class"); - CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClassTemplate(src, "A")); REQUIRE(IsClassTemplate(src, "B")); diff --git a/tests/t00043/test_case.h b/tests/t00043/test_case.h index ce65f719..1f81bb68 100644 --- a/tests/t00043/test_case.h +++ b/tests/t00043/test_case.h @@ -20,16 +20,8 @@ TEST_CASE("t00043") { using namespace clanguml::test; - auto [config, db] = load_config("t00043"); - - auto diagram = config.diagrams["t00043_class"]; - - REQUIRE(diagram->name == "t00043_class"); - REQUIRE(diagram->generate_packages() == true); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00043_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00043", "t00043_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, {"dependants", "A"})); diff --git a/tests/t00044/test_case.h b/tests/t00044/test_case.h index 18955892..da66d8e7 100644 --- a/tests/t00044/test_case.h +++ b/tests/t00044/test_case.h @@ -20,16 +20,8 @@ TEST_CASE("t00044") { using namespace clanguml::test; - auto [config, db] = load_config("t00044"); - - auto diagram = config.diagrams["t00044_class"]; - - REQUIRE(diagram->name == "t00044_class"); - REQUIRE(diagram->generate_packages() == true); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00044_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00044", "t00044_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(!src.contains("type-parameter-")); diff --git a/tests/t00045/test_case.h b/tests/t00045/test_case.h index a70c4da9..be6b8957 100644 --- a/tests/t00045/test_case.h +++ b/tests/t00045/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00045") { using namespace clanguml::test; - auto [config, db] = load_config("t00045"); - - auto diagram = config.diagrams["t00045_class"]; - - REQUIRE(diagram->name == "t00045_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00045_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00045", "t00045_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A")); diff --git a/tests/t00046/test_case.h b/tests/t00046/test_case.h index 35285e25..b7fca9a4 100644 --- a/tests/t00046/test_case.h +++ b/tests/t00046/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00046") { using namespace clanguml::test; - auto [config, db] = load_config("t00046"); - - auto diagram = config.diagrams["t00046_class"]; - - REQUIRE(diagram->name == "t00046_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00046_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00046", "t00046_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A")); @@ -40,6 +33,6 @@ TEST_CASE("t00046") REQUIRE(IsClass(src, {"ns1::ns2", "R"})); REQUIRE(IsField( - src, "ns1::ns2::R", "i", "std::vector")); + src, {"ns1::ns2", "R"}, "i", "std::vector")); }); } \ No newline at end of file diff --git a/tests/t00047/test_case.h b/tests/t00047/test_case.h index 07a3b334..bef97c84 100644 --- a/tests/t00047/test_case.h +++ b/tests/t00047/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00047") { using namespace clanguml::test; - auto [config, db] = load_config("t00047"); - - auto diagram = config.diagrams["t00047_class"]; - - REQUIRE(diagram->name == "t00047_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00047_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00047", "t00047_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClassTemplate(src, "conditional_t")); diff --git a/tests/t00048/test_case.h b/tests/t00048/test_case.h index 69b726a3..f7f7b5f3 100644 --- a/tests/t00048/test_case.h +++ b/tests/t00048/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00048") { using namespace clanguml::test; - auto [config, db] = load_config("t00048"); - - auto diagram = config.diagrams["t00048_class"]; - - REQUIRE(diagram->name == "t00048_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00048_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00048", "t00048_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { // Check if all classes exist diff --git a/tests/t00049/test_case.h b/tests/t00049/test_case.h index 4272f408..b75afa8f 100644 --- a/tests/t00049/test_case.h +++ b/tests/t00049/test_case.h @@ -20,15 +20,9 @@ TEST_CASE("t00049") { using namespace clanguml::test; - auto [config, db] = load_config("t00049"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00049", "t00049_class"); - auto diagram = config.diagrams["t00049_class"]; - - REQUIRE(diagram->name == "t00049_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00049_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "R")); diff --git a/tests/t00050/test_case.h b/tests/t00050/test_case.h index 9363db62..32802240 100644 --- a/tests/t00050/test_case.h +++ b/tests/t00050/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00050") { using namespace clanguml::test; - auto [config, db] = load_config("t00050"); - - auto diagram = config.diagrams["t00050_class"]; - - REQUIRE(diagram->name == "t00050_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00050_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00050", "t00050_class"); CHECK_CLASS_DIAGRAM( config, diagram, *model, diff --git a/tests/t00051/test_case.h b/tests/t00051/test_case.h index cfcebade..f3f3c39a 100644 --- a/tests/t00051/test_case.h +++ b/tests/t00051/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00051") { using namespace clanguml::test; - auto [config, db] = load_config("t00051"); - - auto diagram = config.diagrams["t00051_class"]; - - REQUIRE(diagram->name == "t00051_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00051_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00051", "t00051_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A")); @@ -59,106 +52,4 @@ TEST_CASE("t00051") REQUIRE(IsDependency(src, "A", "B<(lambda at t00051.cc:43:18),(lambda at t00051.cc:43:27)>")); }); - /* - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsInnerClass(_A("A"), _A("A::custom_thread1"))); - REQUIRE_THAT(src, IsInnerClass(_A("A"), _A("A::custom_thread2"))); - - REQUIRE_THAT(src, - (IsMethod("custom_thread1", "void", - "Function && f, Args &&... args"))); - REQUIRE_THAT(src, - (IsMethod( - "thread", "void", "(lambda at t00051.cc:59:27) &&"))); - REQUIRE_THAT(src, - (IsMethod("start_thread3", - "B<(lambda at t00051.cc:43:18),(lambda at " - "t00051.cc:43:27)>"))); - REQUIRE_THAT(src, - (IsMethod("get_function", "(lambda at t00051.cc:48:16)"))); - - REQUIRE_THAT(src, IsClassTemplate("B", "F,FF=F")); - REQUIRE_THAT(src, (IsMethod("f", "void"))); - REQUIRE_THAT(src, (IsMethod("ff", "void"))); - - REQUIRE_THAT(src, - IsClassTemplate("B", - "(lambda at t00051.cc:43:18),(lambda at t00051.cc:43:27)")); - - REQUIRE_THAT(src, - IsInstantiation(_A("B"), - _A("B<(lambda at t00051.cc:43:18),(lambda at " - "t00051.cc:43:27)>"))); - - REQUIRE_THAT(src, - IsDependency(_A("A"), - _A("B<(lambda at t00051.cc:43:18),(lambda " - "at t00051.cc:43:27)>"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsInnerClass(j, "A", "A::custom_thread1")); - REQUIRE(IsInnerClass(j, "A", "A::custom_thread2")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsInnerClass; - using mermaid::IsMethod; - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsInnerClass(_A("A"), _A("A::custom_thread1"))); - REQUIRE_THAT(src, IsInnerClass(_A("A"), _A("A::custom_thread2"))); - - REQUIRE_THAT(src, - (IsMethod("custom_thread1", "void", - "Function && f, Args &&... args"))); - REQUIRE_THAT(src, - (IsMethod( - "thread", "void", "(lambda at t00051.cc:59:27) &&"))); - REQUIRE_THAT(src, - (IsMethod("start_thread3", - "B<(lambda at t00051.cc:43:18),(lambda at t00051.cc:43:27)>"))); - REQUIRE_THAT(src, - (IsMethod("get_function", "(lambda at t00051.cc:48:16)"))); - - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, (IsMethod("f", "void"))); - REQUIRE_THAT(src, (IsMethod("ff", "void"))); - - REQUIRE_THAT(src, - IsClass(_A("B<(lambda at t00051.cc:43:18),(lambda at " - "t00051.cc:43:27)>"))); - - REQUIRE_THAT(src, - IsInstantiation(_A("B"), - _A("B<(lambda at t00051.cc:43:18),(lambda at " - "t00051.cc:43:27)>"))); - - REQUIRE_THAT(src, - IsDependency(_A("A"), - _A("B<(lambda at t00051.cc:43:18),(lambda " - "at t00051.cc:43:27)>"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } - */ } \ No newline at end of file diff --git a/tests/t00052/test_case.h b/tests/t00052/test_case.h index ee2dce46..e9c27346 100644 --- a/tests/t00052/test_case.h +++ b/tests/t00052/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00052") { using namespace clanguml::test; - auto [config, db] = load_config("t00052"); - - auto diagram = config.diagrams["t00052_class"]; - - REQUIRE(diagram->name == "t00052_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00052_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00052", "t00052_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A")); @@ -40,57 +33,4 @@ TEST_CASE("t00052") REQUIRE(IsMethod(src, "B", "b", "T", "T t")); REQUIRE(IsMethod(src, "B", "bb", "T", "F && f, T t")); }); - /* - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("A"))); - - // Check if class templates exist - REQUIRE_THAT(src, IsClassTemplate("B", "T")); - - // Check if all methods exist - REQUIRE_THAT(src, (IsMethod("a", "T", "T p"))); - REQUIRE_THAT(src, (IsMethod("aa", "void", "F && f, Q q"))); - REQUIRE_THAT(src, (IsMethod("b", "T", "T t"))); - REQUIRE_THAT(src, (IsMethod("bb", "T", "F && f, T t"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClassTemplate(j, "B")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsMethod; - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("A"))); - - // Check if class templates exist - REQUIRE_THAT(src, IsClass(_A("B"))); - - // Check if all methods exist - REQUIRE_THAT(src, (IsMethod("a", "T", "T p"))); - REQUIRE_THAT(src, (IsMethod("aa", "void", "F && f, Q q"))); - REQUIRE_THAT(src, (IsMethod("b", "T", "T t"))); - REQUIRE_THAT(src, (IsMethod("bb", "T", "F && f, T t"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } - */ } \ No newline at end of file diff --git a/tests/t00053/test_case.h b/tests/t00053/test_case.h index badae765..23d3b4ac 100644 --- a/tests/t00053/test_case.h +++ b/tests/t00053/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00053") { using namespace clanguml::test; - auto [config, db] = load_config("t00053"); - - auto diagram = config.diagrams["t00053_class"]; - - REQUIRE(diagram->name == "t00053_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00053_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00053", "t00053_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "a")); @@ -47,81 +40,4 @@ TEST_CASE("t00053") REQUIRE(IsClass(src, "F")); REQUIRE(IsClass(src, "G")); }); - /* - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("a"))); - REQUIRE_THAT(src, IsClass(_A("b"))); - REQUIRE_THAT(src, IsClass(_A("c"))); - REQUIRE_THAT(src, IsClass(_A("d"))); - REQUIRE_THAT(src, IsClass(_A("e"))); - REQUIRE_THAT(src, IsClass(_A("f"))); - REQUIRE_THAT(src, IsClass(_A("g"))); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - REQUIRE_THAT(src, IsClass(_A("F"))); - REQUIRE_THAT(src, IsClass(_A("G"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "a")); - REQUIRE(IsClass(j, "b")); - REQUIRE(IsClass(j, "c")); - REQUIRE(IsClass(j, "d")); - REQUIRE(IsClass(j, "e")); - REQUIRE(IsClass(j, "f")); - REQUIRE(IsClass(j, "g")); - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - REQUIRE(IsClass(j, "C")); - REQUIRE(IsClass(j, "D")); - REQUIRE(IsClass(j, "E")); - REQUIRE(IsClass(j, "F")); - REQUIRE(IsClass(j, "G")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("a"))); - REQUIRE_THAT(src, IsClass(_A("b"))); - REQUIRE_THAT(src, IsClass(_A("c"))); - REQUIRE_THAT(src, IsClass(_A("d"))); - REQUIRE_THAT(src, IsClass(_A("e"))); - REQUIRE_THAT(src, IsClass(_A("f"))); - REQUIRE_THAT(src, IsClass(_A("g"))); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - REQUIRE_THAT(src, IsClass(_A("F"))); - REQUIRE_THAT(src, IsClass(_A("G"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - } - */ } \ No newline at end of file diff --git a/tests/t00054/test_case.h b/tests/t00054/test_case.h index 2f53b3ec..43ff755b 100644 --- a/tests/t00054/test_case.h +++ b/tests/t00054/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00054") { using namespace clanguml::test; - auto [config, db] = load_config("t00054"); - - auto diagram = config.diagrams["t00054_class"]; - - REQUIRE(diagram->name == "t00054_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00054_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00054", "t00054_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "a")); @@ -51,92 +44,4 @@ TEST_CASE("t00054") REQUIRE(IsEnum(src, {"detail4", "h"})); REQUIRE(IsEnum(src, {"detail4", "j"})); }); - /* - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("a"))); - REQUIRE_THAT(src, IsClass(_A("b"))); - REQUIRE_THAT(src, IsClass(_A("c"))); - REQUIRE_THAT(src, IsClass(_A("d"))); - REQUIRE_THAT(src, IsClass(_A("e"))); - REQUIRE_THAT(src, IsClass(_A("f"))); - REQUIRE_THAT(src, IsClass(_A("g"))); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - REQUIRE_THAT(src, IsClass(_A("F"))); - REQUIRE_THAT(src, IsClass(_A("G"))); - - REQUIRE_THAT(src, IsEnum(_A("i"))); - REQUIRE_THAT(src, IsEnum(_A("h"))); - REQUIRE_THAT(src, IsEnum(_A("j"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "a")); - REQUIRE(IsClass(j, "b")); - REQUIRE(IsClass(j, "detail::c")); - REQUIRE(IsClass(j, "detail::d")); - REQUIRE(IsClass(j, "detail::e")); - REQUIRE(IsClass(j, "f")); - REQUIRE(IsClass(j, "g")); - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - REQUIRE(IsClass(j, "detail2::C")); - REQUIRE(IsClass(j, "detail2::detail3::D")); - REQUIRE(IsClass(j, "detail2::detail3::E")); - REQUIRE(IsClass(j, "detail2::F")); - REQUIRE(IsClass(j, "G")); - - REQUIRE(IsEnum(j, "detail4::i")); - REQUIRE(IsEnum(j, "detail4::h")); - REQUIRE(IsEnum(j, "detail4::j")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsEnum; - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("a"))); - REQUIRE_THAT(src, IsClass(_A("b"))); - REQUIRE_THAT(src, IsClass(_A("detail::c"))); - REQUIRE_THAT(src, IsClass(_A("detail::d"))); - REQUIRE_THAT(src, IsClass(_A("detail::e"))); - REQUIRE_THAT(src, IsClass(_A("f"))); - REQUIRE_THAT(src, IsClass(_A("g"))); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("detail2::C"))); - REQUIRE_THAT(src, IsClass(_A("detail2::detail3::D"))); - REQUIRE_THAT(src, IsClass(_A("detail2::detail3::E"))); - REQUIRE_THAT(src, IsClass(_A("detail2::F"))); - REQUIRE_THAT(src, IsClass(_A("G"))); - - REQUIRE_THAT(src, IsEnum(_A("detail4::i"))); - REQUIRE_THAT(src, IsEnum(_A("detail4::h"))); - REQUIRE_THAT(src, IsEnum(_A("detail4::j"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } \ No newline at end of file diff --git a/tests/t00055/test_case.h b/tests/t00055/test_case.h index 6dc4056c..25afa8d0 100644 --- a/tests/t00055/test_case.h +++ b/tests/t00055/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00055") { using namespace clanguml::test; - auto [config, db] = load_config("t00055"); - - auto diagram = config.diagrams["t00055_class"]; - - REQUIRE(diagram->name == "t00055_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00055_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00055", "t00055_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A")); @@ -52,74 +45,4 @@ TEST_CASE("t00055") REQUIRE(IsLayoutHint(src, "F", "down", "H")); REQUIRE(IsLayoutHint(src, "H", "down", "J")); }); - /* - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - REQUIRE_THAT(src, IsClass(_A("F"))); - REQUIRE_THAT(src, IsClass(_A("G"))); - REQUIRE_THAT(src, IsClass(_A("H"))); - REQUIRE_THAT(src, IsClass(_A("I"))); - REQUIRE_THAT(src, IsClass(_A("J"))); - - REQUIRE_THAT(src, IsLayoutHint(_A("A"), "right", _A("C"))); - REQUIRE_THAT(src, IsLayoutHint(_A("C"), "right", _A("E"))); - REQUIRE_THAT(src, IsLayoutHint(_A("E"), "right", _A("G"))); - REQUIRE_THAT(src, IsLayoutHint(_A("G"), "right", _A("I"))); - - REQUIRE_THAT(src, IsLayoutHint(_A("B"), "down", _A("D"))); - REQUIRE_THAT(src, IsLayoutHint(_A("D"), "down", _A("F"))); - REQUIRE_THAT(src, IsLayoutHint(_A("F"), "down", _A("H"))); - REQUIRE_THAT(src, IsLayoutHint(_A("H"), "down", _A("J"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - REQUIRE(IsClass(j, "C")); - REQUIRE(IsClass(j, "D")); - REQUIRE(IsClass(j, "E")); - REQUIRE(IsClass(j, "F")); - REQUIRE(IsClass(j, "G")); - REQUIRE(IsClass(j, "H")); - REQUIRE(IsClass(j, "I")); - REQUIRE(IsClass(j, "J")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - REQUIRE_THAT(src, IsClass(_A("F"))); - REQUIRE_THAT(src, IsClass(_A("G"))); - REQUIRE_THAT(src, IsClass(_A("H"))); - REQUIRE_THAT(src, IsClass(_A("I"))); - REQUIRE_THAT(src, IsClass(_A("J"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } \ No newline at end of file diff --git a/tests/t00056/test_case.h b/tests/t00056/test_case.h index 238175b9..a74fcd43 100644 --- a/tests/t00056/test_case.h +++ b/tests/t00056/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00056") { using namespace clanguml::test; - auto [config, db] = load_config("t00056"); - - auto diagram = config.diagrams["t00056_class"]; - - REQUIRE(diagram->name == "t00056_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00056_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00056", "t00056_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsConcept(src, "greater_than_simple")); @@ -39,7 +32,8 @@ TEST_CASE("t00056") REQUIRE(IsConcept(src, "convertible_to_string")); REQUIRE(IsConcept(src, "iterable_with_value_type")); REQUIRE(IsConcept(src, "iterable_or_small_value_type")); - + REQUIRE(IsConceptParameterList( + src, "greater_than_with_requires", "(T l,P r)")); REQUIRE(IsConceptRequirement( src, "greater_than_with_requires", "sizeof (l) > sizeof (r)")); @@ -93,204 +87,4 @@ TEST_CASE("t00056") REQUIRE(IsConstraint( src, "F", "greater_than_simple", "T1,T3")); }); - /* - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all classes exist - REQUIRE_THAT(src, IsConcept(_A("greater_than_simple"))); - REQUIRE_THAT(src, IsConcept(_A("greater_than_with_requires"))); - REQUIRE_THAT(src, IsConcept(_A("max_four_bytes"))); - REQUIRE_THAT(src, IsConcept(_A("iterable"))); - REQUIRE_THAT(src, IsConcept(_A("has_value_type"))); - REQUIRE_THAT(src, IsConcept(_A("convertible_to_string"))); - REQUIRE_THAT(src, IsConcept(_A("iterable_with_value_type"))); - REQUIRE_THAT(src, IsConcept(_A("iterable_or_small_value_type"))); - - REQUIRE_THAT(src, - IsConceptRequirement(_A("greater_than_with_requires"), - "sizeof (l) > sizeof (r)")); - - REQUIRE_THAT( - src, IsConceptRequirement(_A("iterable"), - "container.begin()")); REQUIRE_THAT( src, - IsConceptRequirement(_A("iterable"), "container.end()")); - - #if (LLVM_VERSION_MAJOR == 13) || (LLVM_VERSION_MAJOR == 14) - REQUIRE_THAT(src, - IsConceptRequirement( - _A("convertible_to_string"), "std::string({s})")); - #else - REQUIRE_THAT(src, - IsConceptRequirement( - _A("convertible_to_string"), "std::string{s}")); - #endif - REQUIRE_THAT(src, - IsConceptRequirement(_A("convertible_to_string"), - "{std::to_string(s)} noexcept")); - REQUIRE_THAT(src, - IsConceptRequirement(_A("convertible_to_string"), - "{std::to_string(s)} -> std::same_as")); - - // Check if class templates exist - REQUIRE_THAT(src, IsClassTemplate("A", "max_four_bytes T")); - REQUIRE_THAT(src, IsClassTemplate("B", "T")); - REQUIRE_THAT(src, IsClassTemplate("C", "convertible_to_string T")); - REQUIRE_THAT( - src, IsClassTemplate("D", "iterable T1,T2,iterable T3,T4,T5")); - REQUIRE_THAT(src, IsClassTemplate("E", "T1,T2,T3")); - REQUIRE_THAT(src, IsClassTemplate("F", "T1,T2,T3")); - - // Check if all relationships exist - REQUIRE_THAT(src, - IsConstraint( - _A("A"), _A("max_four_bytes"), "T")); - - REQUIRE_THAT(src, - IsConstraint(_A("D"), - _A("max_four_bytes"), "T2")); - REQUIRE_THAT(src, - IsConstraint(_A("D"), - _A("max_four_bytes"), "T5")); - REQUIRE_THAT(src, - IsConstraint(_A("D"), - _A("iterable"), "T1")); - REQUIRE_THAT(src, - IsConstraint(_A("D"), - _A("iterable"), "T3")); - - REQUIRE_THAT(src, - IsConstraint(_A("iterable_with_value_type"), - _A("has_value_type"), "T")); - - REQUIRE_THAT(src, - IsConstraint(_A("iterable_or_small_value_type"), - _A("max_four_bytes"), "T")); - REQUIRE_THAT(src, - IsConstraint(_A("iterable_or_small_value_type"), - _A("iterable_with_value_type"), "T")); - - REQUIRE_THAT(src, - IsConstraint(_A("E"), - _A("greater_than_with_requires"), "T1,T3")); - - REQUIRE_THAT(src, - IsConstraint( - _A("F"), _A("greater_than_simple"), - "T1,T3")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsConcept(j, "greater_than_simple")); - REQUIRE(IsConcept(j, "greater_than_with_requires")); - REQUIRE(IsConcept(j, "max_four_bytes")); - REQUIRE(IsConcept(j, "iterable")); - REQUIRE(IsConcept(j, "has_value_type")); - REQUIRE(IsConcept(j, "convertible_to_string")); - REQUIRE(IsConcept(j, "iterable_with_value_type")); - REQUIRE(IsConcept(j, "iterable_or_small_value_type")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsConcept; - using mermaid::IsConceptRequirement; - using mermaid::IsConstraint; - - // Check if all classes exist - REQUIRE_THAT(src, IsConcept(_A("greater_than_simple"))); - REQUIRE_THAT(src, IsConcept(_A("greater_than_with_requires"))); - REQUIRE_THAT(src, IsConcept(_A("max_four_bytes"))); - REQUIRE_THAT(src, IsConcept(_A("iterable"))); - REQUIRE_THAT(src, IsConcept(_A("has_value_type"))); - REQUIRE_THAT(src, IsConcept(_A("convertible_to_string"))); - REQUIRE_THAT(src, IsConcept(_A("iterable_with_value_type"))); - REQUIRE_THAT(src, IsConcept(_A("iterable_or_small_value_type"))); - - REQUIRE_THAT(src, - IsConceptRequirement(_A("greater_than_with_requires"), - "sizeof (l) > sizeof (r)")); - - REQUIRE_THAT( - src, IsConceptRequirement(_A("iterable"), - "container.begin()")); REQUIRE_THAT( src, - IsConceptRequirement(_A("iterable"), "container.end()")); - - #if (LLVM_VERSION_MAJOR == 13) || (LLVM_VERSION_MAJOR == 14) - REQUIRE_THAT(src, - IsConceptRequirement( - _A("convertible_to_string"), "std::string({s})")); - #else - REQUIRE_THAT(src, - IsConceptRequirement( - _A("convertible_to_string"), "std::string{s}")); - #endif - REQUIRE_THAT(src, - IsConceptRequirement(_A("convertible_to_string"), - "{std::to_string(s)} noexcept")); - REQUIRE_THAT(src, - IsConceptRequirement(_A("convertible_to_string"), - "{std::to_string(s)} -> std::same_as")); - - // Check if class templates exist - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); REQUIRE_THAT(src, IsClass(_A("E"))); - REQUIRE_THAT(src, IsClass(_A("F"))); - - // Check if all relationships exist - REQUIRE_THAT(src, - IsConstraint( - _A("A"), _A("max_four_bytes"), "T")); - - REQUIRE_THAT(src, - IsConstraint(_A("D"), - _A("max_four_bytes"), "T2")); - REQUIRE_THAT(src, - IsConstraint(_A("D"), - _A("max_four_bytes"), "T5")); - REQUIRE_THAT(src, - IsConstraint(_A("D"), - _A("iterable"), "T1")); - REQUIRE_THAT(src, - IsConstraint(_A("D"), - _A("iterable"), "T3")); - - REQUIRE_THAT(src, - IsConstraint(_A("iterable_with_value_type"), - _A("has_value_type"), "T")); - - REQUIRE_THAT(src, - IsConstraint(_A("iterable_or_small_value_type"), - _A("max_four_bytes"), "T")); - REQUIRE_THAT(src, - IsConstraint(_A("iterable_or_small_value_type"), - _A("iterable_with_value_type"), "T")); - - REQUIRE_THAT(src, - IsConstraint(_A("E"), - _A("greater_than_with_requires"), "T1,T3")); - - REQUIRE_THAT(src, - IsConstraint( - _A("F"), _A("greater_than_simple"), - "T1,T3")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t00057/test_case.h b/tests/t00057/test_case.h index fcbdfdcf..662c6606 100644 --- a/tests/t00057/test_case.h +++ b/tests/t00057/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00057") { using namespace clanguml::test; - auto [config, db] = load_config("t00057"); - - auto diagram = config.diagrams["t00057_class"]; - - REQUIRE(diagram->name == "t00057_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00057_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00057", "t00057_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "t00057_A")); @@ -52,88 +45,4 @@ TEST_CASE("t00057") REQUIRE(IsAggregation( src, "t00057_E", "t00057_E::(height)", "height")); }); - - /* - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("t00057_A"))); - REQUIRE_THAT(src, IsClass(_A("t00057_B"))); - REQUIRE_THAT(src, IsClass(_A("t00057_C"))); - REQUIRE_THAT(src, IsUnion(_A("t00057_D"))); - REQUIRE_THAT(src, IsClass(_A("t00057_E"))); - REQUIRE_THAT(src, IsClass(_A("t00057_F"))); - REQUIRE_THAT(src, IsClass(_A("t00057_G"))); - REQUIRE_THAT(src, !IsClass(_A("(anonymous)"))); - REQUIRE_THAT(src, IsClass(_A("t00057_R"))); - - // Check if all relationships exist - REQUIRE_THAT(src, IsAggregation(_A("t00057_R"), _A("t00057_A"), - "+a")); REQUIRE_THAT(src, IsAggregation(_A("t00057_R"), _A("t00057_B"), - "+b")); REQUIRE_THAT(src, IsAssociation(_A("t00057_R"), _A("t00057_C"), - "+c")); REQUIRE_THAT(src, IsAggregation(_A("t00057_R"), _A("t00057_D"), - "+d")); REQUIRE_THAT(src, IsAssociation(_A("t00057_R"), _A("t00057_E"), - "+e")); REQUIRE_THAT(src, IsAssociation(_A("t00057_R"), _A("t00057_F"), - "+f")); REQUIRE_THAT(src, IsAggregation( _A("t00057_E"), - _A("t00057_E::(coordinates)"), "+coordinates")); REQUIRE_THAT(src, - IsAggregation(_A("t00057_E"), _A("t00057_E::(height)"), - "+height")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(get_element(j, "t00057_A").value()["type"] == "class"); - REQUIRE(get_element(j, "t00057_B").value()["type"] == "class"); - REQUIRE(get_element(j, "t00057_C").value()["type"] == "class"); - REQUIRE(get_element(j, "t00057_D").value()["type"] == "class"); - REQUIRE(get_element(j, "t00057_E").value()["type"] == "class"); - REQUIRE(get_element(j, "t00057_F").value()["type"] == "class"); - REQUIRE(get_element(j, "t00057_G").value()["type"] == "class"); - REQUIRE(get_element(j, "t00057_R").value()["type"] == "class"); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsUnion; - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("t00057_A"))); - REQUIRE_THAT(src, IsClass(_A("t00057_B"))); - REQUIRE_THAT(src, IsClass(_A("t00057_C"))); - REQUIRE_THAT(src, IsUnion(_A("t00057_D"))); - REQUIRE_THAT(src, IsClass(_A("t00057_E"))); - REQUIRE_THAT(src, IsClass(_A("t00057_F"))); - REQUIRE_THAT(src, IsClass(_A("t00057_G"))); - REQUIRE_THAT(src, !IsClass(_A("(anonymous)"))); - REQUIRE_THAT(src, IsClass(_A("t00057_R"))); - - // Check if all relationships exist - REQUIRE_THAT(src, IsAggregation(_A("t00057_R"), _A("t00057_A"), - "+a")); REQUIRE_THAT(src, IsAggregation(_A("t00057_R"), _A("t00057_B"), - "+b")); REQUIRE_THAT(src, IsAssociation(_A("t00057_R"), _A("t00057_C"), - "+c")); REQUIRE_THAT(src, IsAggregation(_A("t00057_R"), _A("t00057_D"), - "+d")); REQUIRE_THAT(src, IsAssociation(_A("t00057_R"), _A("t00057_E"), - "+e")); REQUIRE_THAT(src, IsAssociation(_A("t00057_R"), _A("t00057_F"), - "+f")); REQUIRE_THAT(src, IsAggregation( _A("t00057_E"), - _A("t00057_E::(coordinates)"), "+coordinates")); REQUIRE_THAT(src, - IsAggregation(_A("t00057_E"), _A("t00057_E::(height)"), - "+height")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - } - */ } \ No newline at end of file diff --git a/tests/t00058/test_case.h b/tests/t00058/test_case.h index 9a0581ae..cceb976b 100644 --- a/tests/t00058/test_case.h +++ b/tests/t00058/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00058") { using namespace clanguml::test; - auto [config, db] = load_config("t00058"); - - auto diagram = config.diagrams["t00058_class"]; - - REQUIRE(diagram->name == "t00058_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00058_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00058", "t00058_class"); CHECK_CLASS_DIAGRAM( config, diagram, *model, @@ -67,97 +60,4 @@ TEST_CASE("t00058") REQUIRE(IsDependency( src, "same_as_first_type", "first_type")); }); - - /* - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsClassTemplate("A", - "int,int,double,std::string")); REQUIRE_THAT( src, IsClassTemplate("B", - "int,std::string,int,double,A")); - - REQUIRE_THAT(src, IsConcept(_A("same_as_first_type"))); - - REQUIRE_THAT(src, - IsConstraint(_A("A"), - _A("same_as_first_type"), "T,Args...")); - - REQUIRE_THAT(src, - IsConstraint(_A("B"), - _A("same_as_first_type"), "T,Args...")); - - REQUIRE_THAT(src, - IsAggregation(_A("R"), _A("A"), - "+aa")); REQUIRE_THAT(src, IsAggregation(_A("R"), - _A("B>"), "+bb")); - - REQUIRE_THAT(src, - IsInstantiation( - _A("A"), _A("A"))); - REQUIRE_THAT(src, - IsInstantiation(_A("B"), - _A("B>"))); - - REQUIRE_THAT(src, - IsDependency(_A("same_as_first_type"), - _A("first_type"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B>")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsConcept; - using mermaid::IsConstraint; - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT( - src, IsClass(_A("B>"))); - - REQUIRE_THAT(src, IsConcept(_A("same_as_first_type"))); - - REQUIRE_THAT(src, - IsConstraint(_A("A"), - _A("same_as_first_type"), "T,Args...")); - - REQUIRE_THAT(src, - IsConstraint(_A("B"), - _A("same_as_first_type"), "T,Args...")); - - REQUIRE_THAT(src, - IsAggregation(_A("R"), _A("A"), - "+aa")); REQUIRE_THAT(src, IsAggregation(_A("R"), - _A("B>"), "+bb")); - - REQUIRE_THAT(src, - IsInstantiation( - _A("A"), _A("A"))); - REQUIRE_THAT(src, - IsInstantiation(_A("B"), - _A("B>"))); - - // TODO - // REQUIRE_THAT(src, - // IsDependency(_A("same_as_first_type"), - // _A("first_type"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t00059/test_case.h b/tests/t00059/test_case.h index 435818db..9d6899c0 100644 --- a/tests/t00059/test_case.h +++ b/tests/t00059/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00059") { using namespace clanguml::test; - auto [config, db] = load_config("t00059"); - - auto diagram = config.diagrams["t00059_class"]; - - REQUIRE(diagram->name == "t00059_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00059_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00059", "t00059_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsConcept(src, "fruit_c")); @@ -39,7 +32,7 @@ TEST_CASE("t00059") REQUIRE(IsConstraint(src, "orange_c", "fruit_c", "T", "up")); REQUIRE(IsConceptRequirement(src, "apple_c", "t.get_sweetness()")); - REQUIRE(IsConceptRequirement(src, "apple_c", "t.get_bitterness()")); + REQUIRE(IsConceptRequirement(src, "orange_c", "t.get_bitterness()")); REQUIRE(IsClass(src, "gala_apple")); REQUIRE(IsClass(src, "empire_apple")); @@ -71,145 +64,4 @@ TEST_CASE("t00059") REQUIRE(IsInstantiation(src, "fruit_factory", "fruit_factory", "up")); }); - /* - - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsConcept(_A("fruit_c"))); - REQUIRE_THAT(src, IsConcept(_A("apple_c"))); - REQUIRE_THAT(src, IsConcept(_A("orange_c"))); - - REQUIRE_THAT( - src, IsConstraint(_A("apple_c"), _A("fruit_c"), "T", - "up")); REQUIRE_THAT( src, IsConstraint(_A("orange_c"), - _A("fruit_c"), "T", "up")); - - REQUIRE_THAT( - src, IsConceptRequirement(_A("apple_c"), - "t.get_sweetness()")); REQUIRE_THAT( src, - IsConceptRequirement(_A("apple_c"), "t.get_bitterness()")); - - REQUIRE_THAT(src, IsClass(_A("gala_apple"))); - REQUIRE_THAT(src, IsClass(_A("empire_apple"))); - REQUIRE_THAT(src, IsClass(_A("valencia_orange"))); - REQUIRE_THAT(src, IsClass(_A("lima_orange"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - - REQUIRE_THAT( - src, IsClassTemplate("fruit_factory", "apple_c TA,orange_c - TO")); - - REQUIRE_THAT(src, - IsDependency(_A("fruit_factory"), - _A("gala_apple"), "up")); - REQUIRE_THAT(src, - IsDependency(_A("fruit_factory"), - _A("valencia_orange"), "up")); - - REQUIRE_THAT(src, - IsDependency(_A("fruit_factory"), - _A("empire_apple"), "up")); - REQUIRE_THAT(src, - IsDependency(_A("fruit_factory"), - _A("lima_orange"), "up")); - - REQUIRE_THAT(src, - IsAggregation(_A("R"), - _A("fruit_factory"), - "+factory_1", - "", "", "up")); - REQUIRE_THAT(src, - IsAggregation(_A("R"), - _A("fruit_factory"), "+factory_2", - "", - "", "up")); - - REQUIRE_THAT(src, - IsInstantiation(_A("fruit_factory"), - _A("fruit_factory"), "up")); - REQUIRE_THAT(src, - IsInstantiation(_A("fruit_factory"), - _A("fruit_factory"), "up")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsConcept(j, "fruit_c")); - REQUIRE(IsConcept(j, "apple_c")); - REQUIRE(IsConcept(j, "orange_c")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsConcept; - using mermaid::IsConceptRequirement; - using mermaid::IsConstraint; - - REQUIRE_THAT(src, IsConcept(_A("fruit_c"))); - REQUIRE_THAT(src, IsConcept(_A("apple_c"))); - REQUIRE_THAT(src, IsConcept(_A("orange_c"))); - - REQUIRE_THAT( - src, IsConstraint(_A("apple_c"), _A("fruit_c"), "T")); - REQUIRE_THAT( - src, IsConstraint(_A("orange_c"), _A("fruit_c"), "T")); - - REQUIRE_THAT( - src, IsConceptRequirement(_A("apple_c"), - "t.get_sweetness()")); REQUIRE_THAT( src, - IsConceptRequirement(_A("apple_c"), "t.get_bitterness()")); - - REQUIRE_THAT(src, IsClass(_A("gala_apple"))); - REQUIRE_THAT(src, IsClass(_A("empire_apple"))); - REQUIRE_THAT(src, IsClass(_A("valencia_orange"))); - REQUIRE_THAT(src, IsClass(_A("lima_orange"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - - REQUIRE_THAT(src, IsClass(_A("fruit_factory"))); - - REQUIRE_THAT(src, - IsDependency(_A("fruit_factory"), - _A("gala_apple"))); - REQUIRE_THAT(src, - IsDependency(_A("fruit_factory"), - _A("valencia_orange"))); - - REQUIRE_THAT(src, - IsDependency(_A("fruit_factory"), - _A("empire_apple"))); - REQUIRE_THAT(src, - IsDependency(_A("fruit_factory"), - _A("lima_orange"))); - - REQUIRE_THAT(src, - IsAggregation(_A("R"), - _A("fruit_factory"), - "+factory_1")); REQUIRE_THAT(src, IsAggregation(_A("R"), - _A("fruit_factory"), - "+factory_2")); - - REQUIRE_THAT(src, - IsInstantiation(_A("fruit_factory"), - _A("fruit_factory"))); - REQUIRE_THAT(src, - IsInstantiation(_A("fruit_factory"), - _A("fruit_factory"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t00060/test_case.h b/tests/t00060/test_case.h index 87251cea..de813fdf 100644 --- a/tests/t00060/test_case.h +++ b/tests/t00060/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00060") { using namespace clanguml::test; - auto [config, db] = load_config("t00060"); - - auto diagram = config.diagrams["t00060_class"]; - - REQUIRE(diagram->name == "t00060_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00060_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00060", "t00060_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A")); @@ -41,61 +34,4 @@ TEST_CASE("t00060") REQUIRE(IsClassTemplate(src, "G")); REQUIRE(IsClassTemplate(src, "H")); }); - /* -{ - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, !IsClass(_A("E"))); - REQUIRE_THAT(src, !IsClass(_A("F"))); - - // Check if class templates exist - REQUIRE_THAT(src, IsClassTemplate("G", "T")); - REQUIRE_THAT(src, IsClassTemplate("H", "T,P")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); -} - -{ - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - REQUIRE(IsClass(j, "C")); - REQUIRE(IsClass(j, "D")); - REQUIRE(!IsClass(j, "E")); - REQUIRE(!IsClass(j, "F")); - - save_json(config.output_directory(), diagram->name + ".json", j); -} -{ - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, !IsClass(_A("E"))); - REQUIRE_THAT(src, !IsClass(_A("F"))); - - // Check if class templates exist - REQUIRE_THAT(src, IsClass(_A("G"))); - REQUIRE_THAT(src, IsClass(_A("H"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); -} - */ } \ No newline at end of file diff --git a/tests/t00061/test_case.h b/tests/t00061/test_case.h index a2086cf8..847cfc6d 100644 --- a/tests/t00061/test_case.h +++ b/tests/t00061/test_case.h @@ -20,59 +20,12 @@ TEST_CASE("t00061") { using namespace clanguml::test; - auto [config, db] = load_config("t00061"); - - auto diagram = config.diagrams["t00061_class"]; - - REQUIRE(diagram->name == "t00061_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00061_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00061", "t00061_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A")); REQUIRE(!IsClass(src, "B")); REQUIRE(!IsClass(src, "C")); }); - /* -{ - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, !IsClass(_A("B"))); - REQUIRE_THAT(src, !IsClass(_A("C"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); -} - -{ - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(!IsClass(j, "B")); - REQUIRE(!IsClass(j, "C")); - - save_json(config.output_directory(), diagram->name + ".json", j); -} -{ - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, !IsClass(_A("B"))); - REQUIRE_THAT(src, !IsClass(_A("C"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); -} - */ } \ No newline at end of file diff --git a/tests/t00062/test_case.h b/tests/t00062/test_case.h index b266a93f..198b875c 100644 --- a/tests/t00062/test_case.h +++ b/tests/t00062/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00062") { using namespace clanguml::test; - auto [config, db] = load_config("t00062"); - - auto diagram = config.diagrams["t00062_class"]; - - REQUIRE(diagram->name == "t00062_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00062_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00062", "t00062_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(!src.contains("type-parameter-")); @@ -37,6 +30,7 @@ TEST_CASE("t00062") REQUIRE(IsClassTemplate(src, "A")); REQUIRE(IsClassTemplate(src, "A")); REQUIRE(IsClassTemplate(src, "A")); + REQUIRE(IsClassTemplate(src, "A")); REQUIRE(IsClassTemplate(src, "A")); REQUIRE(IsClassTemplate(src, "A")); REQUIRE(IsClassTemplate(src, "A")); @@ -53,11 +47,9 @@ TEST_CASE("t00062") REQUIRE(IsClassTemplate(src, "A>")); REQUIRE(IsField(src, "A", "u", "U &")); - REQUIRE(IsField(src, "A", "u", "U **")); - REQUIRE(IsField(src, "A", "u", "U ***")); + REQUIRE(IsField(src, "A", "u", "U ***")); REQUIRE(IsField(src, "A", "u", "U &&")); - REQUIRE(IsField(src, "A", "u", "const U &")); - REQUIRE(IsField(src, "A", "c", "C &")); + REQUIRE(IsField(src, "A", "u", "const U &")); REQUIRE(IsField(src, "A", "m", "M C::*")); REQUIRE(IsInstantiation(src, "A", "A")); @@ -77,127 +69,4 @@ TEST_CASE("t00062") REQUIRE(IsInstantiation(src, "A", "A>")); REQUIRE(IsInstantiation(src, "A", "A>")); }); - - /* - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, !Contains("type-parameter-")); - - // Check if all classes exist - REQUIRE_THAT(src, IsClassTemplate("A", "T")); - REQUIRE_THAT(src, IsClassTemplate("A", "U &")); - REQUIRE_THAT(src, IsClassTemplate("A", "U &&")); - REQUIRE_THAT(src, IsClassTemplate("A", "U const&")); - REQUIRE_THAT(src, IsClassTemplate("A", "M C::*")); - REQUIRE_THAT(src, IsClassTemplate("A", "M C::* &&")); - REQUIRE_THAT(src, IsClassTemplate("A", "M (C::*)(Arg)")); - REQUIRE_THAT(src, IsClassTemplate("A", "int (C::*)(bool)")); - REQUIRE_THAT(src, IsClassTemplate("A", "M (C::*)(Arg) &&")); - REQUIRE_THAT(src, IsClassTemplate("A", "M (C::*)(Arg1,Arg2,Arg3)")); - REQUIRE_THAT(src, IsClassTemplate("A", "float (C::*)(int) &&")); - - REQUIRE_THAT(src, IsClassTemplate("A", "char[N]")); - REQUIRE_THAT(src, IsClassTemplate("A", "char[1000]")); - - REQUIRE_THAT(src, IsClassTemplate("A", "U(...)")); - REQUIRE_THAT(src, IsClassTemplate("A", "C")); - REQUIRE_THAT(src, IsClassTemplate("A", "C")); - - REQUIRE_THAT(src, (IsField("u", "U &"))); - REQUIRE_THAT(src, (IsField("u", "U **"))); - REQUIRE_THAT(src, (IsField("u", "U ***"))); - REQUIRE_THAT(src, (IsField("u", "U &&"))); - REQUIRE_THAT(src, (IsField("u", "const U &"))); - REQUIRE_THAT(src, (IsField("c", "C &"))); - REQUIRE_THAT(src, (IsField("m", "M C::*"))); - - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, - IsInstantiation(_A("A"), _A("A"))); - - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A>"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A>"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsField; - - REQUIRE_THAT(src, !Contains("type-parameter-")); - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("A>"))); - REQUIRE_THAT(src, IsClass(_A("A>"))); - - REQUIRE_THAT(src, (IsField("u", "U &"))); - REQUIRE_THAT(src, (IsField("u", "U **"))); - REQUIRE_THAT(src, (IsField("u", "U ***"))); - REQUIRE_THAT(src, (IsField("u", "U &&"))); - REQUIRE_THAT(src, (IsField("u", "const U &"))); - REQUIRE_THAT(src, (IsField("c", "C &"))); - REQUIRE_THAT(src, (IsField("m", "M C::*"))); - - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, - IsInstantiation(_A("A"), _A("A"))); - - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT( - src, IsInstantiation(_A("A"), _A("A"))); - - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A>"))); - REQUIRE_THAT(src, IsInstantiation(_A("A"), _A("A>"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } \ No newline at end of file diff --git a/tests/t00063/test_case.h b/tests/t00063/test_case.h index 8c87872f..c66ae44e 100644 --- a/tests/t00063/test_case.h +++ b/tests/t00063/test_case.h @@ -20,59 +20,12 @@ TEST_CASE("t00063") { using namespace clanguml::test; - auto [config, db] = load_config("t00063"); - - auto diagram = config.diagrams["t00063_class"]; - - REQUIRE(diagram->name == "t00063_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00063_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00063", "t00063_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A")); REQUIRE(!IsEnum(src, "B")); REQUIRE(!IsEnum(src, "C")); }); - /* - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, !IsEnum(_A("B"))); - REQUIRE_THAT(src, !IsEnum(_A("C"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(!IsEnum(j, "B")); - REQUIRE(!IsEnum(j, "C")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsEnum; - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, !IsEnum(_A("B"))); - REQUIRE_THAT(src, !IsEnum(_A("C"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - } - */ } \ No newline at end of file diff --git a/tests/t00064/test_case.h b/tests/t00064/test_case.h index 6089a397..de0d9fd6 100644 --- a/tests/t00064/test_case.h +++ b/tests/t00064/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00064") { using namespace clanguml::test; - auto [config, db] = load_config("t00064"); - - auto diagram = config.diagrams["t00064_class"]; - - REQUIRE(diagram->name == "t00064_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00064_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00064", "t00064_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(!src.contains("type-parameter-")); @@ -54,129 +47,24 @@ TEST_CASE("t00064") REQUIRE(IsClassTemplate(src, "type_group_pair_it,type_list>")); - REQUIRE(IsMethod(src, "get", "ref_t", "unsigned int i")); + REQUIRE(IsMethod(src, + "type_group_pair_it,type_list>", + "get", "ref_t", "unsigned int i")); #if LLVM_VERSION_MAJOR < 16 - REQUIRE(IsMethod( - src, "getp", "value_type const*", "unsigned int i")); - REQUIRE(IsMethod( - src, "find", "unsigned int", "value_type const& v")); + REQUIRE(IsMethod(src, + "type_group_pair_it,type_list>", + "getp", "value_type const*", "unsigned int i")); + REQUIRE(IsMethod(src, + "type_group_pair_it,type_list>", + "find", "unsigned int", "value_type const& v")); #else REQUIRE( - IsMethod(src, "getp", "const value_type *", "unsigned int i")); + IsMethod(src, + "type_group_pair_it,type_list>", + "getp", "const value_type *", "unsigned int i")); REQUIRE( - IsMethod(src, + IsMethod(src,"type_group_pair_it,type_list>", "find", "unsigned int", "const value_type & v")); #endif }); - /* - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, !Contains("type-parameter-")); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - - REQUIRE_THAT(src, IsClassTemplate("type_list", "Ts...")); - REQUIRE_THAT(src, IsClassTemplate("type_list", "Ret(Arg &&),Ts...")); - REQUIRE_THAT(src, IsClassTemplate("type_list", "T const,Ts...")); - - REQUIRE_THAT(src, IsClassTemplate("head", "typename")); - REQUIRE_THAT(src, IsClassTemplate("head", "type_list")); - REQUIRE_THAT( - src, IsClassTemplate("type_group_pair", "typename,typename")); - REQUIRE_THAT(src, - IsClassTemplate( - "type_group_pair", "type_list,type_list")); - REQUIRE_THAT(src, - IsClassTemplate( - "type_group_pair", "type_list,type_list")); - - REQUIRE_THAT(src, IsClassTemplate("optional_ref", "T")); - - REQUIRE_THAT(src, - IsClassTemplate("type_group_pair_it", - "It,type_list,type_list")); - REQUIRE_THAT(src, (IsMethod("get", "ref_t", "unsigned int i"))); -#if LLVM_VERSION_MAJOR < 16 - REQUIRE_THAT(src, - (IsMethod("getp", "value_type const*", "unsigned int i"))); - REQUIRE_THAT(src, - (IsMethod( - "find", "unsigned int", "value_type const& v"))); -#else - REQUIRE_THAT(src, - (IsMethod("getp", "const value_type *", "unsigned int i"))); - REQUIRE_THAT(src, - (IsMethod( - "find", "unsigned int", "const value_type & v"))); - -#endif - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsMethod; - - REQUIRE_THAT(src, !Contains("type-parameter-")); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - - REQUIRE_THAT(src, IsClass(_A("type_list"))); - REQUIRE_THAT(src, IsClass(_A("type_list"))); - REQUIRE_THAT(src, IsClass(_A("type_list"))); - - REQUIRE_THAT(src, IsClass(_A("head"))); - REQUIRE_THAT(src, IsClass(_A("head>"))); - REQUIRE_THAT(src, IsClass(_A("type_group_pair"))); - REQUIRE_THAT(src, - IsClass(_A( - "type_group_pair,type_list>"))); - REQUIRE_THAT(src, - IsClass(_A( - "type_group_pair,type_list>"))); - - REQUIRE_THAT(src, IsClass(_A("optional_ref"))); - - REQUIRE_THAT(src, - IsClass(_A("type_group_pair_it,type_list<" - "Second...>>"))); - REQUIRE_THAT(src, (IsMethod("get", "ref_t", "unsigned int i"))); -#if LLVM_VERSION_MAJOR < 16 - REQUIRE_THAT(src, - (IsMethod("getp", "value_type const*", "unsigned int i"))); - REQUIRE_THAT(src, - (IsMethod( - "find", "unsigned int", "value_type const& v"))); -#else - REQUIRE_THAT(src, - (IsMethod("getp", "const value_type *", "unsigned int i"))); - REQUIRE_THAT(src, - (IsMethod( - "find", "unsigned int", "const value_type & v"))); - -#endif - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } - */ } \ No newline at end of file diff --git a/tests/t00065/test_case.h b/tests/t00065/test_case.h index 7c127154..00da8823 100644 --- a/tests/t00065/test_case.h +++ b/tests/t00065/test_case.h @@ -19,16 +19,10 @@ TEST_CASE("t00065") { using namespace clanguml::test; + using namespace std::string_literals; - auto [config, db] = load_config("t00065"); - - auto diagram = config.diagrams["t00065_class"]; - - REQUIRE(diagram->name == "t00065_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00065_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00065", "t00065_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "R")); @@ -37,55 +31,9 @@ TEST_CASE("t00065") REQUIRE(IsEnum(src, "XYZ")); REQUIRE(IsEnum(src, "ABC")); - REQUIRE(IsPackage("module1")); - REQUIRE(IsPackage("module2")); - REQUIRE(IsPackage("submodule1a")); - REQUIRE(IsPackage("concepts")); + REQUIRE(IsDirectoryPackage(src, "module1"s)); + REQUIRE(IsDirectoryPackage(src, "module2"s)); + REQUIRE(IsDirectoryPackage(src, "module1"s, "submodule1a"s)); + REQUIRE(IsDirectoryPackage(src, "module2"s, "concepts"s)); }); - /* - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("R"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("detail::AImpl"))); - REQUIRE_THAT(src, IsEnum(_A("XYZ"))); - REQUIRE_THAT(src, IsEnum(_A("ABC"))); - - REQUIRE_THAT(src, IsPackage("module1")); - REQUIRE_THAT(src, IsPackage("module2")); - REQUIRE_THAT(src, IsPackage("submodule1a")); - REQUIRE_THAT(src, IsPackage("concepts")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsEnum; - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("R"))); - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("detail::AImpl"))); - REQUIRE_THAT(src, IsEnum(_A("XYZ"))); - REQUIRE_THAT(src, IsEnum(_A("ABC"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t00066/test_case.h b/tests/t00066/test_case.h index 89959407..4f930b04 100644 --- a/tests/t00066/test_case.h +++ b/tests/t00066/test_case.h @@ -20,142 +20,39 @@ TEST_CASE("t00066") { using namespace clanguml::test; - auto [config, db] = load_config("t00066"); - - auto diagram = config.diagrams["t00066_class"]; - - REQUIRE(diagram->name == "t00066_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00066_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00066", "t00066_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A")); REQUIRE(!IsDependency(src, "A", "A")); - REQUIRE(IsMethod(src,"A"))); - REQUIRE(IsMethod(src, "A", "void", "A &&")); - REQUIRE(IsMethod(src, "A", "void", "const A &")); + REQUIRE(IsMethod(src, "A", "A")); + REQUIRE(IsMethod(src, "A", "A", "void", "A &&")); + REQUIRE(IsMethod(src, "A", "A", "void", "const A &")); - REQUIRE(IsMethod(src, "~A")); + REQUIRE(IsMethod(src, "A", "~A")); - REQUIRE(IsMethod(src,"basic_method"))); - REQUIRE(IsMethod(src,"static_method", "int"))); - REQUIRE(IsMethod(src,"const_method"))); - REQUIRE(IsMethod(src,"default_int", "int", "int i = 12"))); - REQUIRE(IsMethod(src, "default_string", "std::string", + REQUIRE(IsMethod(src, "A", "basic_method")); + REQUIRE(IsMethod(src, "A", "static_method", "int")); + REQUIRE(IsMethod(src, "A", "const_method")); + REQUIRE(IsMethod(src, "A", "default_int", "int", "int i = 12")); + REQUIRE(IsMethod(src, "A", "default_string", "std::string", "int i, std::string s = \"abc\"")); - REQUIRE(IsMethod(src, "size", "std::size_t")); + REQUIRE(IsMethod(src, "A", "size", "std::size_t")); - REQUIRE(IsMethod(src, "protected_method")); - REQUIRE(IsMethod(src, "private_method")); - REQUIRE(IsField(src, "public_member", "int")); - REQUIRE(IsField(src, "protected_member", "int")); - REQUIRE(IsField(src, "private_member", "int")); - REQUIRE( - (IsField(src,"auto_member", "const unsigned long")); + REQUIRE(IsMethod(src, "A", "protected_method")); + REQUIRE(IsMethod(src, "A", "private_method")); + REQUIRE(IsField(src, "A", "public_member", "int")); + REQUIRE(IsField(src, "A", "protected_member", "int")); + REQUIRE(IsField(src, "A", "private_member", "int")); + REQUIRE(IsField( + src, "A", "auto_member", "const unsigned long")); - REQUIRE(IsField(src,"a_", "int")); - REQUIRE(IsField(src,"b_", "int")); - REQUIRE(IsField(src,"c_", "int")); + REQUIRE(IsField(src, "A", "a_", "int")); + REQUIRE(IsField(src, "A", "b_", "int")); + REQUIRE(IsField(src, "A", "c_", "int")); }); - - /* -{ - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsClass(_A("A"))); - - REQUIRE_THAT(src, !IsDependency(_A("A"), _A("A"))); - - REQUIRE_THAT(src, (IsMethod("A"))); - REQUIRE_THAT(src, (IsMethod("A", "void", "A &&"))); - REQUIRE_THAT( - src, (IsMethod("A", "void", "const A &"))); - - REQUIRE_THAT(src, (IsMethod("~A"))); - - REQUIRE_THAT(src, (IsMethod("basic_method"))); - REQUIRE_THAT(src, (IsMethod("static_method", "int"))); - REQUIRE_THAT(src, (IsMethod("const_method"))); - REQUIRE_THAT( - src, (IsMethod("default_int", "int", "int i = 12"))); - REQUIRE_THAT(src, - (IsMethod("default_string", "std::string", - "int i, std::string s = \"abc\""))); - - REQUIRE_THAT(src, (IsMethod("size", "std::size_t"))); - - REQUIRE_THAT(src, (IsMethod("protected_method"))); - REQUIRE_THAT(src, (IsMethod("private_method"))); - REQUIRE_THAT(src, (IsField("public_member", "int"))); - REQUIRE_THAT(src, (IsField("protected_member", "int"))); - REQUIRE_THAT(src, (IsField("private_member", "int"))); - REQUIRE_THAT(src, - (IsField("auto_member", "const unsigned long"))); - - REQUIRE_THAT(src, (IsField("a_", "int"))); - REQUIRE_THAT(src, (IsField("b_", "int"))); - REQUIRE_THAT(src, (IsField("c_", "int"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); -} - -{ - auto j = generate_class_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); -} -{ - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsField; - using mermaid::IsMethod; - - REQUIRE_THAT(src, IsClass(_A("A"))); - - REQUIRE_THAT(src, !IsDependency(_A("A"), _A("A"))); - - REQUIRE_THAT(src, (IsMethod("A"))); - REQUIRE_THAT(src, (IsMethod("A", "void", "A &&"))); - REQUIRE_THAT( - src, (IsMethod("A", "void", "const A &"))); - - REQUIRE_THAT(src, (IsMethod("~A"))); - - REQUIRE_THAT(src, (IsMethod("basic_method"))); - REQUIRE_THAT(src, (IsMethod("static_method", "int"))); - REQUIRE_THAT(src, (IsMethod("const_method"))); - REQUIRE_THAT( - src, (IsMethod("default_int", "int", "int i = 12"))); - REQUIRE_THAT(src, - (IsMethod("default_string", "std::string", - "int i, std::string s = \"abc\""))); - - REQUIRE_THAT(src, (IsMethod("size", "std::size_t"))); - - REQUIRE_THAT(src, (IsMethod("protected_method"))); - REQUIRE_THAT(src, (IsMethod("private_method"))); - REQUIRE_THAT(src, (IsField("public_member", "int"))); - REQUIRE_THAT(src, (IsField("protected_member", "int"))); - REQUIRE_THAT(src, (IsField("private_member", "int"))); - REQUIRE_THAT(src, - (IsField("auto_member", "const unsigned long"))); - - REQUIRE_THAT(src, (IsField("a_", "int"))); - REQUIRE_THAT(src, (IsField("b_", "int"))); - REQUIRE_THAT(src, (IsField("c_", "int"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); -}*/ } \ No newline at end of file diff --git a/tests/t00067/test_case.h b/tests/t00067/test_case.h index 62e8775b..5182cad3 100644 --- a/tests/t00067/test_case.h +++ b/tests/t00067/test_case.h @@ -20,68 +20,16 @@ TEST_CASE("t00067") { using namespace clanguml::test; - auto [config, db] = load_config("t00067"); - - auto diagram = config.diagrams["t00067_class"]; - - REQUIRE(diagram->name == "t00067_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00067_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00067", "t00067_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { - REQUIRE(!(IsMethod(src, "A"))); - REQUIRE(!(IsMethod(src, "A", "void", "A &&"))); - REQUIRE(!(IsMethod(src, "A", "void", "const A &"))); + REQUIRE(!IsMethod(src, "A", "A")); + REQUIRE(!IsMethod(src, "A", "void", "A &&")); + REQUIRE(!IsMethod(src, "A", "void", "const A &")); - REQUIRE(!(IsMethod(src, "~A"))); + REQUIRE(!IsMethod(src, "A", "~A")); - REQUIRE(!(IsMethod(src, "~A"))); + REQUIRE(!IsMethod(src, "A", "~A")); }); - /* - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, !(IsMethod("A"))); - REQUIRE_THAT(src, !(IsMethod("A", "void", "A &&"))); - REQUIRE_THAT( - src, !(IsMethod("A", "void", "const A &"))); - - REQUIRE_THAT(src, !(IsMethod("~A"))); - - REQUIRE_THAT(src, !(IsMethod("~A"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsMethod; - - REQUIRE_THAT(src, !(IsMethod("A"))); - REQUIRE_THAT(src, !(IsMethod("A", "void", "A &&"))); - REQUIRE_THAT( - src, !(IsMethod("A", "void", "const A &"))); - - REQUIRE_THAT(src, !(IsMethod("~A"))); - - REQUIRE_THAT(src, !(IsMethod("~A"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } \ No newline at end of file diff --git a/tests/t00068/test_case.h b/tests/t00068/test_case.h index 57b96ffb..ab6bd96b 100644 --- a/tests/t00068/test_case.h +++ b/tests/t00068/test_case.h @@ -20,13 +20,8 @@ TEST_CASE("t00068_r0") { using namespace clanguml::test; - auto [config, db] = load_config("t00068"); - - auto diagram = config.diagrams["t00068_r0_class"]; - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00068_r0_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00068", "t00068_r0_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(!IsClass(src, "A")); @@ -47,13 +42,9 @@ TEST_CASE("t00068_r1") { using namespace clanguml::test; - auto [config, db] = load_config("t00068"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00068", "t00068_r1_class"); - auto diagram = config.diagrams["t00068_r1_class"]; - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00068_r1_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(!IsClass(src, "A")); REQUIRE(IsClass(src, "AA")); @@ -73,13 +64,8 @@ TEST_CASE("t00068_r2") { using namespace clanguml::test; - auto [config, db] = load_config("t00068"); - - auto diagram = config.diagrams["t00068_r2_class"]; - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00068_r2_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00068", "t00068_r2_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A")); diff --git a/tests/t00069/test_case.h b/tests/t00069/test_case.h index b72232e3..2f56279c 100644 --- a/tests/t00069/test_case.h +++ b/tests/t00069/test_case.h @@ -20,92 +20,23 @@ TEST_CASE("t00069") { using namespace clanguml::test; - auto [config, db] = load_config("t00069"); - - auto diagram = config.diagrams["t00069_class"]; - - REQUIRE(diagram->name == "t00069_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00069_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00069", "t00069_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A")); - REQUIRE(IsClassTemplate(src, "generator", "T")); + REQUIRE(IsClassTemplate(src, "generator")); - REQUIRE( - IsInnerClass(src,("generator", "generator::promise_type")); + REQUIRE(IsInnerClass(src, "generator", "generator::promise_type")); - REQUIRE( - IsMethod(src,"iota", "generator")); - REQUIRE( - IsMethod(src,"seed", "generator")); + REQUIRE(IsMethod( + src, "A", "iota", "generator")); + REQUIRE(IsMethod( + src, "A", "seed", "generator")); + REQUIRE(IsDependency(src, "A", "generator")); REQUIRE( - IsDependency(src,"A", "generator")); - REQUIRE( - IsInstantiation( - src,"generator", "generator")); + IsInstantiation(src, "generator", "generator")); }); - /* - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("A"))); - - // Check if class templates exist - REQUIRE_THAT(src, IsClassTemplate("generator", "T")); - - // Check if all inner classes exist - REQUIRE_THAT(src, - IsInnerClass(_A("generator"), - _A("generator::promise_type"))); - - // Check if all methods exist - REQUIRE_THAT(src, - (IsMethod("iota", "generator"))); REQUIRE_THAT(src, (IsMethod("seed", - "generator"))); - - // Check if all relationships exist - REQUIRE_THAT( - src, IsDependency(_A("A"), _A("generator"))); - REQUIRE_THAT(src, - IsInstantiation( - _A("generator"), _A("generator"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsClass; - using mermaid::IsMethod; - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, - (IsMethod("iota", "generator"))); REQUIRE_THAT(src, (IsMethod("seed", - "generator"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t00070/test_case.h b/tests/t00070/test_case.h index 84d6644e..edde2b70 100644 --- a/tests/t00070/test_case.h +++ b/tests/t00070/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00070") { using namespace clanguml::test; - auto [config, db] = load_config("t00070"); - - auto diagram = config.diagrams["t00070_class"]; - - REQUIRE(diagram->name == "t00070_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00070_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00070", "t00070_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A")); @@ -42,55 +35,4 @@ TEST_CASE("t00070") REQUIRE(!IsClass(src, "BBBB")); REQUIRE(!IsEnum(src, "CCC")); }); - - /* - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - REQUIRE(!IsClass(j, "C")); - - REQUIRE(InPublicModule(j, "A", "t00070")); - REQUIRE(InPublicModule(j, "B", "t00070.lib1")); - - REQUIRE(!IsClass(j, "BBBB")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsClass; - using mermaid::IsEnum; - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, !IsClass(_A("C"))); - - REQUIRE_THAT(src, IsClass(_A("BB"))); - REQUIRE_THAT(src, !IsClass(_A("CC"))); - - REQUIRE_THAT(src, IsEnum(_A("BBB"))); - REQUIRE_THAT(src, !IsClass(_A("BBBB"))); - REQUIRE_THAT(src, !IsEnum(_A("CCC"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t00071/test_case.h b/tests/t00071/test_case.h index 485dd416..fcdec30b 100644 --- a/tests/t00071/test_case.h +++ b/tests/t00071/test_case.h @@ -19,16 +19,10 @@ TEST_CASE("t00071") { using namespace clanguml::test; + using namespace std::string_literals; - auto [config, db] = load_config("t00071"); - - auto diagram = config.diagrams["t00071_class"]; - - REQUIRE(diagram->name == "t00071_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00071_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00071", "t00071_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A")); @@ -42,51 +36,4 @@ TEST_CASE("t00071") REQUIRE(IsModulePackage(src, "app"s, "lib1"s, "mod1"s)); REQUIRE(IsModulePackage(src, "app"s, "lib1"s, "mod2"s)); }); - /* - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - - REQUIRE_THAT(src, IsEnum(_A("detail::BBB"))); - REQUIRE_THAT(src, IsEnum(_A("detail::CCC"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - using namespace std::string_literals; - - REQUIRE(IsModulePackage(j, "app"s)); - REQUIRE(IsModulePackage(j, "app"s, "lib1"s)); - REQUIRE(IsModulePackage(j, "app"s, "lib1"s, "mod1"s)); - REQUIRE(IsModulePackage(j, "app"s, "lib1"s, "mod2"s)); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsClass; - using mermaid::IsEnum; - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - - REQUIRE_THAT(src, IsEnum(_A("detail::BBB"))); - REQUIRE_THAT(src, IsEnum(_A("detail::CCC"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t00072/test_case.h b/tests/t00072/test_case.h index d383d907..87d29ab0 100644 --- a/tests/t00072/test_case.h +++ b/tests/t00072/test_case.h @@ -19,23 +19,17 @@ TEST_CASE("t00072") { using namespace clanguml::test; + using namespace std::string_literals; - auto [config, db] = load_config("t00072"); - - auto diagram = config.diagrams["t00072_class"]; - - REQUIRE(diagram->name == "t00072_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00072_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00072", "t00072_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { - REQUIRE(IsPackage(src, "app")); - REQUIRE(IsPackage(src, ":lib1")); - REQUIRE(IsPackage(src, ":lib2")); - REQUIRE(IsPackage(src, "mod1")); - REQUIRE(IsPackage(src, "mod2")); + REQUIRE(IsModulePackage(src, "app"s)); + REQUIRE(IsModulePackage(src, "app"s, ":lib1"s)); + REQUIRE(IsModulePackage(src, "app"s, ":lib1"s, "mod1"s)); + REQUIRE(IsModulePackage(src, "app"s, ":lib1"s, "mod2"s)); + REQUIRE(IsModulePackage(src, "app"s, ":lib2"s)); REQUIRE(IsClass(src, "A")); REQUIRE(IsClass(src, "C")); @@ -49,79 +43,4 @@ TEST_CASE("t00072") REQUIRE(IsClass(src, "D")); REQUIRE(IsClass(src, "E")); }); - /* - - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all classes exist - REQUIRE_THAT(src, IsPackage("app")); - REQUIRE_THAT(src, IsPackage(":lib1")); - REQUIRE_THAT(src, IsPackage(":lib2")); - REQUIRE_THAT(src, IsPackage("mod1")); - REQUIRE_THAT(src, IsPackage("mod2")); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClassTemplate("CC", "T")); - REQUIRE_THAT(src, IsEnum(_A("detail::CCC"))); - - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClassTemplate("BB", "T")); - REQUIRE_THAT(src, IsEnum(_A("detail::BBB"))); - - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - using namespace std::string_literals; - - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - REQUIRE(IsClass(j, "C")); - REQUIRE(IsClass(j, "D")); - REQUIRE(IsEnum(j, "detail::CCC")); - REQUIRE(IsEnum(j, "detail::BBB")); - - REQUIRE(IsModulePackage(j, "app"s)); - REQUIRE(IsModulePackage(j, "app"s, ":lib1"s)); - REQUIRE(IsModulePackage(j, "app"s, ":lib1"s, "mod1"s)); - REQUIRE(IsModulePackage(j, "app"s, ":lib1"s, "mod2"s)); - REQUIRE(IsModulePackage(j, "app"s, ":lib2"s)); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsClass; - using mermaid::IsEnum; - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("C"))); - REQUIRE_THAT(src, IsClass(_A("CC"))); - REQUIRE_THAT(src, IsEnum(_A("detail::CCC"))); - - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("BB"))); - REQUIRE_THAT(src, IsEnum(_A("detail::BBB"))); - - REQUIRE_THAT(src, IsClass(_A("D"))); - REQUIRE_THAT(src, IsClass(_A("E"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } - */ } \ No newline at end of file diff --git a/tests/t00073/test_case.h b/tests/t00073/test_case.h index 3168358f..9491a1c9 100644 --- a/tests/t00073/test_case.h +++ b/tests/t00073/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t00073") { using namespace clanguml::test; - auto [config, db] = load_config("t00073"); - - auto diagram = config.diagrams["t00073_class"]; - - REQUIRE(diagram->name == "t00073_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00073_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00073", "t00073_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsClass(src, "A")); @@ -45,69 +38,4 @@ TEST_CASE("t00073") REQUIRE(IsAggregation( src, "R", "Overload", "dispatch")); }); - /* - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("AHandler"))); - REQUIRE_THAT(src, IsClass(_A("BHandler"))); - REQUIRE_THAT(src, IsClassTemplate("Overload", "Bases...")); - REQUIRE_THAT(src, IsClassTemplate("Overload", "AHandler,BHandler")); - - REQUIRE_THAT(src, IsDependency(_A("AHandler"), _A("A"))); - REQUIRE_THAT(src, IsDependency(_A("BHandler"), _A("B"))); - REQUIRE_THAT(src, - IsInstantiation( - _A("Overload"), - _A("Overload"))); REQUIRE_THAT(src, IsAggregation( - _A("R"), _A("Overload"), "+dispatch")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsClassTemplate(j, "Overload")); - REQUIRE(IsClass(j, "A")); - REQUIRE(IsClass(j, "B")); - REQUIRE(IsClass(j, "AHandler")); - REQUIRE(IsClass(j, "BHandler")); - REQUIRE(IsClass(j, "Overload")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsClass; - - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("AHandler"))); - REQUIRE_THAT(src, IsClass(_A("BHandler"))); - REQUIRE_THAT(src, IsClass(_A("Overload"))); - REQUIRE_THAT(src, IsClass(_A("Overload"))); - - REQUIRE_THAT(src, IsDependency(_A("AHandler"), _A("A"))); - REQUIRE_THAT(src, IsDependency(_A("BHandler"), _A("B"))); - REQUIRE_THAT(src, - IsInstantiation( - _A("Overload"), - _A("Overload"))); REQUIRE_THAT(src, IsAggregation( - _A("R"), _A("Overload"), "+dispatch")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t00074/test_case.h b/tests/t00074/test_case.h index 94d4b6c1..3c18a396 100644 --- a/tests/t00074/test_case.h +++ b/tests/t00074/test_case.h @@ -20,87 +20,29 @@ TEST_CASE("t00074") { using namespace clanguml::test; - auto [config, db] = load_config("t00074"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00074", "t00074_class"); - auto diagram = config.diagrams["t00074_class"]; + CHECK_CLASS_DIAGRAM( + config, diagram, *model, + [](const auto &src) { + REQUIRE(IsConcept(src, "fruit_c")); + REQUIRE(IsConcept(src, "apple_c")); + REQUIRE(IsConcept(src, "orange_c")); - REQUIRE(diagram->name == "t00074_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00074_class"); - - CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { - REQUIRE(IsConcept(src, "fruit_c")); - REQUIRE(IsConcept(src, "apple_c")); - REQUIRE(IsConcept(src, "orange_c")); - - REQUIRE(IsConstraint(src, "apple_c", "fruit_c", "T")); - REQUIRE(IsConstraint(src, "orange_c", "fruit_c", "T")); - - REQUIRE(!IsConceptRequirement(src, "apple_c", "t.get_sweetness()")); - REQUIRE( - !IsConceptRequirement(src, "orange_c", "t.get_bitterness()")); - }); -/* - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsConcept(_A("fruit_c"))); - REQUIRE_THAT(src, IsConcept(_A("apple_c"))); - REQUIRE_THAT(src, IsConcept(_A("orange_c"))); - - REQUIRE_THAT( - src, IsConstraint(_A("apple_c"), _A("fruit_c"), "T")); - REQUIRE_THAT( - src, IsConstraint(_A("orange_c"), _A("fruit_c"), "T")); - - REQUIRE_THAT( - src, !IsConceptRequirement(_A("apple_c"), "t.get_sweetness()")); - REQUIRE_THAT(src, - !IsConceptRequirement(_A("orange_c"), "t.get_bitterness()")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - REQUIRE(IsConcept(j, "fruit_c")); - REQUIRE(IsConcept(j, "apple_c")); - REQUIRE(IsConcept(j, "orange_c")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsConcept; - using mermaid::IsConceptRequirement; - using mermaid::IsConstraint; - - REQUIRE_THAT(src, IsConcept(_A("fruit_c"))); - REQUIRE_THAT(src, IsConcept(_A("apple_c"))); - REQUIRE_THAT(src, IsConcept(_A("orange_c"))); - - REQUIRE_THAT( - src, IsConstraint(_A("apple_c"), _A("fruit_c"), "T")); - REQUIRE_THAT( - src, IsConstraint(_A("orange_c"), _A("fruit_c"), "T")); - - REQUIRE_THAT( - src, !IsConceptRequirement(_A("apple_c"), "t.get_sweetness()")); - REQUIRE_THAT( - src, !IsConceptRequirement(_A("apple_c"), "t.get_bitterness()")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ + REQUIRE(IsConstraint(src, "apple_c", "fruit_c", "T")); + REQUIRE(IsConstraint(src, "orange_c", "fruit_c", "T")); + }, + [](const plantuml_t &src) { + REQUIRE( + !IsConceptRequirement(src, "apple_c", "t.get_sweetness()")); + REQUIRE(!IsConceptRequirement( + src, "orange_c", "t.get_bitterness()")); + }, + [](const mermaid_t &src) { + REQUIRE( + !IsConceptRequirement(src, "apple_c", "t.get_sweetness()")); + REQUIRE(!IsConceptRequirement( + src, "orange_c", "t.get_bitterness()")); + }); } \ No newline at end of file diff --git a/tests/t00075/test_case.h b/tests/t00075/test_case.h index 7170d6dc..7d551eb0 100644 --- a/tests/t00075/test_case.h +++ b/tests/t00075/test_case.h @@ -20,94 +20,25 @@ TEST_CASE("t00075") { using namespace clanguml::test; - auto [config, db] = load_config("t00075"); - - auto diagram = config.diagrams["t00075_class"]; - - REQUIRE(diagram->name == "t00075_class"); - - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t00075_class"); + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t00075", "t00075_class"); CHECK_CLASS_DIAGRAM(config, diagram, *model, [](const auto &src) { - REQUIRE(IsClass(src, "A")); - REQUIRE(IsClass(src, "B")); - REQUIRE(IsClassTemplate(src, "ABE")); - REQUIRE(IsClass(src, "R")); + REQUIRE(IsClass(src, {"ns1::ns2", "A"})); + REQUIRE(IsClass(src, {"ns1::ns2", "B"})); + REQUIRE(IsClass(src, {"ns1::ns2", "ABE"})); + REQUIRE(IsClass(src, {"ns1::ns2", "R"})); - REQUIRE(IsEnum(src, "E")); + REQUIRE(IsEnum(src, {"ns1::ns2", "E"})); - REQUIRE(IsConcept(src, "C")); + REQUIRE(IsConcept(src, {"ns1::ns2", "C"})); REQUIRE(IsConceptRequirement(src, "C", "T{}")); REQUIRE(IsConceptRequirement(src, "C", "t.e()")); - REQUIRE(IsConceptRequirement(src, "C", "(T t)")); - REQUIRE(!IsConceptRequirement(src, "C", "(T ns1::ns2::t)")); + REQUIRE(IsConceptParameterList(src, "C", "(T t)")); + REQUIRE(!IsConceptParameterList(src, "C", "(T ns1::ns2::t)")); - REQUIRE(IsConstraint(src, "ABE", "C", "T", - "up[#green,dashed,thickness=2]")); + REQUIRE(IsConstraint(src, {"ns1::ns2", "ABE"}, + {"ns1::ns2", "C"}, "T", "up[#green,dashed,thickness=2]")); }); - - { - auto src = generate_class_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("A"))); - REQUIRE_THAT(src, IsClass(_A("B"))); - REQUIRE_THAT(src, IsClass(_A("ABE"))); - REQUIRE_THAT(src, IsClass(_A("R"))); - - REQUIRE_THAT(src, IsEnum(_A("E"))); - - REQUIRE_THAT(src, IsConcept(_A("C"))); - - REQUIRE_THAT(src, IsConceptRequirement(_A("C"), "T{}")); - REQUIRE_THAT(src, IsConceptRequirement(_A("C"), "t.e()")); - REQUIRE_THAT(src, IsConceptRequirement(_A("C"), "(T t)")); - REQUIRE_THAT(src, !IsConceptRequirement(_A("C"), "(T ns1::ns2::t)")); - - REQUIRE_THAT(src, - IsConstraint(_A("ABE"), _A("C"), "T", - "up[#green,dashed,thickness=2]")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_class_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsClass; - using mermaid::IsConcept; - using mermaid::IsConceptRequirement; - using mermaid::IsEnum; - - // Check if all classes exist - REQUIRE_THAT(src, IsClass(_A("ns1::ns2::A"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns2::B"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns2::ABE"))); - REQUIRE_THAT(src, IsClass(_A("ns1::ns2::R"))); - - REQUIRE_THAT(src, IsEnum(_A("ns1::ns2::E"))); - - REQUIRE_THAT(src, IsConcept(_A("ns1::ns2::C"))); - - REQUIRE_THAT(src, IsConceptRequirement(_A("ns1::ns2::C"), "T{}")); - REQUIRE_THAT(src, IsConceptRequirement(_A("ns1::ns2::C"), "t.e()")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } } \ No newline at end of file diff --git a/tests/t30001/test_case.h b/tests/t30001/test_case.h index 8b85fbe1..80e3e4f2 100644 --- a/tests/t30001/test_case.h +++ b/tests/t30001/test_case.h @@ -21,15 +21,8 @@ TEST_CASE("t30001") using namespace clanguml::test; using namespace std::string_literals; - auto [config, db] = load_config("t30001"); - - auto diagram = config.diagrams["t30001_package"]; - - REQUIRE(diagram->name == "t30001_package"); - - auto model = generate_package_diagram(*db, diagram); - - REQUIRE(model->name() == "t30001_package"); + auto [config, db, diagram, model] = + CHECK_PACKAGE_MODEL("t30001", "t30001_package"); CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(HasTitle(src, "Basic package diagram example")); diff --git a/tests/t30002/test_case.h b/tests/t30002/test_case.h index 8b5daa65..bc0badda 100644 --- a/tests/t30002/test_case.h +++ b/tests/t30002/test_case.h @@ -21,15 +21,8 @@ TEST_CASE("t30002") using namespace clanguml::test; using namespace std::string_literals; - auto [config, db] = load_config("t30002"); - - auto diagram = config.diagrams["t30002_package"]; - - REQUIRE(diagram->name == "t30002_package"); - - auto model = generate_package_diagram(*db, diagram); - - REQUIRE(model->name() == "t30002_package"); + auto [config, db, diagram, model] = + CHECK_PACKAGE_MODEL("t30002", "t30002_package"); CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsNamespacePackage(src, "A"s, "AA"s)); @@ -73,149 +66,4 @@ TEST_CASE("t30002") REQUIRE(IsDependency(src, "BBB", "A17")); REQUIRE(IsDependency(src, "BBB", "A18")); }); - /* - { - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsPackage("A1")); - REQUIRE_THAT(src, IsPackage("A2")); - REQUIRE_THAT(src, IsPackage("A3")); - REQUIRE_THAT(src, IsPackage("A4")); - REQUIRE_THAT(src, IsPackage("A5")); - REQUIRE_THAT(src, IsPackage("A6")); - REQUIRE_THAT(src, IsPackage("A7")); - REQUIRE_THAT(src, IsPackage("A8")); - REQUIRE_THAT(src, IsPackage("A9")); - REQUIRE_THAT(src, IsPackage("A11")); - REQUIRE_THAT(src, IsPackage("A12")); - REQUIRE_THAT(src, IsPackage("A13")); - REQUIRE_THAT(src, IsPackage("A14")); - REQUIRE_THAT(src, IsPackage("A15")); - REQUIRE_THAT(src, IsPackage("A16")); - REQUIRE_THAT(src, IsPackage("A17")); - REQUIRE_THAT(src, IsPackage("A18")); - - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A1"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A2"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A3"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A4"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A5"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A6"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A7"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A8"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A9"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A10"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A11"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A12"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A13"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A14"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A15"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A16"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A17"))); - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("A18"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_package_json(diagram, *model); - - using namespace json; - using namespace std::string_literals; - - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A1"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A2"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A3"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A4"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A5"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A6"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A7"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A8"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A9"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A10"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A11"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A12"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A13"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A14"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A15"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A16"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A17"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "A18"s)); - - REQUIRE(IsNamespacePackage(j, "B"s, "BB"s, "BBB"s)); - - REQUIRE(IsDependency(j, "BBB", "A1")); - REQUIRE(IsDependency(j, "BBB", "A2")); - REQUIRE(IsDependency(j, "BBB", "A3")); - REQUIRE(IsDependency(j, "BBB", "A4")); - REQUIRE(IsDependency(j, "BBB", "A5")); - REQUIRE(IsDependency(j, "BBB", "A6")); - REQUIRE(IsDependency(j, "BBB", "A7")); - REQUIRE(IsDependency(j, "BBB", "A8")); - REQUIRE(IsDependency(j, "BBB", "A9")); - REQUIRE(IsDependency(j, "BBB", "A10")); - REQUIRE(IsDependency(j, "BBB", "A11")); - REQUIRE(IsDependency(j, "BBB", "A12")); - REQUIRE(IsDependency(j, "BBB", "A13")); - REQUIRE(IsDependency(j, "BBB", "A14")); - REQUIRE(IsDependency(j, "BBB", "A15")); - REQUIRE(IsDependency(j, "BBB", "A16")); - REQUIRE(IsDependency(j, "BBB", "A17")); - REQUIRE(IsDependency(j, "BBB", "A18")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_package_mermaid(diagram, *model); - mermaid::AliasMatcher _A(src); - using mermaid::IsPackage; - using mermaid::IsPackageDependency; - - REQUIRE_THAT(src, IsPackage(_A("A1"))); - REQUIRE_THAT(src, IsPackage(_A("A2"))); - REQUIRE_THAT(src, IsPackage(_A("A3"))); - REQUIRE_THAT(src, IsPackage(_A("A4"))); - REQUIRE_THAT(src, IsPackage(_A("A5"))); - REQUIRE_THAT(src, IsPackage(_A("A6"))); - REQUIRE_THAT(src, IsPackage(_A("A7"))); - REQUIRE_THAT(src, IsPackage(_A("A8"))); - REQUIRE_THAT(src, IsPackage(_A("A9"))); - REQUIRE_THAT(src, IsPackage(_A("A11"))); - REQUIRE_THAT(src, IsPackage(_A("A12"))); - REQUIRE_THAT(src, IsPackage(_A("A13"))); - REQUIRE_THAT(src, IsPackage(_A("A14"))); - REQUIRE_THAT(src, IsPackage(_A("A15"))); - REQUIRE_THAT(src, IsPackage(_A("A16"))); - REQUIRE_THAT(src, IsPackage(_A("A17"))); - REQUIRE_THAT(src, IsPackage(_A("A18"))); - - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A1"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A2"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A3"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A4"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A5"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A6"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A7"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A8"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A9"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A10"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A11"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A12"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A13"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A14"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A15"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A16"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A17"))); - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("A18"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - } - */ } diff --git a/tests/t30003/test_case.h b/tests/t30003/test_case.h index 301bbb73..841e14b4 100644 --- a/tests/t30003/test_case.h +++ b/tests/t30003/test_case.h @@ -21,15 +21,8 @@ TEST_CASE("t30003") using namespace clanguml::test; using namespace std::string_literals; - auto [config, db] = load_config("t30003"); - - auto diagram = config.diagrams["t30003_package"]; - - REQUIRE(diagram->name == "t30003_package"); - - auto model = generate_package_diagram(*db, diagram); - - REQUIRE(model->name() == "t30003_package"); + auto [config, db, diagram, model] = + CHECK_PACKAGE_MODEL("t30003", "t30003_package"); CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsNamespacePackage(src, "ns1"s)); @@ -39,7 +32,7 @@ TEST_CASE("t30003") REQUIRE(IsNamespacePackage(src, "ns3"s, "ns1"s)); REQUIRE(IsNamespacePackage(src, "ns3"s, "ns1"s, "ns2"s)); - // REQUIRE(IsDeprecated(src, "ns2_v0_9_0")); - // REQUIRE(IsDeprecated(src, "ns3")); + REQUIRE(IsDeprecated(src, "ns2_v0_9_0")); + REQUIRE(IsDeprecated(src, "ns3")); }); } diff --git a/tests/t30004/test_case.h b/tests/t30004/test_case.h index 4829f92a..91c49361 100644 --- a/tests/t30004/test_case.h +++ b/tests/t30004/test_case.h @@ -21,15 +21,8 @@ TEST_CASE("t30004") using namespace clanguml::test; using namespace std::string_literals; - auto [config, db] = load_config("t30004"); - - auto diagram = config.diagrams["t30004_package"]; - - REQUIRE(diagram->name == "t30004_package"); - - auto model = generate_package_diagram(*db, diagram); - - REQUIRE(model->name() == "t30004_package"); + auto [config, db, diagram, model] = + CHECK_PACKAGE_MODEL("t30004", "t30004_package"); CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsNamespacePackage(src, "A"s)); @@ -39,49 +32,4 @@ TEST_CASE("t30004") REQUIRE(!IsNamespacePackage(src, "A"s, "DDD"s)); REQUIRE(IsNamespacePackage(src, "A"s, "EEE"s)); }); - /*{ - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsPackage("AAA")); - REQUIRE_THAT(src, IsPackage("BBB")); - REQUIRE_THAT(src, IsPackage("CCC")); - REQUIRE_THAT(src, !IsPackage("DDD")); - REQUIRE_THAT(src, IsPackage("EEE")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_package_json(diagram, *model); - - using namespace json; - using namespace std::string_literals; - - REQUIRE(IsNamespacePackage(j, "A"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AAA"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "BBB"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "CCC"s)); - REQUIRE(!IsNamespacePackage(j, "A"s, "DDD"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "EEE"s)); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_package_mermaid(diagram, *model); - mermaid::AliasMatcher _A(src); - using mermaid::IsPackage; - - REQUIRE_THAT(src, IsPackage(_A("AAA"))); - REQUIRE_THAT(src, IsPackage(_A("BBB"))); - REQUIRE_THAT(src, IsPackage(_A("CCC"))); - REQUIRE_THAT(src, !IsPackage(_A("DDD"))); - REQUIRE_THAT(src, IsPackage(_A("EEE"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } diff --git a/tests/t30005/test_case.h b/tests/t30005/test_case.h index ef0098b3..055f8359 100644 --- a/tests/t30005/test_case.h +++ b/tests/t30005/test_case.h @@ -21,15 +21,8 @@ TEST_CASE("t30005") using namespace clanguml::test; using namespace std::string_literals; - auto [config, db] = load_config("t30005"); - - auto diagram = config.diagrams["t30005_package"]; - - REQUIRE(diagram->name == "t30005_package"); - - auto model = generate_package_diagram(*db, diagram); - - REQUIRE(model->name() == "t30005_package"); + auto [config, db, diagram, model] = + CHECK_PACKAGE_MODEL("t30005", "t30005_package"); CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsNamespacePackage(src, "A"s)); @@ -45,60 +38,4 @@ TEST_CASE("t30005") REQUIRE(IsDependency(src, "BBB", "AAA")); REQUIRE(IsDependency(src, "CCC", "AAA")); }); -/* - { - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsPackage("AAA")); - REQUIRE_THAT(src, IsPackage("BBB")); - REQUIRE_THAT(src, IsPackage("CCC")); - - REQUIRE_THAT(src, IsDependency(_A("BBB"), _A("AAA"))); - REQUIRE_THAT(src, IsDependency(_A("CCC"), _A("AAA"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_package_json(diagram, *model); - - using namespace json; - using namespace std::string_literals; - - REQUIRE(IsNamespacePackage(j, "A"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s, "AAA"s)); - REQUIRE(IsNamespacePackage(j, "B"s)); - REQUIRE(IsNamespacePackage(j, "B"s, "BB"s)); - REQUIRE(IsNamespacePackage(j, "B"s, "BB"s, "BBB"s)); - REQUIRE(IsNamespacePackage(j, "C"s)); - REQUIRE(IsNamespacePackage(j, "C"s, "CC"s)); - REQUIRE(IsNamespacePackage(j, "C"s, "CC"s, "CCC"s)); - - REQUIRE(IsDependency(j, "BBB", "AAA")); - REQUIRE(IsDependency(j, "CCC", "AAA")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_package_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsPackage; - using mermaid::IsPackageDependency; - - REQUIRE_THAT(src, IsPackage(_A("AAA"))); - REQUIRE_THAT(src, IsPackage(_A("BBB"))); - REQUIRE_THAT(src, IsPackage(_A("CCC"))); - - REQUIRE_THAT(src, IsPackageDependency(_A("BBB"), _A("AAA"))); - REQUIRE_THAT(src, IsPackageDependency(_A("CCC"), _A("AAA"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } diff --git a/tests/t30006/test_case.h b/tests/t30006/test_case.h index 3e580e14..b71807cb 100644 --- a/tests/t30006/test_case.h +++ b/tests/t30006/test_case.h @@ -21,15 +21,8 @@ TEST_CASE("t30006") using namespace clanguml::test; using namespace std::string_literals; - auto [config, db] = load_config("t30006"); - - auto diagram = config.diagrams["t30006_package"]; - - REQUIRE(diagram->name == "t30006_package"); - - auto model = generate_package_diagram(*db, diagram); - - REQUIRE(model->name() == "t30006_package"); + auto [config, db, diagram, model] = + CHECK_PACKAGE_MODEL("t30006", "t30006_package"); CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsNamespacePackage(src, "A"s)); @@ -39,54 +32,4 @@ TEST_CASE("t30006") REQUIRE(IsDependency(src, "A", "B")); REQUIRE(IsDependency(src, "A", "C")); }); - - /* - { - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsPackage("A")); - REQUIRE_THAT(src, IsPackage("B")); - REQUIRE_THAT(src, IsPackage("C")); - - REQUIRE_THAT(src, IsDependency(_A("A"), _A("B"))); - REQUIRE_THAT(src, IsDependency(_A("A"), _A("C"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_package_json(diagram, *model); - - using namespace json; - using namespace std::string_literals; - - REQUIRE(IsNamespacePackage(j, "A"s)); - REQUIRE(IsNamespacePackage(j, "B"s)); - REQUIRE(IsNamespacePackage(j, "C"s)); - - REQUIRE(IsDependency(j, "A", "B")); - REQUIRE(IsDependency(j, "A", "C")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_package_mermaid(diagram, *model); - mermaid::AliasMatcher _A(src); - using mermaid::IsPackage; - using mermaid::IsPackageDependency; - - REQUIRE_THAT(src, IsPackage(_A("A"))); - REQUIRE_THAT(src, IsPackage(_A("B"))); - REQUIRE_THAT(src, IsPackage(_A("C"))); - - REQUIRE_THAT(src, IsPackageDependency(_A("A"), _A("B"))); - REQUIRE_THAT(src, IsPackageDependency(_A("A"), _A("C"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } diff --git a/tests/t30007/test_case.h b/tests/t30007/test_case.h index 58fd9b39..3832c181 100644 --- a/tests/t30007/test_case.h +++ b/tests/t30007/test_case.h @@ -21,15 +21,8 @@ TEST_CASE("t30007") using namespace clanguml::test; using namespace std::string_literals; - auto [config, db] = load_config("t30007"); - - auto diagram = config.diagrams["t30007_package"]; - - REQUIRE(diagram->name == "t30007_package"); - - auto model = generate_package_diagram(*db, diagram); - - REQUIRE(model->name() == "t30007_package"); + auto [config, db, diagram, model] = + CHECK_PACKAGE_MODEL("t30007", "t30007_package"); CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsNamespacePackage(src, "A"s)); @@ -39,60 +32,8 @@ TEST_CASE("t30007") REQUIRE(IsDependency(src, "AA", "B")); REQUIRE(IsDependency(src, "AA", "C")); + + REQUIRE(IsLayoutHint(src, "C", "up", "AA")); + REQUIRE(IsLayoutHint(src, "C", "left", "B")); }); - /* - { - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsPackage("A")); - REQUIRE_THAT(src, IsPackage("B")); - REQUIRE_THAT(src, IsPackage("C")); - - REQUIRE_THAT(src, IsDependency(_A("AA"), _A("B"))); - REQUIRE_THAT(src, IsDependency(_A("AA"), _A("C"))); - - REQUIRE_THAT(src, IsLayoutHint(_A("C"), "up", _A("AA"))); - REQUIRE_THAT(src, IsLayoutHint(_A("C"), "left", _A("B"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_package_json(diagram, *model); - - using namespace json; - using namespace std::string_literals; - - REQUIRE(IsNamespacePackage(j, "A"s)); - REQUIRE(IsNamespacePackage(j, "A"s, "AA"s)); - REQUIRE(IsNamespacePackage(j, "B"s)); - REQUIRE(IsNamespacePackage(j, "C"s)); - - REQUIRE(IsDependency(j, "AA", "B")); - REQUIRE(IsDependency(j, "AA", "C")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_package_mermaid(diagram, *model); - mermaid::AliasMatcher _A(src); - using mermaid::IsPackage; - using mermaid::IsPackageDependency; - - REQUIRE_THAT(src, IsPackage(_A("A"))); - REQUIRE_THAT(src, IsPackage(_A("B"))); - REQUIRE_THAT(src, IsPackage(_A("C"))); - - REQUIRE_THAT(src, IsPackageDependency(_A("AA"), _A("B"))); - REQUIRE_THAT(src, IsPackageDependency(_A("AA"), _A("C"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - } - */ } diff --git a/tests/t30008/test_case.h b/tests/t30008/test_case.h index 9100a09e..95c3d048 100644 --- a/tests/t30008/test_case.h +++ b/tests/t30008/test_case.h @@ -21,15 +21,8 @@ TEST_CASE("t30008") using namespace clanguml::test; using namespace std::string_literals; - auto [config, db] = load_config("t30008"); - - auto diagram = config.diagrams["t30008_package"]; - - REQUIRE(diagram->name == "t30008_package"); - - auto model = generate_package_diagram(*db, diagram); - - REQUIRE(model->name() == "t30008_package"); + auto [config, db, diagram, model] = + CHECK_PACKAGE_MODEL("t30008", "t30008_package"); CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsNamespacePackage(src, "dependants"s, "A"s)); @@ -48,81 +41,4 @@ TEST_CASE("t30008") REQUIRE(IsDependency(src, "E", "D")); REQUIRE(IsDependency(src, "F", "E")); }); - /* - { - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsPackage("A")); - REQUIRE_THAT(src, IsPackage("B")); - REQUIRE_THAT(src, IsPackage("C")); - REQUIRE_THAT(src, !IsPackage("X")); - - REQUIRE_THAT(src, IsDependency(_A("B"), _A("A"))); - REQUIRE_THAT(src, IsDependency(_A("C"), _A("B"))); - - REQUIRE_THAT(src, IsPackage("D")); - REQUIRE_THAT(src, IsPackage("E")); - REQUIRE_THAT(src, IsPackage("F")); - REQUIRE_THAT(src, !IsPackage("Y")); - - REQUIRE_THAT(src, IsDependency(_A("E"), _A("D"))); - REQUIRE_THAT(src, IsDependency(_A("F"), _A("E"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_package_json(diagram, *model); - - using namespace json; - using namespace std::string_literals; - - REQUIRE(IsNamespacePackage(j, "dependants"s, "A"s)); - REQUIRE(IsNamespacePackage(j, "dependants"s, "B"s)); - REQUIRE(IsNamespacePackage(j, "dependants"s, "C"s)); - REQUIRE(!IsNamespacePackage(j, "dependants"s, "X"s)); - - REQUIRE(IsDependency(j, "B", "A")); - REQUIRE(IsDependency(j, "C", "B")); - - REQUIRE(IsNamespacePackage(j, "dependencies"s, "D"s)); - REQUIRE(IsNamespacePackage(j, "dependencies"s, "E"s)); - REQUIRE(IsNamespacePackage(j, "dependencies"s, "F"s)); - REQUIRE(!IsNamespacePackage(j, "dependencies"s, "Y"s)); - - REQUIRE(IsDependency(j, "E", "D")); - REQUIRE(IsDependency(j, "F", "E")); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_package_mermaid(diagram, *model); - mermaid::AliasMatcher _A(src); - using mermaid::IsPackage; - using mermaid::IsPackageDependency; - - REQUIRE_THAT(src, IsPackage(_A("A"))); - REQUIRE_THAT(src, IsPackage(_A("B"))); - REQUIRE_THAT(src, IsPackage(_A("C"))); - REQUIRE_THAT(src, !IsPackage(_A("X"))); - - REQUIRE_THAT(src, IsPackageDependency(_A("B"), _A("A"))); - REQUIRE_THAT(src, IsPackageDependency(_A("C"), _A("B"))); - - REQUIRE_THAT(src, IsPackage(_A("D"))); - REQUIRE_THAT(src, IsPackage(_A("E"))); - REQUIRE_THAT(src, IsPackage(_A("F"))); - REQUIRE_THAT(src, !IsPackage(_A("Y"))); - - REQUIRE_THAT(src, IsPackageDependency(_A("E"), _A("D"))); - REQUIRE_THAT(src, IsPackageDependency(_A("F"), _A("E"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } diff --git a/tests/t30009/test_case.h b/tests/t30009/test_case.h index 8a2156b3..6644441a 100644 --- a/tests/t30009/test_case.h +++ b/tests/t30009/test_case.h @@ -21,15 +21,8 @@ TEST_CASE("t30009") using namespace clanguml::test; using namespace std::string_literals; - auto [config, db] = load_config("t30009"); - - auto diagram = config.diagrams["t30009_package"]; - - REQUIRE(diagram->name == "t30009_package"); - - auto model = generate_package_diagram(*db, diagram); - - REQUIRE(model->name() == "t30009_package"); + auto [config, db, diagram, model] = + CHECK_PACKAGE_MODEL("t30009", "t30009_package"); CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsNamespacePackage(src, "One"s)); @@ -43,58 +36,4 @@ TEST_CASE("t30009") REQUIRE(IsNamespacePackage(src, "Two"s, "C"s)); REQUIRE(IsNamespacePackage(src, "Two"s, "D"s)); }); - /* - { - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all packages exist - REQUIRE_THAT(src, IsPackage("One")); - REQUIRE_THAT(src, IsPackage("Two")); - REQUIRE_THAT(src, IsPackage("A")); - REQUIRE_THAT(src, IsPackage("B")); - REQUIRE_THAT(src, IsPackage("C")); - REQUIRE_THAT(src, IsPackage("D")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_package_json(diagram, *model); - - using namespace json; - using namespace std::string_literals; - - REQUIRE(IsNamespacePackage(j, "One"s)); - REQUIRE(IsNamespacePackage(j, "Two"s)); - REQUIRE(IsNamespacePackage(j, "One"s, "A"s)); - REQUIRE(IsNamespacePackage(j, "One"s, "B"s)); - REQUIRE(IsNamespacePackage(j, "One"s, "C"s)); - REQUIRE(IsNamespacePackage(j, "One"s, "D"s)); - REQUIRE(IsNamespacePackage(j, "Two"s, "A"s)); - REQUIRE(IsNamespacePackage(j, "Two"s, "B"s)); - REQUIRE(IsNamespacePackage(j, "Two"s, "C"s)); - REQUIRE(IsNamespacePackage(j, "Two"s, "D"s)); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_package_mermaid(diagram, *model); - mermaid::AliasMatcher _A(src); - using mermaid::IsPackage; - - REQUIRE_THAT(src, IsPackage(_A("One"))); - REQUIRE_THAT(src, IsPackage(_A("Two"))); - REQUIRE_THAT(src, IsPackage(_A("A"))); - REQUIRE_THAT(src, IsPackage(_A("B"))); - REQUIRE_THAT(src, IsPackage(_A("C"))); - REQUIRE_THAT(src, IsPackage(_A("D"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t30010/test_case.h b/tests/t30010/test_case.h index cab73e2b..e48ebbc2 100644 --- a/tests/t30010/test_case.h +++ b/tests/t30010/test_case.h @@ -21,15 +21,8 @@ TEST_CASE("t30010") using namespace clanguml::test; using namespace std::string_literals; - auto [config, db] = load_config("t30010"); - - auto diagram = config.diagrams["t30010_package"]; - - REQUIRE(diagram->name == "t30010_package"); - - auto model = generate_package_diagram(*db, diagram); - - REQUIRE(model->name() == "t30010_package"); + auto [config, db, diagram, model] = + CHECK_PACKAGE_MODEL("t30010", "t30010_package"); CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsDirectoryPackage(src, "app"s)); @@ -43,63 +36,4 @@ TEST_CASE("t30010") REQUIRE(IsDependency(src, "app", "lib3")); REQUIRE(IsDependency(src, "app", "lib4")); }); - /* - { - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsPackage("app")); - REQUIRE_THAT(src, IsPackage("libraries")); - REQUIRE_THAT(src, IsPackage("lib1")); - REQUIRE_THAT(src, IsPackage("lib2")); - REQUIRE_THAT(src, !IsPackage("library1")); - REQUIRE_THAT(src, !IsPackage("library2")); - - REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib1"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib2"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib3"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib4"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_package_json(diagram, *model); - - using namespace json; - using namespace std::string_literals; - - REQUIRE(IsDirectoryPackage(j, "app"s)); - REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib1"s)); - REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib2"s)); - REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib3"s)); - REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib4"s)); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_package_mermaid(diagram, *model); - mermaid::AliasMatcher _A(src); - using mermaid::IsPackage; - using mermaid::IsPackageDependency; - - REQUIRE_THAT(src, IsPackage(_A("app"))); - REQUIRE_THAT(src, IsPackage(_A("libraries"))); - REQUIRE_THAT(src, IsPackage(_A("lib1"))); - REQUIRE_THAT(src, IsPackage(_A("lib2"))); - REQUIRE_THAT(src, !IsPackage(_A("library1"))); - REQUIRE_THAT(src, !IsPackage(_A("library2"))); - - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib1"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib2"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib3"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib4"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t30011/test_case.h b/tests/t30011/test_case.h index 098ab003..70153b43 100644 --- a/tests/t30011/test_case.h +++ b/tests/t30011/test_case.h @@ -21,15 +21,8 @@ TEST_CASE("t30011") using namespace clanguml::test; using namespace std::string_literals; - auto [config, db] = load_config("t30011"); - - auto diagram = config.diagrams["t30011_package"]; - - REQUIRE(diagram->name == "t30011_package"); - - auto model = generate_package_diagram(*db, diagram); - - REQUIRE(model->name() == "t30011_package"); + auto [config, db, diagram, model] = + CHECK_PACKAGE_MODEL("t30011", "t30011_package"); CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsDirectoryPackage(src, "app"s)); @@ -43,69 +36,4 @@ TEST_CASE("t30011") REQUIRE(IsDependency(src, "app", "lib3")); REQUIRE(IsDependency(src, "app", "lib4")); }); - /* - { - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, IsPackage("app")); - REQUIRE_THAT(src, IsPackage("libraries")); - REQUIRE_THAT(src, IsPackage("lib1")); - REQUIRE_THAT(src, IsPackage("lib2")); - REQUIRE_THAT(src, !IsPackage("library1")); - REQUIRE_THAT(src, !IsPackage("library2")); - - REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib1"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib2"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib3"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("lib4"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_package_json(diagram, *model); - - using namespace json; - using namespace std::string_literals; - - REQUIRE(IsDirectoryPackage(j, "app"s)); - REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib1"s)); - REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib2"s)); - REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib3"s)); - REQUIRE(IsDirectoryPackage(j, "libraries"s, "lib4"s)); - - REQUIRE(IsDependency(j, "app"s, "lib1"s)); - REQUIRE(IsDependency(j, "app"s, "lib2"s)); - REQUIRE(IsDependency(j, "app"s, "lib3"s)); - REQUIRE(IsDependency(j, "app"s, "lib4"s)); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_package_mermaid(diagram, *model); - mermaid::AliasMatcher _A(src); - using mermaid::IsPackage; - using mermaid::IsPackageDependency; - - REQUIRE_THAT(src, IsPackage(_A("app"))); - REQUIRE_THAT(src, IsPackage(_A("libraries"))); - REQUIRE_THAT(src, IsPackage(_A("lib1"))); - REQUIRE_THAT(src, IsPackage(_A("lib2"))); - REQUIRE_THAT(src, !IsPackage(_A("library1"))); - REQUIRE_THAT(src, !IsPackage(_A("library2"))); - - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib1"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib2"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib3"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("lib4"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - } - */ } \ No newline at end of file diff --git a/tests/t30012/test_case.h b/tests/t30012/test_case.h index 8c4a6736..1c919c44 100644 --- a/tests/t30012/test_case.h +++ b/tests/t30012/test_case.h @@ -21,15 +21,8 @@ TEST_CASE("t30012") using namespace clanguml::test; using namespace std::string_literals; - auto [config, db] = load_config("t30012"); - - auto diagram = config.diagrams["t30012_package"]; - - REQUIRE(diagram->name == "t30012_package"); - - auto model = generate_package_diagram(*db, diagram); - - REQUIRE(model->name() == "t30012_package"); + auto [config, db, diagram, model] = + CHECK_PACKAGE_MODEL("t30012", "t30012_package"); CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsModulePackage(src, "app"s)); @@ -38,51 +31,4 @@ TEST_CASE("t30012") REQUIRE(IsModulePackage(src, "app"s, "lib1"s, "mod2"s)); REQUIRE(IsModulePackage(src, "app"s, "lib2"s)); }); -/* - { - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all packages exist - REQUIRE_THAT(src, IsPackage("app")); - REQUIRE_THAT(src, IsPackage("lib1")); - REQUIRE_THAT(src, IsPackage("lib2")); - REQUIRE_THAT(src, IsPackage("mod1")); - REQUIRE_THAT(src, IsPackage("mod2")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_package_json(diagram, *model); - - using namespace json; - using namespace std::string_literals; - - REQUIRE(IsModulePackage(j, "app"s)); - REQUIRE(IsModulePackage(j, "app"s, "lib1"s)); - REQUIRE(IsModulePackage(j, "app"s, "lib1"s, "mod1"s)); - REQUIRE(IsModulePackage(j, "app"s, "lib1"s, "mod2"s)); - REQUIRE(IsModulePackage(j, "app"s, "lib2"s)); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_package_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsPackage; - - REQUIRE_THAT(src, IsPackage(_A("app"))); - REQUIRE_THAT(src, IsPackage(_A("lib1"))); - REQUIRE_THAT(src, IsPackage(_A("lib2"))); - REQUIRE_THAT(src, IsPackage(_A("mod1"))); - REQUIRE_THAT(src, IsPackage(_A("mod2"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } \ No newline at end of file diff --git a/tests/t30013/test_case.h b/tests/t30013/test_case.h index bfdf866e..5a5ac1db 100644 --- a/tests/t30013/test_case.h +++ b/tests/t30013/test_case.h @@ -21,15 +21,8 @@ TEST_CASE("t30013") using namespace clanguml::test; using namespace std::string_literals; - auto [config, db] = load_config("t30013"); - - auto diagram = config.diagrams["t30013_package"]; - - REQUIRE(diagram->name == "t30013_package"); - - auto model = generate_package_diagram(*db, diagram); - - REQUIRE(model->name() == "t30013_package"); + auto [config, db, diagram, model] = + CHECK_PACKAGE_MODEL("t30013", "t30013_package"); CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsModulePackage(src, "app"s)); @@ -71,133 +64,4 @@ TEST_CASE("t30013") REQUIRE(IsDependency(src, "app", "mod17")); REQUIRE(IsDependency(src, "app", "mod18")); }); - /* - { - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all packages exist - REQUIRE_THAT(src, IsPackage("app")); - REQUIRE_THAT(src, IsPackage("mod1")); - REQUIRE_THAT(src, IsPackage("mod2")); - REQUIRE_THAT(src, IsPackage("mod3")); - REQUIRE_THAT(src, IsPackage("mod4")); - REQUIRE_THAT(src, IsPackage("mod5")); - REQUIRE_THAT(src, IsPackage("mod6")); - REQUIRE_THAT(src, IsPackage("mod7")); - REQUIRE_THAT(src, IsPackage("mod8")); - REQUIRE_THAT(src, IsPackage("mod9")); - REQUIRE_THAT(src, IsPackage("mod10")); - REQUIRE_THAT(src, IsPackage("mod11")); - REQUIRE_THAT(src, IsPackage("mod12")); - REQUIRE_THAT(src, IsPackage("mod13")); - REQUIRE_THAT(src, IsPackage("mod14")); - REQUIRE_THAT(src, IsPackage("mod15")); - REQUIRE_THAT(src, IsPackage("mod16")); - REQUIRE_THAT(src, IsPackage("mod17")); - REQUIRE_THAT(src, IsPackage("mod18")); - - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod1"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod2"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod3"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod4"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod5"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod6"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod7"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod8"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod9"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod10"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod11"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod12"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod13"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod14"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod15"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod16"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod17"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A("mod18"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_package_json(diagram, *model); - - using namespace json; - using namespace std::string_literals; - REQUIRE(IsModulePackage(j, "app"s)); - REQUIRE(IsModulePackage(j, "mod1"s)); - REQUIRE(IsModulePackage(j, "mod2"s)); - REQUIRE(IsModulePackage(j, "mod3"s)); - REQUIRE(IsModulePackage(j, "mod4"s)); - REQUIRE(IsModulePackage(j, "mod5"s)); - REQUIRE(IsModulePackage(j, "mod6"s)); - REQUIRE(IsModulePackage(j, "mod7"s)); - REQUIRE(IsModulePackage(j, "mod8"s)); - REQUIRE(IsModulePackage(j, "mod9"s)); - REQUIRE(IsModulePackage(j, "mod10"s)); - REQUIRE(IsModulePackage(j, "mod11"s)); - REQUIRE(IsModulePackage(j, "mod12"s)); - REQUIRE(IsModulePackage(j, "mod13"s)); - REQUIRE(IsModulePackage(j, "mod14"s)); - REQUIRE(IsModulePackage(j, "mod15"s)); - REQUIRE(IsModulePackage(j, "mod16"s)); - REQUIRE(IsModulePackage(j, "mod17"s)); - REQUIRE(IsModulePackage(j, "mod18"s)); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_package_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsPackage; - using mermaid::IsPackageDependency; - - REQUIRE_THAT(src, IsPackage(_A("app"))); - REQUIRE_THAT(src, IsPackage(_A("mod1"))); - REQUIRE_THAT(src, IsPackage(_A("mod2"))); - REQUIRE_THAT(src, IsPackage(_A("mod3"))); - REQUIRE_THAT(src, IsPackage(_A("mod4"))); - REQUIRE_THAT(src, IsPackage(_A("mod5"))); - REQUIRE_THAT(src, IsPackage(_A("mod6"))); - REQUIRE_THAT(src, IsPackage(_A("mod7"))); - REQUIRE_THAT(src, IsPackage(_A("mod8"))); - REQUIRE_THAT(src, IsPackage(_A("mod9"))); - REQUIRE_THAT(src, IsPackage(_A("mod10"))); - REQUIRE_THAT(src, IsPackage(_A("mod11"))); - REQUIRE_THAT(src, IsPackage(_A("mod12"))); - REQUIRE_THAT(src, IsPackage(_A("mod13"))); - REQUIRE_THAT(src, IsPackage(_A("mod14"))); - REQUIRE_THAT(src, IsPackage(_A("mod15"))); - REQUIRE_THAT(src, IsPackage(_A("mod16"))); - REQUIRE_THAT(src, IsPackage(_A("mod17"))); - REQUIRE_THAT(src, IsPackage(_A("mod18"))); - - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod1"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod2"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod3"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod4"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod5"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod6"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod7"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod8"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod9"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod10"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod11"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod12"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod13"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod14"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod15"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod16"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod17"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A("mod18"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - } - */ } \ No newline at end of file diff --git a/tests/t30014/test_case.h b/tests/t30014/test_case.h index 63005d94..e98fee7d 100644 --- a/tests/t30014/test_case.h +++ b/tests/t30014/test_case.h @@ -21,15 +21,8 @@ TEST_CASE("t30014") using namespace clanguml::test; using namespace std::string_literals; - auto [config, db] = load_config("t30014"); - - auto diagram = config.diagrams["t30014_package"]; - - REQUIRE(diagram->name == "t30014_package"); - - auto model = generate_package_diagram(*db, diagram); - - REQUIRE(model->name() == "t30014_package"); + auto [config, db, diagram, model] = + CHECK_PACKAGE_MODEL("t30014", "t30014_package"); CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsModulePackage(src, "app"s)); @@ -38,50 +31,4 @@ TEST_CASE("t30014") REQUIRE(IsModulePackage(src, "app"s, ":lib1"s, "mod1"s)); REQUIRE(!IsModulePackage(src, "app"s, ":lib1"s, "mod2"s)); }); -/* - { - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all packages exist - REQUIRE_THAT(src, IsPackage("app")); - REQUIRE_THAT(src, IsPackage(":lib1")); - REQUIRE_THAT(src, IsPackage(":lib2")); - REQUIRE_THAT(src, IsPackage("mod1")); - REQUIRE_THAT(src, !IsPackage("mod2")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_package_json(diagram, *model); - - using namespace json; - using namespace std::string_literals; - - REQUIRE(IsModulePackage(j, "app"s)); - REQUIRE(IsModulePackage(j, "app"s, ":lib1"s)); - REQUIRE(IsModulePackage(j, "app"s, ":lib2"s)); - REQUIRE(IsModulePackage(j, "app"s, ":lib1"s, "mod1"s)); - REQUIRE(!IsModulePackage(j, "app"s, ":lib1"s, "mod2"s)); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_package_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsPackage; - - REQUIRE_THAT(src, IsPackage(_A("app"))); - REQUIRE_THAT(src, IsPackage(_A(":lib1"))); - REQUIRE_THAT(src, IsPackage(_A(":lib2"))); - REQUIRE_THAT(src, IsPackage(_A("mod1"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } \ No newline at end of file diff --git a/tests/t30015/test_case.h b/tests/t30015/test_case.h index ee24f2df..1cce3c53 100644 --- a/tests/t30015/test_case.h +++ b/tests/t30015/test_case.h @@ -21,15 +21,8 @@ TEST_CASE("t30015") using namespace clanguml::test; using namespace std::string_literals; - auto [config, db] = load_config("t30015"); - - auto diagram = config.diagrams["t30015_package"]; - - REQUIRE(diagram->name == "t30015_package"); - - auto model = generate_package_diagram(*db, diagram); - - REQUIRE(model->name() == "t30015_package"); + auto [config, db, diagram, model] = + CHECK_PACKAGE_MODEL("t30015", "t30015_package"); CHECK_PACKAGE_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsModulePackage(src, "app"s)); @@ -72,137 +65,4 @@ TEST_CASE("t30015") REQUIRE(IsDependency(src, "app", ":mod17")); REQUIRE(IsDependency(src, "app", ":mod18")); }); - /* - { - auto src = generate_package_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all packages exist - REQUIRE_THAT(src, IsPackage("app")); - REQUIRE_THAT(src, IsPackage("lib1")); - REQUIRE_THAT(src, IsPackage(":mod1")); - REQUIRE_THAT(src, IsPackage(":mod2")); - REQUIRE_THAT(src, IsPackage(":mod3")); - REQUIRE_THAT(src, IsPackage(":mod4")); - REQUIRE_THAT(src, IsPackage(":mod5")); - REQUIRE_THAT(src, IsPackage(":mod6")); - REQUIRE_THAT(src, IsPackage(":mod7")); - REQUIRE_THAT(src, IsPackage(":mod8")); - REQUIRE_THAT(src, IsPackage(":mod9")); - REQUIRE_THAT(src, IsPackage(":mod10")); - REQUIRE_THAT(src, IsPackage(":mod11")); - REQUIRE_THAT(src, IsPackage(":mod12")); - REQUIRE_THAT(src, IsPackage(":mod13")); - REQUIRE_THAT(src, IsPackage(":mod14")); - REQUIRE_THAT(src, IsPackage(":mod15")); - REQUIRE_THAT(src, IsPackage(":mod16")); - REQUIRE_THAT(src, IsPackage(":mod17")); - REQUIRE_THAT(src, IsPackage(":mod18")); - - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod1"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod2"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod3"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod4"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod5"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod6"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod7"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod8"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod9"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod10"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod11"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod12"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod13"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod14"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod15"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod16"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod17"))); - REQUIRE_THAT(src, IsDependency(_A("app"), _A(":mod18"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_package_json(diagram, *model); - - using namespace json; - using namespace std::string_literals; - - REQUIRE(IsModulePackage(j, "app"s)); - REQUIRE(IsModulePackage(j, "lib1"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod1"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod2"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod3"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod4"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod5"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod6"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod7"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod8"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod9"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod10"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod11"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod12"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod13"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod14"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod15"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod16"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod17"s)); - REQUIRE(IsModulePackage(j, "lib1"s, ":mod18"s)); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_package_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsPackage; - using mermaid::IsPackageDependency; - - REQUIRE_THAT(src, IsPackage(_A("app"))); - REQUIRE_THAT(src, IsPackage(_A("lib1"))); - REQUIRE_THAT(src, IsPackage(_A(":mod1"))); - REQUIRE_THAT(src, IsPackage(_A(":mod2"))); - REQUIRE_THAT(src, IsPackage(_A(":mod3"))); - REQUIRE_THAT(src, IsPackage(_A(":mod4"))); - REQUIRE_THAT(src, IsPackage(_A(":mod5"))); - REQUIRE_THAT(src, IsPackage(_A(":mod6"))); - REQUIRE_THAT(src, IsPackage(_A(":mod7"))); - REQUIRE_THAT(src, IsPackage(_A(":mod8"))); - REQUIRE_THAT(src, IsPackage(_A(":mod9"))); - REQUIRE_THAT(src, IsPackage(_A(":mod10"))); - REQUIRE_THAT(src, IsPackage(_A(":mod11"))); - REQUIRE_THAT(src, IsPackage(_A(":mod12"))); - REQUIRE_THAT(src, IsPackage(_A(":mod13"))); - REQUIRE_THAT(src, IsPackage(_A(":mod14"))); - REQUIRE_THAT(src, IsPackage(_A(":mod15"))); - REQUIRE_THAT(src, IsPackage(_A(":mod16"))); - REQUIRE_THAT(src, IsPackage(_A(":mod17"))); - REQUIRE_THAT(src, IsPackage(_A(":mod18"))); - - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod1"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod2"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod3"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod4"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod5"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod6"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod7"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod8"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod9"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod10"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod11"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod12"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod13"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod14"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod15"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod16"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod17"))); - REQUIRE_THAT(src, IsPackageDependency(_A("app"), _A(":mod18"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - } - */ } \ No newline at end of file diff --git a/tests/t40001/test_case.h b/tests/t40001/test_case.h index b972f298..7aa56330 100644 --- a/tests/t40001/test_case.h +++ b/tests/t40001/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t40001") { using namespace clanguml::test; - auto [config, db] = load_config("t40001"); - - auto diagram = config.diagrams["t40001_include"]; - - REQUIRE(diagram->name == "t40001_include"); - - auto model = generate_include_diagram(*db, diagram); - - REQUIRE(model->name() == "t40001_include"); + auto [config, db, diagram, model] = + CHECK_INCLUDE_MODEL("t40001", "t40001_include"); CHECK_INCLUDE_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(HasTitle(src, "Basic include diagram example")); diff --git a/tests/t40002/test_case.h b/tests/t40002/test_case.h index 52e7659c..456d9d2e 100644 --- a/tests/t40002/test_case.h +++ b/tests/t40002/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t40002") { using namespace clanguml::test; - auto [config, db] = load_config("t40002"); - - auto diagram = config.diagrams["t40002_include"]; - - REQUIRE(diagram->name == "t40002_include"); - - auto model = generate_include_diagram(*db, diagram); - - REQUIRE(model->name() == "t40002_include"); + auto [config, db, diagram, model] = + CHECK_INCLUDE_MODEL("t40002", "t40002_include"); CHECK_INCLUDE_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsFolder(src, "include")); diff --git a/tests/t40003/test_case.h b/tests/t40003/test_case.h index 9e76177d..119c43d3 100644 --- a/tests/t40003/test_case.h +++ b/tests/t40003/test_case.h @@ -20,15 +20,8 @@ TEST_CASE("t40003") { using namespace clanguml::test; - auto [config, db] = load_config("t40003"); - - auto diagram = config.diagrams["t40003_include"]; - - REQUIRE(diagram->name == "t40003_include"); - - auto model = generate_include_diagram(*db, diagram); - - REQUIRE(model->name() == "t40003_include"); + auto [config, db, diagram, model] = + CHECK_INCLUDE_MODEL("t40003", "t40003_include"); CHECK_INCLUDE_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(IsFolder(src, "include/dependants")); diff --git a/tests/test_cases.cc b/tests/test_cases.cc index 6ebd360c..0c1c84b6 100644 --- a/tests/test_cases.cc +++ b/tests/test_cases.cc @@ -387,7 +387,8 @@ void try_run_test_case(const diagram_source_storage &diagrams, TC &&tc) std::cout << "-----------------------------------------------------" "--------------------------\n"; std::cout << "Test case failed for diagram type " - << T::diagram_type_name << ": " << "\n\n"; + << T::diagram_type_name << ": " + << "\n\n"; std::cout << diagrams.get().to_string() << "\n"; throw e; @@ -399,9 +400,11 @@ template DiagramType render_class_diagram(std::shared_ptr c, clanguml::class_diagram::model::diagram &model) { - return DiagramType{common::model::diagram_t::kClass, + auto d = DiagramType{common::model::diagram_t::kClass, detail::render_diagram( c, model)}; + d.generate_packages = c->generate_packages(); + return d; } template @@ -432,6 +435,74 @@ DiagramType render_include_diagram(std::shared_ptr c, c, model)}; } +auto CHECK_CLASS_MODEL( + const std::string &test_name, const std::string &diagram_name) +{ + auto [config, db] = load_config(test_name); + + auto diagram = config.diagrams[diagram_name]; + + REQUIRE(diagram->name == diagram_name); + + auto model = generate_class_diagram(*db, diagram); + + REQUIRE(model->name() == diagram_name); + + return std::make_tuple( + std::move(config), std::move(db), std::move(diagram), std::move(model)); +} + +auto CHECK_SEQUENCE_MODEL( + const std::string &test_name, const std::string &diagram_name) +{ + auto [config, db] = load_config(test_name); + + auto diagram = config.diagrams[diagram_name]; + + REQUIRE(diagram->name == diagram_name); + + auto model = generate_sequence_diagram(*db, diagram); + + REQUIRE(model->name() == diagram_name); + + return std::make_tuple( + std::move(config), std::move(db), std::move(diagram), std::move(model)); +} + +auto CHECK_PACKAGE_MODEL( + const std::string &test_name, const std::string &diagram_name) +{ + auto [config, db] = load_config(test_name); + + auto diagram = config.diagrams[diagram_name]; + + REQUIRE(diagram->name == diagram_name); + + auto model = generate_package_diagram(*db, diagram); + + REQUIRE(model->name() == diagram_name); + + return std::make_tuple( + std::move(config), std::move(db), std::move(diagram), std::move(model)); +} + +auto CHECK_INCLUDE_MODEL( + const std::string &test_name, const std::string &diagram_name) +{ + auto [config, db] = load_config(test_name); + + auto diagram = config.diagrams[diagram_name]; + + REQUIRE(diagram->name == diagram_name); + + auto model = generate_include_diagram(*db, diagram); + + REQUIRE(model->name() == diagram_name); + + return std::make_tuple( + std::move(config), std::move(db), std::move(diagram), std::move(model)); +} + template void CHECK_DIAGRAM_IMPL( const diagram_source_storage &diagrams, TC &&tc, TCs &&...tcs) @@ -1082,10 +1153,6 @@ template <> bool IsClass(json_t d, std::string name) #include "t00062/test_case.h" #include "t00063/test_case.h" #include "t00064/test_case.h" -/* - - - #if defined(ENABLE_CXX_STD_20_TEST_CASES) #include "t00065/test_case.h" #endif @@ -1107,7 +1174,7 @@ template <> bool IsClass(json_t d, std::string name) #include "t00074/test_case.h" #include "t00075/test_case.h" #endif - +/* /// /// Sequence diagram tests /// @@ -1223,7 +1290,7 @@ int main(int argc, char *argv[]) std::vector argvv = { "clang-uml", "--config", "./test_config_data/simple.yml"}; - argvv.push_back("-vvv"); + argvv.push_back("-q"); clih.handle_options(argvv.size(), argvv.data()); diff --git a/tests/test_cases.h b/tests/test_cases.h index d6d8a1cd..5732ce98 100644 --- a/tests/test_cases.h +++ b/tests/test_cases.h @@ -135,6 +135,7 @@ template struct diagram_source_t { T src; clanguml::common::model::diagram_t diagram_type; + bool generate_packages{false}; }; struct plantuml_t : public diagram_source_t { @@ -394,9 +395,9 @@ struct QualifiedName { operator std::string() const { return str(); } - std::string str() const + std::string str(bool generate_packages = false) const { - if (ns) + if (ns && !generate_packages) return fmt::format("{}::{}", ns.value(), name); return name; @@ -464,8 +465,8 @@ bool IsMethod(const DiagramType &d, const std::string &cls, const std::string ¶ms = ""); template -bool IsField(const DiagramType &d, std::string const &cls, - std::string const &name, std::string type = "void"); +bool IsField(const DiagramType &d, QualifiedName cls, std::string const &name, + std::string type = "void"); template bool IsAssociation(const DiagramType &d, std::string const &from, @@ -506,11 +507,15 @@ bool IsIncludeDependency( const DiagramType &d, std::string const &from, std::string const &to); template -bool IsConstraint(const DiagramType &d, std::string const &from, - std::string const &to, std::string label = {}, std::string style = ""); +bool IsConstraint(const DiagramType &d, QualifiedName from, QualifiedName to, + std::string label = {}, std::string style = ""); template -bool IsConcept(const DiagramType &d, std::string const &cpt); +bool IsConcept(const DiagramType &d, QualifiedName cpt); + +template +bool IsConceptParameterList( + const DiagramType &d, std::string const &cpt, std::string param); template bool IsConceptRequirement( @@ -598,33 +603,38 @@ template <> bool HasTitle(const plantuml_t &d, std::string const &str) template <> bool IsEnum(const plantuml_t &d, QualifiedName enm) { - return d.contains(fmt::format("enum {}", d.get_alias(enm.name))); + return d.contains( + fmt::format("enum {}", d.get_alias(enm.str(d.generate_packages)))); } template <> bool IsUnion(const plantuml_t &d, QualifiedName cls) { - return d.contains(fmt::format("class {} <>", d.get_alias(cls))); + return d.contains(fmt::format( + "class {} <>", d.get_alias(cls.str(d.generate_packages)))); } template <> bool IsClass(const plantuml_t &d, QualifiedName cls) { - return d.contains(fmt::format("class {}", d.get_alias(cls.name))) || - d.contains(fmt::format("class {}", d.get_alias(cls.str()))); + return d.contains( + fmt::format("class {}", d.get_alias(cls.str(d.generate_packages)))); } template <> bool IsClassTemplate(const plantuml_t &d, QualifiedName cls) { - return d.contains(fmt::format("class \"{}\"", cls.name)); + return d.contains( + fmt::format("class \"{}\"", cls.str(d.generate_packages))); } template <> bool IsAbstractClassTemplate(const plantuml_t &d, QualifiedName cls) { - return d.contains(fmt::format("abstract \"{}\"", cls.name)); + return d.contains( + fmt::format("abstract \"{}\"", cls.str(d.generate_packages))); } template <> bool IsAbstractClass(const plantuml_t &d, QualifiedName cls) { - return d.contains(fmt::format("abstract {}", d.get_alias(cls.name))); + return d.contains( + fmt::format("abstract {}", d.get_alias(cls.str(d.generate_packages)))); } template <> @@ -632,7 +642,8 @@ bool IsBaseClass( const plantuml_t &d, QualifiedName base, QualifiedName subclass) { return d.contains( - fmt::format("{} <|-- {}", d.get_alias(base), d.get_alias(subclass))); + fmt::format("{} <|-- {}", d.get_alias(base.str(d.generate_packages)), + d.get_alias(subclass.str(d.generate_packages)))); } template <> @@ -692,8 +703,8 @@ bool IsMethod(const plantuml_t &d, std::string const &cls, } template -bool IsField(const plantuml_t &d, std::string const &cls, - std::string const &name, std::string type) +bool IsField(const plantuml_t &d, QualifiedName cls, std::string const &name, + std::string type) { std::string pattern; if constexpr (has_type()) @@ -858,20 +869,21 @@ bool IsIncludeDependency( } template <> -bool IsConstraint(const plantuml_t &d, std::string const &from, - std::string const &to, std::string label, std::string style) +bool IsConstraint(const plantuml_t &d, QualifiedName from, QualifiedName to, + std::string label, std::string style) { if (label.empty()) - return d.contains(fmt::format( - "{} .{}.> {}", d.get_alias(from), style, d.get_alias(to))); + return d.contains(fmt::format("{} .{}.> {}", d.get_alias(from.name), + style, d.get_alias(to.name))); - return d.contains(fmt::format( - "{} .{}.> {} : {}", d.get_alias(from), style, d.get_alias(to), label)); + return d.contains(fmt::format("{} .{}.> {} : {}", d.get_alias(from.name), + style, d.get_alias(to.name), label)); } -template <> bool IsConcept(const plantuml_t &d, std::string const &cpt) +template <> bool IsConcept(const plantuml_t &d, QualifiedName cpt) { - return d.contains("class " + d.get_alias(cpt) + " <>"); + return d.contains("class " + d.get_alias(cpt) + " <>") || + d.contains("class " + d.get_alias(cpt.name) + " <>"); } template <> @@ -881,6 +893,13 @@ bool IsConceptRequirement( return d.contains(requirement); } +template <> +bool IsConceptParameterList( + const plantuml_t &d, std::string const &cpt, std::string params) +{ + return d.contains(params); +} + template <> bool IsLayoutHint(const plantuml_t &d, std::string const &from, std::string const &hint, std::string const &to) @@ -1122,8 +1141,8 @@ bool IsMethod(const mermaid_t &d, std::string const &cls, } template -bool IsField(const mermaid_t &d, std::string const &cls, - std::string const &name, std::string type) +bool IsField(const mermaid_t &d, QualifiedName cls, std::string const &name, + std::string type) { std::string pattern; if constexpr (has_type()) @@ -1321,8 +1340,8 @@ bool IsIncludeDependency( } template <> -bool IsConstraint(const mermaid_t &d, std::string const &from, - std::string const &to, std::string label, std::string style) +bool IsConstraint(const mermaid_t &d, QualifiedName from, QualifiedName to, + std::string label, std::string style) { auto from_id = d.get_alias(from); auto to_id = d.get_alias(to); @@ -1344,7 +1363,7 @@ bool IsConstraint(const mermaid_t &d, std::string const &from, return d.contains(fmt::format("{} ..> {} : {}", from_id, to_id, label)); } -template <> bool IsConcept(const mermaid_t &d, std::string const &cpt) +template <> bool IsConcept(const mermaid_t &d, QualifiedName cpt) { return d.search( std::string("class ") + d.get_alias(cpt) + " \\{\\n\\s+<>"); @@ -1356,8 +1375,8 @@ bool IsConceptRequirement( { util::replace_all(requirement, "<", "<"); util::replace_all(requirement, ">", ">"); - util::replace_all(requirement, "(", "("); - util::replace_all(requirement, ")", ")"); + // util::replace_all(requirement, "(", "("); + // util::replace_all(requirement, ")", ")"); util::replace_all(requirement, "##", "::"); util::replace_all(requirement, "{", "{"); util::replace_all(requirement, "}", "}"); @@ -1365,6 +1384,21 @@ bool IsConceptRequirement( return d.contains(requirement); } +template <> +bool IsConceptParameterList( + const mermaid_t &d, std::string const &cpt, std::string params) +{ + util::replace_all(params, "<", "<"); + util::replace_all(params, ">", ">"); + // util::replace_all(requirement, "(", "("); + // util::replace_all(requirement, ")", ")"); + util::replace_all(params, "##", "::"); + util::replace_all(params, "{", "{"); + util::replace_all(params, "}", "}"); + + return d.contains(params); +} + template <> bool IsLayoutHint(const mermaid_t &d, std::string const &from, std::string const &hint, std::string const &to) @@ -1457,6 +1491,11 @@ bool IsNamespacePackage(const mermaid_t &d, Args... args) template bool IsDirectoryPackage(const mermaid_t &d, Args... args) { + if (d.diagram_type == class_diagram::model::diagram_t::kClass) { + // MermaidJS does not support packages in class diagrams + return true; + } + const auto &name = get_last(args...); return d.contains("subgraph " + d.get_alias(name)); } @@ -1464,13 +1503,18 @@ bool IsDirectoryPackage(const mermaid_t &d, Args... args) template bool IsModulePackage(const mermaid_t &d, Args... args) { + if (d.diagram_type == class_diagram::model::diagram_t::kClass) { + // MermaidJS does not support packages in class diagrams + return true; + } + const auto &name = get_last(args...); return d.contains("subgraph " + d.get_alias(name)); } template <> bool IsDeprecated(const mermaid_t &d, const std::string &name) { - return d.contains(d.get_alias(name) + " <> "); + return d.contains(d.get_alias(name)); } // @@ -1492,37 +1536,43 @@ template <> bool HasTitle(const json_t &d, std::string const &str) template <> bool IsAbstractClass(const json_t &d, QualifiedName cls) { - auto e = get_element(d.src, expand_name(d.src, cls)); + auto e = + get_element(d.src, expand_name(d.src, cls.str(d.generate_packages))); return e && e->at("type") == "class" && e->at("is_abstract"); } template <> bool IsEnum(const json_t &d, QualifiedName enm) { - auto e = get_element(d.src, expand_name(d.src, enm)); + auto e = + get_element(d.src, expand_name(d.src, enm.str(d.generate_packages))); return e && e->at("type") == "enum"; } template <> bool IsUnion(const json_t &d, QualifiedName enm) { - auto e = get_element(d.src, expand_name(d.src, enm)); + auto e = + get_element(d.src, expand_name(d.src, enm.str(d.generate_packages))); return e && e->at("type") == "class" && e->at("is_union"); } template <> bool IsClass(const json_t &d, QualifiedName cls) { - auto e = get_element(d.src, expand_name(d.src, cls)); + auto e = + get_element(d.src, expand_name(d.src, cls.str(d.generate_packages))); return e && e->at("type") == "class" && !e->at("is_abstract"); } template <> bool IsClassTemplate(const json_t &d, QualifiedName cls) { - auto e = get_element(d.src, expand_name(d.src, cls)); + auto e = + get_element(d.src, expand_name(d.src, cls.str(d.generate_packages))); return e && e->at("type") == "class"; } template <> bool IsAbstractClassTemplate(const json_t &d, QualifiedName cls) { - auto e = get_element(d.src, expand_name(d.src, cls)); + auto e = + get_element(d.src, expand_name(d.src, cls.str(d.generate_packages))); return e && e->at("type") == "class" && e->at("is_abstract"); } @@ -1530,8 +1580,10 @@ template <> bool IsBaseClass(const json_t &d, QualifiedName base, QualifiedName subclass) { const auto &j = d.src; - auto base_el = get_element(j, expand_name(j, base)); - auto subclass_el = get_element(j, expand_name(j, subclass)); + auto base_el = + get_element(j, expand_name(j, base.str(d.generate_packages))); + auto subclass_el = + get_element(j, expand_name(j, subclass.str(d.generate_packages))); if (!base_el || !subclass_el) return false; @@ -1573,12 +1625,12 @@ bool IsMethod(const json_t &d, const std::string &cls, std::string const &name, } template -bool IsField(const json_t &d, std::string const &cls, std::string const &name, +bool IsField(const json_t &d, QualifiedName cls, std::string const &name, std::string type) { const auto &j = d.src; - auto sc = get_element(j, expand_name(j, cls)); + auto sc = get_element(j, expand_name(j, cls.str(d.generate_packages))); if (!sc) return false; @@ -1704,8 +1756,9 @@ bool IsDependency( { const auto &j = d.src; - auto rel = get_relationship( - j, expand_name(j, from), expand_name(j, to), "dependency"); + auto rel = + get_relationship(j, expand_name(j, from.str(d.generate_packages)), + expand_name(j, to.str(d.generate_packages)), "dependency"); if (rel == j["relationships"].end()) return false; @@ -1763,22 +1816,23 @@ bool IsIncludeDependency( return true; } -template <> bool IsConcept(const json_t &d, std::string const &cpt) +template <> bool IsConcept(const json_t &d, QualifiedName cpt) { const auto &j = d.src; - auto e = get_element(j, expand_name(j, cpt)); + auto e = get_element(j, expand_name(j, cpt.str(d.generate_packages))); return e && e->at("type") == "concept"; } template <> -bool IsConstraint(const json_t &d, std::string const &from, - std::string const &to, std::string label, std::string style) +bool IsConstraint(const json_t &d, QualifiedName from, QualifiedName to, + std::string label, std::string style) { const auto &j = d.src; - auto rel = get_relationship( - j, expand_name(j, from), expand_name(j, to), "constraint", label); + auto rel = + get_relationship(j, expand_name(j, from.str(d.generate_packages)), + expand_name(j, to.str(d.generate_packages)), "constraint", label); if (rel == j["relationships"].end()) return false; @@ -1807,6 +1861,27 @@ bool IsConceptRequirement( statements.end(); } +template <> +bool IsConceptParameterList( + const json_t &d, std::string const &cpt, std::string parameter_list) +{ + const auto &j = d.src; + + auto e = get_element(j, expand_name(j, cpt)); + + if (!e) + return false; + + const nlohmann::json ¶meters = (*e)["parameters"]; + + std::vector params; + for (const auto &it : parameters) { + params.push_back(fmt::format("{} {}", it["type"], it["name"])); + } + + return parameter_list == fmt::format("({})", fmt::join(params, ",")); +} + template <> bool IsLayoutHint(const json_t &d, std::string const &from, std::string const &hint, std::string const &to) diff --git a/tests/test_util.cc b/tests/test_util.cc index 98145004..4caa265b 100644 --- a/tests/test_util.cc +++ b/tests/test_util.cc @@ -20,7 +20,6 @@ #include "util/util.h" #include - #include #include "doctest/doctest.h" From 6d3d1ae4504432ca90c50705f3a47c12364b0d62 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Tue, 14 May 2024 17:27:34 +0200 Subject: [PATCH 05/15] Fixed building on LLVM < 14 (#266) --- CMakeLists.txt | 2 ++ .../json/class_diagram_generator.cc | 14 +++++++++ tests/CMakeLists.txt | 2 +- tests/test_cases.cc | 29 ------------------- 4 files changed, 17 insertions(+), 30 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f6a9841a..f690f761 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,8 @@ cmake_minimum_required(VERSION 3.16) # project(clang-uml C CXX) +cmake_policy(SET CMP0054 NEW) + # # CMake standard defines # diff --git a/src/class_diagram/generators/json/class_diagram_generator.cc b/src/class_diagram/generators/json/class_diagram_generator.cc index 7c6f3697..4fabe622 100644 --- a/src/class_diagram/generators/json/class_diagram_generator.cc +++ b/src/class_diagram/generators/json/class_diagram_generator.cc @@ -248,10 +248,24 @@ void generator::generate(const class_ &c, nlohmann::json &parent) const { nlohmann::json object = c; + // Perform config dependent postprocessing on generated class; if (!config().generate_fully_qualified_name()) object["display_name"] = common::generators::json::render_name(c.full_name_no_ns()); + for (auto &tp : object["template_parameters"]) { + if (tp.contains("type") && tp.at("type").is_string()) { + tp["type"] = config().using_namespace().relative(tp.at("type")); + } + } + for (auto &tp : object["members"]) { + if (tp.contains("type") && tp.at("type").is_string()) { + tp["type"] = config().using_namespace().relative(tp.at("type")); + } + } + + std::string object_str = object.dump(2); + parent["elements"].push_back(std::move(object)); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3ce15f5f..b958948c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -6,7 +6,7 @@ file(GLOB_RECURSE TEST_CONFIG_YMLS test_config_data/*.yml test_compilation_database_data/*.yml test_compilation_database_data/*.json) -set(TEST_CASES_REQUIRING_CXX20 t00056 t00058 t00059 t00065 t00069) +set(TEST_CASES_REQUIRING_CXX20 t00056 t00058 t00059 t00065 t00069 t00074 t00075) set(TEST_CASES_REQUIRING_CXX20_MODULES t00070 t00071 t00072 t30012 t30013 t30014 t30015) set(TEST_CASES_REQUIRING_CUDA t20049 t20050 t20051) diff --git a/tests/test_cases.cc b/tests/test_cases.cc index 0c1c84b6..c18cba56 100644 --- a/tests/test_cases.cc +++ b/tests/test_cases.cc @@ -1300,33 +1300,4 @@ int main(int argc, char *argv[]) return res; return res; - - /* - Catch::Session session; - using namespace Catch::clara; - - bool debug_log{false}; - auto cli = session.cli() | - Opt(debug_log, "debug_log")["-u"]["--debug-log"]("Enable debug logs"); - - session.cli(cli); - - int returnCode = session.applyCommandLine(argc, argv); - if (returnCode != 0) - return returnCode; - - clanguml::cli::cli_handler clih; - - std::vector argvv = { - "clang-uml", "--config", "./test_config_data/simple.yml"}; - - if (debug_log) - argvv.push_back("-vvv"); - else - argvv.push_back("-q"); - - clih.handle_options(argvv.size(), argvv.data()); - - return session.run(); - */ } From 5d69f5063a80a8e2eea25baf9874b37b4b5a4759 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Tue, 14 May 2024 17:47:37 +0200 Subject: [PATCH 06/15] Refactored config based test cases (#266) --- tests/t90000/test_case.h | 49 ++++++++++++-------------------------- tests/t90001/test_case.h | 51 ++++++++++++++++++++-------------------- tests/test_cases.cc | 3 --- tests/test_cases.h | 8 ------- 4 files changed, 41 insertions(+), 70 deletions(-) diff --git a/tests/t90000/test_case.h b/tests/t90000/test_case.h index a517f474..945733c5 100644 --- a/tests/t90000/test_case.h +++ b/tests/t90000/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t90000/test_case.cc + * tests/t90000/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,40 +16,21 @@ * limitations under the License. */ -TEST_CASE("t90000", "[test-case][config]") +TEST_CASE("t90000") { - auto [config, db] = load_config("t90000"); + using namespace clanguml::test; - auto diagram = config.diagrams["t90000_class"]; + auto [config, db, diagram, model] = + CHECK_CLASS_MODEL("t90000", "t90000_class"); - auto model = generate_class_diagram(*db, diagram); - - REQUIRE(model->name() == "t90000_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("Foo"))); - REQUIRE_THAT(puml, IsClass(_A("Boo"))); - - save_puml(config.output_directory(), diagram->name + ".puml", puml); - } - - { - auto j = generate_class_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto mmd = generate_class_mermaid(diagram, *model); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", mmd); - } + CHECK_CLASS_DIAGRAM( + config, diagram, *model, + [](const plantuml_t &src) { + REQUIRE(IsClass(src, "Foo")); + REQUIRE(IsClass(src, "Boo")); + }, + [](const mermaid_t &src) { + REQUIRE(IsClass(src, "Foo")); + REQUIRE(IsClass(src, "Boo")); + }); } diff --git a/tests/t90001/test_case.h b/tests/t90001/test_case.h index 812f5a0d..99767514 100644 --- a/tests/t90001/test_case.h +++ b/tests/t90001/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t90001/test_case.cc + * tests/t90001/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,8 +16,9 @@ * limitations under the License. */ -TEST_CASE("t90001", "[test-case][config]") +TEST_CASE("t90001") { + using namespace clanguml::test; using clanguml::error::empty_diagram_error; auto [config, db] = load_config("t90001"); @@ -31,12 +32,12 @@ TEST_CASE("t90001", "[test-case][config]") REQUIRE(model->name() == "t90001_class"); + REQUIRE_THROWS_AS(render_class_diagram(diagram, *model), + empty_diagram_error); + REQUIRE_THROWS_AS(render_class_diagram(diagram, *model), + empty_diagram_error); REQUIRE_THROWS_AS( - generate_class_puml(diagram, *model), empty_diagram_error); - REQUIRE_THROWS_AS( - generate_class_json(diagram, *model), empty_diagram_error); - REQUIRE_THROWS_AS( - generate_class_mermaid(diagram, *model), empty_diagram_error); + render_class_diagram(diagram, *model), empty_diagram_error); } { @@ -48,12 +49,12 @@ TEST_CASE("t90001", "[test-case][config]") REQUIRE(model->name() == "t90001_sequence"); - REQUIRE_THROWS_AS( - generate_sequence_puml(diagram, *model), empty_diagram_error); - REQUIRE_THROWS_AS( - generate_sequence_json(diagram, *model), empty_diagram_error); - REQUIRE_THROWS_AS( - generate_sequence_mermaid(diagram, *model), empty_diagram_error); + REQUIRE_THROWS_AS(render_sequence_diagram(diagram, *model), + empty_diagram_error); + REQUIRE_THROWS_AS(render_sequence_diagram(diagram, *model), + empty_diagram_error); + REQUIRE_THROWS_AS(render_sequence_diagram(diagram, *model), + empty_diagram_error); } { @@ -65,12 +66,12 @@ TEST_CASE("t90001", "[test-case][config]") REQUIRE(model->name() == "t90001_package"); - REQUIRE_THROWS_AS( - generate_package_puml(diagram, *model), empty_diagram_error); - REQUIRE_THROWS_AS( - generate_package_json(diagram, *model), empty_diagram_error); - REQUIRE_THROWS_AS( - generate_package_mermaid(diagram, *model), empty_diagram_error); + REQUIRE_THROWS_AS(render_package_diagram(diagram, *model), + empty_diagram_error); + REQUIRE_THROWS_AS(render_package_diagram(diagram, *model), + empty_diagram_error); + REQUIRE_THROWS_AS(render_package_diagram(diagram, *model), + empty_diagram_error); } { @@ -82,11 +83,11 @@ TEST_CASE("t90001", "[test-case][config]") REQUIRE(model->name() == "t90001_include"); - REQUIRE_THROWS_AS( - generate_include_puml(diagram, *model), empty_diagram_error); - REQUIRE_THROWS_AS( - generate_include_json(diagram, *model), empty_diagram_error); - REQUIRE_THROWS_AS( - generate_include_mermaid(diagram, *model), empty_diagram_error); + REQUIRE_THROWS_AS(render_include_diagram(diagram, *model), + empty_diagram_error); + REQUIRE_THROWS_AS(render_include_diagram(diagram, *model), + empty_diagram_error); + REQUIRE_THROWS_AS(render_include_diagram(diagram, *model), + empty_diagram_error); } } diff --git a/tests/test_cases.cc b/tests/test_cases.cc index c18cba56..e235089b 100644 --- a/tests/test_cases.cc +++ b/tests/test_cases.cc @@ -1266,15 +1266,12 @@ template <> bool IsClass(json_t d, std::string name) #include "t40001/test_case.h" #include "t40002/test_case.h" #include "t40003/test_case.h" -/* - /// /// Other tests (e.g. configuration file) /// #include "t90000/test_case.h" #include "t90001/test_case.h" -*/ /// /// Main test function diff --git a/tests/test_cases.h b/tests/test_cases.h index 5732ce98..06f0d65f 100644 --- a/tests/test_cases.h +++ b/tests/test_cases.h @@ -51,14 +51,6 @@ using namespace clanguml::util; std::pair load_config(const std::string &test_name); -// std::string generate_sequence_puml( -// std::shared_ptr config, -// clanguml::sequence_diagram::model::diagram &model); -// -// std::string generate_class_puml( -// std::shared_ptr config, -// clanguml::class_diagram::model::diagram &model); - void save_puml(const std::string &path, const std::string &puml); namespace clanguml::test { From 7c1e0420c6e8a358ea8ef273e20c7df241724bbe Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Thu, 16 May 2024 21:58:45 +0200 Subject: [PATCH 07/15] Refactoring sequence diagrams test cases (#266) --- .../json/class_diagram_generator.cc | 2 +- .../json/sequence_diagram_generator.cc | 10 + tests/t20001/test_case.h | 63 +- tests/t20002/test_case.h | 30 +- tests/t20003/test_case.h | 85 +-- tests/t20004/test_case.h | 167 +++--- tests/t20005/test_case.h | 89 +-- tests/t20006/test_case.h | 224 +++---- tests/t20007/test_case.h | 114 ++-- tests/t20008/test_case.h | 143 ++--- tests/t20009/test_case.h | 121 ++-- tests/t20010/test_case.h | 115 ++-- tests/t20011/test_case.h | 24 +- tests/t20012/test_case.h | 56 +- tests/t20013/test_case.h | 25 +- tests/t20014/test_case.h | 26 +- tests/t20015/test_case.h | 105 ++-- tests/t20016/test_case.h | 97 ++-- tests/t20017/test_case.h | 28 +- tests/t20018/test_case.h | 147 ++--- tests/t20019/test_case.h | 25 +- tests/t20020/test_case.h | 160 ++--- tests/t20021/test_case.h | 32 +- tests/t20022/test_case.h | 77 +-- tests/t20023/test_case.h | 92 +-- tests/t20024/test_case.h | 30 +- tests/t20025/test_case.h | 23 +- tests/t20026/test_case.h | 22 +- tests/t20027/test_case.h | 22 +- tests/t20028/test_case.h | 24 +- tests/t20029/test_case.h | 249 ++++---- tests/t20030/test_case.h | 126 ++-- tests/t20031/test_case.h | 26 +- tests/t20032/test_case.h | 33 +- tests/t20033/test_case.h | 106 ++-- tests/t20034/test_case.h | 158 +++-- tests/t20035/test_case.h | 80 +-- tests/t20036/test_case.h | 149 +++-- tests/t20037/test_case.h | 96 +-- tests/t20038/test_case.h | 172 +++--- tests/t20039/test_case.h | 28 +- tests/t20040/test_case.h | 121 ++-- tests/t20041/test_case.h | 120 ++-- tests/t20042/test_case.h | 88 +-- tests/t20043/test_case.h | 26 +- tests/t20044/test_case.h | 43 +- tests/t20045/test_case.h | 26 +- tests/test_cases.cc | 9 +- tests/test_cases.h | 549 +++++++++++++++++- 49 files changed, 2807 insertions(+), 1576 deletions(-) diff --git a/src/class_diagram/generators/json/class_diagram_generator.cc b/src/class_diagram/generators/json/class_diagram_generator.cc index 4fabe622..f8cb28d5 100644 --- a/src/class_diagram/generators/json/class_diagram_generator.cc +++ b/src/class_diagram/generators/json/class_diagram_generator.cc @@ -248,7 +248,7 @@ void generator::generate(const class_ &c, nlohmann::json &parent) const { nlohmann::json object = c; - // Perform config dependent postprocessing on generated class; + // Perform config dependent postprocessing on generated class if (!config().generate_fully_qualified_name()) object["display_name"] = common::generators::json::render_name(c.full_name_no_ns()); diff --git a/src/sequence_diagram/generators/json/sequence_diagram_generator.cc b/src/sequence_diagram/generators/json/sequence_diagram_generator.cc index 3c0bdfec..8c17daf9 100644 --- a/src/sequence_diagram/generators/json/sequence_diagram_generator.cc +++ b/src/sequence_diagram/generators/json/sequence_diagram_generator.cc @@ -286,6 +286,8 @@ void generator::process_call_message( else LOG_DBG("Skipping activity {} --> {} - missing sequence {}", m.from(), m.to(), m.to()); + + visited.pop_back(); } void generator::process_while_message(const message &m) const @@ -816,6 +818,14 @@ void generator::generate_diagram(nlohmann::json &parent) const } } + // Perform config dependent postprocessing on generated participants + for (auto &p : json_["participants"]) { + if (p.contains("display_name")) { + p["display_name"] = + config().simplify_template_type(p["display_name"]); + } + } + parent["participants"] = json_["participants"]; } } // namespace clanguml::sequence_diagram::generators::json diff --git a/tests/t20001/test_case.h b/tests/t20001/test_case.h index f06f150d..ed29917d 100644 --- a/tests/t20001/test_case.h +++ b/tests/t20001/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t20001/test_case.cc + * tests/t20001/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,18 +16,66 @@ * limitations under the License. */ -TEST_CASE("t20001", "[test-case][sequence]") +TEST_CASE("t20001") { - auto [config, db] = load_config("t20001"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20001_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20001", "t20001_sequence"); - REQUIRE(diagram->name == "t20001_sequence"); + CHECK_SEQUENCE_DIAGRAM( + config, diagram, *model, + [](const auto &src) { + REQUIRE(HasTitle(src, "Basic sequence diagram example")); - auto model = generate_sequence_diagram(*db, diagram); + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "A", "A()"}, // + {"tmain()", "B", "B(A &)"}, // - REQUIRE(model->name() == "t20001_sequence"); + {"tmain()", "A", "add(int,int)"}, // + {"tmain()", "B", "wrap_add3(int,int,int)"}, // + {"B", "A", "add3(int,int,int)"}, // + {"A", "A", "add(int,int)"}, // + {"A", "A", "log_result(int)", Static{}}, // + {"B", "A", "log_result(int)", Static{}} // + })); + + REQUIRE(!HasMessage(src, {"A", {"detail", "C"}, "add(int,int)"})); + + REQUIRE(HasComment(src, "t20001 test diagram of type sequence")); + + REQUIRE(HasMessageComment(src, "tmain()", "Just add 2 numbers")); + + REQUIRE(HasMessageComment(src, "tmain()", "And now add another 2")); + }, + [](const json_t &src) { + const auto &A = get_participant(src.src, "A"); + + CHECK(A.has_value()); + + CHECK(A.value()["type"] == "class"); + CHECK(A.value()["name"] == "A"); + CHECK(A.value()["display_name"] == "A"); + CHECK(A.value()["namespace"] == "clanguml::t20001"); + CHECK(A.value()["source_location"]["file"] == "t20001.cc"); + CHECK(A.value()["source_location"]["line"] == 13); + + const auto &tmain = get_participant(src.src, "tmain()"); + + CHECK(tmain.has_value()); + + CHECK(tmain.value()["type"] == "function"); + CHECK(tmain.value()["name"] == "tmain"); + CHECK(tmain.value()["display_name"] == "tmain()"); + CHECK(tmain.value()["namespace"] == "clanguml::t20001"); + CHECK(tmain.value()["source_location"]["file"] == "t20001.cc"); + CHECK(tmain.value()["source_location"]["line"] == 61); + }); + + /* { auto src = generate_sequence_puml(diagram, *model); AliasMatcher _A(src); @@ -118,4 +166,5 @@ TEST_CASE("t20001", "[test-case][sequence]") save_mermaid(config.output_directory(), diagram->name + ".mmd", src); } + */ } diff --git a/tests/t20002/test_case.h b/tests/t20002/test_case.h index 65b08719..bc0f8034 100644 --- a/tests/t20002/test_case.h +++ b/tests/t20002/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t20002/test_case.cc + * tests/t20002/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,18 +16,28 @@ * limitations under the License. */ -TEST_CASE("t20002", "[test-case][sequence]") +TEST_CASE("t20002") { - auto [config, db] = load_config("t20002"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20002_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20002", "t20002_sequence"); - REQUIRE(diagram->name == "t20002_sequence"); - - auto model = generate_sequence_diagram(*db, diagram); - - REQUIRE(model->name() == "t20002_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsFunctionParticipant(src, "m1()")); + REQUIRE(IsFunctionParticipant(src, "m2()")); + REQUIRE(IsFunctionParticipant(src, "m3()")); + REQUIRE(IsFunctionParticipant(src, "m4()")); + REQUIRE(MessageOrder(src, + { + // + {"m1()", "m2()", ""}, // + {"m2()", "m3()", ""}, // + {"m3()", "m4()", ""} // + })); + }); + /* { auto src = generate_sequence_puml(diagram, *model); AliasMatcher _A(src); @@ -72,5 +82,5 @@ TEST_CASE("t20002", "[test-case][sequence]") REQUIRE_THAT(src, HasCall(_A("m3()"), _A("m4()"), "")); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } diff --git a/tests/t20003/test_case.h b/tests/t20003/test_case.h index 6d8fbe3c..ab08e227 100644 --- a/tests/t20003/test_case.h +++ b/tests/t20003/test_case.h @@ -1,5 +1,5 @@ /** - * tests/t20003/test_case.cc + * tests/t20003/test_case.h * * Copyright (c) 2021-2024 Bartek Kryza * @@ -16,56 +16,67 @@ * limitations under the License. */ -TEST_CASE("t20003", "[test-case][sequence]") +TEST_CASE("t20003") { - auto [config, db] = load_config("t20003"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20003_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20003", "t20003_sequence"); - REQUIRE(diagram->name == "t20003_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsFunctionTemplateParticipant(src, "m1(T)")); + REQUIRE(IsFunctionTemplateParticipant(src, "m2(T)")); + REQUIRE(IsFunctionTemplateParticipant(src, "m3(T)")); + REQUIRE(IsFunctionTemplateParticipant(src, "m4(T)")); - auto model = generate_sequence_diagram(*db, diagram); + REQUIRE(MessageOrder(src, + { + // + {"m1(T)", "m2(T)", ""}, // + {"m2(T)", "m3(T)", ""}, // + {"m3(T)", "m4(T)", ""} // + })); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE(model->name() == "t20003_sequence"); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + REQUIRE_THAT(src, HasCall(_A("m1(T)"), _A("m2(T)"), "")); + REQUIRE_THAT(src, HasCall(_A("m2(T)"), _A("m3(T)"), "")); + REQUIRE_THAT(src, HasCall(_A("m3(T)"), _A("m4(T)"), "")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - REQUIRE_THAT(src, HasCall(_A("m1(T)"), _A("m2(T)"), "")); - REQUIRE_THAT(src, HasCall(_A("m2(T)"), _A("m3(T)"), "")); - REQUIRE_THAT(src, HasCall(_A("m3(T)"), _A("m4(T)"), "")); + { + auto j = generate_sequence_json(diagram, *model); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + using namespace json; - { - auto j = generate_sequence_json(diagram, *model); + std::vector messages = {FindMessage(j, "m1(T)", "m2(T)", + ""), FindMessage(j, "m2(T)", "m3(T)", ""), FindMessage(j, + "m3(T)", "m4(T)", "")}; - using namespace json; + REQUIRE(std::is_sorted(messages.begin(), messages.end())); - std::vector messages = {FindMessage(j, "m1(T)", "m2(T)", ""), - FindMessage(j, "m2(T)", "m3(T)", ""), - FindMessage(j, "m3(T)", "m4(T)", "")}; + save_json(config.output_directory(), diagram->name + ".json", j); + } - REQUIRE(std::is_sorted(messages.begin(), messages.end())); + { + auto src = generate_sequence_mermaid(diagram, *model); - save_json(config.output_directory(), diagram->name + ".json", j); - } + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; - { - auto src = generate_sequence_mermaid(diagram, *model); + REQUIRE_THAT(src, HasCall(_A("m1(T)"), _A("m2(T)"), "")); + REQUIRE_THAT(src, HasCall(_A("m2(T)"), _A("m3(T)"), "")); + REQUIRE_THAT(src, HasCall(_A("m3(T)"), _A("m4(T)"), "")); - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("m1(T)"), _A("m2(T)"), "")); - REQUIRE_THAT(src, HasCall(_A("m2(T)"), _A("m3(T)"), "")); - REQUIRE_THAT(src, HasCall(_A("m3(T)"), _A("m4(T)"), "")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } diff --git a/tests/t20004/test_case.h b/tests/t20004/test_case.h index 67b37ed9..cb87263a 100644 --- a/tests/t20004/test_case.h +++ b/tests/t20004/test_case.h @@ -16,102 +16,115 @@ * limitations under the License. */ -TEST_CASE("t20004", "[test-case][sequence]") +TEST_CASE("t20004") { - auto [config, db] = load_config("t20004"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20004_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20004", "t20004_sequence"); - REQUIRE(diagram->name == "t20004_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"main()", "m1(float)", ""}, // + {"main()", "m1(unsigned long)", ""}, // + {"m1(unsigned long)", + "m4(unsigned long)", ""}, // + {"main()", "m1(std::string)", ""}, // + {"m1(std::string)", "m2(std::string)", + ""}, // + {"main()", "m1(int)", ""}, // + {"m1(int)", "m2(int)", ""}, // + {"m2(int)", "m3(int)", ""}, // + {"m3(int)", "m4(int)", ""} // + })); - auto model = generate_sequence_diagram(*db, diagram); + REQUIRE(!HasMessage(src, {"m1(float)", "m1(float)", ""})); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE(model->name() == "t20004_sequence"); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, HasCall(_A("main()"), _A("m1(float)"), + "")); + REQUIRE_THAT( src, !HasCall(_A("m1(float)"), + _A("m1(float)"), "")); + REQUIRE_THAT( src, + !HasCall(_A("m1(float)"), _A("m1(float)"), "")); - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + REQUIRE_THAT(src, + HasCall(_A("main()"), _A("m1(unsigned long)"), + "")); + REQUIRE_THAT(src, HasCall(_A("m1(unsigned long)"), + _A("m4(unsigned long)"), "")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, HasCall(_A("main()"), _A("m1(float)"), "")); - REQUIRE_THAT( - src, !HasCall(_A("m1(float)"), _A("m1(float)"), "")); - REQUIRE_THAT( - src, !HasCall(_A("m1(float)"), _A("m1(float)"), "")); + REQUIRE_THAT( + src, HasCall(_A("main()"), _A("m1(std::string)"), + "")); REQUIRE_THAT(src, HasCall(_A("m1(std::string)"), + _A("m2(std::string)"), "")); - REQUIRE_THAT(src, - HasCall(_A("main()"), _A("m1(unsigned long)"), "")); - REQUIRE_THAT(src, - HasCall(_A("m1(unsigned long)"), - _A("m4(unsigned long)"), "")); + REQUIRE_THAT(src, HasCall(_A("main()"), _A("m1(int)"), "")); + REQUIRE_THAT(src, HasCall(_A("m1(int)"), _A("m2(int)"), + "")); REQUIRE_THAT(src, HasCall(_A("m2(int)"), _A("m3(int)"), + "")); REQUIRE_THAT(src, HasCall(_A("m3(int)"), _A("m4(int)"), + "")); REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT( - src, HasCall(_A("main()"), _A("m1(std::string)"), "")); - REQUIRE_THAT(src, - HasCall(_A("m1(std::string)"), - _A("m2(std::string)"), "")); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - REQUIRE_THAT(src, HasCall(_A("main()"), _A("m1(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("m1(int)"), _A("m2(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("m2(int)"), _A("m3(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("m3(int)"), _A("m4(int)"), "")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + { + auto j = generate_sequence_json(diagram, *model); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + using namespace json; - { - auto j = generate_sequence_json(diagram, *model); + std::vector messages = { + FindMessage(j, "main()", "m1(float)", ""), + FindMessage(j, "main()", "m1(unsigned long)", + ""), FindMessage(j, "m1(unsigned long)", "m4(unsigned long)", ""), FindMessage(j, "main()", + "m1(std::string)", ""), FindMessage(j, + "m1(std::string)", "m2(std::string)", ""), + FindMessage(j, "main()", "m1(int)", ""), + FindMessage(j, "m1(int)", "m2(int)", ""), + FindMessage(j, "m2(int)", "m3(int)", ""), + FindMessage(j, "m3(int)", "m4(int)", "")}; - using namespace json; + REQUIRE(std::is_sorted(messages.begin(), messages.end())); - std::vector messages = { - FindMessage(j, "main()", "m1(float)", ""), - FindMessage(j, "main()", "m1(unsigned long)", ""), - FindMessage(j, "m1(unsigned long)", - "m4(unsigned long)", ""), - FindMessage(j, "main()", "m1(std::string)", ""), - FindMessage(j, "m1(std::string)", - "m2(std::string)", ""), - FindMessage(j, "main()", "m1(int)", ""), - FindMessage(j, "m1(int)", "m2(int)", ""), - FindMessage(j, "m2(int)", "m3(int)", ""), - FindMessage(j, "m3(int)", "m4(int)", "")}; + save_json(config.output_directory(), diagram->name + ".json", j); + } - REQUIRE(std::is_sorted(messages.begin(), messages.end())); + { + auto src = generate_sequence_mermaid(diagram, *model); - save_json(config.output_directory(), diagram->name + ".json", j); - } + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; - { - auto src = generate_sequence_mermaid(diagram, *model); + REQUIRE_THAT(src, HasCall(_A("main()"), _A("m1(float)"), + "")); REQUIRE_THAT( src, !HasCall(_A("m1(float)"), + _A("m1(float)"), "")); REQUIRE_THAT( src, + !HasCall(_A("m1(float)"), _A("m1(float)"), "")); - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; + REQUIRE_THAT(src, + HasCall(_A("main()"), _A("m1(unsigned long)"), + "")); REQUIRE_THAT(src, HasCall(_A("m1(unsigned long)"), + _A("m4(unsigned long)"), "")); - REQUIRE_THAT(src, HasCall(_A("main()"), _A("m1(float)"), "")); - REQUIRE_THAT( - src, !HasCall(_A("m1(float)"), _A("m1(float)"), "")); - REQUIRE_THAT( - src, !HasCall(_A("m1(float)"), _A("m1(float)"), "")); + REQUIRE_THAT( + src, HasCall(_A("main()"), _A("m1(std::string)"), + "")); REQUIRE_THAT(src, HasCall(_A("m1(std::string)"), + _A("m2(std::string)"), "")); - REQUIRE_THAT(src, - HasCall(_A("main()"), _A("m1(unsigned long)"), "")); - REQUIRE_THAT(src, - HasCall(_A("m1(unsigned long)"), - _A("m4(unsigned long)"), "")); + REQUIRE_THAT(src, HasCall(_A("main()"), _A("m1(int)"), "")); + REQUIRE_THAT(src, HasCall(_A("m1(int)"), _A("m2(int)"), + "")); REQUIRE_THAT(src, HasCall(_A("m2(int)"), _A("m3(int)"), + "")); REQUIRE_THAT(src, HasCall(_A("m3(int)"), _A("m4(int)"), + "")); - REQUIRE_THAT( - src, HasCall(_A("main()"), _A("m1(std::string)"), "")); - REQUIRE_THAT(src, - HasCall(_A("m1(std::string)"), - _A("m2(std::string)"), "")); - - REQUIRE_THAT(src, HasCall(_A("main()"), _A("m1(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("m1(int)"), _A("m2(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("m2(int)"), _A("m3(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("m3(int)"), _A("m4(int)"), "")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t20005/test_case.h b/tests/t20005/test_case.h index 330bbdb1..abc56f9d 100644 --- a/tests/t20005/test_case.h +++ b/tests/t20005/test_case.h @@ -16,60 +16,67 @@ * limitations under the License. */ -TEST_CASE("t20005", "[test-case][sequence]") +TEST_CASE("t20005") { - auto [config, db] = load_config("t20005"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20005_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20005", "t20005_sequence"); - REQUIRE(diagram->name == "t20005_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {Entrypoint{}, "C", "c(T)"}, // + {"C", "B", "b(T)"}, // + {"B", "A", "a(T)"}, // + {Exitpoint{}, "C"} // + })); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - auto model = generate_sequence_diagram(*db, diagram); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE(model->name() == "t20005_sequence"); + // Check if all calls exist + REQUIRE_THAT(src, HasEntrypoint(_A("C"), "c(T)")); + REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b(T)")); + REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a(T)")); + REQUIRE_THAT(src, HasExitpoint(_A("C"))); - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + { + auto j = generate_sequence_json(diagram, *model); - // Check if all calls exist - REQUIRE_THAT(src, HasEntrypoint(_A("C"), "c(T)")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b(T)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a(T)")); - REQUIRE_THAT(src, HasExitpoint(_A("C"))); + using namespace json; - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + std::vector messages = {FindMessage(j, "C", "B", "b(T)"), + FindMessage(j, "B", "A", "a(T)")}; - { - auto j = generate_sequence_json(diagram, *model); + REQUIRE(std::is_sorted(messages.begin(), messages.end())); - using namespace json; + save_json(config.output_directory(), diagram->name + ".json", j); + } - std::vector messages = {FindMessage(j, "C", "B", "b(T)"), - FindMessage(j, "B", "A", "a(T)")}; + { + auto src = generate_sequence_mermaid(diagram, *model); - REQUIRE(std::is_sorted(messages.begin(), messages.end())); + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; + using mermaid::HasEntrypoint; + using mermaid::HasExitpoint; - save_json(config.output_directory(), diagram->name + ".json", j); - } + REQUIRE_THAT(src, HasEntrypoint(_A("C"), "c(T)")); + REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b(T)")); + REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a(T)")); + REQUIRE_THAT(src, HasExitpoint(_A("C"))); - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - using mermaid::HasEntrypoint; - using mermaid::HasExitpoint; - - REQUIRE_THAT(src, HasEntrypoint(_A("C"), "c(T)")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b(T)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a(T)")); - REQUIRE_THAT(src, HasExitpoint(_A("C"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t20006/test_case.h b/tests/t20006/test_case.h index c825244f..8ac04b5c 100644 --- a/tests/t20006/test_case.h +++ b/tests/t20006/test_case.h @@ -16,132 +16,156 @@ * limitations under the License. */ -TEST_CASE("t20006", "[test-case][sequence]") +TEST_CASE("t20006") { - auto [config, db] = load_config("t20006"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20006_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20006", "t20006_sequence"); - REQUIRE(diagram->name == "t20006_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "B", "b(int)"}, // + {"B", "A", "a1(int)"}, // + {"tmain()", "B", "b(std::string)"}, // + {"B", "A", "a2(std::string)"}, // + {"tmain()", "BB", "bb1(int,int)"}, // + {"BB", "AA", "aa1(int)"}, // + {"tmain()", "BB", "bb2(int,int)"}, // + {"BB", "AA", "aa2(int)"}, // + {"tmain()", "BB", "bb1(int,std::string)"}, // + {"BB", "AA", "aa2(int)"}, // + {"tmain()", "BB", "bb2(int,std::string)"}, // + {"BB", "AA", "aa1(int)"}, // + {"tmain()", "BB", "bb1(int,float)"}, // + {"BB", "BB", "bb2(int,float)"}, // + {"BB", "AA", "aa2(int)"} // - auto model = generate_sequence_diagram(*db, diagram); + })); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE(model->name() == "t20006_sequence"); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + // Check if all calls exist + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b(int)")); + REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a1(int)")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("B"), "b(std::string)")); + REQUIRE_THAT(src, + HasCall( + _A("B"), _A("A"), + "a2(std::string)")); - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b(int)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a1(int)")); + REQUIRE_THAT( + src, HasCall(_A("tmain()"), _A("BB"), "bb1(int,int)")); + REQUIRE_THAT( + src, HasCall(_A("BB"), _A("AA"), "aa1(int)")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("B"), "b(std::string)")); - REQUIRE_THAT(src, - HasCall( - _A("B"), _A("A"), "a2(std::string)")); + REQUIRE_THAT( + src, HasCall(_A("tmain()"), _A("BB"), "bb2(int,int)")); + REQUIRE_THAT( + src, HasCall(_A("BB"), _A("AA"), "aa2(int)")); - REQUIRE_THAT( - src, HasCall(_A("tmain()"), _A("BB"), "bb1(int,int)")); - REQUIRE_THAT( - src, HasCall(_A("BB"), _A("AA"), "aa1(int)")); + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("BB"), + "bb1(int,std::string)")); + REQUIRE_THAT( + src, HasCall(_A("BB"), _A("AA"), + "aa2(int)")); - REQUIRE_THAT( - src, HasCall(_A("tmain()"), _A("BB"), "bb2(int,int)")); - REQUIRE_THAT( - src, HasCall(_A("BB"), _A("AA"), "aa2(int)")); + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("BB"), + "bb2(int,std::string)")); + REQUIRE_THAT( + src, HasCall(_A("BB"), _A("AA"), + "aa1(int)")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("BB"), - "bb1(int,std::string)")); - REQUIRE_THAT( - src, HasCall(_A("BB"), _A("AA"), "aa2(int)")); + REQUIRE_THAT( + src, HasCall(_A("tmain()"), _A("BB"), + "bb1(int,float)")); + REQUIRE_THAT(src, HasCall( _A("BB"), + _A("BB"), "bb2(int,float)")); + REQUIRE_THAT( src, + HasCall(_A("BB"), _A("AA"), "aa2(int)")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("BB"), - "bb2(int,std::string)")); - REQUIRE_THAT( - src, HasCall(_A("BB"), _A("AA"), "aa1(int)")); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - REQUIRE_THAT( - src, HasCall(_A("tmain()"), _A("BB"), "bb1(int,float)")); - REQUIRE_THAT(src, - HasCall( - _A("BB"), _A("BB"), "bb2(int,float)")); - REQUIRE_THAT( - src, HasCall(_A("BB"), _A("AA"), "aa2(int)")); + { + auto j = generate_sequence_json(diagram, *model); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + using namespace json; - { - auto j = generate_sequence_json(diagram, *model); + std::vector messages = { + FindMessage(j, "tmain()", "B", "b(int)"), + FindMessage(j, "B", "A", "a1(int)"), + FindMessage(j, "tmain()", "B", "b(std::string)"), + FindMessage(j, "tmain()", "BB", "bb1(int,int)"), + FindMessage(j, "BB", "AA", "aa1(int)"), + FindMessage( + j, "tmain()", "BB", + "bb1(int,std::string)")}; - using namespace json; + REQUIRE(std::is_sorted(messages.begin(), messages.end())); - std::vector messages = { - FindMessage(j, "tmain()", "B", "b(int)"), - FindMessage(j, "B", "A", "a1(int)"), - FindMessage(j, "tmain()", "B", "b(std::string)"), - FindMessage(j, "tmain()", "BB", "bb1(int,int)"), - FindMessage(j, "BB", "AA", "aa1(int)"), - FindMessage( - j, "tmain()", "BB", "bb1(int,std::string)")}; + save_json(config.output_directory(), diagram->name + ".json", j); + } - REQUIRE(std::is_sorted(messages.begin(), messages.end())); + { + auto src = generate_sequence_mermaid(diagram, *model); - save_json(config.output_directory(), diagram->name + ".json", j); - } + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; - { - auto src = generate_sequence_mermaid(diagram, *model); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b(int)")); + REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a1(int)")); - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("B"), "b(std::string)")); + REQUIRE_THAT(src, + HasCall( + _A("B"), _A("A"), + "a2(std::string)")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b(int)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a1(int)")); + REQUIRE_THAT( + src, HasCall(_A("tmain()"), _A("BB"), "bb1(int,int)")); + REQUIRE_THAT( + src, HasCall(_A("BB"), _A("AA"), "aa1(int)")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("B"), "b(std::string)")); - REQUIRE_THAT(src, - HasCall( - _A("B"), _A("A"), "a2(std::string)")); + REQUIRE_THAT( + src, HasCall(_A("tmain()"), _A("BB"), "bb2(int,int)")); + REQUIRE_THAT( + src, HasCall(_A("BB"), _A("AA"), "aa2(int)")); - REQUIRE_THAT( - src, HasCall(_A("tmain()"), _A("BB"), "bb1(int,int)")); - REQUIRE_THAT( - src, HasCall(_A("BB"), _A("AA"), "aa1(int)")); + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("BB"), + "bb1(int,std::string)")); + REQUIRE_THAT( + src, HasCall(_A("BB"), _A("AA"), + "aa2(int)")); - REQUIRE_THAT( - src, HasCall(_A("tmain()"), _A("BB"), "bb2(int,int)")); - REQUIRE_THAT( - src, HasCall(_A("BB"), _A("AA"), "aa2(int)")); + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("BB"), + "bb2(int,std::string)")); + REQUIRE_THAT( + src, HasCall(_A("BB"), _A("AA"), + "aa1(int)")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("BB"), - "bb1(int,std::string)")); - REQUIRE_THAT( - src, HasCall(_A("BB"), _A("AA"), "aa2(int)")); + REQUIRE_THAT( + src, HasCall(_A("tmain()"), _A("BB"), + "bb1(int,float)")); REQUIRE_THAT(src, HasCall( _A("BB"), + _A("BB"), "bb2(int,float)")); REQUIRE_THAT( src, + HasCall(_A("BB"), _A("AA"), "aa2(int)")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("BB"), - "bb2(int,std::string)")); - REQUIRE_THAT( - src, HasCall(_A("BB"), _A("AA"), "aa1(int)")); - - REQUIRE_THAT( - src, HasCall(_A("tmain()"), _A("BB"), "bb1(int,float)")); - REQUIRE_THAT(src, - HasCall( - _A("BB"), _A("BB"), "bb2(int,float)")); - REQUIRE_THAT( - src, HasCall(_A("BB"), _A("AA"), "aa2(int)")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t20007/test_case.h b/tests/t20007/test_case.h index 97cfa231..0bfa1b19 100644 --- a/tests/t20007/test_case.h +++ b/tests/t20007/test_case.h @@ -16,73 +16,79 @@ * limitations under the License. */ -TEST_CASE("t20007", "[test-case][sequence]") +TEST_CASE("t20007") { - auto [config, db] = load_config("t20007"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20007_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20007", "t20007_sequence"); - REQUIRE(diagram->name == "t20007_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + {"tmain()", "Adder", "add(int &&,int &&)"}, // + {"tmain()", "Adder", + "add(int &&,float &&,double &&)"}, // + {"tmain()", "Adder", + "add(std::string &&,std::string &&,std::string &&)"} // + })); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - auto model = generate_sequence_diagram(*db, diagram); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE(model->name() == "t20007_sequence"); + // Check if all calls exist + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("Adder"), "add(int &&,int + &&)")); REQUIRE_THAT(src, HasCall(_A("tmain()"), + _A("Adder"), "add(int &&,float &&,double &&)")); + REQUIRE_THAT(src, + HasCall(_A("tmain()"), + _A("Adder"), + "add(std::string &&,std::string &&,std::string &&)")); - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + save_puml(config.output_directory(), diagram->name + ".puml", + src); + } - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + { + auto j = generate_sequence_json(diagram, *model); - // Check if all calls exist - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("Adder"), "add(int &&,int &&)")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("Adder"), - "add(int &&,float &&,double &&)")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), - _A("Adder"), - "add(std::string &&,std::string &&,std::string &&)")); + using namespace json; - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + std::vector messages = { + FindMessage(j, "tmain()", "Adder", "add(int &&,int + &&)"), FindMessage(j, "tmain()", "Adder", "add(int + &&,float &&,double &&)"), FindMessage(j, "tmain()", + "Adder", + "add(std::string &&,std::string &&,std::string &&)")}; - { - auto j = generate_sequence_json(diagram, *model); + REQUIRE(std::is_sorted(messages.begin(), messages.end())); - using namespace json; + save_json(config.output_directory(), diagram->name + ".json", + j); + } - std::vector messages = { - FindMessage(j, "tmain()", "Adder", "add(int &&,int &&)"), - FindMessage(j, "tmain()", "Adder", - "add(int &&,float &&,double &&)"), - FindMessage(j, "tmain()", - "Adder", - "add(std::string &&,std::string &&,std::string &&)")}; + { + auto src = generate_sequence_mermaid(diagram, *model); - REQUIRE(std::is_sorted(messages.begin(), messages.end())); + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; - save_json(config.output_directory(), diagram->name + ".json", j); - } + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("Adder"), "add(int &&,int + &&)")); REQUIRE_THAT(src, HasCall(_A("tmain()"), + _A("Adder"), "add(int &&,float &&,double &&)")); + REQUIRE_THAT(src, + HasCall(_A("tmain()"), + _A("Adder"), + "add(std::string &&,std::string &&,std::string &&)")); - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("Adder"), "add(int &&,int &&)")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("Adder"), - "add(int &&,float &&,double &&)")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), - _A("Adder"), - "add(std::string &&,std::string &&,std::string &&)")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t20008/test_case.h b/tests/t20008/test_case.h index 0a98e6fd..ac9c7a05 100644 --- a/tests/t20008/test_case.h +++ b/tests/t20008/test_case.h @@ -16,91 +16,104 @@ * limitations under the License. */ -TEST_CASE("t20008", "[test-case][sequence]") +TEST_CASE("t20008") { - auto [config, db] = load_config("t20008"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20008_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20008", "t20008_sequence"); - REQUIRE(diagram->name == "t20008_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "B", "b(int)"}, // + {"B", "A", "a1(int)"}, // - auto model = generate_sequence_diagram(*db, diagram); + {"tmain()", "B", "b(const char *)"}, // + {"B", "A", "a2(const char *)"}, // - REQUIRE(model->name() == "t20008_sequence"); + {"tmain()", "B", "b(std::string)"}, // + {"B", "A", "a3(std::string)"} // + })); - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + REQUIRE(!HasMessage(src, {"B", "A", "a2(int)"})); + REQUIRE(!HasMessage(src, {"B", "A", "a3(int)"})); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b(int)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a1(int)")); - // REQUIRE_THAT(puml, !HasCall(_A("B"), _A("A"), - // "a2(int)")); REQUIRE_THAT(puml, !HasCall(_A("B"), - // _A("A"), "a3(int)")); + // Check if all calls exist + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), + "b(int)")); REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), + "a1(int)")); + // REQUIRE_THAT(puml, !HasCall(_A("B"), _A("A"), + // "a2(int)")); REQUIRE_THAT(puml, !HasCall(_A("B"), + // _A("A"), "a3(int)")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("B"), "b(const char *)")); - REQUIRE_THAT(src, - HasCall(_A("B"), _A("A"), - "a2(const char *)")); + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("B"), "b(const char + *)")); REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2(const char *)")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("B"), "b(std::string)")); - REQUIRE_THAT(src, - HasCall( - _A("B"), _A("A"), "a3(std::string)")); + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("B"), + "b(std::string)")); REQUIRE_THAT(src, HasCall( _A("B"), + _A("A"), "a3(std::string)")); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + save_puml(config.output_directory(), diagram->name + ".puml", + src); + } - { - auto j = generate_sequence_json(diagram, *model); + { + auto j = generate_sequence_json(diagram, *model); - using namespace json; + using namespace json; - std::vector messages = { - FindMessage(j, "tmain()", "B", "b(int)"), - FindMessage(j, "B", "A", "a1(int)"), - FindMessage(j, "tmain()", "B", "b(const char *)"), - FindMessage( - j, "B", "A", "a2(const char *)"), - FindMessage(j, "tmain()", "B", "b(std::string)"), - FindMessage( - j, "B", "A", "a3(std::string)")}; + std::vector messages = { + FindMessage(j, "tmain()", "B", "b(int)"), + FindMessage(j, "B", "A", "a1(int)"), + FindMessage(j, "tmain()", "B", "b(const char + *)"), FindMessage( j, "B", "A", "a2(const + char *)"), FindMessage(j, "tmain()", "B", + "b(std::string)"), FindMessage( j, "B", + "A", "a3(std::string)")}; - REQUIRE(std::is_sorted(messages.begin(), messages.end())); + REQUIRE(std::is_sorted(messages.begin(), messages.end())); - save_json(config.output_directory(), diagram->name + ".json", j); - } + save_json(config.output_directory(), diagram->name + ".json", + j); + } - { - auto src = generate_sequence_mermaid(diagram, *model); + { + auto src = generate_sequence_mermaid(diagram, *model); - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b(int)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a1(int)")); - // REQUIRE_THAT(puml, !HasCall(_A("B"), _A("A"), - // "a2(int)")); REQUIRE_THAT(puml, !HasCall(_A("B"), - // _A("A"), "a3(int)")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), + "b(int)")); REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), + "a1(int)")); + // REQUIRE_THAT(puml, !HasCall(_A("B"), _A("A"), + // "a2(int)")); REQUIRE_THAT(puml, !HasCall(_A("B"), + // _A("A"), "a3(int)")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("B"), "b(const char *)")); - REQUIRE_THAT(src, - HasCall(_A("B"), _A("A"), - "a2(const char *)")); + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("B"), "b(const char + *)")); REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2(const char *)")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("B"), "b(std::string)")); - REQUIRE_THAT(src, - HasCall( - _A("B"), _A("A"), "a3(std::string)")); + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("B"), + "b(std::string)")); REQUIRE_THAT(src, HasCall( _A("B"), + _A("A"), "a3(std::string)")); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t20009/test_case.h b/tests/t20009/test_case.h index 64bc4235..0a7600bb 100644 --- a/tests/t20009/test_case.h +++ b/tests/t20009/test_case.h @@ -16,78 +16,93 @@ * limitations under the License. */ -TEST_CASE("t20009", "[test-case][sequence]") +TEST_CASE("t20009") { - auto [config, db] = load_config("t20009"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20009_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20009", "t20009_sequence"); - REQUIRE(diagram->name == "t20009_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "B", "b(std::string)"}, // + {"B", "A", "a(std::string)"}, // - auto model = generate_sequence_diagram(*db, diagram); + {"tmain()", "B", "b(int)"}, // + {"B", "A", "a(int)"}, // - REQUIRE(model->name() == "t20009_sequence"); + {"tmain()", "B", "b(float)"}, // + {"B", "A", "a(float)"} // + })); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + // Check if all calls exist + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("B"), "b(std::string)")); + REQUIRE_THAT(src, + HasCall( + _A("B"), _A("A"), + "a(std::string)")); - // Check if all calls exist - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("B"), "b(std::string)")); - REQUIRE_THAT(src, - HasCall( - _A("B"), _A("A"), "a(std::string)")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b(int)")); + REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a(int)")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b(int)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a(int)")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), + "b(float)")); REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), + "a(float)")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b(float)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a(float)")); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + { + auto j = generate_sequence_json(diagram, *model); - { - auto j = generate_sequence_json(diagram, *model); + using namespace json; - using namespace json; + std::vector messages = { + FindMessage(j, "tmain()", "B", "b(std::string)"), + FindMessage( + j, "B", "A", "a(std::string)"), + FindMessage(j, "tmain()", "B", "b(int)"), + FindMessage(j, "B", "A", "a(int)"), + FindMessage(j, "tmain()", "B", "b(float)"), + FindMessage(j, "B", "A", "a(float)")}; - std::vector messages = { - FindMessage(j, "tmain()", "B", "b(std::string)"), - FindMessage( - j, "B", "A", "a(std::string)"), - FindMessage(j, "tmain()", "B", "b(int)"), - FindMessage(j, "B", "A", "a(int)"), - FindMessage(j, "tmain()", "B", "b(float)"), - FindMessage(j, "B", "A", "a(float)")}; + REQUIRE(std::is_sorted(messages.begin(), messages.end())); - REQUIRE(std::is_sorted(messages.begin(), messages.end())); + save_json(config.output_directory(), diagram->name + ".json", j); + } - save_json(config.output_directory(), diagram->name + ".json", j); - } + { + auto src = generate_sequence_mermaid(diagram, *model); - { - auto src = generate_sequence_mermaid(diagram, *model); + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("B"), "b(std::string)")); + REQUIRE_THAT(src, + HasCall( + _A("B"), _A("A"), + "a(std::string)")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("B"), "b(std::string)")); - REQUIRE_THAT(src, - HasCall( - _A("B"), _A("A"), "a(std::string)")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b(int)")); + REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a(int)")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b(int)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a(int)")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), + "b(float)")); REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), + "a(float)")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b(float)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a(float)")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t20010/test_case.h b/tests/t20010/test_case.h index a4e0f76c..e17b4f57 100644 --- a/tests/t20010/test_case.h +++ b/tests/t20010/test_case.h @@ -16,79 +16,92 @@ * limitations under the License. */ -TEST_CASE("t20010", "[test-case][sequence]") +TEST_CASE("t20010") { - auto [config, db] = load_config("t20010"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20010_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20010", "t20010_sequence"); - REQUIRE(diagram->name == "t20010_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + {"tmain()", "B", "b1()"}, // + {"B", "A", "a1()"}, // - auto model = generate_sequence_diagram(*db, diagram); + {"tmain()", "B", "b2()"}, // + {"B", "A", "a2()"}, // - REQUIRE(model->name() == "t20010_sequence"); + {"tmain()", "B", "b3()"}, // + {"B", "A", "a3()"}, // - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + {"tmain()", "B", "b4()"}, // + {"B", "A", "a4()"} // + })); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b1()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a1()")); + // Check if all calls exist + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b1()")); + REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a1()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b2()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b2()")); + REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b3()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a3()")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b3()")); + REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a3()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b4()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a4()")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b4()")); + REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a4()")); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - { - auto j = generate_sequence_json(diagram, *model); + { + auto j = generate_sequence_json(diagram, *model); - using namespace json; + using namespace json; - std::vector messages = { - FindMessage(j, "tmain()", "B", "b1()"), - FindMessage(j, "B", "A", "a1()"), - FindMessage(j, "tmain()", "B", "b2()"), - FindMessage(j, "B", "A", "a2()"), - FindMessage(j, "tmain()", "B", "b3()"), - FindMessage(j, "B", "A", "a3()"), - FindMessage(j, "tmain()", "B", "b4()"), - FindMessage(j, "B", "A", "a4()")}; + std::vector messages = { + FindMessage(j, "tmain()", "B", "b1()"), + FindMessage(j, "B", "A", "a1()"), + FindMessage(j, "tmain()", "B", "b2()"), + FindMessage(j, "B", "A", "a2()"), + FindMessage(j, "tmain()", "B", "b3()"), + FindMessage(j, "B", "A", "a3()"), + FindMessage(j, "tmain()", "B", "b4()"), + FindMessage(j, "B", "A", "a4()")}; - REQUIRE(std::is_sorted(messages.begin(), messages.end())); + REQUIRE(std::is_sorted(messages.begin(), messages.end())); - save_json(config.output_directory(), diagram->name + ".json", j); - } + save_json(config.output_directory(), diagram->name + ".json", j); + } - { - auto src = generate_sequence_mermaid(diagram, *model); + { + auto src = generate_sequence_mermaid(diagram, *model); - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b1()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a1()")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b1()")); + REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a1()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b2()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b2()")); + REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b3()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a3()")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b3()")); + REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a3()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b4()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a4()")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b4()")); + REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a4()")); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t20011/test_case.h b/tests/t20011/test_case.h index e6f4b81a..9923d2e7 100644 --- a/tests/t20011/test_case.h +++ b/tests/t20011/test_case.h @@ -16,17 +16,28 @@ * limitations under the License. */ -TEST_CASE("t20011", "[test-case][sequence]") +TEST_CASE("t20011") { - auto [config, db] = load_config("t20011"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20011_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20011", "t20011_sequence"); - REQUIRE(diagram->name == "t20011_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "A", "a(int)"}, // + {"A", "A", "a(int)"}, // - auto model = generate_sequence_diagram(*db, diagram); + {"tmain()", "A", "b(int)"}, // + {"A", "A", "c(int)"}, // + {"A", "A", "d(int)"}, // + {"A", "A", "b(int)"} // + })); + }); - REQUIRE(model->name() == "t20011_sequence"); + /* { auto src = generate_sequence_puml(diagram, *model); AliasMatcher _A(src); @@ -80,4 +91,5 @@ TEST_CASE("t20011", "[test-case][sequence]") save_mermaid(config.output_directory(), diagram->name + ".mmd", src); } + */ } \ No newline at end of file diff --git a/tests/t20012/test_case.h b/tests/t20012/test_case.h index 918a7d96..dd7a50f8 100644 --- a/tests/t20012/test_case.h +++ b/tests/t20012/test_case.h @@ -16,17 +16,60 @@ * limitations under the License. */ -TEST_CASE("t20012", "[test-case][sequence]") +TEST_CASE("t20012") { - auto [config, db] = load_config("t20012"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20012_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20012", "t20012_sequence"); - REQUIRE(diagram->name == "t20012_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + {"tmain()", "tmain()::(lambda t20012.cc:67:20)", + "operator()() const"}, // + {"tmain()::(lambda t20012.cc:67:20)", "A", "a()"}, // + {"A", "A", "aa()"}, // + {"A", "A", "aaa()"}, // - auto model = generate_sequence_diagram(*db, diagram); + {"tmain()::(lambda t20012.cc:67:20)", "B", "b()"}, // + {"B", "B", "bb()"}, // + {"B", "B", "bbb()"}, // - REQUIRE(model->name() == "t20012_sequence"); + {"tmain()", "tmain()::(lambda t20012.cc:80:20)", + "operator()() const"}, // + {"tmain()::(lambda t20012.cc:80:20)", "C", "c()"}, // + {"C", "C", "cc()"}, // + {"C", "C", "ccc()"}, // + + {"tmain()::(lambda t20012.cc:80:20)", + "tmain()::(lambda t20012.cc:67:20)", + "operator()() const"}, // + + {"tmain()::(lambda t20012.cc:67:20)", "A", "a()"}, // + + {"A", "A", "aa()"}, // + {"A", "A", "aaa()"}, // + + {"tmain()::(lambda t20012.cc:67:20)", "B", "b()"}, // + {"B", "B", "bb()"}, // + {"B", "B", "bbb()"}, // + + {"tmain()", "R<(lambda at t20012.cc:86:9)>", + "R((lambda at t20012.cc:86:9) &&)"}, // + {"tmain()", "R<(lambda at t20012.cc:86:9)>", "r()"}, // + {"R<(lambda at t20012.cc:86:9)>", + "tmain()::(lambda t20012.cc:86:9)", + "operator()() const"}, // + {"tmain()::(lambda t20012.cc:86:9)", "C", "c()"}, // + + {"tmain()", "tmain()::(lambda t20012.cc:94:9)", + "operator()(auto) const"}, // + {"tmain()::(lambda t20012.cc:94:9)", "D", "add5(int) const"} // + })); + }); + + /* { auto src = generate_sequence_puml(diagram, *model); AliasMatcher _A(src); @@ -155,4 +198,5 @@ TEST_CASE("t20012", "[test-case][sequence]") save_mermaid(config.output_directory(), diagram->name + ".mmd", src); } + */ } diff --git a/tests/t20013/test_case.h b/tests/t20013/test_case.h index 733f7e20..e0594057 100644 --- a/tests/t20013/test_case.h +++ b/tests/t20013/test_case.h @@ -16,17 +16,28 @@ * limitations under the License. */ -TEST_CASE("t20013", "[test-case][sequence]") +TEST_CASE("t20013") { - auto [config, db] = load_config("t20013"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20013_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20013", "t20013_sequence"); - REQUIRE(diagram->name == "t20013_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain(int,char **)", "B", "b(int)"}, // + {"B", "A", "a1(int)"}, // - auto model = generate_sequence_diagram(*db, diagram); + {"tmain(int,char **)", "B", "b(double)"}, // + {"B", "A", "a2(double)"}, // - REQUIRE(model->name() == "t20013_sequence"); + {"tmain(int,char **)", "B", "b(const char *)"}, // + {"B", "A", "a3(const char *)"} // + })); + }); + /* { auto src = generate_sequence_puml(diagram, *model); AliasMatcher _A(src); @@ -85,5 +96,5 @@ TEST_CASE("t20013", "[test-case][sequence]") REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a3(const char *)")); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } \ No newline at end of file diff --git a/tests/t20014/test_case.h b/tests/t20014/test_case.h index 8bb84bbc..d835bb9f 100644 --- a/tests/t20014/test_case.h +++ b/tests/t20014/test_case.h @@ -16,17 +16,28 @@ * limitations under the License. */ -TEST_CASE("t20014", "[test-case][sequence]") +TEST_CASE("t20014") { - auto [config, db] = load_config("t20014"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20014_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20014", "t20014_sequence"); - REQUIRE(diagram->name == "t20014_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "B", "b1(int,int)"}, // + {"B", "A", "a1(int,int)"}, // - auto model = generate_sequence_diagram(*db, diagram); + {"tmain()", "B", "b2(int,int)"}, // + {"B", "A", "a2(int,int)"}, // - REQUIRE(model->name() == "t20014_sequence"); + {"tmain()", "C", "c1(int,int)"}, // + {"C", "B", "b1(int,int)"}, // + })); + }); +/* { auto src = generate_sequence_puml(diagram, *model); AliasMatcher _A(src); @@ -84,4 +95,5 @@ TEST_CASE("t20014", "[test-case][sequence]") save_mermaid(config.output_directory(), diagram->name + ".mmd", src); } -} \ No newline at end of file +*/ + } \ No newline at end of file diff --git a/tests/t20015/test_case.h b/tests/t20015/test_case.h index 259cafb7..2a752921 100644 --- a/tests/t20015/test_case.h +++ b/tests/t20015/test_case.h @@ -16,69 +16,82 @@ * limitations under the License. */ -TEST_CASE("t20015", "[test-case][sequence]") +TEST_CASE("t20015") { - auto [config, db] = load_config("t20015"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20015_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20015", "t20015_sequence"); - REQUIRE(diagram->name == "t20015_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + {"tmain()", "B", "setup_a(std::shared_ptr &)"} // + })); - auto model = generate_sequence_diagram(*db, diagram); + REQUIRE(!HasMessage(src, {"B", {"detail", "A"}, "set_x(int)"})); + REQUIRE(!HasMessage(src, {"B", {"detail" ,"A"}, "set_y(int)"})); + REQUIRE(!HasMessage(src, {"B", {"detail", "A"}, "set_z(int)"})); - REQUIRE(model->name() == "t20015_sequence"); - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + REQUIRE(!HasMessage(src, {"B", "B", "set_x(int)"})); + REQUIRE(!HasMessage(src, {"B", "B", "set_y(int)"})); + REQUIRE(!HasMessage(src, {"B", "B", "set_z(int)"})); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - // Check if all calls exist - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("B"), - "setup_a(std::shared_ptr &)")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("detail::A"), "set_x(int)")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("detail::A"), "set_y(int)")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("detail::A"), "set_z(int)")); + // Check if all calls exist + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("B"), + "setup_a(std::shared_ptr &)")); + REQUIRE_THAT(src, !HasCall(_A("B"), _A("detail::A"), "set_x(int)")); + REQUIRE_THAT(src, !HasCall(_A("B"), _A("detail::A"), "set_y(int)")); + REQUIRE_THAT(src, !HasCall(_A("B"), _A("detail::A"), "set_z(int)")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("B"), "set_x(int)")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("B"), "set_y(int)")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("B"), "set_z(int)")); + REQUIRE_THAT(src, !HasCall(_A("B"), _A("B"), "set_x(int)")); + REQUIRE_THAT(src, !HasCall(_A("B"), _A("B"), "set_y(int)")); + REQUIRE_THAT(src, !HasCall(_A("B"), _A("B"), "set_z(int)")); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - { - auto j = generate_sequence_json(diagram, *model); + { + auto j = generate_sequence_json(diagram, *model); - using namespace json; + using namespace json; - std::vector messages = {FindMessage( - j, "tmain()", "B", "setup_a(std::shared_ptr &)")}; + std::vector messages = {FindMessage( + j, "tmain()", "B", "setup_a(std::shared_ptr &)")}; - REQUIRE(std::is_sorted(messages.begin(), messages.end())); + REQUIRE(std::is_sorted(messages.begin(), messages.end())); - save_json(config.output_directory(), diagram->name + ".json", j); - } + save_json(config.output_directory(), diagram->name + ".json", j); + } - { - auto src = generate_sequence_mermaid(diagram, *model); + { + auto src = generate_sequence_mermaid(diagram, *model); - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("B"), - "setup_a(std::shared_ptr &)")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("detail::A"), "set_x(int)")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("detail::A"), "set_y(int)")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("detail::A"), "set_z(int)")); + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("B"), + "setup_a(std::shared_ptr &)")); + REQUIRE_THAT(src, !HasCall(_A("B"), _A("detail::A"), "set_x(int)")); + REQUIRE_THAT(src, !HasCall(_A("B"), _A("detail::A"), "set_y(int)")); + REQUIRE_THAT(src, !HasCall(_A("B"), _A("detail::A"), "set_z(int)")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("B"), "set_x(int)")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("B"), "set_y(int)")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("B"), "set_z(int)")); + REQUIRE_THAT(src, !HasCall(_A("B"), _A("B"), "set_x(int)")); + REQUIRE_THAT(src, !HasCall(_A("B"), _A("B"), "set_y(int)")); + REQUIRE_THAT(src, !HasCall(_A("B"), _A("B"), "set_z(int)")); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + } + */ } \ No newline at end of file diff --git a/tests/t20016/test_case.h b/tests/t20016/test_case.h index b9bf1d12..ec213523 100644 --- a/tests/t20016/test_case.h +++ b/tests/t20016/test_case.h @@ -16,62 +16,77 @@ * limitations under the License. */ -TEST_CASE("t20016", "[test-case][sequence]") +TEST_CASE("t20016") { - auto [config, db] = load_config("t20016"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20016_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20016", "t20016_sequence"); - REQUIRE(diagram->name == "t20016_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "B", "b1(long)"}, // + {"B", "A", "a1(int)"}, // + {"tmain()", "B", "b2(long)"}, // + {"B", "A", "a2(const long &)"} // + })); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - auto model = generate_sequence_diagram(*db, diagram); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE(model->name() == "t20016_sequence"); - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + // Check if all calls exist + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), + "b1(long)")); REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), + "a1(int)")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), + "b2(long)")); REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), + "a2(const long &)")); - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b1(long)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a1(int)")); + save_puml(config.output_directory(), diagram->name + ".puml", + src); + } - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b2(long)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2(const long &)")); + { + auto j = generate_sequence_json(diagram, *model); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + using namespace json; - { - auto j = generate_sequence_json(diagram, *model); + std::vector messages = { + FindMessage(j, "tmain()", "B", "b1(long)"), + FindMessage(j, "B", "A", "a1(int)"), + FindMessage(j, "tmain()", "B", "b2(long)"), + FindMessage(j, "B", "A", "a2(const long &)")}; - using namespace json; + REQUIRE(std::is_sorted(messages.begin(), messages.end())); - std::vector messages = { - FindMessage(j, "tmain()", "B", "b1(long)"), - FindMessage(j, "B", "A", "a1(int)"), - FindMessage(j, "tmain()", "B", "b2(long)"), - FindMessage(j, "B", "A", "a2(const long &)")}; + save_json(config.output_directory(), diagram->name + ".json", + j); + } - REQUIRE(std::is_sorted(messages.begin(), messages.end())); + { + auto src = generate_sequence_mermaid(diagram, *model); - save_json(config.output_directory(), diagram->name + ".json", j); - } + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; - { - auto src = generate_sequence_mermaid(diagram, *model); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), + "b1(long)")); REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), + "a1(int)")); - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), + "b2(long)")); REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), + "a2(const long &)")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b1(long)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a1(int)")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b2(long)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2(const long &)")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + } + */ } \ No newline at end of file diff --git a/tests/t20017/test_case.h b/tests/t20017/test_case.h index 37519ce6..9ae03f82 100644 --- a/tests/t20017/test_case.h +++ b/tests/t20017/test_case.h @@ -16,17 +16,27 @@ * limitations under the License. */ -TEST_CASE("t20017", "[test-case][sequence]") +TEST_CASE("t20017") { - auto [config, db] = load_config("t20017"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20017_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20017", "t20017_sequence"); - REQUIRE(diagram->name == "t20017_sequence"); - - auto model = generate_sequence_diagram(*db, diagram); - - REQUIRE(model->name() == "t20017_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + // {Entrypoint{}, "t20017.cc", "tmain()"}, // + {"t20017.cc", "include/t20017_a.h", "a3(int,int)"}, // + {"t20017.cc", "include/t20017_b.h", "b1(int,int)"}, // + /* {"t20017.cc", "include/t20017_a.h", "a2(int,int)"}, // + {"t20017.cc", "include/t20017_a.h", "a1(int,int)"}, // + {"t20017.cc", "include/t20017_b.h", "b2(int,int)"}, // + {Exitpoint{}, "t20017.cc"}, //*/ + })); + }); + /* { auto src = generate_sequence_puml(diagram, *model); AliasMatcher _A(src); @@ -105,5 +115,5 @@ TEST_CASE("t20017", "[test-case][sequence]") REQUIRE_THAT(src, HasExitpoint(_A("t20017.cc"))); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } \ No newline at end of file diff --git a/tests/t20018/test_case.h b/tests/t20018/test_case.h index ae618cae..c43591ef 100644 --- a/tests/t20018/test_case.h +++ b/tests/t20018/test_case.h @@ -16,88 +16,97 @@ * limitations under the License. */ -TEST_CASE("t20018", "[test-case][sequence]") +TEST_CASE("t20018") { - auto [config, db] = load_config("t20018"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20018_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20018", "t20018_sequence"); - REQUIRE(diagram->name == "t20018_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "Answer,120>", "print()", Static{}}, // + {"Answer,120>", "Factorial<5>", "print(int)", + Static{}}, // + {"Factorial<5>", "Factorial<4>", "print(int)", Static{}}, // + {"Factorial<4>", "Factorial<3>", "print(int)", Static{}}, // + {"Factorial<3>", "Factorial<2>", "print(int)", Static{}}, // + {"Factorial<2>", "Factorial<1>", "print(int)", Static{}}, // + {"Factorial<1>", "Factorial<0>", "print(int)", Static{}}, // + })); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - auto model = generate_sequence_diagram(*db, diagram); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE(model->name() == "t20018_sequence"); + // Check if all calls exist + REQUIRE_THAT(src, + HasCall( + _A("tmain()"), _A("Answer,120>"), + "__print()__")); REQUIRE_THAT(src, + HasCall(_A("Answer,120>"), _A("Factorial<5>"), + "__print(int)__")); + REQUIRE_THAT(src, + HasCall(_A("Factorial<5>"), _A("Factorial<4>"), + "__print(int)__")); REQUIRE_THAT(src, HasCall(_A("Factorial<4>"), + _A("Factorial<3>"), "__print(int)__")); REQUIRE_THAT(src, + HasCall(_A("Factorial<3>"), _A("Factorial<2>"), + "__print(int)__")); REQUIRE_THAT(src, HasCall(_A("Factorial<2>"), + _A("Factorial<1>"), "__print(int)__")); REQUIRE_THAT(src, + HasCall(_A("Factorial<1>"), _A("Factorial<0>"), + "__print(int)__")); - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + { + auto j = generate_sequence_json(diagram, *model); - // Check if all calls exist - REQUIRE_THAT(src, - HasCall( - _A("tmain()"), _A("Answer,120>"), "__print()__")); - REQUIRE_THAT(src, - HasCall(_A("Answer,120>"), _A("Factorial<5>"), - "__print(int)__")); - REQUIRE_THAT(src, - HasCall(_A("Factorial<5>"), _A("Factorial<4>"), "__print(int)__")); - REQUIRE_THAT(src, - HasCall(_A("Factorial<4>"), _A("Factorial<3>"), "__print(int)__")); - REQUIRE_THAT(src, - HasCall(_A("Factorial<3>"), _A("Factorial<2>"), "__print(int)__")); - REQUIRE_THAT(src, - HasCall(_A("Factorial<2>"), _A("Factorial<1>"), "__print(int)__")); - REQUIRE_THAT(src, - HasCall(_A("Factorial<1>"), _A("Factorial<0>"), "__print(int)__")); + using namespace json; - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + std::vector messages = { + FindMessage(j, "tmain()", "Answer,120>", + "print()"), FindMessage( j, "Answer,120>", "Factorial<5>", + "print(int)"), FindMessage(j, "Factorial<5>", "Factorial<4>", + "print(int)"), FindMessage(j, "Factorial<4>", "Factorial<3>", + "print(int)"), FindMessage(j, "Factorial<3>", "Factorial<2>", + "print(int)"), FindMessage(j, "Factorial<2>", "Factorial<1>", + "print(int)"), FindMessage(j, "Factorial<1>", "Factorial<0>", + "print(int)")}; - { - auto j = generate_sequence_json(diagram, *model); + REQUIRE(std::is_sorted(messages.begin(), messages.end())); - using namespace json; + save_json(config.output_directory(), diagram->name + ".json", j); + } - std::vector messages = { - FindMessage(j, "tmain()", "Answer,120>", "print()"), - FindMessage( - j, "Answer,120>", "Factorial<5>", "print(int)"), - FindMessage(j, "Factorial<5>", "Factorial<4>", "print(int)"), - FindMessage(j, "Factorial<4>", "Factorial<3>", "print(int)"), - FindMessage(j, "Factorial<3>", "Factorial<2>", "print(int)"), - FindMessage(j, "Factorial<2>", "Factorial<1>", "print(int)"), - FindMessage(j, "Factorial<1>", "Factorial<0>", "print(int)")}; + { + auto src = generate_sequence_mermaid(diagram, *model); - REQUIRE(std::is_sorted(messages.begin(), messages.end())); + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; - save_json(config.output_directory(), diagram->name + ".json", j); - } + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("Answer,120>"), + "print()")); REQUIRE_THAT(src, HasCall(_A("Answer,120>"), + _A("Factorial<5>"), "print(int)")); REQUIRE_THAT( src, + HasCall(_A("Factorial<5>"), _A("Factorial<4>"), "print(int)")); + REQUIRE_THAT( + src, HasCall(_A("Factorial<4>"), _A("Factorial<3>"), + "print(int)")); REQUIRE_THAT( src, HasCall(_A("Factorial<3>"), + _A("Factorial<2>"), "print(int)")); REQUIRE_THAT( src, + HasCall(_A("Factorial<2>"), _A("Factorial<1>"), "print(int)")); + REQUIRE_THAT( + src, HasCall(_A("Factorial<1>"), _A("Factorial<0>"), + "print(int)")); - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("Answer,120>"), "print()")); - REQUIRE_THAT(src, - HasCall(_A("Answer,120>"), _A("Factorial<5>"), - "print(int)")); - REQUIRE_THAT( - src, HasCall(_A("Factorial<5>"), _A("Factorial<4>"), "print(int)")); - REQUIRE_THAT( - src, HasCall(_A("Factorial<4>"), _A("Factorial<3>"), "print(int)")); - REQUIRE_THAT( - src, HasCall(_A("Factorial<3>"), _A("Factorial<2>"), "print(int)")); - REQUIRE_THAT( - src, HasCall(_A("Factorial<2>"), _A("Factorial<1>"), "print(int)")); - REQUIRE_THAT( - src, HasCall(_A("Factorial<1>"), _A("Factorial<0>"), "print(int)")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + } + */ } \ No newline at end of file diff --git a/tests/t20019/test_case.h b/tests/t20019/test_case.h index 195655ff..6f809823 100644 --- a/tests/t20019/test_case.h +++ b/tests/t20019/test_case.h @@ -16,18 +16,24 @@ * limitations under the License. */ -TEST_CASE("t20019", "[test-case][sequence]") +TEST_CASE("t20019") { - auto [config, db] = load_config("t20019"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20019_sequence"]; - - REQUIRE(diagram->name == "t20019_sequence"); - - auto model = generate_sequence_diagram(*db, diagram); - - REQUIRE(model->name() == "t20019_sequence"); + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20019", "t20019_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "Base", "name()"}, // + {"Base", "D1", "impl()"}, // + {"tmain()", "Base", "name()"}, // + {"Base", "D2", "impl()"} // + })); + }); +/* { auto src = generate_sequence_puml(diagram, *model); AliasMatcher _A(src); @@ -73,4 +79,5 @@ TEST_CASE("t20019", "[test-case][sequence]") save_mermaid(config.output_directory(), diagram->name + ".mmd", src); } + */ } \ No newline at end of file diff --git a/tests/t20020/test_case.h b/tests/t20020/test_case.h index bc5c2d0d..1653e737 100644 --- a/tests/t20020/test_case.h +++ b/tests/t20020/test_case.h @@ -16,95 +16,115 @@ * limitations under the License. */ -TEST_CASE("t20020", "[test-case][sequence]") +TEST_CASE("t20020") { - auto [config, db] = load_config("t20020"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20020_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20020", "t20020_sequence"); - REQUIRE(diagram->name == "t20020_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "A", "a1()"}, // + {"tmain()", "A", "a5()"}, // + {"tmain()", "A", "a2()", InControlCondition{}}, // + {"tmain()", "C", "c3(int)", InControlCondition{}}, // + {"tmain()", "B", "b1()"}, // + {"tmain()", "A", "a3()", InControlCondition{}}, // + {"tmain()", "B", "b2()"}, // + {"tmain()", "A", "a4()"}, // + {"tmain()", "B", "log()"}, // + {"tmain()", "C", "c1() const"}, // + {"C", "C", "c2() const", InControlCondition{}}, // + {"C", "C", "log() const"}, // + {"tmain()", "D", "d1(int,int)"}, // + })); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - auto model = generate_sequence_diagram(*db, diagram); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE(model->name() == "t20020_sequence"); - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + // Check if all calls exist + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a1()")); + REQUIRE_THAT( + src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a2()")); + REQUIRE_THAT( + src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a3()")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b1()")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b2()")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "log()")); - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a1()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a2()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a3()")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("C"), "c1() const")); + REQUIRE_THAT( + src, HasCallInControlCondition(_A("C"), _A("C"), "c2() const")); + REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "log() const")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b1()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b2()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "log()")); + REQUIRE_THAT( + src, HasCallInControlCondition(_A("tmain()"), _A("C"), + "c3(int)")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("C"), "c1() const")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("C"), _A("C"), "c2() const")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "log() const")); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("C"), "c3(int)")); + { + auto j = generate_sequence_json(diagram, *model); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + using namespace json; - { - auto j = generate_sequence_json(diagram, *model); + std::vector messages = {FindMessage(j, "tmain()", "A", "a1()"), + FindMessage(j, "tmain()", "A", "a5()"), + FindMessage(j, "tmain()", "A", "a2()"), + FindMessage(j, "tmain()", "C", "c3(int)"), + FindMessage(j, "tmain()", "B", "b1()"), + FindMessage(j, "tmain()", "A", "a3()"), + FindMessage(j, "tmain()", "B", "b2()"), + FindMessage(j, "tmain()", "A", "a4()"), + FindMessage(j, "tmain()", "B", "log()"), + FindMessage(j, "tmain()", "C", "c1() const"), + FindMessage(j, "C", "C", "c2() const"), + FindMessage(j, "C", "C", "log() const"), + FindMessage(j, "tmain()", "D", "d1(int,int)")}; - using namespace json; + REQUIRE(std::is_sorted(messages.begin(), messages.end())); - std::vector messages = {FindMessage(j, "tmain()", "A", "a1()"), - FindMessage(j, "tmain()", "A", "a5()"), - FindMessage(j, "tmain()", "A", "a2()"), - FindMessage(j, "tmain()", "C", "c3(int)"), - FindMessage(j, "tmain()", "B", "b1()"), - FindMessage(j, "tmain()", "A", "a3()"), - FindMessage(j, "tmain()", "B", "b2()"), - FindMessage(j, "tmain()", "A", "a4()"), - FindMessage(j, "tmain()", "B", "log()"), - FindMessage(j, "tmain()", "C", "c1() const"), - FindMessage(j, "C", "C", "c2() const"), - FindMessage(j, "C", "C", "log() const"), - FindMessage(j, "tmain()", "D", "d1(int,int)")}; + save_json(config.output_directory(), diagram->name + ".json", j); + } - REQUIRE(std::is_sorted(messages.begin(), messages.end())); + { + auto src = generate_sequence_mermaid(diagram, *model); - save_json(config.output_directory(), diagram->name + ".json", j); - } + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; + using mermaid::HasCallInControlCondition; - { - auto src = generate_sequence_mermaid(diagram, *model); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a1()")); + REQUIRE_THAT( + src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a2()")); + REQUIRE_THAT( + src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a3()")); - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - using mermaid::HasCallInControlCondition; + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b1()")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b2()")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "log()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a1()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a2()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a3()")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("C"), "c1() const")); + REQUIRE_THAT( + src, HasCallInControlCondition(_A("C"), _A("C"), "c2() const")); + REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "log() const")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b1()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b2()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "log()")); + REQUIRE_THAT( + src, HasCallInControlCondition(_A("tmain()"), _A("C"), + "c3(int)")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("C"), "c1() const")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("C"), _A("C"), "c2() const")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "log() const")); - - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("C"), "c3(int)")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + } + */ } \ No newline at end of file diff --git a/tests/t20021/test_case.h b/tests/t20021/test_case.h index afcedf98..92e9d1f9 100644 --- a/tests/t20021/test_case.h +++ b/tests/t20021/test_case.h @@ -16,17 +16,31 @@ * limitations under the License. */ -TEST_CASE("t20021", "[test-case][sequence]") +TEST_CASE("t20021") { - auto [config, db] = load_config("t20021"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20021_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20021", "t20021_sequence"); - REQUIRE(diagram->name == "t20021_sequence"); - - auto model = generate_sequence_diagram(*db, diagram); - - REQUIRE(model->name() == "t20021_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "C", "c4()", InControlCondition{}}, // + {"C", "C", "c5()"}, // + {"tmain()", "A", "a3()"}, // + {"tmain()", "A", "a2()", InControlCondition{}}, // + {"tmain()", "C", "c1()", InControlCondition{}}, // + {"tmain()", "C", "c2()", InControlCondition{}}, // + {"tmain()", "A", "a1()"}, // + {"tmain()", "C", "c3()", InControlCondition{}}, // + {"tmain()", "B", "b2() const"}, // + {"tmain()", "C", "contents()", InControlCondition{}}, // + {"tmain()", "B", "b2() const"}, // + })); + }); + /* { auto src = generate_sequence_puml(diagram, *model); AliasMatcher _A(src); @@ -113,5 +127,5 @@ TEST_CASE("t20021", "[test-case][sequence]") HasCallInControlCondition(_A("tmain()"), _A("C"), "contents()")); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } \ No newline at end of file diff --git a/tests/t20022/test_case.h b/tests/t20022/test_case.h index 330e14fa..cdcc5cf4 100644 --- a/tests/t20022/test_case.h +++ b/tests/t20022/test_case.h @@ -16,53 +16,64 @@ * limitations under the License. */ -TEST_CASE("t20022", "[test-case][sequence]") +TEST_CASE("t20022") { - auto [config, db] = load_config("t20022"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20022_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20022", "t20022_sequence"); - REQUIRE(diagram->name == "t20022_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + // TODO: ")" is incorrently rendered by PlantUML + // in a way that ) is bold, if it was ) it's rendered + // properly + {"tmain()", "A", "A(std::unique_ptr)"}, // + {"tmain()", "A", "a()"}, // + {"A", "B", "b()"}, // + })); + }); - auto model = generate_sequence_diagram(*db, diagram); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE(model->name() == "t20022_sequence"); - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + // Check if all calls exist + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a()")); + REQUIRE_THAT(src, HasCall(_A("A"), _A("B"), "b()")); - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("B"), "b()")); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + { + auto j = generate_sequence_json(diagram, *model); - { - auto j = generate_sequence_json(diagram, *model); + using namespace json; - using namespace json; + std::vector messages = {FindMessage(j, "tmain()", "A", "a()"), + FindMessage(j, "A", "B", "b()")}; - std::vector messages = {FindMessage(j, "tmain()", "A", "a()"), - FindMessage(j, "A", "B", "b()")}; + REQUIRE(std::is_sorted(messages.begin(), messages.end())); - REQUIRE(std::is_sorted(messages.begin(), messages.end())); + save_json(config.output_directory(), diagram->name + ".json", j); + } - save_json(config.output_directory(), diagram->name + ".json", j); - } + { + auto src = generate_sequence_mermaid(diagram, *model); - { - auto src = generate_sequence_mermaid(diagram, *model); + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a()")); + REQUIRE_THAT(src, HasCall(_A("A"), _A("B"), "b()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("B"), "b()")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t20023/test_case.h b/tests/t20023/test_case.h index 130d06b8..8a09799c 100644 --- a/tests/t20023/test_case.h +++ b/tests/t20023/test_case.h @@ -16,60 +16,72 @@ * limitations under the License. */ -TEST_CASE("t20023", "[test-case][sequence]") +TEST_CASE("t20023") { - auto [config, db] = load_config("t20023"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20023_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20023", "t20023_sequence"); - REQUIRE(diagram->name == "t20023_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "A", "a()"}, // + {"A", "A", "a2()"}, // + {"A", "A", "a2()"}, // + {"A", "A", "a3()"}, // + {"A", "A", "a4()"}, // - auto model = generate_sequence_diagram(*db, diagram); + })); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE(model->name() == "t20023_sequence"); - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + // Check if all calls exist + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a()")); + REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a1()")); + REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a2()")); + REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a3()")); + REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a4()")); - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a1()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a2()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a3()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a4()")); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + { + auto j = generate_sequence_json(diagram, *model); - { - auto j = generate_sequence_json(diagram, *model); + using namespace json; - using namespace json; + std::vector messages = {FindMessage(j, "tmain()", "A", "a()"), + FindMessage(j, "A", "A", "a1()"), FindMessage(j, "A", "A", + "a2()"), FindMessage(j, "A", "A", "a3()"), FindMessage(j, "A", "A", + "a4()")}; - std::vector messages = {FindMessage(j, "tmain()", "A", "a()"), - FindMessage(j, "A", "A", "a1()"), FindMessage(j, "A", "A", "a2()"), - FindMessage(j, "A", "A", "a3()"), FindMessage(j, "A", "A", "a4()")}; + REQUIRE(std::is_sorted(messages.begin(), messages.end())); - REQUIRE(std::is_sorted(messages.begin(), messages.end())); + save_json(config.output_directory(), diagram->name + ".json", j); + } - save_json(config.output_directory(), diagram->name + ".json", j); - } + { + auto src = generate_sequence_mermaid(diagram, *model); - { - auto src = generate_sequence_mermaid(diagram, *model); + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a()")); + REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a1()")); + REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a2()")); + REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a3()")); + REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a4()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a1()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a2()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a3()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a4()")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + } + */ } \ No newline at end of file diff --git a/tests/t20024/test_case.h b/tests/t20024/test_case.h index 46d85a0b..72ea1dfd 100644 --- a/tests/t20024/test_case.h +++ b/tests/t20024/test_case.h @@ -16,17 +16,31 @@ * limitations under the License. */ -TEST_CASE("t20024", "[test-case][sequence]") +TEST_CASE("t20024") { - auto [config, db] = load_config("t20024"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20024_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20024", "t20024_sequence"); - REQUIRE(diagram->name == "t20024_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "A", "select(enum_a)"}, // + {"A", "A", "a0()"}, // + {"A", "A", "a1()"}, // + {"A", "A", "a2()"}, // + {"A", "A", "a3()"}, // - auto model = generate_sequence_diagram(*db, diagram); - - REQUIRE(model->name() == "t20024_sequence"); + {"tmain()", "B", "select(colors)"}, // + {"B", "B", "red()"}, // + {"B", "B", "orange()"}, // + {"B", "B", "green()"}, // + {"B", "B", "grey()"} // + })); + }); + /* { auto src = generate_sequence_puml(diagram, *model); AliasMatcher _A(src); @@ -82,5 +96,5 @@ TEST_CASE("t20024", "[test-case][sequence]") REQUIRE_THAT(src, HasCall(_A("B"), _A("B"), "green()")); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } \ No newline at end of file diff --git a/tests/t20025/test_case.h b/tests/t20025/test_case.h index 2875c4f7..432ab52a 100644 --- a/tests/t20025/test_case.h +++ b/tests/t20025/test_case.h @@ -16,17 +16,22 @@ * limitations under the License. */ -TEST_CASE("t20025", "[test-case][sequence]") +TEST_CASE("t20025") { - auto [config, db] = load_config("t20025"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20025_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20025", "t20025_sequence"); - REQUIRE(diagram->name == "t20025_sequence"); - - auto model = generate_sequence_diagram(*db, diagram); - - REQUIRE(model->name() == "t20025_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "A", "a()"}, // + {"tmain()", "add(int,int)", ""} // + })); + }); + /* { auto src = generate_sequence_puml(diagram, *model); AliasMatcher _A(src); @@ -71,5 +76,5 @@ TEST_CASE("t20025", "[test-case][sequence]") REQUIRE_THAT(src, !HasCall(_A("tmain()"), _A("add2(int,int)"), "")); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } \ No newline at end of file diff --git a/tests/t20026/test_case.h b/tests/t20026/test_case.h index be0bf34d..44a399ab 100644 --- a/tests/t20026/test_case.h +++ b/tests/t20026/test_case.h @@ -16,17 +16,21 @@ * limitations under the License. */ -TEST_CASE("t20026", "[test-case][sequence]") +TEST_CASE("t20026") { - auto [config, db] = load_config("t20026"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20026_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20026", "t20026_sequence"); - REQUIRE(diagram->name == "t20026_sequence"); - - auto model = generate_sequence_diagram(*db, diagram); - - REQUIRE(model->name() == "t20026_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "A", "a()"} // + })); + }); +/* { auto src = generate_sequence_puml(diagram, *model); AliasMatcher _A(src); @@ -61,5 +65,5 @@ TEST_CASE("t20026", "[test-case][sequence]") REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a()")); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } \ No newline at end of file diff --git a/tests/t20027/test_case.h b/tests/t20027/test_case.h index 97f42249..12d2e962 100644 --- a/tests/t20027/test_case.h +++ b/tests/t20027/test_case.h @@ -16,17 +16,25 @@ * limitations under the License. */ -TEST_CASE("t20027", "[test-case][sequence]") +TEST_CASE("t20027") { - auto [config, db] = load_config("t20027"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20027_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20027", "t20027_sequence"); - REQUIRE(diagram->name == "t20027_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "A", "a()"} // + })); - auto model = generate_sequence_diagram(*db, diagram); + REQUIRE(!HasMessage(src, {"A", "A", "aa()"})); + REQUIRE(!HasMessage(src, {"A", "A", "aaa()"})); + }); - REQUIRE(model->name() == "t20027_sequence"); + /* { auto src = generate_sequence_puml(diagram, *model); AliasMatcher _A(src); @@ -65,5 +73,5 @@ TEST_CASE("t20027", "[test-case][sequence]") REQUIRE_THAT(src, !HasCall(_A("A"), _A("A"), "aaa()")); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } \ No newline at end of file diff --git a/tests/t20028/test_case.h b/tests/t20028/test_case.h index e0947a9f..0f1312ac 100644 --- a/tests/t20028/test_case.h +++ b/tests/t20028/test_case.h @@ -16,17 +16,27 @@ * limitations under the License. */ -TEST_CASE("t20028", "[test-case][sequence]") +TEST_CASE("t20028") { - auto [config, db] = load_config("t20028"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20028_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20028", "t20028_sequence"); - REQUIRE(diagram->name == "t20028_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "A", "a()", InControlCondition{}}, // + {"tmain()", "A", "b()"}, // + {"tmain()", "A", "c()"}, // + {"tmain()", "A", "d()"}, // + })); - auto model = generate_sequence_diagram(*db, diagram); + REQUIRE(!HasMessage(src, {"tmain()", "B", "e()"})); + }); - REQUIRE(model->name() == "t20028_sequence"); + /* { auto src = generate_sequence_puml(diagram, *model); AliasMatcher _A(src); @@ -75,5 +85,5 @@ TEST_CASE("t20028", "[test-case][sequence]") REQUIRE_THAT(src, !HasCall(_A("tmain()"), _A("B"), "e()")); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } \ No newline at end of file diff --git a/tests/t20029/test_case.h b/tests/t20029/test_case.h index cfbfc6c4..a03d527e 100644 --- a/tests/t20029/test_case.h +++ b/tests/t20029/test_case.h @@ -16,143 +16,182 @@ * limitations under the License. */ -TEST_CASE("t20029", "[test-case][sequence]") +TEST_CASE("t20029") { - auto [config, db] = load_config("t20029"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20029_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20029", "t20029_sequence"); - REQUIRE(diagram->name == "t20029_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "ConnectionPool", "connect()"}, // + {"tmain()", "Encoder>", + "send(std::string &&)", InControlCondition{}}, // + {"Encoder>", + "Encoder>", + "encode(std::string &&)"}, // + {"Encoder>", + "encode_b64(std::string &&)", ""}, // + {"Encoder>", "Retrier", + "send(std::string &&)"}, // + {"Retrier", "ConnectionPool", + "send(const std::string &)", InControlCondition{}} // + })); - auto model = generate_sequence_diagram(*db, diagram); + REQUIRE(!HasMessage( + src, {"ConnectionPool", "ConnectionPool", "connect_impl()"})); - REQUIRE(model->name() == "t20029_sequence"); - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + REQUIRE(HasMessageComment(src, "tmain()", + "Establish connection to the\\n" + "remote server synchronously")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE(HasMessageComment(src, "tmain()", + "Repeat for each line in the\\n" + "input stream")); - // Check if all calls exist - REQUIRE_THAT( - src, HasCall(_A("tmain()"), _A("ConnectionPool"), "connect()")); - REQUIRE_THAT(src, - HasCallInControlCondition(_A("tmain()"), - _A("Encoder>"), - "send(std::string &&)")); + REQUIRE(HasMessageComment(src, "Encoder>", + "Encode the message using\\n" + "Base64 encoding and pass\\n" + "it to the next layer")); - REQUIRE_THAT(src, - HasCall(_A("Encoder>"), - _A("Encoder>"), - "encode(std::string &&)")); + REQUIRE(HasMessageComment(src, "Retrier", + "Repeat until send() succeeds\\n" + "or retry count is exceeded")); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE_THAT(src, - HasCall(_A("Encoder>"), - _A("encode_b64(std::string &&)"), "")); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, - HasCallInControlCondition(_A("Retrier"), - _A("ConnectionPool"), "send(const std::string &)")); + // Check if all calls exist + REQUIRE_THAT( + src, HasCall(_A("tmain()"), _A("ConnectionPool"), "connect()")); + REQUIRE_THAT(src, + HasCallInControlCondition(_A("tmain()"), + _A("Encoder>"), + "send(std::string &&)")); - REQUIRE_THAT(src, - !HasCall( - _A("ConnectionPool"), _A("ConnectionPool"), "connect_impl()")); + REQUIRE_THAT(src, + HasCall(_A("Encoder>"), + _A("Encoder>"), + "encode(std::string &&)")); - REQUIRE_THAT(src, - HasMessageComment(_A("tmain()"), - "Establish connection to the\\n" - "remote server synchronously")); + REQUIRE_THAT(src, + HasCall(_A("Encoder>"), + _A("encode_b64(std::string &&)"), "")); - REQUIRE_THAT(src, - HasMessageComment(_A("tmain()"), - "Repeat for each line in the\\n" - "input stream")); + REQUIRE_THAT(src, + HasCallInControlCondition(_A("Retrier"), + _A("ConnectionPool"), "send(const std::string &)")); - REQUIRE_THAT(src, - HasMessageComment(_A("Encoder>"), - "Encode the message using\\n" - "Base64 encoding and pass\\n" - "it to the next layer")); + REQUIRE_THAT(src, + !HasCall( + _A("ConnectionPool"), _A("ConnectionPool"), + "connect_impl()")); - REQUIRE_THAT(src, - HasMessageComment(_A("Retrier"), - "Repeat until send\\(\\) succeeds\\n" - "or retry count is exceeded")); + REQUIRE_THAT(src, + HasMessageComment(_A("tmain()"), + "Establish connection to the\\n" + "remote server synchronously")); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + REQUIRE_THAT(src, + HasMessageComment(_A("tmain()"), + "Repeat for each line in the\\n" + "input stream")); - { - auto j = generate_sequence_json(diagram, *model); + REQUIRE_THAT(src, + HasMessageComment(_A("Encoder>"), + "Encode the message using\\n" + "Base64 encoding and pass\\n" + "it to the next layer")); - using namespace json; + REQUIRE_THAT(src, + HasMessageComment(_A("Retrier"), + "Repeat until send\\(\\) succeeds\\n" + "or retry count is exceeded")); - REQUIRE(!j["participants"].is_null()); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - std::vector messages = { - FindMessage(j, "tmain()", "ConnectionPool", "connect()"), - FindMessage(j, "tmain()", "Encoder>", - "send(std::string &&)")}; + { + auto j = generate_sequence_json(diagram, *model); - REQUIRE(std::is_sorted(messages.begin(), messages.end())); + using namespace json; - save_json(config.output_directory(), diagram->name + ".json", j); - } + REQUIRE(!j["participants"].is_null()); - { - auto src = generate_sequence_mermaid(diagram, *model); + std::vector messages = { + FindMessage(j, "tmain()", "ConnectionPool", "connect()"), + FindMessage(j, "tmain()", "Encoder>", + "send(std::string &&)")}; - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - using mermaid::HasCallInControlCondition; - using mermaid::HasMessageComment; + REQUIRE(std::is_sorted(messages.begin(), messages.end())); - REQUIRE_THAT( - src, HasCall(_A("tmain()"), _A("ConnectionPool"), "connect()")); - REQUIRE_THAT(src, - HasCallInControlCondition(_A("tmain()"), - _A("Encoder>"), - "send(std::string &&)")); + save_json(config.output_directory(), diagram->name + ".json", j); + } - REQUIRE_THAT(src, - HasCall(_A("Encoder>"), - _A("Encoder>"), - "encode(std::string &&)")); + { + auto src = generate_sequence_mermaid(diagram, *model); - REQUIRE_THAT(src, - HasCall(_A("Encoder>"), - _A("encode_b64(std::string &&)"), "")); + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; + using mermaid::HasCallInControlCondition; + using mermaid::HasMessageComment; - REQUIRE_THAT(src, - HasCallInControlCondition(_A("Retrier"), - _A("ConnectionPool"), "send(const std::string &)")); + REQUIRE_THAT( + src, HasCall(_A("tmain()"), _A("ConnectionPool"), "connect()")); + REQUIRE_THAT(src, + HasCallInControlCondition(_A("tmain()"), + _A("Encoder>"), + "send(std::string &&)")); - REQUIRE_THAT(src, - !HasCall( - _A("ConnectionPool"), _A("ConnectionPool"), "connect_impl()")); + REQUIRE_THAT(src, + HasCall(_A("Encoder>"), + _A("Encoder>"), + "encode(std::string &&)")); - REQUIRE_THAT(src, - HasMessageComment(_A("tmain()"), - "Establish connection to the
" - "remote server synchronously")); + REQUIRE_THAT(src, + HasCall(_A("Encoder>"), + _A("encode_b64(std::string &&)"), "")); - REQUIRE_THAT(src, - HasMessageComment(_A("tmain()"), - "Repeat for each line in the
" - "input stream")); + REQUIRE_THAT(src, + HasCallInControlCondition(_A("Retrier"), + _A("ConnectionPool"), "send(const std::string &)")); - REQUIRE_THAT(src, - HasMessageComment(_A("Encoder>"), - "Encode the message using
" - "Base64 encoding and pass
" - "it to the next layer")); + REQUIRE_THAT(src, + !HasCall( + _A("ConnectionPool"), _A("ConnectionPool"), + "connect_impl()")); - REQUIRE_THAT(src, - HasMessageComment(_A("Retrier"), - "Repeat until send\\(\\) succeeds
" - "or retry count is exceeded")); + REQUIRE_THAT(src, + HasMessageComment(_A("tmain()"), + "Establish connection to the
" + "remote server synchronously")); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE_THAT(src, + HasMessageComment(_A("tmain()"), + "Repeat for each line in the
" + "input stream")); + + REQUIRE_THAT(src, + HasMessageComment(_A("Encoder>"), + "Encode the message using
" + "Base64 encoding and pass
" + "it to the next layer")); + + REQUIRE_THAT(src, + HasMessageComment(_A("Retrier"), + "Repeat until send\\(\\) succeeds
" + "or retry count is exceeded")); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + } + */ } \ No newline at end of file diff --git a/tests/t20030/test_case.h b/tests/t20030/test_case.h index fdda6293..c2b8fefb 100644 --- a/tests/t20030/test_case.h +++ b/tests/t20030/test_case.h @@ -16,75 +16,93 @@ * limitations under the License. */ -TEST_CASE("t20030", "[test-case][sequence]") +TEST_CASE("t20030") { - auto [config, db] = load_config("t20030"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20030_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20030", "t20030_sequence"); - REQUIRE(diagram->name == "t20030_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain(int)", "magic()", ""}, // + {"tmain(int)", "A", "A(int)"}, // + {"tmain(int)", "A", "operator+=(int)"}, // + {"A", "A", "add(int)"}, // + {"tmain(bool,int)", "A", "A()"}, // + // {"A", "A", "create()"}, // + // {"tmain(bool,int)", "A", "A()"}, // + // {"A", "A", "create()"}, // + // {"tmain(bool,int)", "A", "operator+=(int)"}, + // // + // {"A", "A", "add(int)"}, // + // {"tmain(bool,int)", "A", "operator=(const A + // &)"}, // + // {"A", "A", "set(int)"}, // + // {"tmain(bool,int)", "A", "value() const"} // + })); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - auto model = generate_sequence_diagram(*db, diagram); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE(model->name() == "t20030_sequence"); + // Check if all calls exist + REQUIRE_THAT(src, HasCall(_A("tmain(int)"), _A("magic()"), "")); - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "create()")); + REQUIRE_THAT( + src, HasCall(_A("tmain(int)"), _A("A"), "operator+=(int)")); + REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "add(int)")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE_THAT(src, HasCall(_A("tmain(bool,int)"), _A("A"), "A()")); + REQUIRE_THAT( + src, HasCall(_A("tmain(bool,int)"), _A("A"), + "operator+=(int)")); REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), + "add(int)")); REQUIRE_THAT(src, HasCall(_A("tmain(bool,int)"), _A("A"), + "operator=(const A &)")); REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), + "set(int)")); REQUIRE_THAT(src, HasCall(_A("tmain(bool,int)"), _A("A"), + "value()")); - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain(int)"), _A("magic()"), "")); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "create()")); - REQUIRE_THAT( - src, HasCall(_A("tmain(int)"), _A("A"), "operator+=(int)")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "add(int)")); + { + auto j = generate_sequence_json(diagram, *model); - REQUIRE_THAT(src, HasCall(_A("tmain(bool,int)"), _A("A"), "A()")); - REQUIRE_THAT( - src, HasCall(_A("tmain(bool,int)"), _A("A"), "operator+=(int)")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "add(int)")); - REQUIRE_THAT(src, - HasCall(_A("tmain(bool,int)"), _A("A"), "operator=(const A &)")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "set(int)")); - REQUIRE_THAT(src, HasCall(_A("tmain(bool,int)"), _A("A"), "value()")); + using namespace json; - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + save_json(config.output_directory(), diagram->name + ".json", j); + } - { - auto j = generate_sequence_json(diagram, *model); + { + auto src = generate_sequence_mermaid(diagram, *model); - using namespace json; + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; - save_json(config.output_directory(), diagram->name + ".json", j); - } + REQUIRE_THAT(src, HasCall(_A("tmain(int)"), _A("magic()"), "")); - { - auto src = generate_sequence_mermaid(diagram, *model); + REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "create()")); + REQUIRE_THAT( + src, HasCall(_A("tmain(int)"), _A("A"), "operator+=(int)")); + REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "add(int)")); - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; + REQUIRE_THAT(src, HasCall(_A("tmain(bool,int)"), _A("A"), "A()")); + REQUIRE_THAT( + src, HasCall(_A("tmain(bool,int)"), _A("A"), + "operator+=(int)")); REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), + "add(int)")); REQUIRE_THAT(src, HasCall(_A("tmain(bool,int)"), _A("A"), + "operator=(const A &)")); REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), + "set(int)")); REQUIRE_THAT(src, HasCall(_A("tmain(bool,int)"), _A("A"), + "value()")); - REQUIRE_THAT(src, HasCall(_A("tmain(int)"), _A("magic()"), "")); - - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "create()")); - REQUIRE_THAT( - src, HasCall(_A("tmain(int)"), _A("A"), "operator+=(int)")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "add(int)")); - - REQUIRE_THAT(src, HasCall(_A("tmain(bool,int)"), _A("A"), "A()")); - REQUIRE_THAT( - src, HasCall(_A("tmain(bool,int)"), _A("A"), "operator+=(int)")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "add(int)")); - REQUIRE_THAT(src, - HasCall(_A("tmain(bool,int)"), _A("A"), "operator=(const A &)")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "set(int)")); - REQUIRE_THAT(src, HasCall(_A("tmain(bool,int)"), _A("A"), "value()")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t20031/test_case.h b/tests/t20031/test_case.h index f325cb53..4fd9c885 100644 --- a/tests/t20031/test_case.h +++ b/tests/t20031/test_case.h @@ -16,18 +16,23 @@ * limitations under the License. */ -TEST_CASE("t20031", "[test-case][sequence]") +TEST_CASE("t20031") { - auto [config, db] = load_config("t20031"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20031_sequence"]; - - REQUIRE(diagram->name == "t20031_sequence"); - - auto model = generate_sequence_diagram(*db, diagram); - - REQUIRE(model->name() == "t20031_sequence"); + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20031", "t20031_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain(int)", "magic()", ""}, // + {"tmain(bool,int)", "execute(std::function)", ""}, // + {"tmain(bool,int)", "A", "value() const"} // + })); + }); +/* { auto src = generate_sequence_puml(diagram, *model); AliasMatcher _A(src); @@ -94,4 +99,5 @@ TEST_CASE("t20031", "[test-case][sequence]") save_mermaid(config.output_directory(), diagram->name + ".mmd", src); } -} \ No newline at end of file +*/ + } \ No newline at end of file diff --git a/tests/t20032/test_case.h b/tests/t20032/test_case.h index c056ed62..5a52d3ea 100644 --- a/tests/t20032/test_case.h +++ b/tests/t20032/test_case.h @@ -16,19 +16,34 @@ * limitations under the License. */ -TEST_CASE("t20032", "[test-case][sequence]") +TEST_CASE("t20032") { - auto [config, db] = load_config("t20032"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20032_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20032", "t20032_sequence"); - REQUIRE(diagram->name == "t20032_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain(int,char **)", "B", "b(int)"}, // + {"B", "A", "a1(int)"}, // + {"A", "B", "int", Response{}}, // + {"B", "tmain(int,char **)", "int", Response{}}, // - auto model = generate_sequence_diagram(*db, diagram); + {"tmain(int,char **)", "B", "b(double)"}, // + {"B", "A", "a2(double)"}, // + {"A", "B", "double", Response{}}, // + {"B", "tmain(int,char **)", "double", Response{}}, // - REQUIRE(model->name() == "t20032_sequence"); - - REQUIRE(model->name() == "t20032_sequence"); + {"tmain(int,char **)", "B", "b(const char *)"}, // + {"B", "A", "a3(const char *)"}, // + {"A", "B", "const char *", Response{}}, // + {"B", "tmain(int,char **)", "const char *", Response{}} // + })); + }); + /* { auto src = generate_sequence_puml(diagram, *model); AliasMatcher _A(src); @@ -100,5 +115,5 @@ TEST_CASE("t20032", "[test-case][sequence]") REQUIRE_THAT(src, HasResponse(_A("B"), _A("A"), "const char *")); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } \ No newline at end of file diff --git a/tests/t20033/test_case.h b/tests/t20033/test_case.h index f1f10c63..172f9076 100644 --- a/tests/t20033/test_case.h +++ b/tests/t20033/test_case.h @@ -16,60 +16,86 @@ * limitations under the License. */ -TEST_CASE("t20033", "[test-case][sequence]") +TEST_CASE("t20033") { - auto [config, db] = load_config("t20033"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20033_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20033", "t20033_sequence"); - REQUIRE(diagram->name == "t20033_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "A", "a1()"}, // + {"tmain()", "A", "a2()"}, // + {"tmain()", "A", "a2()", InControlCondition{}}, // + {"tmain()", "A", "a3()", InControlCondition{}}, // + {"tmain()", "A", "a3()"}, // + {"tmain()", "A", "a4()"}, // - auto model = generate_sequence_diagram(*db, diagram); + {"tmain()", "A", "a2()", InControlCondition{}}, // + {"tmain()", "A", "a3()"}, // - REQUIRE(model->name() == "t20033_sequence"); + {"tmain()", "A", "a2()", InControlCondition{}}, // + {"tmain()", "A", "a3()"}, // - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + {"tmain()", "A", "a3()"}, // - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + {"tmain()", "A", "a2()"}, // - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a1()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a2()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a3()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a4()")); + {"tmain()", "A", "a4()"}, // + {"tmain()", "A", "a3()", InControlCondition{}}, // - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + {"tmain()", "A", "a4()", InControlCondition{}}, // - { - auto j = generate_sequence_json(diagram, *model); + {"tmain()", "A", "a4()"} // + })); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - using namespace json; + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - save_json(config.output_directory(), diagram->name + ".json", j); - } + // Check if all calls exist + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a1()")); + REQUIRE_THAT( + src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a2()")); + REQUIRE_THAT( + src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a3()")); + REQUIRE_THAT( + src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a4()")); - { - auto src = generate_sequence_mermaid(diagram, *model); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - using mermaid::HasCallInControlCondition; + { + auto j = generate_sequence_json(diagram, *model); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a1()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a2()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a3()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a4()")); + using namespace json; - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_json(config.output_directory(), diagram->name + ".json", j); + } + + { + auto src = generate_sequence_mermaid(diagram, *model); + + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; + using mermaid::HasCallInControlCondition; + + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a1()")); + REQUIRE_THAT( + src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a2()")); + REQUIRE_THAT( + src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a3()")); + REQUIRE_THAT( + src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a4()")); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t20034/test_case.h b/tests/t20034/test_case.h index 26290368..49af0319 100644 --- a/tests/t20034/test_case.h +++ b/tests/t20034/test_case.h @@ -16,79 +16,127 @@ * limitations under the License. */ -TEST_CASE("t20034", "[test-case][sequence]") +TEST_CASE("t20034") { - auto [config, db] = load_config("t20034"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20034_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20034", "t20034_sequence"); - REQUIRE(diagram->name == "t20034_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageChainsOrder(src, + { + // + { + // + {Entrypoint{}, "D", "d2()"}, // + {"D", "C", "c2()"}, // + {"C", "B", "b2()"}, // + {"B", "A", "a2()"} // + }, // + { + // + {Entrypoint{}, "D", "d2()"}, // + {"D", "D::d2()::(lambda t20034.cc:56:18)", + "operator()() const"}, // + {"D::d2()::(lambda t20034.cc:56:18)", "A", "a2()"} // + }, // + { + // + {Entrypoint{}, "D", "d2()"}, // + {"D", "A", "a2()"} // + }, // + { + // + {Entrypoint{}, "D", "d2()"}, // + {"D", "C", "c4()"}, // + {"C", "B", "b4()"}, // + {"B", "B", "b2()"}, // + {"B", "A", "a2()"} // + }, // + { + // + {Entrypoint{}, "D", "d2()"}, // + {"D", "C", "c1()"}, // + {"C", "B", "b1()"}, // + {"B", "A", "a2()"} // + }, // + { + // + {Entrypoint{}, "D", "d2()"}, // + {"D", "C", "c3()"}, // + {"C", "C", "c2()"}, // + {"C", "B", "b2()"}, // + {"B", "A", "a2()"} // + } // + })); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - auto model = generate_sequence_diagram(*db, diagram); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE(model->name() == "t20034_sequence"); + // Check if all calls exist + REQUIRE_THAT(src, HasCall(_A("D"), _A("A"), "a2()")); - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + REQUIRE_THAT(src, HasCall(_A("D"), _A("C"), "c3()")); + REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "c2()")); + REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b2()")); + REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE_THAT(src, HasCall(_A("D"), _A("C"), "c4()")); - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("D"), _A("A"), "a2()")); + REQUIRE_THAT(src, !HasCall(_A("C"), _A("B"), "b3()")); - REQUIRE_THAT(src, HasCall(_A("D"), _A("C"), "c3()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "c2()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b2()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); + save_puml(config.output_directory(), diagram->name + + ".puml", src); + } - REQUIRE_THAT(src, HasCall(_A("D"), _A("C"), "c4()")); + { + auto j = generate_sequence_json(diagram, *model); - REQUIRE_THAT(src, !HasCall(_A("C"), _A("B"), "b3()")); + using namespace json; - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + REQUIRE(HasMessageChain(j, + {{"d2()", "c3()", "void"}, {"c3()", "c2()", "void"}, + {"c2()", "b2()", "void"}, {"b2()", "a2()", + "void"}})); REQUIRE(HasMessageChain(j, + {{"d2()", "c4()", "void"}, {"c4()", "b4()", "void"}, + {"b4()", "b2()", "void"}, {"b2()", "a2()", + "void"}})); REQUIRE(HasMessageChain(j, {{"d2()", "a2()", + "void"}})); REQUIRE(HasMessageChain(j, + {{"d2()", "c1()", "void"}, {"c1()", "b1()", "void"}, + {"b1()", "a2()", "void"}})); + REQUIRE(HasMessageChain(j, + {{"d2()", "c2()", "void"}, {"c2()", "b2()", "void"}, + {"b2()", "a2()", "void"}})); - { - auto j = generate_sequence_json(diagram, *model); + save_json(config.output_directory(), diagram->name + + ".json", j); + } - using namespace json; + { + auto src = generate_sequence_mermaid(diagram, *model); - REQUIRE(HasMessageChain(j, - {{"d2()", "c3()", "void"}, {"c3()", "c2()", "void"}, - {"c2()", "b2()", "void"}, {"b2()", "a2()", "void"}})); - REQUIRE(HasMessageChain(j, - {{"d2()", "c4()", "void"}, {"c4()", "b4()", "void"}, - {"b4()", "b2()", "void"}, {"b2()", "a2()", "void"}})); - REQUIRE(HasMessageChain(j, {{"d2()", "a2()", "void"}})); - REQUIRE(HasMessageChain(j, - {{"d2()", "c1()", "void"}, {"c1()", "b1()", "void"}, - {"b1()", "a2()", "void"}})); - REQUIRE(HasMessageChain(j, - {{"d2()", "c2()", "void"}, {"c2()", "b2()", "void"}, - {"b2()", "a2()", "void"}})); + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; - save_json(config.output_directory(), diagram->name + ".json", j); - } + REQUIRE_THAT(src, HasCall(_A("D"), _A("A"), "a2()")); - { - auto src = generate_sequence_mermaid(diagram, *model); + REQUIRE_THAT(src, HasCall(_A("D"), _A("C"), "c3()")); + REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "c2()")); + REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b2()")); + REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; + REQUIRE_THAT(src, HasCall(_A("D"), _A("C"), "c4()")); - REQUIRE_THAT(src, HasCall(_A("D"), _A("A"), "a2()")); + REQUIRE_THAT(src, !HasCall(_A("C"), _A("B"), "b3()")); - REQUIRE_THAT(src, HasCall(_A("D"), _A("C"), "c3()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "c2()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b2()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - - REQUIRE_THAT(src, HasCall(_A("D"), _A("C"), "c4()")); - - REQUIRE_THAT(src, !HasCall(_A("C"), _A("B"), "b3()")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + + ".mmd", src); + } + */ } \ No newline at end of file diff --git a/tests/t20035/test_case.h b/tests/t20035/test_case.h index 8213597d..d04ce96c 100644 --- a/tests/t20035/test_case.h +++ b/tests/t20035/test_case.h @@ -16,54 +16,62 @@ * limitations under the License. */ -TEST_CASE("t20035", "[test-case][sequence]") +TEST_CASE("t20035") { - auto [config, db] = load_config("t20035"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20035_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20035", "t20035_sequence"); - REQUIRE(diagram->name == "t20035_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageChainsOrder(src, + {{ + // + {"tmain(int,char **)", "a(int)", ""}, // + {"a(int)", "b1(int)", ""}, // + {"b1(int)", "c(int)", ""} // + }})); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - auto model = generate_sequence_diagram(*db, diagram); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE(model->name() == "t20035_sequence"); + REQUIRE_THAT(src, HasCall(_A("tmain(int,char **)"), _A("a(int)"), + "")); REQUIRE_THAT(src, HasCall(_A("a(int)"), _A("b1(int)"), "")); + REQUIRE_THAT(src, HasCall(_A("b1(int)"), _A("c(int)"), "")); - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + { + auto j = generate_sequence_json(diagram, *model); - REQUIRE_THAT(src, HasCall(_A("tmain(int,char **)"), _A("a(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("a(int)"), _A("b1(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("b1(int)"), _A("c(int)"), "")); + using namespace json; - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + REQUIRE(HasMessageChain(j, + {{"tmain(int,char **)", "a(int)", "int"}, + {"a(int)", "b1(int)", "int"}, {"b1(int)", "c(int)", + "int"}})); - { - auto j = generate_sequence_json(diagram, *model); + save_json(config.output_directory(), diagram->name + ".json", j); + } - using namespace json; + { + auto src = generate_sequence_mermaid(diagram, *model); - REQUIRE(HasMessageChain(j, - {{"tmain(int,char **)", "a(int)", "int"}, - {"a(int)", "b1(int)", "int"}, {"b1(int)", "c(int)", "int"}})); + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; - save_json(config.output_directory(), diagram->name + ".json", j); - } + REQUIRE_THAT(src, HasCall(_A("tmain(int,char **)"), _A("a(int)"), + "")); REQUIRE_THAT(src, HasCall(_A("a(int)"), _A("b1(int)"), "")); + REQUIRE_THAT(src, HasCall(_A("b1(int)"), _A("c(int)"), "")); - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("tmain(int,char **)"), _A("a(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("a(int)"), _A("b1(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("b1(int)"), _A("c(int)"), "")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + } + */ } \ No newline at end of file diff --git a/tests/t20036/test_case.h b/tests/t20036/test_case.h index f8da4cd2..27819a5a 100644 --- a/tests/t20036/test_case.h +++ b/tests/t20036/test_case.h @@ -16,78 +16,119 @@ * limitations under the License. */ -TEST_CASE("t20036", "[test-case][sequence]") +TEST_CASE("t20036") { - auto [config, db] = load_config("t20036"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20036_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20036", "t20036_sequence"); - REQUIRE(diagram->name == "t20036_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageChainsOrder(src, + { + // + { + // + {Entrypoint{}, "C", "c1()"}, // + {"C", "B", "b1()"}, // + {"B", "A", "a2()"}, // + }, // + { + // + {Entrypoint{}, "D", "d1()"}, // + {"D", "C", "c2()"}, // + {"C", "B", "b2()"}, // + {"B", "A", "a2()"}, // + }, // + { + // + {Entrypoint{}, "D", "d3()"}, // + {"D", "A", "a2()"}, // + }, // + { + // + {Entrypoint{}, "C", "c4()"}, // + {"C", "B", "b2()"}, // + {"B", "A", "a2()"}, // + }, // + { + // + {Entrypoint{}, "C", "c3()"}, // + {"C", "C", "c2()"}, // + {"C", "B", "b2()"}, // + {"B", "A", "a2()"}, // + }, // + { + // + {Entrypoint{}, "D", "d2()"}, // + {"D", "C", "c2()"}, // + {"C", "B", "b2()"}, // + {"B", "A", "a2()"}, // + }, // + })); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - auto model = generate_sequence_diagram(*db, diagram); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE(model->name() == "t20036_sequence"); + REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "c2()")); + REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b2()")); + REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b2()")); + REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE_THAT(src, HasCall(_A("D"), _A("A"), "a2()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "c2()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b2()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); + REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b1()")); + REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b2()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - REQUIRE_THAT(src, HasCall(_A("D"), _A("A"), "a2()")); + { + auto j = generate_sequence_json(diagram, *model); - REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b1()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); + using namespace json; - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + REQUIRE(HasMessageChain(j, + {{"c3()", "c2()", "void"}, {"c2()", "b2()", "void"}, + {"b2()", "a2()", "void"}})); + REQUIRE(HasMessageChain( + j, {{"c4()", "b2()", "void"}, {"b2()", "a2()", "void"}})); + REQUIRE(HasMessageChain(j, {{"d3()", "a2()", "void"}})); + REQUIRE(HasMessageChain(j, + {{"d1()", "c2()", "void"}, {"c2()", "b2()", "void"}, + {"b2()", "a2()", "void"}})); + REQUIRE(HasMessageChain( + j, {{"c1()", "b1()", "void"}, {"b1()", "a2()", "void"}})); - { - auto j = generate_sequence_json(diagram, *model); + save_json(config.output_directory(), diagram->name + ".json", j); + } - using namespace json; + { + auto src = generate_sequence_mermaid(diagram, *model); - REQUIRE(HasMessageChain(j, - {{"c3()", "c2()", "void"}, {"c2()", "b2()", "void"}, - {"b2()", "a2()", "void"}})); - REQUIRE(HasMessageChain( - j, {{"c4()", "b2()", "void"}, {"b2()", "a2()", "void"}})); - REQUIRE(HasMessageChain(j, {{"d3()", "a2()", "void"}})); - REQUIRE(HasMessageChain(j, - {{"d1()", "c2()", "void"}, {"c2()", "b2()", "void"}, - {"b2()", "a2()", "void"}})); - REQUIRE(HasMessageChain( - j, {{"c1()", "b1()", "void"}, {"b1()", "a2()", "void"}})); + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; - save_json(config.output_directory(), diagram->name + ".json", j); - } + REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "c2()")); + REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b2()")); + REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - { - auto src = generate_sequence_mermaid(diagram, *model); + REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b2()")); + REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; + REQUIRE_THAT(src, HasCall(_A("D"), _A("A"), "a2()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "c2()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b2()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); + REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b1()")); + REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b2()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - - REQUIRE_THAT(src, HasCall(_A("D"), _A("A"), "a2()")); - - REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b1()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t20037/test_case.h b/tests/t20037/test_case.h index 15f20df3..a5d6efbf 100644 --- a/tests/t20037/test_case.h +++ b/tests/t20037/test_case.h @@ -16,60 +16,76 @@ * limitations under the License. */ -TEST_CASE("t20037", "[test-case][sequence]") +TEST_CASE("t20037") { - auto [config, db] = load_config("t20037"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20037_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20037", "t20037_sequence"); - REQUIRE(diagram->name == "t20037_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain(int,char **)", "a()", ""}, // + {"a()", "A", "A()"}, // + {"a()", "initb()", ""}, // + {"a()", "B", "get()"}, // + {"a()", "c()", ""}, // - auto model = generate_sequence_diagram(*db, diagram); +// {"tmain(int,char **)", "a()", ""}, // +// {"a()", "B", "get()"}, // +// {"a()", "c()", ""}, // +// +// {"tmain(int,char **)", "a()", ""}, // +// {"a()", "B", "get()"}, // +// {"a()", "c()", ""} // + })); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE(model->name() == "t20037_sequence"); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + REQUIRE_THAT(src, HasCall(_A("tmain(int,char **)"), _A("a()"), "")); + REQUIRE_THAT(src, HasCall(_A("a()"), _A("initb()"), "")); + REQUIRE_THAT(src, HasCall(_A("a()"), _A("B"), "get()")); + REQUIRE_THAT(src, HasCall(_A("a()"), _A("c()"), "")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - REQUIRE_THAT(src, HasCall(_A("tmain(int,char **)"), _A("a()"), "")); - REQUIRE_THAT(src, HasCall(_A("a()"), _A("initb()"), "")); - REQUIRE_THAT(src, HasCall(_A("a()"), _A("B"), "get()")); - REQUIRE_THAT(src, HasCall(_A("a()"), _A("c()"), "")); + { + auto j = generate_sequence_json(diagram, *model); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + using namespace json; - { - auto j = generate_sequence_json(diagram, *model); + std::vector messages = { + FindMessage(j, "tmain(int,char **)", "a()", ""), + FindMessage(j, "a()", "initb()", ""), + FindMessage(j, "a()", "B", "get()"), + FindMessage(j, "a()", "c()", "")}; - using namespace json; + REQUIRE(std::is_sorted(messages.begin(), messages.end())); - std::vector messages = { - FindMessage(j, "tmain(int,char **)", "a()", ""), - FindMessage(j, "a()", "initb()", ""), - FindMessage(j, "a()", "B", "get()"), - FindMessage(j, "a()", "c()", "")}; + save_json(config.output_directory(), diagram->name + ".json", j); + } - REQUIRE(std::is_sorted(messages.begin(), messages.end())); + { + auto src = generate_sequence_mermaid(diagram, *model); - save_json(config.output_directory(), diagram->name + ".json", j); - } + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; - { - auto src = generate_sequence_mermaid(diagram, *model); + REQUIRE_THAT(src, HasCall(_A("tmain(int,char **)"), _A("a()"), "")); + REQUIRE_THAT(src, HasCall(_A("a()"), _A("initb()"), "")); + REQUIRE_THAT(src, HasCall(_A("a()"), _A("B"), "get()")); + REQUIRE_THAT(src, HasCall(_A("a()"), _A("c()"), "")); - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("tmain(int,char **)"), _A("a()"), "")); - REQUIRE_THAT(src, HasCall(_A("a()"), _A("initb()"), "")); - REQUIRE_THAT(src, HasCall(_A("a()"), _A("B"), "get()")); - REQUIRE_THAT(src, HasCall(_A("a()"), _A("c()"), "")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t20038/test_case.h b/tests/t20038/test_case.h index dc0c8be9..d5e9336c 100644 --- a/tests/t20038/test_case.h +++ b/tests/t20038/test_case.h @@ -16,110 +16,144 @@ * limitations under the License. */ -TEST_CASE("t20038", "[test-case][sequence]") +TEST_CASE("t20038") { - auto [config, db] = load_config("t20038"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20038_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20038", "t20038_sequence"); - REQUIRE(diagram->name == "t20038_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "B", "b()"}, // + {"B", "A", "a()"}, // + {"tmain()", "B", "b()"}, // + {"B", "A", "a()"}, // - auto model = generate_sequence_diagram(*db, diagram); + {"tmain()", "B", "bbb()"}, // + {"B", "A", "aaa()"}, // - REQUIRE(model->name() == "t20038_sequence"); + {"tmain()", "B", "bbbb()"}, // + {"B", "A", "aaaa()"}, // + {"A", "add(int,int)", ""}, // + {"add(int,int)", "add_impl(int,int)", ""}, // - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + {"tmain()", "B", "wrap(int)"}, // - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + {"tmain()", "add_impl(double,double)", ""}, // - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b()")); + {"tmain()", "B", "bbbbb()"}, // + {"B", "A", "aaaa()"}, // + {"A", "add(int,int)", ""}, // + {"add(int,int)", "add_impl(int,int)", ""}, // - REQUIRE_THAT(src, !HasCall(_A("tmain()"), _A("B"), "bb()")); + {"tmain()", "B", "bbb()", InControlCondition{}}, // + {"B", "A", "aaa()"}, // + })); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "bbb()")); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "bbbb()")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b()")); - REQUIRE_THAT(src, - HasMessageComment(_A("tmain()"), - "This comment should be rendered only\\n" - "once")); + REQUIRE_THAT(src, !HasCall(_A("tmain()"), _A("B"), "bb()")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("add_impl(double,double)"), "")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "bbb()")); - REQUIRE_THAT( - src, HasMessageComment(_A("tmain()"), "What is 2 \\+ 2\\?")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "bbbb()")); - REQUIRE_THAT(src, - !HasMessageComment( - _A("tmain()"), "This is specific for some_other_diagram")); + REQUIRE_THAT(src, + HasMessageComment(_A("tmain()"), + "This comment should be rendered only\\n" + "once")); - REQUIRE_THAT( - src, HasMessageComment(_A("tmain()"), "Calling B::bbbbb\\(\\)")); + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("add_impl(double,double)"), + "")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "bbbbb()")); + REQUIRE_THAT( + src, HasMessageComment(_A("tmain()"), "What is 2 \\+ 2\\?")); - REQUIRE_THAT(src, - HasMessageComment(_A("tmain()"), "This is a conditional operator")); + REQUIRE_THAT(src, + !HasMessageComment( + _A("tmain()"), "This is specific for some_other_diagram")); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + REQUIRE_THAT( + src, HasMessageComment(_A("tmain()"), "Calling + B::bbbbb\\(\\)")); - { - auto j = generate_sequence_json(diagram, *model); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "bbbbb()")); - using namespace json; + REQUIRE_THAT(src, + HasMessageComment(_A("tmain()"), "This is a conditional + operator")); - save_json(config.output_directory(), diagram->name + ".json", j); - } + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - { - auto src = generate_sequence_mermaid(diagram, *model); + { + auto j = generate_sequence_json(diagram, *model); - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - using mermaid::HasCallInControlCondition; - using mermaid::HasMessageComment; + using namespace json; - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b()")); + save_json(config.output_directory(), diagram->name + ".json", j); + } - REQUIRE_THAT(src, !HasCall(_A("tmain()"), _A("B"), "bb()")); + { + auto src = generate_sequence_mermaid(diagram, *model); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "bbb()")); + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; + using mermaid::HasCallInControlCondition; + using mermaid::HasMessageComment; - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "bbbb()")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b()")); - REQUIRE_THAT(src, - HasMessageComment(_A("tmain()"), - "This comment should be rendered only
" - "once")); + REQUIRE_THAT(src, !HasCall(_A("tmain()"), _A("B"), "bb()")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("add_impl(double,double)"), "")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "bbb()")); - REQUIRE_THAT( - src, HasMessageComment(_A("tmain()"), "What is 2 \\+ 2\\?")); + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "bbbb()")); - REQUIRE_THAT(src, - !HasMessageComment( - _A("tmain()"), "This is specific for some_other_diagram")); + REQUIRE_THAT(src, + HasMessageComment(_A("tmain()"), + "This comment should be rendered only
" + "once")); - REQUIRE_THAT( - src, HasMessageComment(_A("tmain()"), "Calling B::bbbbb\\(\\)")); + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("add_impl(double,double)"), + "")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "bbbbb()")); + REQUIRE_THAT( + src, HasMessageComment(_A("tmain()"), "What is 2 \\+ 2\\?")); - REQUIRE_THAT(src, - !HasMessageComment( - _A("tmain()"), "This is specific for some_other_diagram")); + REQUIRE_THAT(src, + !HasMessageComment( + _A("tmain()"), "This is specific for some_other_diagram")); - REQUIRE_THAT( - src, HasMessageComment(_A("tmain()"), "Calling B::bbbbb\\(\\)")); + REQUIRE_THAT( + src, HasMessageComment(_A("tmain()"), "Calling + B::bbbbb\\(\\)")); - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "bbbbb()")); + + REQUIRE_THAT(src, + !HasMessageComment( + _A("tmain()"), "This is specific for some_other_diagram")); + + REQUIRE_THAT( + src, HasMessageComment(_A("tmain()"), "Calling + B::bbbbb\\(\\)")); + + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + } + */ } \ No newline at end of file diff --git a/tests/t20039/test_case.h b/tests/t20039/test_case.h index 316d20e0..628bef51 100644 --- a/tests/t20039/test_case.h +++ b/tests/t20039/test_case.h @@ -16,18 +16,26 @@ * limitations under the License. */ -TEST_CASE("t20039", "[test-case][sequence]") +TEST_CASE("t20039") { - auto [config, db] = load_config("t20039"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20039_sequence"]; - - REQUIRE(diagram->name == "t20039_sequence"); - - auto model = generate_sequence_diagram(*db, diagram); - - REQUIRE(model->name() == "t20039_sequence"); + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20039", "t20039_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "R", "run()"}, // + {"R", "A", "a(int)"}, // + {"R", "A", "a(int_vec_t)"}, // + {"R", "A", "a(string_vec_t)"}, // + {"R", "A", "a(int_map_t)"}, // + {"R", "A", "a(string_map_t)"} // + })); + }); +/* { auto src = generate_sequence_puml(diagram, *model); AliasMatcher _A(src); @@ -72,5 +80,5 @@ TEST_CASE("t20039", "[test-case][sequence]") src, HasCall(_A("R"), _A("A"), "a(string_map_t)")); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } \ No newline at end of file diff --git a/tests/t20040/test_case.h b/tests/t20040/test_case.h index 9ff98228..a9297bbd 100644 --- a/tests/t20040/test_case.h +++ b/tests/t20040/test_case.h @@ -16,74 +16,95 @@ * limitations under the License. */ -TEST_CASE("t20040", "[test-case][sequence]") +TEST_CASE("t20040") { - auto [config, db] = load_config("t20040"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20040_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20040", "t20040_sequence"); - REQUIRE(diagram->name == "t20040_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", + "print(int,double,std::string)", + ""}, // + {"print(int,double,std::string)", + "print(double,std::string)", ""}, // + {"print(double,std::string)", + "print(std::string)", ""}, // + {"print(std::string)", "print()", ""}, // - auto model = generate_sequence_diagram(*db, diagram); + {"tmain()", "doublePrint(std::string,int)", + ""}, // + {"doublePrint(std::string,int)", + "print(std::string,int)", ""}, // + {"print(std::string,int)", "print(int)", + ""}, // + {"print(int)", "print()", ""}, // + })); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE(model->name() == "t20040_sequence"); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + REQUIRE_THAT(src, + HasCall(_A("tmain()"), + _A("print(int,double,std::string)"), + "")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + REQUIRE_THAT(src, + HasCall(_A("print(int,double,std::string)"), + _A("print(double,std::string)"), "")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), - _A("print(int,double,std::string)"), - "")); + REQUIRE_THAT(src, + HasCall(_A("print(double,std::string)"), + _A("print(std::string)"), "")); - REQUIRE_THAT(src, - HasCall(_A("print(int,double,std::string)"), - _A("print(double,std::string)"), "")); + REQUIRE_THAT(src, + HasCall(_A("print(std::string)"), _A("print()"), + "")); - REQUIRE_THAT(src, - HasCall(_A("print(double,std::string)"), - _A("print(std::string)"), "")); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - REQUIRE_THAT(src, - HasCall(_A("print(std::string)"), _A("print()"), "")); + { + auto j = generate_sequence_json(diagram, *model); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + using namespace json; - { - auto j = generate_sequence_json(diagram, *model); + save_json(config.output_directory(), diagram->name + ".json", j); + } - using namespace json; + { + auto src = generate_sequence_mermaid(diagram, *model); - save_json(config.output_directory(), diagram->name + ".json", j); - } + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; - { - auto src = generate_sequence_mermaid(diagram, *model); + REQUIRE_THAT(src, + HasCall(_A("tmain()"), + _A("print(int,double,std::string)"), + "")); - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; + REQUIRE_THAT(src, + HasCall(_A("print(int,double,std::string)"), + _A("print(double,std::string)"), "")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), - _A("print(int,double,std::string)"), - "")); + REQUIRE_THAT(src, + HasCall(_A("print(double,std::string)"), + _A("print(std::string)"), "")); - REQUIRE_THAT(src, - HasCall(_A("print(int,double,std::string)"), - _A("print(double,std::string)"), "")); + REQUIRE_THAT(src, + HasCall(_A("print(std::string)"), _A("print()"), + "")); - REQUIRE_THAT(src, - HasCall(_A("print(double,std::string)"), - _A("print(std::string)"), "")); - - REQUIRE_THAT(src, - HasCall(_A("print(std::string)"), _A("print()"), "")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t20041/test_case.h b/tests/t20041/test_case.h index c3198068..7e8bb3ed 100644 --- a/tests/t20041/test_case.h +++ b/tests/t20041/test_case.h @@ -16,74 +16,84 @@ * limitations under the License. */ -TEST_CASE("t20041", "[test-case][sequence]") +TEST_CASE("t20041") { - auto [config, db] = load_config("t20041"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20041_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20041", "t20041_sequence"); - REQUIRE(diagram->name == "t20041_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "A", + "print(int,double,std::string)"}, // + {"A", "A", + "print(double,std::string)"}, // + {"A", "A", + "print(std::string)"}, // + {"A", "A", "print()"}, // + })); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - auto model = generate_sequence_diagram(*db, diagram); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - REQUIRE(model->name() == "t20041_sequence"); + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("A"), + "print(int,double,std::string)")); + REQUIRE_THAT(src, + HasCall(_A("A"), + _A("A"), "print(double,std::string)")); + REQUIRE_THAT(src, + HasCall(_A("A"), _A("A"), + "print(std::string)")); + REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), + "print()")); - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + { + auto j = generate_sequence_json(diagram, *model); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("A"), - "print(int,double,std::string)")); - REQUIRE_THAT(src, - HasCall(_A("A"), - _A("A"), "print(double,std::string)")); - REQUIRE_THAT(src, - HasCall(_A("A"), _A("A"), - "print(std::string)")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "print()")); + using namespace json; - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + std::vector messages = { + FindMessage(j, "tmain()", "A", + "print(int,double,std::string)"), + FindMessage(j, "A", + "A", "print(double,std::string)"), FindMessage(j, + "A", "A", "print(std::string)"), + FindMessage(j, "A", "A", "print()")}; - { - auto j = generate_sequence_json(diagram, *model); + REQUIRE(std::is_sorted(messages.begin(), messages.end())); - using namespace json; + save_json(config.output_directory(), diagram->name + ".json", j); + } - std::vector messages = { - FindMessage(j, "tmain()", "A", - "print(int,double,std::string)"), - FindMessage(j, "A", "A", - "print(double,std::string)"), - FindMessage(j, "A", "A", - "print(std::string)"), - FindMessage(j, "A", "A", "print()")}; + { + auto src = generate_sequence_mermaid(diagram, *model); - REQUIRE(std::is_sorted(messages.begin(), messages.end())); + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; - save_json(config.output_directory(), diagram->name + ".json", j); - } + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("A"), + "print(int,double,std::string)")); + REQUIRE_THAT(src, + HasCall(_A("A"), + _A("A"), "print(double,std::string)")); + REQUIRE_THAT(src, + HasCall(_A("A"), _A("A"), + "print(std::string)")); - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("A"), - "print(int,double,std::string)")); - REQUIRE_THAT(src, - HasCall(_A("A"), - _A("A"), "print(double,std::string)")); - REQUIRE_THAT(src, - HasCall(_A("A"), _A("A"), - "print(std::string)")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t20042/test_case.h b/tests/t20042/test_case.h index 3e2276d8..31db9cc9 100644 --- a/tests/t20042/test_case.h +++ b/tests/t20042/test_case.h @@ -16,60 +16,64 @@ * limitations under the License. */ -TEST_CASE("t20042", "[test-case][sequence]") +TEST_CASE("t20042") { - auto [config, db] = load_config("t20042"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20042_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20042", "t20042_sequence"); - REQUIRE(diagram->name == "t20042_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "AHandler", "operator()(A &) const"}, // + {"AHandler", "AHandler", "handle(A &) const"}, // - auto model = generate_sequence_diagram(*db, diagram); + {"tmain()", "BHandler", "operator()(B &) const"}, // + {"BHandler", "BHandler", "handle(B &) const"}, // + })); + }); + /* + { + auto src = generate_sequence_puml(diagram, *model); + AliasMatcher _A(src); - REQUIRE(model->name() == "t20042_sequence"); + REQUIRE_THAT(src, StartsWith("@startuml")); + REQUIRE_THAT(src, EndsWith("@enduml\n")); - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("AHandler"), "operator()(A &) + const")); REQUIRE_THAT( src, HasCall(_A("AHandler"), _A("AHandler"), + "handle(A &) const")); REQUIRE_THAT(src, HasCall(_A("tmain()"), + _A("BHandler"), "operator()(B &) const")); REQUIRE_THAT( src, + HasCall(_A("BHandler"), _A("BHandler"), "handle(B &) const")); - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + save_puml(config.output_directory(), diagram->name + ".puml", src); + } - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("AHandler"), "operator()(A &) const")); - REQUIRE_THAT( - src, HasCall(_A("AHandler"), _A("AHandler"), "handle(A &) const")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("BHandler"), "operator()(B &) const")); - REQUIRE_THAT( - src, HasCall(_A("BHandler"), _A("BHandler"), "handle(B &) const")); + { + auto j = generate_sequence_json(diagram, *model); - save_puml(config.output_directory(), diagram->name + ".puml", src); - } + using namespace json; - { - auto j = generate_sequence_json(diagram, *model); + save_json(config.output_directory(), diagram->name + ".json", j); + } - using namespace json; + { + auto src = generate_sequence_mermaid(diagram, *model); - save_json(config.output_directory(), diagram->name + ".json", j); - } + mermaid::SequenceDiagramAliasMatcher _A(src); + using mermaid::HasCall; - { - auto src = generate_sequence_mermaid(diagram, *model); + REQUIRE_THAT(src, + HasCall(_A("tmain()"), _A("AHandler"), "operator()(A &) + const")); REQUIRE_THAT( src, HasCall(_A("AHandler"), _A("AHandler"), + "handle(A &) const")); REQUIRE_THAT(src, HasCall(_A("tmain()"), + _A("BHandler"), "operator()(B &) const")); REQUIRE_THAT( src, + HasCall(_A("BHandler"), _A("BHandler"), "handle(B &) const")); - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("AHandler"), "operator()(A &) const")); - REQUIRE_THAT( - src, HasCall(_A("AHandler"), _A("AHandler"), "handle(A &) const")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("BHandler"), "operator()(B &) const")); - REQUIRE_THAT( - src, HasCall(_A("BHandler"), _A("BHandler"), "handle(B &) const")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + save_mermaid(config.output_directory(), diagram->name + ".mmd", + src); + }*/ } \ No newline at end of file diff --git a/tests/t20043/test_case.h b/tests/t20043/test_case.h index 84c0a4e9..6a17feb1 100644 --- a/tests/t20043/test_case.h +++ b/tests/t20043/test_case.h @@ -16,18 +16,28 @@ * limitations under the License. */ -TEST_CASE("t20043", "[test-case][sequence]") +TEST_CASE("t20043") { - auto [config, db] = load_config("t20043"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20043_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20043", "t20043_sequence"); - REQUIRE(diagram->name == "t20043_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "D", "d()"}, // + {"D", "C", "c()"}, // + })); - auto model = generate_sequence_diagram(*db, diagram); - - REQUIRE(model->name() == "t20043_sequence"); + REQUIRE(!HasMessage(src, {"tmain()", "F", "f()"})); + REQUIRE(!HasMessage(src, {"D", {"detail", "E"}, "e()"})); + REQUIRE(!HasMessage(src, {"C", "B", "b()"})); + REQUIRE(!HasMessage(src, {"B", "A", "a()"})); + }); +/* { auto src = generate_sequence_puml(diagram, *model); AliasMatcher _A(src); @@ -69,5 +79,5 @@ TEST_CASE("t20043", "[test-case][sequence]") REQUIRE_THAT(src, !HasCall(_A("B"), _A("A"), "a()")); save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } \ No newline at end of file diff --git a/tests/t20044/test_case.h b/tests/t20044/test_case.h index 3ff700b3..8ff25df6 100644 --- a/tests/t20044/test_case.h +++ b/tests/t20044/test_case.h @@ -16,18 +16,47 @@ * limitations under the License. */ -TEST_CASE("t20044", "[test-case][sequence]") +TEST_CASE("t20044") { - auto [config, db] = load_config("t20044"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20044_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20044", "t20044_sequence"); - REQUIRE(diagram->name == "t20044_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "R", "R((lambda at t20044.cc:74:9) &&)"}, // + {"R", "tmain()::(lambda t20044.cc:74:9)", + "operator()() const"}, // + {"tmain()::(lambda t20044.cc:74:9)", "A", "a() const"}, // - auto model = generate_sequence_diagram(*db, diagram); + {"tmain()", "tmain()::(lambda t20044.cc:84:18)", + "operator()() const"}, // + {"tmain()::(lambda t20044.cc:84:18)", "A", "a5()"}, // - REQUIRE(model->name() == "t20044_sequence"); + {"tmain()", "A", "a1() const"}, // + {"A", "detail::expected", "expected(int)"}, // + {"tmain()", "detail::expected", + "and_then((lambda at t20044.cc:90:19) &&)"}, // + {"detail::expected", + "tmain()::(lambda t20044.cc:90:19)", + "operator()(auto &&) const"}, // + {"tmain()::(lambda t20044.cc:90:19)", "A", "a2(int) const"}, // + {"A", "detail::expected", "expected(int)"}, // + + {"tmain()", "detail::expected", + "and_then(result_t (&)(int))"}, // // + {"tmain()", "detail::expected", + "and_then(std::function &)"}, // // + {"tmain()", "detail::expected", + "value() const"}, // // + + })); + }); +/* { auto src = generate_sequence_puml(diagram, *model); AliasMatcher _A(src); @@ -88,5 +117,5 @@ TEST_CASE("t20044", "[test-case][sequence]") using mermaid::IsClass; save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + }*/ } \ No newline at end of file diff --git a/tests/t20045/test_case.h b/tests/t20045/test_case.h index 5d8d7775..fe49289e 100644 --- a/tests/t20045/test_case.h +++ b/tests/t20045/test_case.h @@ -16,18 +16,25 @@ * limitations under the License. */ -TEST_CASE("t20045", "[test-case][sequence]") +TEST_CASE("t20045") { - auto [config, db] = load_config("t20045"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20045_sequence"]; - - REQUIRE(diagram->name == "t20045_sequence"); - - auto model = generate_sequence_diagram(*db, diagram); - - REQUIRE(model->name() == "t20045_sequence"); + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20045", "t20045_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "a2(int)", ""}, // + {"tmain()", + "a1<(lambda at t20045.cc:35:18)>((lambda at " + "t20045.cc:35:18) &&)", + ""}, // + })); + }); +/* { auto src = generate_sequence_puml(diagram, *model); AliasMatcher _A(src); @@ -80,4 +87,5 @@ TEST_CASE("t20045", "[test-case][sequence]") save_mermaid(config.output_directory(), diagram->name + ".mmd", src); } + */ } \ No newline at end of file diff --git a/tests/test_cases.cc b/tests/test_cases.cc index e235089b..fef05561 100644 --- a/tests/test_cases.cc +++ b/tests/test_cases.cc @@ -387,8 +387,7 @@ void try_run_test_case(const diagram_source_storage &diagrams, TC &&tc) std::cout << "-----------------------------------------------------" "--------------------------\n"; std::cout << "Test case failed for diagram type " - << T::diagram_type_name << ": " - << "\n\n"; + << T::diagram_type_name << ": " << "\n\n"; std::cout << diagrams.get().to_string() << "\n"; throw e; @@ -591,7 +590,6 @@ void CHECK_INCLUDE_DIAGRAM(const clanguml::config::config &config, save_mermaid(config.output_directory(), diagram->name + ".mmd", diagram_sources.mermaid.src); } - } // namespace clanguml::test /* @@ -1174,7 +1172,7 @@ template <> bool IsClass(json_t d, std::string name) #include "t00074/test_case.h" #include "t00075/test_case.h" #endif -/* + /// /// Sequence diagram tests /// @@ -1188,6 +1186,7 @@ template <> bool IsClass(json_t d, std::string name) #include "t20005/test_case.h" #endif #include "t20006/test_case.h" + #include "t20007/test_case.h" #include "t20008/test_case.h" #include "t20009/test_case.h" @@ -1222,11 +1221,13 @@ template <> bool IsClass(json_t d, std::string name) #include "t20038/test_case.h" #include "t20039/test_case.h" #include "t20040/test_case.h" + #include "t20041/test_case.h" #include "t20042/test_case.h" #include "t20043/test_case.h" #include "t20044/test_case.h" #include "t20045/test_case.h" +/* #include "t20046/test_case.h" #include "t20047/test_case.h" #include "t20048/test_case.h" diff --git a/tests/test_cases.h b/tests/test_cases.h index 06f0d65f..b85defb3 100644 --- a/tests/test_cases.h +++ b/tests/test_cases.h @@ -84,6 +84,12 @@ struct Default { }; struct Deleted { }; +struct Entrypoint { }; + +struct Exitpoint { }; + +struct InControlCondition { }; +struct Response { }; struct NamespacePackage { }; struct ModulePackage { }; struct DirectoryPackage { }; @@ -123,6 +129,8 @@ template struct diagram_source_t { bool search(const std::string &pattern) const; + int64_t find(const std::string &pattern, int64_t offset = 0) const; + std::string to_string() const; T src; @@ -189,7 +197,7 @@ struct mermaid_t : public diagram_source_t { inline static const std::string diagram_type_name{"MermaidJS"}; - std::string get_alias(std::string name) const override + std::string get_alias_impl(std::string name) const { std::vector patterns; @@ -224,6 +232,44 @@ struct mermaid_t : public diagram_source_t { return fmt::format("__INVALID__ALIAS__({})", name); } + + std::string get_alias_sequence_diagram_impl(std::string name) const + { + std::vector patterns; + + const std::string alias_regex("([A-Z]_[0-9]+)"); + + util::replace_all(name, "(", "\\("); + util::replace_all(name, ")", "\\)"); + util::replace_all(name, " ", "\\s"); + util::replace_all(name, "*", "\\*"); + util::replace_all(name, "[", "\\["); + util::replace_all(name, "]", "\\]"); + + patterns.push_back( + std::regex{"participant\\s" + alias_regex + "\\sas\\s" + name+"\\n"}); + + std::smatch base_match; + + for (const auto &pattern : patterns) { + if (std::regex_search(src, base_match, pattern) && + base_match.size() == 2) { + std::ssub_match base_sub_match = base_match[1]; + std::string alias = base_sub_match.str(); + return trim(alias); + } + } + + return fmt::format("__INVALID__ALIAS__({})", name); + } + + std::string get_alias(std::string name) const override + { + if (diagram_type == common::model::diagram_t::kSequence) + return get_alias_sequence_diagram_impl(name); + + return get_alias_impl(name); + } }; struct json_t : public diagram_source_t { @@ -338,12 +384,26 @@ template <> bool diagram_source_t::contains(std::string name) const } template <> -bool diagram_source_t::search(const std::string &pattern) const +int64_t diagram_source_t::find( + const std::string &pattern, int64_t offset) const { std::regex pattern_regex{pattern}; std::smatch base_match; - return std::regex_search(src, base_match, pattern_regex); + auto offset_it = src.begin(); + std::advance(offset_it, offset); + bool found = + std::regex_search(offset_it, src.end(), base_match, pattern_regex); + if (!found) + return -1; + + return base_match.position(0); +} + +template <> +bool diagram_source_t::search(const std::string &pattern) const +{ + return find(pattern) > -1; } template <> @@ -399,6 +459,46 @@ struct QualifiedName { std::string name; }; +struct Message { + template + Message(QualifiedName f, QualifiedName t, std::string m, Attrs &&...attrs) + : from{std::move(f)} + , to{std::move(t)} + , message{std::move(m)} + , is_static{has_type()} + , is_incontrolcondition{has_type()} + , is_response{has_type()} + { + } + + template + Message(Entrypoint &&e, QualifiedName t, std::string m, Attrs &&...attrs) + : Message(QualifiedName{""}, std::move(t), {}, + std::forward(attrs)...) + { + is_entrypoint = true; + } + + template + Message(Exitpoint &&e, QualifiedName t, Attrs &&...attrs) + : Message(QualifiedName{""}, std::move(t), {}, + std::forward(attrs)...) + { + is_exitpoint = true; + } + + QualifiedName from; + QualifiedName to; + std::string message; + std::optional return_type; + + bool is_static{false}; + bool is_entrypoint{false}; + bool is_exitpoint{false}; + bool is_incontrolcondition{false}; + bool is_response{false}; +}; + /// /// The following functions declarations define various checks on generated /// diagrams. @@ -574,6 +674,80 @@ bool IsModulePackage(const DiagramType &d, Args... args); template bool IsDeprecated(const DiagramType &d, std::string const &str); +template +int64_t FindMessage(const DiagramType &d, const Message &msg, + int64_t offset = 0, bool fail = true); + +template +bool HasMessage(const DiagramType &d, const Message &msg) +{ + return FindMessage(d, msg, 0, false) >= 0; +} + +template +bool MessageOrder(const DiagramType &d, std::vector messages) +{ + std::vector order; + int64_t offset{0}; + order.reserve(messages.size()); + std::transform(messages.begin(), messages.end(), std::back_inserter(order), + [&d, &offset](const auto &m) { + offset = FindMessage(d, m, offset); + return offset; + }); + bool are_messages_in_order = std::is_sorted(order.begin(), order.end()); + + if (!are_messages_in_order) { + FAIL(fmt::format( + "Messages are not in order: \n[{}]", fmt::join(order, ",\n"))); + return false; + } + + return true; +} + +template +bool MessageChainsOrder( + const DiagramType &d, std::vector> message_chains) +{ + std::vector flattenned; + for (const auto &mc : message_chains) { + for (const auto &m : mc) + flattenned.emplace_back(m); + } + + return MessageOrder(d, std::move(flattenned)); +} + +template +bool IsParticipant( + const DiagramType &d, const std::string &name, const std::string &type); + +template +bool IsFunctionParticipant(const DiagramType &d, const std::string &name) +{ + return IsParticipant(d, name, "function"); +} + +template +bool IsFunctionTemplateParticipant( + const DiagramType &d, const std::string &name) +{ + return IsParticipant(d, name, "function_template"); +} + +template +bool IsClassParticipant(const DiagramType &d, const std::string &name) +{ + return IsParticipant(d, name, "class"); +} + +template +bool IsFileParticipant(const DiagramType &d, const std::string &name) +{ + return IsParticipant(d, name, "file"); +} + /// /// @} /// @@ -912,14 +1086,6 @@ bool HasNote(const plantuml_t &d, std::string const &cls, return d.contains(fmt::format("note {} of {}", position, d.get_alias(cls))); } -template <> -bool HasMessageComment(const plantuml_t &d, std::string const &participant, - std::string const ¬e) -{ - return d.contains(std::string("note over ") + d.get_alias(participant) + - "\\n" + note + "\\n" + "end note"); -} - template <> bool HasMemberNote(const plantuml_t &d, std::string const &cls, std::string const &member, std::string const &position, @@ -1019,6 +1185,81 @@ template <> bool IsDeprecated(const plantuml_t &d, const std::string &name) return d.contains(d.get_alias(name) + " <> "); } +template <> +int64_t FindMessage( + const plantuml_t &d, const Message &msg, int64_t offset, bool fail) +{ + auto msg_str = msg.message; + util::replace_all(msg_str, "(", "\\("); + util::replace_all(msg_str, ")", "\\)"); + util::replace_all(msg_str, "*", "\\*"); + util::replace_all(msg_str, "[", "\\["); + util::replace_all(msg_str, "]", "\\]"); + util::replace_all(msg_str, "+", "\\+"); + + std::string style; + if (msg.is_static) + style = "__"; + + std::string call_pattern{"__INVALID__"}; + + if (msg.is_entrypoint) { + call_pattern = + fmt::format("\\[-> {} : {}", d.get_alias(msg.to), msg_str); + } + else if (msg.is_exitpoint) { + call_pattern = fmt::format("\\[<-- {}", d.get_alias(msg.to)); + } + else if (msg.is_incontrolcondition) { + call_pattern = fmt::format( + "{} {} {} " + "(\\[\\[.*\\]\\] )?: \\*\\*\\[\\*\\*{}{}{}\\*\\*\\]\\*\\*", + d.get_alias(msg.from), "->", d.get_alias(msg.to), style, msg_str, + style); + } + else if (msg.is_response) { + call_pattern = fmt::format("{} {} {} : //{}//", d.get_alias(msg.from), + "-->", d.get_alias(msg.to), msg_str); + } + else { + call_pattern = fmt::format("{} {} {} " + "(\\[\\[.*\\]\\] )?: {}{}{}", + d.get_alias(msg.from), "->", d.get_alias(msg.to), style, msg_str, + style); + } + + auto match_offset = d.find(call_pattern, offset); + + if (match_offset < 0) { + if (fail) + FAIL(fmt::format("Missing message: {} -> {} {} ({})", + msg.from.str(), msg.to.str(), msg.message, call_pattern)); + return -1; + } + + return match_offset + offset; +} + +template <> +bool HasMessageComment(const plantuml_t &d, std::string const &participant, + std::string const ¬e) +{ + std::string note_escaped{note}; + util::replace_all(note_escaped, "(", "\\("); + util::replace_all(note_escaped, ")", "\\)"); + + return d.search(fmt::format("note over {}\\n{}\\nend note", + d.get_alias(participant), note_escaped)); +} + +template <> +bool IsParticipant( + const plantuml_t &d, const std::string &name, const std::string &type) +{ + return d.contains( + fmt::format("participant \"{}\" as ", name, d.get_alias(name))); +} + // // MermaidJS test helpers // @@ -1052,7 +1293,6 @@ template <> bool IsClassTemplate(const mermaid_t &d, QualifiedName cls) template <> bool IsAbstractClassTemplate(const mermaid_t &d, QualifiedName cls) { - // return d.contains(fmt::format("class {}", d.get_alias(cls))); return d.search( std::string("class ") + d.get_alias(cls) + " \\{\\n\\s+<>"); } @@ -1367,8 +1607,6 @@ bool IsConceptRequirement( { util::replace_all(requirement, "<", "<"); util::replace_all(requirement, ">", ">"); - // util::replace_all(requirement, "(", "("); - // util::replace_all(requirement, ")", ")"); util::replace_all(requirement, "##", "::"); util::replace_all(requirement, "{", "{"); util::replace_all(requirement, "}", "}"); @@ -1382,8 +1620,6 @@ bool IsConceptParameterList( { util::replace_all(params, "<", "<"); util::replace_all(params, ">", ">"); - // util::replace_all(requirement, "(", "("); - // util::replace_all(requirement, ")", ")"); util::replace_all(params, "##", "::"); util::replace_all(params, "{", "{"); util::replace_all(params, "}", "}"); @@ -1414,14 +1650,6 @@ bool HasNote(const mermaid_t &d, std::string const &cls, return d.contains(fmt::format("note for {}", d.get_alias(cls))); } -template <> -bool HasMessageComment( - const mermaid_t &d, std::string const &participant, std::string const ¬e) -{ - return d.contains( - std::string("note over ") + d.get_alias(participant) + ": " + note); -} - template <> bool HasMemberNote(const mermaid_t &d, std::string const &cls, std::string const &member, std::string const &position, @@ -1509,6 +1737,71 @@ template <> bool IsDeprecated(const mermaid_t &d, const std::string &name) return d.contains(d.get_alias(name)); } +template <> +int64_t FindMessage( + const mermaid_t &d, const Message &msg, int64_t offset, bool fail) +{ + auto msg_str = msg.message; + + util::replace_all(msg_str, "(", "\\("); + util::replace_all(msg_str, ")", "\\)"); + util::replace_all(msg_str, "*", "\\*"); + util::replace_all(msg_str, "[", "\\["); + util::replace_all(msg_str, "]", "\\]"); + util::replace_all(msg_str, "+", "\\+"); + + std::string call_pattern{"__INVALID__"}; + + if (msg.is_entrypoint) { + call_pattern = + fmt::format("\\* ->> {} : {}", d.get_alias(msg.to), msg_str); + } + else if (msg.is_exitpoint) { + call_pattern = fmt::format("{} -->> \\*", d.get_alias(msg.to), msg_str); + } + else if (msg.is_incontrolcondition) { + call_pattern = fmt::format("{} {} {} : \\[{}\\]", d.get_alias(msg.from), + "->>", d.get_alias(msg.to), msg_str); + } + else if (msg.is_response) { + call_pattern = fmt::format("{} {} {} : {}", d.get_alias(msg.from), + "-->>", d.get_alias(msg.to), msg_str); + } + else { + call_pattern = fmt::format("{} {} {} : {}", d.get_alias(msg.from), + "->>", d.get_alias(msg.to), msg_str); + } + + auto match_offset = d.find(call_pattern, offset); + + if (match_offset < 0) { + if (fail) + FAIL(fmt::format("Missing message: {} -> {} {} ({})", + msg.from.str(), msg.to.str(), msg.message, call_pattern)); + return -1; + } + + return match_offset + offset; +} + +template <> +bool HasMessageComment( + const mermaid_t &d, std::string const &participant, std::string const ¬e) +{ + std::string note_escaped{note}; + util::replace_all(note_escaped, "\\n", "
"); + + return d.contains(std::string("note over ") + d.get_alias(participant) + + ": " + note_escaped); +} + +template <> +bool IsParticipant( + const mermaid_t &d, const std::string &name, const std::string &type) +{ + return d.contains(fmt::format("participant {}", d.get_alias(name))); +} + // // JSON test helpers // @@ -1910,13 +2203,6 @@ bool HasPackageNote(const json_t &d, std::string const &cls, return true; } -template <> -bool HasMessageComment( - const json_t &d, std::string const &alias, std::string const ¬e) -{ - return true; -} - template <> bool HasMemberNote(const json_t &d, std::string const &cls, std::string const &member, std::string const &position, @@ -2044,6 +2330,207 @@ template <> bool IsDeprecated(const json_t &d, const std::string &name) auto e = get_element(j, expand_name(j, name)); return e && e->at("is_deprecated") == true; } + +namespace json_helpers { +int find_message_nested(const nlohmann::json &j, const std::string &from, + const std::string &to, const std::string &msg, + std::optional return_type, const nlohmann::json &from_p, + const nlohmann::json &to_p, int &count, const int64_t offset, + std::optional chain_index = {}) +{ + if (!j.contains("messages") && !j.contains("message_chains")) + return -1; + + const auto &messages = !chain_index.has_value() + ? j["messages"] + : j["message_chains"][chain_index.value()]["messages"]; + + int res{-1}; + + for (const auto &m : messages) { + if (m.contains("branches")) { + for (const auto &b : m["branches"]) { + auto nested_res = find_message_nested( + b, from, to, msg, return_type, from_p, to_p, count, offset); + + if (nested_res >= offset) + return nested_res; + } + } + else if (m.contains("messages")) { + auto nested_res = find_message_nested( + m, from, to, msg, return_type, from_p, to_p, count, offset); + + if (nested_res >= offset) + return nested_res; + } + else { + if (count >= offset && + (m["from"]["participant_id"] == from_p["id"]) && + (m["to"]["participant_id"] == to_p["id"]) && + (m["name"] == msg) && + (!return_type || m["return_type"] == *return_type)) + return count; + + count++; + } + } + + return res; +} + +int find_message_impl(const nlohmann::json &j, const std::string &from, + const std::string &to, const std::string &msg, + std::optional return_type, int64_t offset, + std::optional chain_index = {}) +{ + + auto from_p = get_participant(j, from); + auto to_p = get_participant(j, to); + + // TODO: support diagrams with multiple sequences... + int count{0}; + + for (const auto &seq : j["sequences"]) { + int64_t res{-1}; + + res = find_message_nested(seq, from, to, msg, return_type, *from_p, + *to_p, count, offset, chain_index); + + if (res >= 0) + return res; + } + + throw std::runtime_error(fmt::format( + "No such message {} {} {} after offset {}", from, to, msg, offset)); +} + +int64_t find_message(const nlohmann::json &j, const File &from, const File &to, + const std::string &msg, int64_t offset) +{ + return find_message_impl(j, from.file, to.file, msg, {}, offset); +} + +int64_t find_message(const nlohmann::json &j, const std::string &from, + const std::string &to, const std::string &msg, + std::optional return_type = {}, int64_t offset = 0) +{ + return find_message_impl( + j, expand_name(j, from), expand_name(j, to), msg, return_type, offset); +} + +int64_t find_message_in_chain(const nlohmann::json &j, const std::string &from, + const std::string &to, const std::string &msg, + std::optional return_type = {}, int64_t offset = 0, + uint32_t chain_index = 0) +{ + return find_message_impl(j, expand_name(j, from), expand_name(j, to), msg, + return_type, offset, chain_index); +} + +} // namespace detail + +template <> +int64_t FindMessage( + const json_t &d, const Message &msg, int64_t offset, bool fail) +{ + if (msg.is_response) { + // TODO: Currently response are not generated as separate messages in + // JSON format + return offset; + } + + if (msg.is_entrypoint || msg.is_exitpoint) + return offset; + + try { + return json_helpers::find_message(d.src, msg.from.str(), msg.to.str(), + msg.message, msg.return_type, offset); + } + catch (std::exception &e) { + if (!fail) + return -1; + + std::cout << "FindMessage failed with error " << e.what() << "\n"; + + throw e; + } +} + +int64_t find_message_in_chain(const json_t &d, const Message &msg, + int64_t offset, bool fail, uint32_t chain_index) +{ + if (msg.is_response) { + // TODO: Currently response are not generated as separate messages in + // JSON format + return offset; + } + + if (msg.is_entrypoint || msg.is_exitpoint) + return offset; + + try { + return json_helpers::find_message_in_chain(d.src, msg.from.str(), + msg.to.str(), msg.message, msg.return_type, offset, chain_index); + } + catch (std::exception &e) { + if (!fail) + return -1; + + std::cout << "find_message_in_chain failed with " << e.what() << "\n"; + + throw e; + } +} + +template <> +bool MessageChainsOrder( + const json_t &d, std::vector> message_chains) +{ + uint32_t chain_index{0}; + for (const auto &messages : message_chains) { + int64_t offset{0}; + + std::vector order; + order.reserve(messages.size()); + std::transform(messages.begin(), messages.end(), + std::back_inserter(order), + [&d, &offset, chain_index](const auto &m) { + offset = find_message_in_chain(d, m, offset, true, chain_index); + return offset; + }); + + bool are_messages_in_order = std::is_sorted(order.begin(), order.end()); + + chain_index++; + + if (!are_messages_in_order) { + FAIL(fmt::format( + "Messages are not in order: \n[{}]", fmt::join(order, ",\n"))); + return false; + } + } + + return true; +} + +template <> +bool HasMessageComment( + const json_t &d, std::string const &alias, std::string const ¬e) +{ + return true; +} + +template <> +bool IsParticipant( + const json_t &d, const std::string &name, const std::string &type) +{ + const auto &j = d.src; + + auto p = get_participant(j, expand_name(j, name)); + + return p && (p->at("type") == type); +} } /* From 4b5cfa7b48aeadf0416d98a36b01ec8027cfc118 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Mon, 20 May 2024 00:09:30 +0200 Subject: [PATCH 08/15] Refactoring sequence diagrams test cases (#266) --- .../json/sequence_diagram_generator.cc | 34 +++- .../json/sequence_diagram_generator.h | 2 + .../plantuml/sequence_diagram_generator.cc | 19 +- tests/t20001/test_case.h | 93 --------- tests/t20002/test_case.h | 46 ----- tests/t20003/test_case.h | 42 ---- tests/t20004/test_case.h | 85 --------- tests/t20005/test_case.h | 46 ----- tests/t20006/test_case.h | 123 ------------ tests/t20007/test_case.h | 58 ------ tests/t20008/test_case.h | 76 -------- tests/t20009/test_case.h | 68 ------- tests/t20010/test_case.h | 65 ------- tests/t20011/test_case.h | 56 ------ tests/t20012/test_case.h | 131 ------------- tests/t20013/test_case.h | 60 ------ tests/t20014/test_case.h | 59 ------ tests/t20015/test_case.h | 57 ------ tests/t20016/test_case.h | 56 ------ tests/t20018/test_case.h | 72 ------- tests/t20019/test_case.h | 47 ----- tests/t20020/test_case.h | 85 --------- tests/t20021/test_case.h | 88 --------- tests/t20022/test_case.h | 41 ---- tests/t20023/test_case.h | 49 ----- tests/t20024/test_case.h | 57 ------ tests/t20025/test_case.h | 46 ----- tests/t20026/test_case.h | 36 ---- tests/t20027/test_case.h | 41 ---- tests/t20028/test_case.h | 57 +----- tests/t20029/test_case.h | 133 ------------- tests/t20041/test_case.h | 60 ------ tests/t20042/test_case.h | 42 ---- tests/t20043/test_case.h | 43 ----- tests/t20044/.clang-uml | 2 +- tests/t20044/test_case.h | 84 ++------ tests/t20045/test_case.h | 80 +++----- tests/t20046/test_case.h | 103 ++++------ tests/t20047/test_case.h | 58 ++---- tests/t20048/test_case.h | 100 ++++------ tests/t20049/test_case.h | 77 ++------ tests/t20050/test_case.h | 76 ++------ tests/t20051/test_case.h | 71 ++----- tests/t20052/test_case.h | 179 ++++-------------- tests/t20053/test_case.h | 65 ++----- tests/test_cases.cc | 6 +- tests/test_cases.h | 35 +++- 47 files changed, 300 insertions(+), 2709 deletions(-) diff --git a/src/sequence_diagram/generators/json/sequence_diagram_generator.cc b/src/sequence_diagram/generators/json/sequence_diagram_generator.cc index 8c17daf9..d126d5a7 100644 --- a/src/sequence_diagram/generators/json/sequence_diagram_generator.cc +++ b/src/sequence_diagram/generators/json/sequence_diagram_generator.cc @@ -40,6 +40,8 @@ void to_json(nlohmann::json &j, const participant &c) j["name"] = dynamic_cast(c).method_name(); } + j["full_name"] = c.full_name(false); + if (c.type_name() == "function" || c.type_name() == "function_template") { const auto &f = dynamic_cast(c); if (f.is_cuda_kernel()) @@ -172,7 +174,7 @@ void generator::generate_call(const message &m, nlohmann::json &parent) const dynamic_cast(m); msg["scope"] = to_string(m.message_scope()); - msg["return_type"] = m.return_type(); + msg["return_type"] = config().simplify_template_type(m.return_type()); parent["messages"].push_back(std::move(msg)); @@ -568,6 +570,12 @@ common::id_t generator::generate_participant( .value() .class_id(); + LOG_DBG("Generating JSON method participant: {}", + model() + .get_participant(participant_id) + .value() + .full_name(false)); + if (!is_participant_generated(class_participant_id)) { const auto &class_participant = model() @@ -580,6 +588,13 @@ common::id_t generator::generate_participant( json_["participants"].push_back(class_participant); json_["participants"].back()["activities"].push_back(participant); + // Perform config dependent postprocessing on generated class + const auto class_participant_full_name = + class_participant.full_name(false); + + json_["participants"].back().at("display_name") = + make_display_name(class_participant_full_name); + return class_participant_id; } @@ -807,7 +822,8 @@ void generator::generate_diagram(nlohmann::json &parent) const if (from.value().type_name() == "method" || config().combine_free_functions_into_file_participants()) { - sequence["return_type"] = from.value().return_type(); + sequence["return_type"] = + make_display_name(from.value().return_type()); } parent["sequences"].push_back(std::move(sequence)); @@ -821,11 +837,21 @@ void generator::generate_diagram(nlohmann::json &parent) const // Perform config dependent postprocessing on generated participants for (auto &p : json_["participants"]) { if (p.contains("display_name")) { - p["display_name"] = - config().simplify_template_type(p["display_name"]); + p["display_name"] = make_display_name(p["display_name"]); } } parent["participants"] = json_["participants"]; } + +std::string generator::make_display_name(const std::string &full_name) const +{ + auto result = config().simplify_template_type(full_name); + result = config().using_namespace().relative(result); + common::ensure_lambda_type_is_relative(config(), result); + result = render_name(result); + + return result; +} + } // namespace clanguml::sequence_diagram::generators::json diff --git a/src/sequence_diagram/generators/json/sequence_diagram_generator.h b/src/sequence_diagram/generators/json/sequence_diagram_generator.h index bbf45078..e519f1bb 100644 --- a/src/sequence_diagram/generators/json/sequence_diagram_generator.h +++ b/src/sequence_diagram/generators/json/sequence_diagram_generator.h @@ -111,6 +111,8 @@ public: */ nlohmann::json ¤t_block_statement() const; + std::string make_display_name(const std::string &full_name) const; + private: /** * @brief Check if specified participant has already been generated. diff --git a/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc b/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc index b46bc00b..11cceb37 100644 --- a/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc +++ b/src/sequence_diagram/generators/plantuml/sequence_diagram_generator.cc @@ -388,8 +388,11 @@ void generator::generate_participant( print_debug(class_participant, ostr); auto participant_name = - config().using_namespace().relative(config().simplify_template_type( - class_participant.full_name(false))); + config().simplify_template_type( + class_participant.full_name(false)); + participant_name = + config().using_namespace().relative(participant_name); + common::ensure_lambda_type_is_relative(config(), participant_name); ostr << "participant \"" << render_name(participant_name) << "\" as " @@ -531,8 +534,7 @@ void generator::generate_diagram(std::ostream &ostr) const if (from.value().type_name() == "method" || config().combine_free_functions_into_file_participants()) { generate_participant(ostr, from_activity_id); - ostr << "[->" - << " " << generate_alias(from.value()) << " : " + ostr << "[->" << " " << generate_alias(from.value()) << " : " << from.value().message_name( select_method_arguments_render_mode()) << '\n'; @@ -571,8 +573,7 @@ void generator::generate_diagram(std::ostream &ostr) const if (from.value().type_name() == "method" || config().combine_free_functions_into_file_participants()) { generate_participant(ostr, from_activity_id); - ostr << "[->" - << " " << generate_alias(from.value()) << " : " + ostr << "[->" << " " << generate_alias(from.value()) << " : " << from.value().message_name( select_method_arguments_render_mode()) << '\n'; @@ -636,8 +637,7 @@ void generator::generate_diagram(std::ostream &ostr) const // first activity for this 'start_from' condition if (from.value().type_name() == "method" || config().combine_free_functions_into_file_participants()) { - ostr << "[->" - << " " << from_alias << " : " + ostr << "[->" << " " << from_alias << " : " << from.value().message_name(render_mode) << '\n'; } @@ -650,8 +650,7 @@ void generator::generate_diagram(std::ostream &ostr) const config().combine_free_functions_into_file_participants()) { if (!from.value().is_void()) { - ostr << "[<--" - << " " << from_alias; + ostr << "[<--" << " " << from_alias; if (config().generate_return_types()) ostr << " : //" << from.value().return_type() << "//"; diff --git a/tests/t20001/test_case.h b/tests/t20001/test_case.h index ed29917d..c0538f34 100644 --- a/tests/t20001/test_case.h +++ b/tests/t20001/test_case.h @@ -74,97 +74,4 @@ TEST_CASE("t20001") CHECK(tmain.value()["source_location"]["file"] == "t20001.cc"); CHECK(tmain.value()["source_location"]["line"] == 61); }); - - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, HasTitle("Basic sequence diagram example")); - - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "add3(int,int,int)")); - REQUIRE_THAT(src, HasCall(_A("A"), "add(int,int)")); - REQUIRE_THAT(src, !HasCall(_A("A"), _A("detail::C"), "add(int,int)")); - REQUIRE_THAT(src, HasCall(_A("A"), "__log_result(int)__")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "__log_result(int)__")); - - REQUIRE_THAT(src, HasComment("t20001 test diagram of type sequence")); - - REQUIRE_THAT( - src, HasMessageComment(_A("tmain()"), "Just add 2 numbers")); - - REQUIRE_THAT( - src, HasMessageComment(_A("tmain()"), "And now add another 2")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - const auto &A = get_participant(j, "A"); - - CHECK(A.has_value()); - - CHECK(A.value()["type"] == "class"); - CHECK(A.value()["name"] == "A"); - CHECK(A.value()["display_name"] == "A"); - CHECK(A.value()["namespace"] == "clanguml::t20001"); - CHECK(A.value()["source_location"]["file"] == "t20001.cc"); - CHECK(A.value()["source_location"]["line"] == 13); - - const auto &tmain = get_participant(j, "tmain()"); - - CHECK(tmain.has_value()); - - CHECK(tmain.value()["type"] == "function"); - CHECK(tmain.value()["name"] == "tmain"); - CHECK(tmain.value()["display_name"] == "tmain()"); - CHECK(tmain.value()["namespace"] == "clanguml::t20001"); - CHECK(tmain.value()["source_location"]["file"] == "t20001.cc"); - CHECK(tmain.value()["source_location"]["line"] == 61); - - REQUIRE(HasTitle(j, "Basic sequence diagram example")); - - REQUIRE(IsFunctionParticipant(j, "tmain()")); - REQUIRE(IsClassParticipant(j, "A")); - REQUIRE(IsClassParticipant(j, "B")); - - std::vector messages = { - FindMessage(j, "tmain()", "A", "add(int,int)"), - FindMessage(j, "tmain()", "B", "wrap_add3(int,int,int)"), - FindMessage(j, "B", "A", "add3(int,int,int)"), - FindMessage(j, "A", "A", "add(int,int)"), - FindMessage(j, "A", "A", "log_result(int)"), - FindMessage(j, "B", "A", "log_result(int)")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - using mermaid::HasComment; - using mermaid::HasTitle; - - REQUIRE_THAT(src, HasTitle("Basic sequence diagram example")); - - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "add3(int,int,int)")); - REQUIRE_THAT(src, HasCall(_A("A"), "add(int,int)")); - REQUIRE_THAT(src, !HasCall(_A("A"), _A("detail::C"), "add(int,int)")); - REQUIRE_THAT(src, HasCall(_A("A"), "log_result(int)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "log_result(int)")); - - REQUIRE_THAT(src, HasComment("t20001 test diagram of type sequence")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } - */ } diff --git a/tests/t20002/test_case.h b/tests/t20002/test_case.h index bc0f8034..aecc06e9 100644 --- a/tests/t20002/test_case.h +++ b/tests/t20002/test_case.h @@ -37,50 +37,4 @@ TEST_CASE("t20002") {"m3()", "m4()", ""} // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, HasCall(_A("m1()"), _A("m2()"), "")); - REQUIRE_THAT(src, HasCall(_A("m2()"), _A("m3()"), "")); - REQUIRE_THAT(src, HasCall(_A("m3()"), _A("m4()"), "")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - REQUIRE(IsFunctionParticipant(j, "m1()")); - REQUIRE(IsFunctionParticipant(j, "m2()")); - REQUIRE(IsFunctionParticipant(j, "m3()")); - REQUIRE(IsFunctionParticipant(j, "m4()")); - - std::vector messages = {FindMessage(j, "m1()", "m2()", ""), - FindMessage(j, "m2()", "m3()", ""), - FindMessage(j, "m3()", "m4()", "")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("m1()"), _A("m2()"), "")); - REQUIRE_THAT(src, HasCall(_A("m2()"), _A("m3()"), "")); - REQUIRE_THAT(src, HasCall(_A("m3()"), _A("m4()"), "")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } diff --git a/tests/t20003/test_case.h b/tests/t20003/test_case.h index ab08e227..ba5c844e 100644 --- a/tests/t20003/test_case.h +++ b/tests/t20003/test_case.h @@ -37,46 +37,4 @@ TEST_CASE("t20003") {"m3(T)", "m4(T)", ""} // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, HasCall(_A("m1(T)"), _A("m2(T)"), "")); - REQUIRE_THAT(src, HasCall(_A("m2(T)"), _A("m3(T)"), "")); - REQUIRE_THAT(src, HasCall(_A("m3(T)"), _A("m4(T)"), "")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = {FindMessage(j, "m1(T)", "m2(T)", - ""), FindMessage(j, "m2(T)", "m3(T)", ""), FindMessage(j, - "m3(T)", "m4(T)", "")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("m1(T)"), _A("m2(T)"), "")); - REQUIRE_THAT(src, HasCall(_A("m2(T)"), _A("m3(T)"), "")); - REQUIRE_THAT(src, HasCall(_A("m3(T)"), _A("m4(T)"), "")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } diff --git a/tests/t20004/test_case.h b/tests/t20004/test_case.h index cb87263a..b576a878 100644 --- a/tests/t20004/test_case.h +++ b/tests/t20004/test_case.h @@ -42,89 +42,4 @@ TEST_CASE("t20004") REQUIRE(!HasMessage(src, {"m1(float)", "m1(float)", ""})); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, HasCall(_A("main()"), _A("m1(float)"), - "")); - REQUIRE_THAT( src, !HasCall(_A("m1(float)"), - _A("m1(float)"), "")); - REQUIRE_THAT( src, - !HasCall(_A("m1(float)"), _A("m1(float)"), "")); - - REQUIRE_THAT(src, - HasCall(_A("main()"), _A("m1(unsigned long)"), - "")); - REQUIRE_THAT(src, HasCall(_A("m1(unsigned long)"), - _A("m4(unsigned long)"), "")); - - REQUIRE_THAT( - src, HasCall(_A("main()"), _A("m1(std::string)"), - "")); REQUIRE_THAT(src, HasCall(_A("m1(std::string)"), - _A("m2(std::string)"), "")); - - REQUIRE_THAT(src, HasCall(_A("main()"), _A("m1(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("m1(int)"), _A("m2(int)"), - "")); REQUIRE_THAT(src, HasCall(_A("m2(int)"), _A("m3(int)"), - "")); REQUIRE_THAT(src, HasCall(_A("m3(int)"), _A("m4(int)"), - "")); REQUIRE_THAT(src, EndsWith("@enduml\n")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = { - FindMessage(j, "main()", "m1(float)", ""), - FindMessage(j, "main()", "m1(unsigned long)", - ""), FindMessage(j, "m1(unsigned long)", "m4(unsigned long)", ""), FindMessage(j, "main()", - "m1(std::string)", ""), FindMessage(j, - "m1(std::string)", "m2(std::string)", ""), - FindMessage(j, "main()", "m1(int)", ""), - FindMessage(j, "m1(int)", "m2(int)", ""), - FindMessage(j, "m2(int)", "m3(int)", ""), - FindMessage(j, "m3(int)", "m4(int)", "")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("main()"), _A("m1(float)"), - "")); REQUIRE_THAT( src, !HasCall(_A("m1(float)"), - _A("m1(float)"), "")); REQUIRE_THAT( src, - !HasCall(_A("m1(float)"), _A("m1(float)"), "")); - - REQUIRE_THAT(src, - HasCall(_A("main()"), _A("m1(unsigned long)"), - "")); REQUIRE_THAT(src, HasCall(_A("m1(unsigned long)"), - _A("m4(unsigned long)"), "")); - - REQUIRE_THAT( - src, HasCall(_A("main()"), _A("m1(std::string)"), - "")); REQUIRE_THAT(src, HasCall(_A("m1(std::string)"), - _A("m2(std::string)"), "")); - - REQUIRE_THAT(src, HasCall(_A("main()"), _A("m1(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("m1(int)"), _A("m2(int)"), - "")); REQUIRE_THAT(src, HasCall(_A("m2(int)"), _A("m3(int)"), - "")); REQUIRE_THAT(src, HasCall(_A("m3(int)"), _A("m4(int)"), - "")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t20005/test_case.h b/tests/t20005/test_case.h index abc56f9d..672b0444 100644 --- a/tests/t20005/test_case.h +++ b/tests/t20005/test_case.h @@ -33,50 +33,4 @@ TEST_CASE("t20005") {Exitpoint{}, "C"} // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasEntrypoint(_A("C"), "c(T)")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b(T)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a(T)")); - REQUIRE_THAT(src, HasExitpoint(_A("C"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = {FindMessage(j, "C", "B", "b(T)"), - FindMessage(j, "B", "A", "a(T)")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - using mermaid::HasEntrypoint; - using mermaid::HasExitpoint; - - REQUIRE_THAT(src, HasEntrypoint(_A("C"), "c(T)")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b(T)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a(T)")); - REQUIRE_THAT(src, HasExitpoint(_A("C"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t20006/test_case.h b/tests/t20006/test_case.h index 8ac04b5c..d643b4c0 100644 --- a/tests/t20006/test_case.h +++ b/tests/t20006/test_case.h @@ -45,127 +45,4 @@ TEST_CASE("t20006") })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b(int)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a1(int)")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("B"), "b(std::string)")); - REQUIRE_THAT(src, - HasCall( - _A("B"), _A("A"), - "a2(std::string)")); - - REQUIRE_THAT( - src, HasCall(_A("tmain()"), _A("BB"), "bb1(int,int)")); - REQUIRE_THAT( - src, HasCall(_A("BB"), _A("AA"), "aa1(int)")); - - REQUIRE_THAT( - src, HasCall(_A("tmain()"), _A("BB"), "bb2(int,int)")); - REQUIRE_THAT( - src, HasCall(_A("BB"), _A("AA"), "aa2(int)")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("BB"), - "bb1(int,std::string)")); - REQUIRE_THAT( - src, HasCall(_A("BB"), _A("AA"), - "aa2(int)")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("BB"), - "bb2(int,std::string)")); - REQUIRE_THAT( - src, HasCall(_A("BB"), _A("AA"), - "aa1(int)")); - - REQUIRE_THAT( - src, HasCall(_A("tmain()"), _A("BB"), - "bb1(int,float)")); - REQUIRE_THAT(src, HasCall( _A("BB"), - _A("BB"), "bb2(int,float)")); - REQUIRE_THAT( src, - HasCall(_A("BB"), _A("AA"), "aa2(int)")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = { - FindMessage(j, "tmain()", "B", "b(int)"), - FindMessage(j, "B", "A", "a1(int)"), - FindMessage(j, "tmain()", "B", "b(std::string)"), - FindMessage(j, "tmain()", "BB", "bb1(int,int)"), - FindMessage(j, "BB", "AA", "aa1(int)"), - FindMessage( - j, "tmain()", "BB", - "bb1(int,std::string)")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b(int)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a1(int)")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("B"), "b(std::string)")); - REQUIRE_THAT(src, - HasCall( - _A("B"), _A("A"), - "a2(std::string)")); - - REQUIRE_THAT( - src, HasCall(_A("tmain()"), _A("BB"), "bb1(int,int)")); - REQUIRE_THAT( - src, HasCall(_A("BB"), _A("AA"), "aa1(int)")); - - REQUIRE_THAT( - src, HasCall(_A("tmain()"), _A("BB"), "bb2(int,int)")); - REQUIRE_THAT( - src, HasCall(_A("BB"), _A("AA"), "aa2(int)")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("BB"), - "bb1(int,std::string)")); - REQUIRE_THAT( - src, HasCall(_A("BB"), _A("AA"), - "aa2(int)")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("BB"), - "bb2(int,std::string)")); - REQUIRE_THAT( - src, HasCall(_A("BB"), _A("AA"), - "aa1(int)")); - - REQUIRE_THAT( - src, HasCall(_A("tmain()"), _A("BB"), - "bb1(int,float)")); REQUIRE_THAT(src, HasCall( _A("BB"), - _A("BB"), "bb2(int,float)")); REQUIRE_THAT( src, - HasCall(_A("BB"), _A("AA"), "aa2(int)")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t20007/test_case.h b/tests/t20007/test_case.h index 0bfa1b19..ada4af73 100644 --- a/tests/t20007/test_case.h +++ b/tests/t20007/test_case.h @@ -33,62 +33,4 @@ TEST_CASE("t20007") "add(std::string &&,std::string &&,std::string &&)"} // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("Adder"), "add(int &&,int - &&)")); REQUIRE_THAT(src, HasCall(_A("tmain()"), - _A("Adder"), "add(int &&,float &&,double &&)")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), - _A("Adder"), - "add(std::string &&,std::string &&,std::string &&)")); - - save_puml(config.output_directory(), diagram->name + ".puml", - src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = { - FindMessage(j, "tmain()", "Adder", "add(int &&,int - &&)"), FindMessage(j, "tmain()", "Adder", "add(int - &&,float &&,double &&)"), FindMessage(j, "tmain()", - "Adder", - "add(std::string &&,std::string &&,std::string &&)")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", - j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("Adder"), "add(int &&,int - &&)")); REQUIRE_THAT(src, HasCall(_A("tmain()"), - _A("Adder"), "add(int &&,float &&,double &&)")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), - _A("Adder"), - "add(std::string &&,std::string &&,std::string &&)")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t20008/test_case.h b/tests/t20008/test_case.h index ac9c7a05..3d0d5c20 100644 --- a/tests/t20008/test_case.h +++ b/tests/t20008/test_case.h @@ -40,80 +40,4 @@ TEST_CASE("t20008") REQUIRE(!HasMessage(src, {"B", "A", "a2(int)"})); REQUIRE(!HasMessage(src, {"B", "A", "a3(int)"})); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), - "b(int)")); REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), - "a1(int)")); - // REQUIRE_THAT(puml, !HasCall(_A("B"), _A("A"), - // "a2(int)")); REQUIRE_THAT(puml, !HasCall(_A("B"), - // _A("A"), "a3(int)")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("B"), "b(const char - *)")); REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2(const char *)")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("B"), - "b(std::string)")); REQUIRE_THAT(src, HasCall( _A("B"), - _A("A"), "a3(std::string)")); - - save_puml(config.output_directory(), diagram->name + ".puml", - src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = { - FindMessage(j, "tmain()", "B", "b(int)"), - FindMessage(j, "B", "A", "a1(int)"), - FindMessage(j, "tmain()", "B", "b(const char - *)"), FindMessage( j, "B", "A", "a2(const - char *)"), FindMessage(j, "tmain()", "B", - "b(std::string)"), FindMessage( j, "B", - "A", "a3(std::string)")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", - j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), - "b(int)")); REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), - "a1(int)")); - // REQUIRE_THAT(puml, !HasCall(_A("B"), _A("A"), - // "a2(int)")); REQUIRE_THAT(puml, !HasCall(_A("B"), - // _A("A"), "a3(int)")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("B"), "b(const char - *)")); REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2(const char *)")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("B"), - "b(std::string)")); REQUIRE_THAT(src, HasCall( _A("B"), - _A("A"), "a3(std::string)")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t20009/test_case.h b/tests/t20009/test_case.h index 0a7600bb..4388615b 100644 --- a/tests/t20009/test_case.h +++ b/tests/t20009/test_case.h @@ -37,72 +37,4 @@ TEST_CASE("t20009") {"B", "A", "a(float)"} // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("B"), "b(std::string)")); - REQUIRE_THAT(src, - HasCall( - _A("B"), _A("A"), - "a(std::string)")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b(int)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a(int)")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), - "b(float)")); REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), - "a(float)")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = { - FindMessage(j, "tmain()", "B", "b(std::string)"), - FindMessage( - j, "B", "A", "a(std::string)"), - FindMessage(j, "tmain()", "B", "b(int)"), - FindMessage(j, "B", "A", "a(int)"), - FindMessage(j, "tmain()", "B", "b(float)"), - FindMessage(j, "B", "A", "a(float)")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("B"), "b(std::string)")); - REQUIRE_THAT(src, - HasCall( - _A("B"), _A("A"), - "a(std::string)")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b(int)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a(int)")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), - "b(float)")); REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), - "a(float)")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t20010/test_case.h b/tests/t20010/test_case.h index e17b4f57..274a88ff 100644 --- a/tests/t20010/test_case.h +++ b/tests/t20010/test_case.h @@ -39,69 +39,4 @@ TEST_CASE("t20010") {"B", "A", "a4()"} // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b1()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a1()")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b2()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b3()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a3()")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b4()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a4()")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = { - FindMessage(j, "tmain()", "B", "b1()"), - FindMessage(j, "B", "A", "a1()"), - FindMessage(j, "tmain()", "B", "b2()"), - FindMessage(j, "B", "A", "a2()"), - FindMessage(j, "tmain()", "B", "b3()"), - FindMessage(j, "B", "A", "a3()"), - FindMessage(j, "tmain()", "B", "b4()"), - FindMessage(j, "B", "A", "a4()")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b1()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a1()")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b2()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b3()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a3()")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b4()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a4()")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t20011/test_case.h b/tests/t20011/test_case.h index 9923d2e7..b9ba1828 100644 --- a/tests/t20011/test_case.h +++ b/tests/t20011/test_case.h @@ -36,60 +36,4 @@ TEST_CASE("t20011") {"A", "A", "b(int)"} // })); }); - - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a(int)")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a(int)")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "b(int)")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "c(int)")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "d(int)")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "b(int)")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - REQUIRE(IsFunctionParticipant(j, "tmain()")); - REQUIRE(IsClassParticipant(j, "A")); - - std::vector messages = {FindMessage(j, "tmain()", "A", "a(int)"), - FindMessage(j, "A", "A", "a(int)"), - FindMessage(j, "tmain()", "A", "b(int)"), - FindMessage(j, "A", "A", "c(int)")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a(int)")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a(int)")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "b(int)")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "c(int)")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "d(int)")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "b(int)")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } - */ } \ No newline at end of file diff --git a/tests/t20012/test_case.h b/tests/t20012/test_case.h index dd7a50f8..2327889d 100644 --- a/tests/t20012/test_case.h +++ b/tests/t20012/test_case.h @@ -68,135 +68,4 @@ TEST_CASE("t20012") {"tmain()::(lambda t20012.cc:94:9)", "D", "add5(int) const"} // })); }); - - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("tmain()::(lambda t20012.cc:67:20)"), - "operator()() const")); - REQUIRE_THAT(src, - HasCall(_A("tmain()::(lambda t20012.cc:67:20)"), _A("A"), "a()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "aa()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "aaa()")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()::(lambda t20012.cc:67:20)"), _A("B"), "b()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("B"), "bb()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("B"), "bbb()")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()::(lambda t20012.cc:80:20)"), _A("C"), "c()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "cc()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "ccc()")); - REQUIRE_THAT(src, - HasCall(_A("tmain()::(lambda t20012.cc:80:20)"), - _A("tmain()::(lambda t20012.cc:67:20)"), "operator()() const")); - - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "ccc()")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("R<(lambda at t20012.cc:86:9)>"), - "R((lambda at t20012.cc:86:9) &&)")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("R<(lambda at t20012.cc:86:9)>"), "r()")); - REQUIRE_THAT(src, - HasCall(_A("R<(lambda at t20012.cc:86:9)>"), - _A("tmain()::(lambda t20012.cc:86:9)"), "operator()() const")); - REQUIRE_THAT(src, - HasCall(_A("tmain()::(lambda t20012.cc:86:9)"), _A("C"), "c()")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("tmain()::(lambda t20012.cc:94:9)"), - "operator()(auto) const")); - REQUIRE_THAT(src, - HasCall(_A("tmain()::(lambda t20012.cc:94:9)"), _A("D"), - "add5(int) const")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = { - FindMessage(j, "tmain()", "tmain()::(lambda t20012.cc:67:20)", - "operator()() const"), - FindMessage(j, "tmain()::(lambda t20012.cc:67:20)", "A", "a()"), - FindMessage(j, "A", "A", "aa()"), - FindMessage(j, "A", "A", "aaa()"), - FindMessage(j, "tmain()::(lambda t20012.cc:67:20)", "B", "b()"), - FindMessage(j, "B", "B", "bb()"), - FindMessage(j, "B", "B", "bbb()"), - FindMessage(j, "tmain()::(lambda t20012.cc:80:20)", "C", "c()"), - FindMessage(j, "C", "C", "cc()"), - FindMessage(j, "C", "C", "ccc()"), - FindMessage(j, "tmain()::(lambda t20012.cc:80:20)", - "tmain()::(lambda t20012.cc:67:20)", "operator()() const"), - FindMessage(j, "tmain()", "R<(lambda at t20012.cc:86:9)>", "r()"), - FindMessage(j, "R<(lambda at t20012.cc:86:9)>", - "tmain()::(lambda t20012.cc:86:9)", "operator()() const"), - FindMessage(j, "tmain()::(lambda t20012.cc:86:9)", "C", "c()"), - }; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("tmain()::(lambda t20012.cc:67:20)"), - "operator()() const")); - REQUIRE_THAT(src, - HasCall(_A("tmain()::(lambda t20012.cc:67:20)"), _A("A"), "a()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "aa()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "aaa()")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()::(lambda t20012.cc:67:20)"), _A("B"), "b()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("B"), "bb()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("B"), "bbb()")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()::(lambda t20012.cc:80:20)"), _A("C"), "c()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "cc()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "ccc()")); - REQUIRE_THAT(src, - HasCall(_A("tmain()::(lambda t20012.cc:80:20)"), - _A("tmain()::(lambda t20012.cc:67:20)"), "operator()() const")); - - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "ccc()")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("R<(lambda at t20012.cc:86:9)>"), "r()")); - REQUIRE_THAT(src, - HasCall(_A("R<(lambda at t20012.cc:86:9)>"), - _A("tmain()::(lambda t20012.cc:86:9)"), "operator()() const")); - REQUIRE_THAT(src, - HasCall(_A("tmain()::(lambda t20012.cc:86:9)"), _A("C"), "c()")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("tmain()::(lambda t20012.cc:94:9)"), - "operator()(auto) const")); - REQUIRE_THAT(src, - HasCall(_A("tmain()::(lambda t20012.cc:94:9)"), _A("D"), - "add5(int) const")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } - */ } diff --git a/tests/t20013/test_case.h b/tests/t20013/test_case.h index e0594057..7dad2a28 100644 --- a/tests/t20013/test_case.h +++ b/tests/t20013/test_case.h @@ -37,64 +37,4 @@ TEST_CASE("t20013") {"B", "A", "a3(const char *)"} // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain(int,char **)"), _A("B"), "b(int)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a1(int)")); - - REQUIRE_THAT( - src, HasCall(_A("tmain(int,char **)"), _A("B"), "b(double)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2(double)")); - - REQUIRE_THAT( - src, HasCall(_A("tmain(int,char **)"), _A("B"), "b(const char *)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a3(const char *)")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = { - FindMessage(j, "tmain(int,char **)", "B", "b(int)"), - FindMessage(j, "B", "A", "a1(int)"), - FindMessage(j, "tmain(int,char **)", "B", "b(double)"), - FindMessage(j, "B", "A", "a2(double)"), - FindMessage(j, "tmain(int,char **)", "B", "b(const char *)"), - FindMessage(j, "B", "A", "a3(const char *)")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("tmain(int,char **)"), _A("B"), "b(int)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a1(int)")); - - REQUIRE_THAT( - src, HasCall(_A("tmain(int,char **)"), _A("B"), "b(double)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2(double)")); - - REQUIRE_THAT( - src, HasCall(_A("tmain(int,char **)"), _A("B"), "b(const char *)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a3(const char *)")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } \ No newline at end of file diff --git a/tests/t20014/test_case.h b/tests/t20014/test_case.h index d835bb9f..cea34203 100644 --- a/tests/t20014/test_case.h +++ b/tests/t20014/test_case.h @@ -37,63 +37,4 @@ TEST_CASE("t20014") {"C", "B", "b1(int,int)"}, // })); }); -/* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b1(int,int)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a1(int,int)")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b2(int,int)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2(int,int)")); - - REQUIRE_THAT( - src, HasCall(_A("tmain()"), _A("C"), "c1(int,int)")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b1(int,int)")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = { - FindMessage(j, "tmain()", "B", "b1(int,int)"), - FindMessage(j, "B", "A", "a1(int,int)"), - FindMessage(j, "tmain()", "B", "b2(int,int)"), - FindMessage(j, "B", "A", "a2(int,int)"), - FindMessage(j, "tmain()", "C", "c1(int,int)"), - FindMessage(j, "C", "B", "b1(int,int)")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b1(int,int)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a1(int,int)")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b2(int,int)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2(int,int)")); - - REQUIRE_THAT( - src, HasCall(_A("tmain()"), _A("C"), "c1(int,int)")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b1(int,int)")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } -*/ } \ No newline at end of file diff --git a/tests/t20015/test_case.h b/tests/t20015/test_case.h index 2a752921..f4510ece 100644 --- a/tests/t20015/test_case.h +++ b/tests/t20015/test_case.h @@ -37,61 +37,4 @@ TEST_CASE("t20015") REQUIRE(!HasMessage(src, {"B", "B", "set_y(int)"})); REQUIRE(!HasMessage(src, {"B", "B", "set_z(int)"})); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("B"), - "setup_a(std::shared_ptr &)")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("detail::A"), "set_x(int)")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("detail::A"), "set_y(int)")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("detail::A"), "set_z(int)")); - - REQUIRE_THAT(src, !HasCall(_A("B"), _A("B"), "set_x(int)")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("B"), "set_y(int)")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("B"), "set_z(int)")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = {FindMessage( - j, "tmain()", "B", "setup_a(std::shared_ptr &)")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("B"), - "setup_a(std::shared_ptr &)")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("detail::A"), "set_x(int)")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("detail::A"), "set_y(int)")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("detail::A"), "set_z(int)")); - - REQUIRE_THAT(src, !HasCall(_A("B"), _A("B"), "set_x(int)")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("B"), "set_y(int)")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("B"), "set_z(int)")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - } - */ } \ No newline at end of file diff --git a/tests/t20016/test_case.h b/tests/t20016/test_case.h index ec213523..df0e4c06 100644 --- a/tests/t20016/test_case.h +++ b/tests/t20016/test_case.h @@ -33,60 +33,4 @@ TEST_CASE("t20016") {"B", "A", "a2(const long &)"} // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), - "b1(long)")); REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), - "a1(int)")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), - "b2(long)")); REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), - "a2(const long &)")); - - save_puml(config.output_directory(), diagram->name + ".puml", - src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = { - FindMessage(j, "tmain()", "B", "b1(long)"), - FindMessage(j, "B", "A", "a1(int)"), - FindMessage(j, "tmain()", "B", "b2(long)"), - FindMessage(j, "B", "A", "a2(const long &)")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", - j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), - "b1(long)")); REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), - "a1(int)")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), - "b2(long)")); REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), - "a2(const long &)")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - } - */ } \ No newline at end of file diff --git a/tests/t20018/test_case.h b/tests/t20018/test_case.h index c43591ef..5f99216a 100644 --- a/tests/t20018/test_case.h +++ b/tests/t20018/test_case.h @@ -37,76 +37,4 @@ TEST_CASE("t20018") {"Factorial<1>", "Factorial<0>", "print(int)", Static{}}, // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, - HasCall( - _A("tmain()"), _A("Answer,120>"), - "__print()__")); REQUIRE_THAT(src, - HasCall(_A("Answer,120>"), _A("Factorial<5>"), - "__print(int)__")); - REQUIRE_THAT(src, - HasCall(_A("Factorial<5>"), _A("Factorial<4>"), - "__print(int)__")); REQUIRE_THAT(src, HasCall(_A("Factorial<4>"), - _A("Factorial<3>"), "__print(int)__")); REQUIRE_THAT(src, - HasCall(_A("Factorial<3>"), _A("Factorial<2>"), - "__print(int)__")); REQUIRE_THAT(src, HasCall(_A("Factorial<2>"), - _A("Factorial<1>"), "__print(int)__")); REQUIRE_THAT(src, - HasCall(_A("Factorial<1>"), _A("Factorial<0>"), - "__print(int)__")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = { - FindMessage(j, "tmain()", "Answer,120>", - "print()"), FindMessage( j, "Answer,120>", "Factorial<5>", - "print(int)"), FindMessage(j, "Factorial<5>", "Factorial<4>", - "print(int)"), FindMessage(j, "Factorial<4>", "Factorial<3>", - "print(int)"), FindMessage(j, "Factorial<3>", "Factorial<2>", - "print(int)"), FindMessage(j, "Factorial<2>", "Factorial<1>", - "print(int)"), FindMessage(j, "Factorial<1>", "Factorial<0>", - "print(int)")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("Answer,120>"), - "print()")); REQUIRE_THAT(src, HasCall(_A("Answer,120>"), - _A("Factorial<5>"), "print(int)")); REQUIRE_THAT( src, - HasCall(_A("Factorial<5>"), _A("Factorial<4>"), "print(int)")); - REQUIRE_THAT( - src, HasCall(_A("Factorial<4>"), _A("Factorial<3>"), - "print(int)")); REQUIRE_THAT( src, HasCall(_A("Factorial<3>"), - _A("Factorial<2>"), "print(int)")); REQUIRE_THAT( src, - HasCall(_A("Factorial<2>"), _A("Factorial<1>"), "print(int)")); - REQUIRE_THAT( - src, HasCall(_A("Factorial<1>"), _A("Factorial<0>"), - "print(int)")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - } - */ } \ No newline at end of file diff --git a/tests/t20019/test_case.h b/tests/t20019/test_case.h index 6f809823..cca2e308 100644 --- a/tests/t20019/test_case.h +++ b/tests/t20019/test_case.h @@ -33,51 +33,4 @@ TEST_CASE("t20019") {"Base", "D2", "impl()"} // })); }); -/* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("Base"), "name()")); - REQUIRE_THAT(src, HasCall(_A("Base"), _A("D1"), "impl()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("Base"), "name()")); - REQUIRE_THAT(src, HasCall(_A("Base"), _A("D2"), "impl()")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = { - FindMessage(j, "tmain()", "Base", "name()"), - FindMessage(j, "Base", "D1", "impl()"), - FindMessage(j, "tmain()", "Base", "name()"), - FindMessage(j, "Base", "D2", "impl()")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("Base"), "name()")); - REQUIRE_THAT(src, HasCall(_A("Base"), _A("D1"), "impl()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("Base"), "name()")); - REQUIRE_THAT(src, HasCall(_A("Base"), _A("D2"), "impl()")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } - */ } \ No newline at end of file diff --git a/tests/t20020/test_case.h b/tests/t20020/test_case.h index 1653e737..55c8cd13 100644 --- a/tests/t20020/test_case.h +++ b/tests/t20020/test_case.h @@ -42,89 +42,4 @@ TEST_CASE("t20020") {"tmain()", "D", "d1(int,int)"}, // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a1()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a2()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a3()")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b1()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b2()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "log()")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("C"), "c1() const")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("C"), _A("C"), "c2() const")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "log() const")); - - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("C"), - "c3(int)")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = {FindMessage(j, "tmain()", "A", "a1()"), - FindMessage(j, "tmain()", "A", "a5()"), - FindMessage(j, "tmain()", "A", "a2()"), - FindMessage(j, "tmain()", "C", "c3(int)"), - FindMessage(j, "tmain()", "B", "b1()"), - FindMessage(j, "tmain()", "A", "a3()"), - FindMessage(j, "tmain()", "B", "b2()"), - FindMessage(j, "tmain()", "A", "a4()"), - FindMessage(j, "tmain()", "B", "log()"), - FindMessage(j, "tmain()", "C", "c1() const"), - FindMessage(j, "C", "C", "c2() const"), - FindMessage(j, "C", "C", "log() const"), - FindMessage(j, "tmain()", "D", "d1(int,int)")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - using mermaid::HasCallInControlCondition; - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a1()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a2()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a3()")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b1()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b2()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "log()")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("C"), "c1() const")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("C"), _A("C"), "c2() const")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "log() const")); - - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("C"), - "c3(int)")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - } - */ } \ No newline at end of file diff --git a/tests/t20021/test_case.h b/tests/t20021/test_case.h index 92e9d1f9..6179831d 100644 --- a/tests/t20021/test_case.h +++ b/tests/t20021/test_case.h @@ -40,92 +40,4 @@ TEST_CASE("t20021") {"tmain()", "B", "b2() const"}, // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a1()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a2()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a3()")); - - REQUIRE_THAT(src, !HasCall(_A("tmain()"), _A("B"), "b1()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b2()")); - - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("C"), "c1()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("C"), "c2()")); - - // TODO: Why is this not working? - // REQUIRE_THAT( - // puml, HasCallInControlCondition(_A("tmain()"), _A("C"), - // "c3()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("C"), "c4()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "c5()")); - REQUIRE_THAT(src, - HasCallInControlCondition(_A("tmain()"), _A("C"), "contents()")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = { - FindMessage(j, "tmain()", "C", "c4()"), - FindMessage(j, "C", "C", "c5()"), - FindMessage(j, "tmain()", "A", "a3()"), - FindMessage(j, "tmain()", "A", "a2()"), - FindMessage(j, "tmain()", "C", "c1()"), - FindMessage(j, "tmain()", "C", "c2()"), - FindMessage(j, "tmain()", "A", "a1()"), - FindMessage(j, "tmain()", "C", "c3()"), - FindMessage(j, "tmain()", "B", "b2() const"), - FindMessage(j, "tmain()", "C", "contents()") - // TODO: Repeated messge gets wrong index - // FindMessage(j, "tmain()", "B", "b2()") - }; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - using mermaid::HasCallInControlCondition; - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a1()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a2()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a3()")); - - REQUIRE_THAT(src, !HasCall(_A("tmain()"), _A("B"), "b1()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b2()")); - - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("C"), "c1()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("C"), "c2()")); - - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("C"), "c4()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "c5()")); - REQUIRE_THAT(src, - HasCallInControlCondition(_A("tmain()"), _A("C"), "contents()")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } \ No newline at end of file diff --git a/tests/t20022/test_case.h b/tests/t20022/test_case.h index cdcc5cf4..edf69bc5 100644 --- a/tests/t20022/test_case.h +++ b/tests/t20022/test_case.h @@ -35,45 +35,4 @@ TEST_CASE("t20022") {"A", "B", "b()"}, // })); }); - - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("B"), "b()")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = {FindMessage(j, "tmain()", "A", "a()"), - FindMessage(j, "A", "B", "b()")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("B"), "b()")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t20023/test_case.h b/tests/t20023/test_case.h index 8a09799c..a7cf3371 100644 --- a/tests/t20023/test_case.h +++ b/tests/t20023/test_case.h @@ -35,53 +35,4 @@ TEST_CASE("t20023") })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a1()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a2()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a3()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a4()")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = {FindMessage(j, "tmain()", "A", "a()"), - FindMessage(j, "A", "A", "a1()"), FindMessage(j, "A", "A", - "a2()"), FindMessage(j, "A", "A", "a3()"), FindMessage(j, "A", "A", - "a4()")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a1()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a2()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a3()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a4()")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - } - */ } \ No newline at end of file diff --git a/tests/t20024/test_case.h b/tests/t20024/test_case.h index 72ea1dfd..e61ecaaf 100644 --- a/tests/t20024/test_case.h +++ b/tests/t20024/test_case.h @@ -40,61 +40,4 @@ TEST_CASE("t20024") {"B", "B", "grey()"} // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "select(enum_a)")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a0()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a1()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a2()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a3()")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "select(colors)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("B"), "red()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("B"), "orange()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("B"), "green()")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = { - FindMessage(j, "tmain()", "A", "select(enum_a)"), - FindMessage(j, "A", "A", "a0()"), FindMessage(j, "A", "A", "a1()"), - FindMessage(j, "A", "A", "a2()"), FindMessage(j, "A", "A", "a3()")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "select(enum_a)")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a0()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a1()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a2()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "a3()")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "select(colors)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("B"), "red()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("B"), "orange()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("B"), "green()")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } \ No newline at end of file diff --git a/tests/t20025/test_case.h b/tests/t20025/test_case.h index 432ab52a..c3c9fa13 100644 --- a/tests/t20025/test_case.h +++ b/tests/t20025/test_case.h @@ -31,50 +31,4 @@ TEST_CASE("t20025") {"tmain()", "add(int,int)", ""} // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a()")); - REQUIRE_THAT(src, !HasCall(_A("A"), _A("A"), "a1()")); - // REQUIRE_THAT(puml, !HasCall(_A("A"), _A("A"), "a2()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("add(int,int)"), "")); - REQUIRE_THAT(src, !HasCall(_A("tmain()"), _A("add2(int,int)"), "")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = {FindMessage(j, "tmain()", "A", "a()"), - // FindMessage(j, "tmain()", "A", "a2()"), - FindMessage(j, "tmain()", "add(int,int)", "")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a()")); - REQUIRE_THAT(src, !HasCall(_A("A"), _A("A"), "a1()")); - // REQUIRE_THAT(puml, !HasCall(_A("A"), _A("A"), "a2()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("add(int,int)"), "")); - REQUIRE_THAT(src, !HasCall(_A("tmain()"), _A("add2(int,int)"), "")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } \ No newline at end of file diff --git a/tests/t20026/test_case.h b/tests/t20026/test_case.h index 44a399ab..1533d993 100644 --- a/tests/t20026/test_case.h +++ b/tests/t20026/test_case.h @@ -30,40 +30,4 @@ TEST_CASE("t20026") {"tmain()", "A", "a()"} // })); }); -/* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a()")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = {FindMessage(j, "tmain()", "A", "a()")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a()")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } \ No newline at end of file diff --git a/tests/t20027/test_case.h b/tests/t20027/test_case.h index 12d2e962..faa3bb66 100644 --- a/tests/t20027/test_case.h +++ b/tests/t20027/test_case.h @@ -33,45 +33,4 @@ TEST_CASE("t20027") REQUIRE(!HasMessage(src, {"A", "A", "aa()"})); REQUIRE(!HasMessage(src, {"A", "A", "aaa()"})); }); - - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a()")); - REQUIRE_THAT(src, !HasCall(_A("A"), _A("A"), "aa()")); - REQUIRE_THAT(src, !HasCall(_A("A"), _A("A"), "aaa()")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = {FindMessage(j, "tmain()", "A", "a()")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a()")); - REQUIRE_THAT(src, !HasCall(_A("A"), _A("A"), "aa()")); - REQUIRE_THAT(src, !HasCall(_A("A"), _A("A"), "aaa()")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } \ No newline at end of file diff --git a/tests/t20028/test_case.h b/tests/t20028/test_case.h index 0f1312ac..b6128e6f 100644 --- a/tests/t20028/test_case.h +++ b/tests/t20028/test_case.h @@ -28,62 +28,11 @@ TEST_CASE("t20028") { // {"tmain()", "A", "a()", InControlCondition{}}, // - {"tmain()", "A", "b()"}, // - {"tmain()", "A", "c()"}, // - {"tmain()", "A", "d()"}, // + {"tmain()", "A", "b()"}, // + {"tmain()", "A", "c()"}, // + {"tmain()", "A", "d()"}, // })); REQUIRE(!HasMessage(src, {"tmain()", "B", "e()"})); }); - - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "b()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "c()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "d()")); - REQUIRE_THAT(src, !HasCall(_A("tmain()"), _A("B"), "e()")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = {FindMessage(j, "tmain()", "A", "a()"), - FindMessage(j, "tmain()", "A", "b()"), - FindMessage(j, "tmain()", "A", "c()"), - FindMessage(j, "tmain()", "A", "d()")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - using mermaid::HasCallInControlCondition; - - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "b()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "c()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "d()")); - REQUIRE_THAT(src, !HasCall(_A("tmain()"), _A("B"), "e()")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } \ No newline at end of file diff --git a/tests/t20029/test_case.h b/tests/t20029/test_case.h index a03d527e..c28a6860 100644 --- a/tests/t20029/test_case.h +++ b/tests/t20029/test_case.h @@ -61,137 +61,4 @@ TEST_CASE("t20029") "Repeat until send() succeeds\\n" "or retry count is exceeded")); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT( - src, HasCall(_A("tmain()"), _A("ConnectionPool"), "connect()")); - REQUIRE_THAT(src, - HasCallInControlCondition(_A("tmain()"), - _A("Encoder>"), - "send(std::string &&)")); - - REQUIRE_THAT(src, - HasCall(_A("Encoder>"), - _A("Encoder>"), - "encode(std::string &&)")); - - REQUIRE_THAT(src, - HasCall(_A("Encoder>"), - _A("encode_b64(std::string &&)"), "")); - - REQUIRE_THAT(src, - HasCallInControlCondition(_A("Retrier"), - _A("ConnectionPool"), "send(const std::string &)")); - - REQUIRE_THAT(src, - !HasCall( - _A("ConnectionPool"), _A("ConnectionPool"), - "connect_impl()")); - - REQUIRE_THAT(src, - HasMessageComment(_A("tmain()"), - "Establish connection to the\\n" - "remote server synchronously")); - - REQUIRE_THAT(src, - HasMessageComment(_A("tmain()"), - "Repeat for each line in the\\n" - "input stream")); - - REQUIRE_THAT(src, - HasMessageComment(_A("Encoder>"), - "Encode the message using\\n" - "Base64 encoding and pass\\n" - "it to the next layer")); - - REQUIRE_THAT(src, - HasMessageComment(_A("Retrier"), - "Repeat until send\\(\\) succeeds\\n" - "or retry count is exceeded")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - REQUIRE(!j["participants"].is_null()); - - std::vector messages = { - FindMessage(j, "tmain()", "ConnectionPool", "connect()"), - FindMessage(j, "tmain()", "Encoder>", - "send(std::string &&)")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - using mermaid::HasCallInControlCondition; - using mermaid::HasMessageComment; - - REQUIRE_THAT( - src, HasCall(_A("tmain()"), _A("ConnectionPool"), "connect()")); - REQUIRE_THAT(src, - HasCallInControlCondition(_A("tmain()"), - _A("Encoder>"), - "send(std::string &&)")); - - REQUIRE_THAT(src, - HasCall(_A("Encoder>"), - _A("Encoder>"), - "encode(std::string &&)")); - - REQUIRE_THAT(src, - HasCall(_A("Encoder>"), - _A("encode_b64(std::string &&)"), "")); - - REQUIRE_THAT(src, - HasCallInControlCondition(_A("Retrier"), - _A("ConnectionPool"), "send(const std::string &)")); - - REQUIRE_THAT(src, - !HasCall( - _A("ConnectionPool"), _A("ConnectionPool"), - "connect_impl()")); - - REQUIRE_THAT(src, - HasMessageComment(_A("tmain()"), - "Establish connection to the
" - "remote server synchronously")); - - REQUIRE_THAT(src, - HasMessageComment(_A("tmain()"), - "Repeat for each line in the
" - "input stream")); - - REQUIRE_THAT(src, - HasMessageComment(_A("Encoder>"), - "Encode the message using
" - "Base64 encoding and pass
" - "it to the next layer")); - - REQUIRE_THAT(src, - HasMessageComment(_A("Retrier"), - "Repeat until send\\(\\) succeeds
" - "or retry count is exceeded")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - } - */ } \ No newline at end of file diff --git a/tests/t20041/test_case.h b/tests/t20041/test_case.h index 7e8bb3ed..044de4a7 100644 --- a/tests/t20041/test_case.h +++ b/tests/t20041/test_case.h @@ -36,64 +36,4 @@ TEST_CASE("t20041") {"A", "A", "print()"}, // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("A"), - "print(int,double,std::string)")); - REQUIRE_THAT(src, - HasCall(_A("A"), - _A("A"), "print(double,std::string)")); - REQUIRE_THAT(src, - HasCall(_A("A"), _A("A"), - "print(std::string)")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), - "print()")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = { - FindMessage(j, "tmain()", "A", - "print(int,double,std::string)"), - FindMessage(j, "A", - "A", "print(double,std::string)"), FindMessage(j, - "A", "A", "print(std::string)"), - FindMessage(j, "A", "A", "print()")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("A"), - "print(int,double,std::string)")); - REQUIRE_THAT(src, - HasCall(_A("A"), - _A("A"), "print(double,std::string)")); - REQUIRE_THAT(src, - HasCall(_A("A"), _A("A"), - "print(std::string)")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t20042/test_case.h b/tests/t20042/test_case.h index 31db9cc9..4a36b7b0 100644 --- a/tests/t20042/test_case.h +++ b/tests/t20042/test_case.h @@ -34,46 +34,4 @@ TEST_CASE("t20042") {"BHandler", "BHandler", "handle(B &) const"}, // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("AHandler"), "operator()(A &) - const")); REQUIRE_THAT( src, HasCall(_A("AHandler"), _A("AHandler"), - "handle(A &) const")); REQUIRE_THAT(src, HasCall(_A("tmain()"), - _A("BHandler"), "operator()(B &) const")); REQUIRE_THAT( src, - HasCall(_A("BHandler"), _A("BHandler"), "handle(B &) const")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("AHandler"), "operator()(A &) - const")); REQUIRE_THAT( src, HasCall(_A("AHandler"), _A("AHandler"), - "handle(A &) const")); REQUIRE_THAT(src, HasCall(_A("tmain()"), - _A("BHandler"), "operator()(B &) const")); REQUIRE_THAT( src, - HasCall(_A("BHandler"), _A("BHandler"), "handle(B &) const")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t20043/test_case.h b/tests/t20043/test_case.h index 6a17feb1..60ee3d59 100644 --- a/tests/t20043/test_case.h +++ b/tests/t20043/test_case.h @@ -37,47 +37,4 @@ TEST_CASE("t20043") REQUIRE(!HasMessage(src, {"C", "B", "b()"})); REQUIRE(!HasMessage(src, {"B", "A", "a()"})); }); -/* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, !HasCall(_A("tmain()"), _A("F"), "f()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("D"), "d()")); - - REQUIRE_THAT(src, HasCall(_A("D"), _A("C"), "c()")); - REQUIRE_THAT(src, !HasCall(_A("D"), _A("detail::E"), "e()")); - REQUIRE_THAT(src, !HasCall(_A("C"), _A("B"), "b()")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("A"), "a()")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, !HasCall(_A("tmain()"), _A("F"), "f()")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("D"), "d()")); - - REQUIRE_THAT(src, HasCall(_A("D"), _A("C"), "c()")); - REQUIRE_THAT(src, !HasCall(_A("D"), _A("detail::E"), "e()")); - REQUIRE_THAT(src, !HasCall(_A("C"), _A("B"), "b()")); - REQUIRE_THAT(src, !HasCall(_A("B"), _A("A"), "a()")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } \ No newline at end of file diff --git a/tests/t20044/.clang-uml b/tests/t20044/.clang-uml index 3526dcf7..bb1a0dcc 100644 --- a/tests/t20044/.clang-uml +++ b/tests/t20044/.clang-uml @@ -6,7 +6,7 @@ diagrams: glob: - t20044.cc type_aliases: - "detail::expected": result_t + "clanguml::t20044::detail::expected": result_t generate_message_comments: true include: namespaces: diff --git a/tests/t20044/test_case.h b/tests/t20044/test_case.h index 8ff25df6..66e52d93 100644 --- a/tests/t20044/test_case.h +++ b/tests/t20044/test_case.h @@ -24,9 +24,11 @@ TEST_CASE("t20044") CHECK_SEQUENCE_MODEL("t20044", "t20044_sequence"); CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(!IsClassParticipant(src, "detail::expected")); + REQUIRE(IsClassParticipant(src, "result_t")); + REQUIRE(MessageOrder(src, { - // {"tmain()", "R", "R((lambda at t20044.cc:74:9) &&)"}, // {"R", "tmain()::(lambda t20044.cc:74:9)", "operator()() const"}, // @@ -36,86 +38,22 @@ TEST_CASE("t20044") "operator()() const"}, // {"tmain()::(lambda t20044.cc:84:18)", "A", "a5()"}, // - {"tmain()", "A", "a1() const"}, // - {"A", "detail::expected", "expected(int)"}, // + {"tmain()", "A", "a1() const"}, // + {"A", "result_t", "expected(int)"}, // - {"tmain()", "detail::expected", + {"tmain()", "result_t", "and_then((lambda at t20044.cc:90:19) &&)"}, // - {"detail::expected", - "tmain()::(lambda t20044.cc:90:19)", + {"result_t", "tmain()::(lambda t20044.cc:90:19)", "operator()(auto &&) const"}, // {"tmain()::(lambda t20044.cc:90:19)", "A", "a2(int) const"}, // - {"A", "detail::expected", "expected(int)"}, // + {"A", "result_t", "expected(int)"}, // - {"tmain()", "detail::expected", + {"tmain()", "result_t", "and_then(result_t (&)(int))"}, // // - {"tmain()", "detail::expected", + {"tmain()", "result_t", "and_then(std::function &)"}, // // - {"tmain()", "detail::expected", + {"tmain()", "result_t", "value() const"}, // // - })); }); -/* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, - HasCall( - _A("tmain()"), _A("R"), "R((lambda at t20044.cc:74:9) &&)")); - REQUIRE_THAT(src, - HasCall(_A("R"), _A("tmain()::(lambda t20044.cc:74:9)"), - "operator()()")); - REQUIRE_THAT(src, - HasCall(_A("tmain()::(lambda t20044.cc:74:9)"), _A("A"), "a()")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("tmain()::(lambda t20044.cc:84:18)"), - "operator()()")); - REQUIRE_THAT(src, - HasCall(_A("tmain()::(lambda t20044.cc:84:18)"), _A("A"), "a5()")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a1()")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("detail::expected"), - "and_then((lambda at t20044.cc:90:19) &&)")); - - REQUIRE_THAT(src, - HasCall(_A("detail::expected"), - _A("tmain()::(lambda t20044.cc:90:19)"), - "operator()(auto &&) const")); - - REQUIRE_THAT(src, - HasCall( - _A("tmain()::(lambda t20044.cc:90:19)"), _A("A"), "a2(int)")); - - REQUIRE_THAT(src, - HasCall( - _A("A"), _A("detail::expected"), "expected(int)")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsClass; - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } \ No newline at end of file diff --git a/tests/t20045/test_case.h b/tests/t20045/test_case.h index fe49289e..8e4b43e5 100644 --- a/tests/t20045/test_case.h +++ b/tests/t20045/test_case.h @@ -32,60 +32,32 @@ TEST_CASE("t20045") "a1<(lambda at t20045.cc:35:18)>((lambda at " "t20045.cc:35:18) &&)", ""}, // + {"a1<(lambda at t20045.cc:35:18)>((lambda at t20045.cc:35:18) " + "&&)", + "tmain()::(lambda t20045.cc:35:18)", + "operator()(auto &&) const"}, // + {"tmain()::(lambda t20045.cc:35:18)", "a3(int)", ""}, // + + {"tmain()", + "a1<(lambda at t20045.cc:37:18)>((lambda at " + "t20045.cc:37:18) " + "&&)", + ""}, // + {"a1<(lambda at t20045.cc:37:18)>((lambda at t20045.cc:37:18) " + "&&)", + "tmain()::(lambda t20045.cc:37:18)", + "operator()(auto &&) const"}, // + {"tmain()::(lambda t20045.cc:37:18)", "B", "b1(int)"}, // + + {"tmain()", + "a1<(lambda at t20045.cc:39:18)>((lambda at " + "t20045.cc:39:18) &&)", + ""}, // + {"a1<(lambda at t20045.cc:39:18)>((lambda at " + "t20045.cc:39:18) &&)", + "tmain()::(lambda t20045.cc:39:18)", + "operator()(auto &&) const"}, // + {"tmain()::(lambda t20045.cc:39:18)", "C", "get_x() const"} // })); }); -/* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("a2(int)"), "")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), - _A("a1<(lambda at t20045.cc:35:18)>((lambda at " - "t20045.cc:35:18) &&)"), - "")); - - REQUIRE_THAT(src, - HasCall(_A("a1<(lambda at t20045.cc:35:18)>((lambda at " - "t20045.cc:35:18) &&)"), - _A("tmain()::(lambda t20045.cc:35:18)"), - "operator()(auto &&) const")); - - REQUIRE_THAT(src, - HasCall( - _A("tmain()::(lambda t20045.cc:35:18)"), _A("a3(int)"), "")); - - REQUIRE_THAT(src, - HasCall( - _A("tmain()::(lambda t20045.cc:37:18)"), _A("B"), "b1(int)")); - - REQUIRE_THAT(src, - HasCall( - _A("tmain()::(lambda t20045.cc:39:18)"), _A("C"), "get_x()")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsClass; - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } - */ } \ No newline at end of file diff --git a/tests/t20046/test_case.h b/tests/t20046/test_case.h index c4ddbacb..89d328ff 100644 --- a/tests/t20046/test_case.h +++ b/tests/t20046/test_case.h @@ -16,80 +16,41 @@ * limitations under the License. */ -TEST_CASE("t20046", "[test-case][sequence]") +TEST_CASE("t20046") { - auto [config, db] = load_config("t20046"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20046_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20046", "t20046_sequence"); - REQUIRE(diagram->name == "t20046_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + {// + {"tmain()", "tmain()::(lambda t20046.cc:13:15)", + "operator()(auto &&) const"}, // + {"tmain()::(lambda t20046.cc:13:15)", + "tmain()::(lambda t20046.cc:13:15)::(lambda " + "t20046.cc:14:16)", + "operator()(auto &&) const"}, // + {"tmain()::(lambda t20046.cc:13:15)::(lambda " + "t20046.cc:14:16)", + "a2(int)", ""}, // - auto model = generate_sequence_diagram(*db, diagram); + {"tmain()", + "a1<(lambda at t20046.cc:19:9)>((lambda at t20046.cc:19:9) " + "&&)", + ""}, + {"a1<(lambda at t20046.cc:19:9)>((lambda at t20046.cc:19:9) " + "&&)", + "tmain()::(lambda t20046.cc:19:9)", + "operator()(auto &&) const"}, // + {"tmain()::(lambda t20046.cc:19:9)", + "tmain()::(lambda t20046.cc:19:9)::(lambda " + "t20046.cc:19:34)", + "operator()(auto &&) const"}, // + {"tmain()::(lambda t20046.cc:19:9)::(lambda t20046.cc:19:34)", + "a3(int)", ""} - REQUIRE(model->name() == "t20046_sequence"); - - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("tmain()::(lambda t20046.cc:13:15)"), - "operator()(auto &&) const")); - REQUIRE_THAT(src, - HasCall(_A("tmain()::(lambda t20046.cc:13:15)"), - _A("tmain()::(lambda t20046.cc:13:15)::(lambda " - "t20046.cc:14:16)"), - "operator()(auto &&) const")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()::(lambda t20046.cc:13:15)::(lambda " - "t20046.cc:14:16)"), - _A("a2(int)"), "")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), - _A("a1<(lambda at t20046.cc:19:9)>((lambda at t20046.cc:19:9) " - "&&)"), - "")); - - REQUIRE_THAT(src, - HasCall( - _A("a1<(lambda at t20046.cc:19:9)>((lambda at t20046.cc:19:9) " - "&&)"), - _A("tmain()::(lambda t20046.cc:19:9)"), - "operator()(auto &&) const")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()::(lambda t20046.cc:19:9)"), - _A("tmain()::(lambda t20046.cc:19:9)::(lambda " - "t20046.cc:19:34)"), - "operator()(auto &&) const")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()::(lambda t20046.cc:19:9)::(lambda " - "t20046.cc:19:34)"), - _A("a3(int)"), "")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsClass; - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + })); + }); } \ No newline at end of file diff --git a/tests/t20047/test_case.h b/tests/t20047/test_case.h index 3643c2db..ab0e68f2 100644 --- a/tests/t20047/test_case.h +++ b/tests/t20047/test_case.h @@ -16,50 +16,24 @@ * limitations under the License. */ -TEST_CASE("t20047", "[test-case][sequence]") +TEST_CASE("t20047") { - auto [config, db] = load_config("t20047"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20047_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20047", "t20047_sequence"); - REQUIRE(diagram->name == "t20047_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "a1(int)", ""}, // + {"tmain()", "a2(int)", ""}, // + {"tmain()", "a3(int)", ""}, // + {"tmain()", "a4(int)", ""}, // + {"tmain()", "a5(int)", ""}, // + {"tmain()", "a6(int)", ""}, // - auto model = generate_sequence_diagram(*db, diagram); - - REQUIRE(model->name() == "t20047_sequence"); - - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("a1(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("a2(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("a3(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("a4(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("a5(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("a6(int)"), "")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsClass; - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + })); + }); } \ No newline at end of file diff --git a/tests/t20048/test_case.h b/tests/t20048/test_case.h index aa83b02f..a45632ba 100644 --- a/tests/t20048/test_case.h +++ b/tests/t20048/test_case.h @@ -16,76 +16,40 @@ * limitations under the License. */ -TEST_CASE("t20048", "[test-case][sequence]") +TEST_CASE("t20048") { - auto [config, db] = load_config("t20048"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20048_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20048", "t20048_sequence"); - REQUIRE(diagram->name == "t20048_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "a3(int)", ""}, // + {"tmain()", "a2(int)", ""}, // + {"tmain()", "a1(int)", ""}, // + {"tmain()", "tmain()::(lambda t20048.cc:26:11)", + "operator()(auto &&) const"}, // + {"tmain()::(lambda t20048.cc:26:11)", "a4(int)", ""}, // + {"tmain()", "a6(int)", ""}, // + {"tmain()", "a5(int)", ""}, // + {"tmain()", "a7(int)", ""}, // - auto model = generate_sequence_diagram(*db, diagram); - - REQUIRE(model->name() == "t20048_sequence"); - - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("a3(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("a2(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("a1(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("a5(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("a6(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("a7(int)"), "")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("tmain()::(lambda t20048.cc:26:11)"), - "operator()(auto &&) const")); - REQUIRE_THAT(src, - HasCall( - _A("tmain()::(lambda t20048.cc:26:11)"), _A("a4(int)"), "")); - - REQUIRE_THAT(src, - HasMessageComment(_A("tmain()"), - "a1\\(\\) adds `1` to the result\\n" - "of a2\\(\\)")); - REQUIRE_THAT(src, - HasMessageComment(_A("tmain()"), - "This lambda calls a4\\(\\) which\\n" - "adds `4` to it's argument")); - REQUIRE_THAT(src, - HasMessageComment( - _A("tmain()"), "a6\\(\\) adds `1` to its argument")); - REQUIRE_THAT(src, - HasMessageComment(_A("tmain()"), - "a5\\(\\) adds `1` to the result\\n" - "of a6\\(\\)")); - REQUIRE_THAT(src, - HasMessageComment( - _A("tmain()"), "a7\\(\\) is called via add std::async")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsClass; - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + })); + REQUIRE(HasMessageComment(src, "tmain()", + "a1() adds `1` to the result\\n" + "of a2()")); + REQUIRE(HasMessageComment(src, "tmain()", + "This lambda calls a4() which\\n" + "adds `4` to it's argument")); + REQUIRE( + HasMessageComment(src, "tmain()", "a6() adds `1` to its argument")); + REQUIRE(HasMessageComment(src, "tmain()", + "a5() adds `1` to the result\\n" + "of a6()")); + REQUIRE(HasMessageComment( + src, "tmain()", "a7() is called via add std::async")); + }); } \ No newline at end of file diff --git a/tests/t20049/test_case.h b/tests/t20049/test_case.h index f73722b9..6655ff89 100644 --- a/tests/t20049/test_case.h +++ b/tests/t20049/test_case.h @@ -16,66 +16,25 @@ * limitations under the License. */ -TEST_CASE("t20049", "[test-case][sequence]") +TEST_CASE("t20049") { - auto [config, db] = load_config("t20049"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20049_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20049", "t20049_sequence"); - REQUIRE(diagram->name == "t20049_sequence"); - - auto model = generate_sequence_diagram(*db, diagram); - - REQUIRE(model->name() == "t20049_sequence"); - - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), - _A("vector_square_add(float *,float *,float *,int)"), "")); - REQUIRE_THAT(src, - HasCall(_A("vector_square_add(float *,float *,float *,int)"), - _A("square(float)"), "")); - REQUIRE_THAT(src, - HasCall(_A("vector_square_add(float *,float *,float *,int)"), - _A("add(float,float)"), "")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), - _A("<< CUDA Kernel >>
vector_square_add(float *,float " - "*,float *,int)"), - "")); - REQUIRE_THAT(src, - HasCall(_A("<< CUDA Kernel >>
vector_square_add(float *,float " - "*,float *,int)"), - _A("<< CUDA Device >>
square(float)"), "")); - REQUIRE_THAT(src, - HasCall(_A("<< CUDA Kernel >>
vector_square_add(float *,float " - "*,float *,int)"), - _A("<< CUDA Device >>
add(float,float)"), "")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "vector_square_add(float *,float *,float *,int)", + ""}, // + {"vector_square_add(float *,float *,float *,int)", + "square(float)", ""}, // + {"vector_square_add(float *,float *,float *,int)", + "square(float)", ""}, // + {"vector_square_add(float *,float *,float *,int)", + "add(float,float)", ""}, // + })); + }); } \ No newline at end of file diff --git a/tests/t20050/test_case.h b/tests/t20050/test_case.h index 935f3e8a..33d0b9db 100644 --- a/tests/t20050/test_case.h +++ b/tests/t20050/test_case.h @@ -16,65 +16,27 @@ * limitations under the License. */ -TEST_CASE("t20050", "[test-case][sequence]") +TEST_CASE("t20050") { - auto [config, db] = load_config("t20050"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20050_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20050", "t20050_sequence"); - REQUIRE(diagram->name == "t20050_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(IsFileParticipant(src, "t20050.cu")); - auto model = generate_sequence_diagram(*db, diagram); - - REQUIRE(model->name() == "t20050_sequence"); - - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, - HasCall(_A("t20050.cu"), _A("t20050.cu"), - "<< CUDA Kernel >>\\\\nvector_square_add(float *,float *,float " - "*,int)")); - REQUIRE_THAT(src, - HasCall(_A("t20050.cu"), _A("t20050.cu"), - "<< CUDA Device >>\\\\nsquare(float)")); - REQUIRE_THAT(src, - HasCall(_A("t20050.cu"), _A("t20050.cu"), - "<< CUDA Device >>\\\\nadd(float,float)")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, - HasCall(_A("t20050.cu"), _A("t20050.cu"), - "<< CUDA Kernel >>
vector_square_add(float *,float *,float " - "*,int)")); - REQUIRE_THAT(src, - HasCall(_A("t20050.cu"), _A("t20050.cu"), - "<< CUDA Device >>
square(float)")); - REQUIRE_THAT(src, - HasCall(_A("t20050.cu"), _A("t20050.cu"), - "<< CUDA Device >>
add(float,float)")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(MessageOrder(src, + { + // + {Entrypoint{}, "t20050.cu", "tmain()"}, // + {"t20050.cu", "t20050.cu", + "vector_square_add(float *,float *,float *,int)", + CUDAKernel{}}, // + {"t20050.cu", "t20050.cu", "square(float)", CUDADevice{}}, // + {"t20050.cu", "t20050.cu", "square(float)", CUDADevice{}}, // + {"t20050.cu", "t20050.cu", "add(float,float)", + CUDADevice{}}, // + })); + }); } \ No newline at end of file diff --git a/tests/t20051/test_case.h b/tests/t20051/test_case.h index 0c3806f0..838536bd 100644 --- a/tests/t20051/test_case.h +++ b/tests/t20051/test_case.h @@ -16,66 +16,21 @@ * limitations under the License. */ -TEST_CASE("t20051", "[test-case][sequence]") +TEST_CASE("t20051") { - auto [config, db] = load_config("t20051"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20051_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20051", "t20051_sequence"); - REQUIRE(diagram->name == "t20051_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(!IsFileParticipant(src, "t20051.cu")); - auto model = generate_sequence_diagram(*db, diagram); - - REQUIRE(model->name() == "t20051_sequence"); - - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), - _A("vector_square_add(float *,float *,float *,int)"), "")); - REQUIRE_THAT(src, - !HasCall(_A("vector_square_add(float *,float *,float *,int)"), - _A("square(float)"), "")); - REQUIRE_THAT(src, - !HasCall(_A("vector_square_add(float *,float *,float *,int)"), - _A("add(float,float)"), "")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), - _A("<< CUDA Kernel >>
vector_square_add(float *,float " - "*,float *,int)"), - "")); - REQUIRE_THAT(src, - !HasCall(_A("<< CUDA Kernel >>
vector_square_add(float *,float " - "*,float *,int)"), - _A("<< CUDA Device >>
square(float)"), "")); - REQUIRE_THAT(src, - !HasCall(_A("<< CUDA Kernel >>
vector_square_add(float *,float " - "*,float *,int)"), - _A("<< CUDA Device >>
add(float,float)"), "")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "vector_square_add(float *,float *,float *,int)", + ""}, // + })); + }); } \ No newline at end of file diff --git a/tests/t20052/test_case.h b/tests/t20052/test_case.h index 60c38e60..24ef4fe2 100644 --- a/tests/t20052/test_case.h +++ b/tests/t20052/test_case.h @@ -16,161 +16,48 @@ * limitations under the License. */ -TEST_CASE("t20052", "[test-case][sequence]") +TEST_CASE("t20052") { - auto [config, db] = load_config("t20052"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20052_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20052", "t20052_sequence"); - REQUIRE(diagram->name == "t20052_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(!IsFileParticipant(src, "t20052.cu")); - auto model = generate_sequence_diagram(*db, diagram); + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "A", "a()"}, // + {"A", "A", "aa()"}, // + {"A", "A", "aaa()"}, // - REQUIRE(model->name() == "t20052_sequence"); + {"tmain()", "B", "b()"}, // + {"B", "B", "bb()"}, // + {"B", "B", "bbb()"}, // - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); + {"tmain()", "C", "c()"}, // + {"C", "C", "cc()"}, // + {"C", "C", "ccc()"}, // - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); + {"tmain()", "A", "a()"}, // + {"A", "A", "aa()"}, // + {"A", "A", "aaa()"}, // - // Check if all calls exist - REQUIRE_THAT(src, - !HasCall(_A("tmain()"), _A("tmain()::(lambda t20052.cc:67:20)"), - "operator()() const")); - REQUIRE_THAT(src, - !HasCall(_A("tmain()::(lambda t20052.cc:67:20)"), _A("A"), "a()")); + {"tmain()", "B", "b()"}, // + {"B", "B", "bb()"}, // + {"B", "B", "bbb()"}, // - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "aa()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "aaa()")); + {"tmain()", "R<(lambda at t20052.cc:86:9)>", + "R((lambda at t20052.cc:86:9) &&)"}, // - REQUIRE_THAT(src, - !HasCall(_A("tmain()::(lambda t20052.cc:67:20)"), _A("B"), "b()")); + {"tmain()", "R<(lambda at t20052.cc:86:9)>", "r()"}, // + {"R<(lambda at t20052.cc:86:9)>", "C", "c()"}, // + {"C", "C", "cc()"}, // + {"C", "C", "ccc()"}, // - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("B"), "bb()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("B"), "bbb()")); - - REQUIRE_THAT(src, - !HasCall(_A("tmain()::(lambda t20052.cc:80:20)"), _A("C"), "c()")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("C"), "c()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "cc()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "ccc()")); - - REQUIRE_THAT(src, - !HasCall(_A("tmain()::(lambda t20052.cc:80:20)"), - _A("tmain()::(lambda t20052.cc:67:20)"), "operator()() const")); - - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "ccc()")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("R<(lambda at t20052.cc:86:9)>"), - "R((lambda at t20052.cc:86:9) &&)")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("R<(lambda at t20052.cc:86:9)>"), "r()")); - REQUIRE_THAT(src, - !HasCall(_A("R<(lambda at t20052.cc:86:9)>"), - _A("tmain()::(lambda t20052.cc:86:9)"), "operator()() const")); - - REQUIRE_THAT( - src, HasCall(_A("R<(lambda at t20052.cc:86:9)>"), _A("C"), "c()")); - - REQUIRE_THAT(src, - !HasCall(_A("tmain()"), _A("tmain()::(lambda t20052.cc:94:9)"), - "operator()(auto) const")); - REQUIRE_THAT(src, - !HasCall(_A("tmain()::(lambda t20052.cc:94:9)"), _A("D"), - "add5(int) const")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("D"), "add5(int) const")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = { - FindMessage(j, "tmain()", "A", "a()"), - FindMessage(j, "A", "A", "aa()"), - FindMessage(j, "A", "A", "aaa()"), - FindMessage(j, "tmain()", "B", "b()"), - FindMessage(j, "B", "B", "bb()"), - FindMessage(j, "B", "B", "bbb()"), - FindMessage(j, "tmain()", "C", "c()"), - FindMessage(j, "C", "C", "cc()"), - FindMessage(j, "C", "C", "ccc()"), - FindMessage(j, "tmain()", "R<(lambda at t20052.cc:86:9)>", "r()"), - FindMessage(j, "R<(lambda at t20052.cc:86:9)>", "C", "c()"), - }; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, - !HasCall(_A("tmain()"), _A("tmain()::(lambda t20052.cc:67:20)"), - "operator()() const")); - REQUIRE_THAT(src, - !HasCall(_A("tmain()::(lambda t20052.cc:67:20)"), _A("A"), "a()")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "aa()")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "aaa()")); - - REQUIRE_THAT(src, - !HasCall(_A("tmain()::(lambda t20052.cc:67:20)"), _A("B"), "b()")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("B"), "bb()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("B"), "bbb()")); - - REQUIRE_THAT(src, - !HasCall(_A("tmain()::(lambda t20052.cc:80:20)"), _A("C"), "c()")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("C"), "c()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "cc()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "ccc()")); - - REQUIRE_THAT(src, - !HasCall(_A("tmain()::(lambda t20052.cc:80:20)"), - _A("tmain()::(lambda t20052.cc:67:20)"), "operator()() const")); - - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "ccc()")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("R<(lambda at t20052.cc:86:9)>"), - "R((lambda at t20052.cc:86:9) &&)")); - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("R<(lambda at t20052.cc:86:9)>"), "r()")); - REQUIRE_THAT(src, - !HasCall(_A("R<(lambda at t20052.cc:86:9)>"), - _A("tmain()::(lambda t20052.cc:86:9)"), "operator()() const")); - - REQUIRE_THAT( - src, HasCall(_A("R<(lambda at t20052.cc:86:9)>"), _A("C"), "c()")); - - REQUIRE_THAT(src, - !HasCall(_A("tmain()"), _A("tmain()::(lambda t20052.cc:94:9)"), - "operator()(auto) const")); - REQUIRE_THAT(src, - !HasCall(_A("tmain()::(lambda t20052.cc:94:9)"), _A("D"), - "add5(int) const")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("D"), "add5(int) const")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + {"tmain()", "D", "add5(int) const"} // + })); + }); } \ No newline at end of file diff --git a/tests/t20053/test_case.h b/tests/t20053/test_case.h index 29dab3e6..a3b54a9a 100644 --- a/tests/t20053/test_case.h +++ b/tests/t20053/test_case.h @@ -16,55 +16,28 @@ * limitations under the License. */ -TEST_CASE("t20053", "[test-case][sequence]") +TEST_CASE("t20053") { - auto [config, db] = load_config("t20053"); + using namespace clanguml::test; - auto diagram = config.diagrams["t20053_sequence"]; + auto [config, db, diagram, model] = + CHECK_SEQUENCE_MODEL("t20053", "t20053_sequence"); - REQUIRE(diagram->name == "t20053_sequence"); + CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { + REQUIRE(!IsFileParticipant(src, "t20053.cu")); - auto model = generate_sequence_diagram(*db, diagram); + REQUIRE(MessageOrder(src, + { + // + {"tmain()", "a2(int)", ""}, // - REQUIRE(model->name() == "t20053_sequence"); - - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("a2(int)"), "")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), - _A("a1<(lambda at t20053.cc:23:9)>((lambda at t20053.cc:23:9) " - "&&)"), - "")); - - REQUIRE_THAT(src, - HasCall(_A("a1<(lambda at t20053.cc:23:9)>((lambda at " - "t20053.cc:23:9) &&)"), - _A("a3(int)"), "")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::AliasMatcher _A(src); - using mermaid::IsClass; - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } + {"tmain()", + "a1<(lambda at t20053.cc:23:9)>((lambda at t20053.cc:23:9) " + "&&)", + ""}, // + {"a1<(lambda at t20053.cc:23:9)>((lambda at t20053.cc:23:9) " + "&&)", + "a3(int)", ""}, // + })); + }); } \ No newline at end of file diff --git a/tests/test_cases.cc b/tests/test_cases.cc index fef05561..6ac3872e 100644 --- a/tests/test_cases.cc +++ b/tests/test_cases.cc @@ -1221,25 +1221,25 @@ template <> bool IsClass(json_t d, std::string name) #include "t20038/test_case.h" #include "t20039/test_case.h" #include "t20040/test_case.h" - #include "t20041/test_case.h" #include "t20042/test_case.h" #include "t20043/test_case.h" #include "t20044/test_case.h" #include "t20045/test_case.h" -/* #include "t20046/test_case.h" #include "t20047/test_case.h" #include "t20048/test_case.h" + #if defined(ENABLE_CUDA_TEST_CASES) #include "t20049/test_case.h" #include "t20050/test_case.h" #include "t20051/test_case.h" #endif + #include "t20052/test_case.h" #include "t20053/test_case.h" -*/ + /// /// Package diagram tests /// diff --git a/tests/test_cases.h b/tests/test_cases.h index b85defb3..e4d3fccd 100644 --- a/tests/test_cases.h +++ b/tests/test_cases.h @@ -88,6 +88,9 @@ struct Entrypoint { }; struct Exitpoint { }; +struct CUDAKernel { }; +struct CUDADevice { }; + struct InControlCondition { }; struct Response { }; struct NamespacePackage { }; @@ -246,8 +249,12 @@ struct mermaid_t : public diagram_source_t { util::replace_all(name, "[", "\\["); util::replace_all(name, "]", "\\]"); - patterns.push_back( - std::regex{"participant\\s" + alias_regex + "\\sas\\s" + name+"\\n"}); + patterns.push_back(std::regex{ + "participant\\s" + alias_regex + "\\sas\\s" + name + "\\n"}); + patterns.push_back(std::regex{"participant\\s" + alias_regex + + "\\sas\\s<< CUDA Kernel >>
" + name + "\\n"}); + patterns.push_back(std::regex{"participant\\s" + alias_regex + + "\\sas\\s<< CUDA Device >>
" + name + "\\n"}); std::smatch base_match; @@ -468,6 +475,8 @@ struct Message { , is_static{has_type()} , is_incontrolcondition{has_type()} , is_response{has_type()} + , is_cuda_kernel{has_type()} + , is_cuda_device{has_type()} { } @@ -497,6 +506,8 @@ struct Message { bool is_exitpoint{false}; bool is_incontrolcondition{false}; bool is_response{false}; + bool is_cuda_kernel{false}; + bool is_cuda_device{false}; }; /// @@ -1197,6 +1208,11 @@ int64_t FindMessage( util::replace_all(msg_str, "]", "\\]"); util::replace_all(msg_str, "+", "\\+"); + if (msg.is_cuda_kernel) + msg_str = fmt::format("<< CUDA Kernel >>\\\\n{}", msg_str); + if (msg.is_cuda_device) + msg_str = fmt::format("<< CUDA Device >>\\\\n{}", msg_str); + std::string style; if (msg.is_static) style = "__"; @@ -1750,6 +1766,11 @@ int64_t FindMessage( util::replace_all(msg_str, "]", "\\]"); util::replace_all(msg_str, "+", "\\+"); + if (msg.is_cuda_kernel) + msg_str = fmt::format("<< CUDA Kernel >>
{}", msg_str); + if (msg.is_cuda_device) + msg_str = fmt::format("<< CUDA Device >>
{}", msg_str); + std::string call_pattern{"__INVALID__"}; if (msg.is_entrypoint) { @@ -2388,6 +2409,16 @@ int find_message_impl(const nlohmann::json &j, const std::string &from, auto from_p = get_participant(j, from); auto to_p = get_participant(j, to); + if (!from_p) + throw std::runtime_error( + fmt::format("Cannot find participant {}", from)); + + if (!to_p) + throw std::runtime_error(fmt::format("Cannot find participant {}", to)); + + assert(from_p->is_object()); + assert(to_p->is_object()); + // TODO: support diagrams with multiple sequences... int count{0}; From 387b46f6836875c629c1a1f033c72e1b7f7740af Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Mon, 20 May 2024 21:56:54 +0200 Subject: [PATCH 09/15] Refactored sequence diagrams test cases (#266) --- tests/t20017/test_case.h | 88 +- tests/t20023/test_case.h | 1 - tests/t20030/test_case.h | 88 +- tests/t20031/test_case.h | 81 +- tests/t20032/test_case.h | 79 +- tests/t20033/test_case.h | 46 -- tests/t20034/test_case.h | 70 +- tests/t20035/test_case.h | 42 - tests/t20036/test_case.h | 64 -- tests/t20038/test_case.h | 103 --- tests/t20039/test_case.h | 48 +- tests/t20040/test_case.h | 62 -- tests/t20046/test_case.h | 3 +- tests/t20047/test_case.h | 1 - tests/test_cases.cc | 629 --------------- tests/test_cases.h | 1635 +------------------------------------- 16 files changed, 40 insertions(+), 3000 deletions(-) diff --git a/tests/t20017/test_case.h b/tests/t20017/test_case.h index 9ae03f82..30cc8778 100644 --- a/tests/t20017/test_case.h +++ b/tests/t20017/test_case.h @@ -27,93 +27,13 @@ TEST_CASE("t20017") REQUIRE(MessageOrder(src, { // - // {Entrypoint{}, "t20017.cc", "tmain()"}, // - {"t20017.cc", "include/t20017_a.h", "a3(int,int)"}, // + {Entrypoint{}, "t20017.cc", "tmain()"}, // + {"t20017.cc", "include/t20017_a.h", "a3(int,int)"}, // {"t20017.cc", "include/t20017_b.h", "b1(int,int)"}, // - /* {"t20017.cc", "include/t20017_a.h", "a2(int,int)"}, // + {"t20017.cc", "include/t20017_a.h", "a2(int,int)"}, // {"t20017.cc", "include/t20017_a.h", "a1(int,int)"}, // {"t20017.cc", "include/t20017_b.h", "b2(int,int)"}, // - {Exitpoint{}, "t20017.cc"}, //*/ + {Exitpoint{}, "t20017.cc"}, // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasEntrypoint(_A("t20017.cc"), "tmain()")); - REQUIRE_THAT(src, - HasCall(_A("t20017.cc"), _A("include/t20017_a.h"), "a1(int,int)")); - REQUIRE_THAT(src, - HasCall(_A("t20017.cc"), _A("include/t20017_a.h"), "a2(int,int)")); - REQUIRE_THAT(src, - HasCall(_A("t20017.cc"), _A("include/t20017_a.h"), "a3(int,int)")); - REQUIRE_THAT(src, - HasCall(_A("t20017.cc"), _A("include/t20017_b.h"), "b1(int,int)")); - REQUIRE_THAT(src, - HasCall( - _A("t20017.cc"), _A("include/t20017_b.h"), "b2(int,int)")); - REQUIRE_THAT(src, HasExitpoint(_A("t20017.cc"))); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - const auto &t20017_cc = get_participant(j, "t20017.cc"); - - CHECK(t20017_cc.has_value()); - - CHECK(t20017_cc.value()["type"] == "file"); - CHECK(t20017_cc.value()["name"] == "t20017.cc"); - CHECK(t20017_cc.value()["display_name"] == "t20017.cc"); - - std::vector messages = { - FindMessage(j, File("t20017.cc"), File("include/t20017_a.h"), - "a3(int,int)"), - FindMessage(j, File("t20017.cc"), File("include/t20017_b.h"), - "b1(int,int)"), - FindMessage(j, File("t20017.cc"), File("include/t20017_a.h"), - "a2(int,int)"), - FindMessage(j, File("t20017.cc"), File("include/t20017_a.h"), - "a1(int,int)"), - FindMessage(j, File("t20017.cc"), File("include/t20017_b.h"), - "b2(int,int)")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - using mermaid::HasEntrypoint; - using mermaid::HasExitpoint; - - REQUIRE_THAT(src, HasEntrypoint(_A("t20017.cc"), "tmain()")); - REQUIRE_THAT(src, - HasCall(_A("t20017.cc"), _A("include/t20017_a.h"), "a1(int,int)")); - REQUIRE_THAT(src, - HasCall(_A("t20017.cc"), _A("include/t20017_a.h"), "a2(int,int)")); - REQUIRE_THAT(src, - HasCall(_A("t20017.cc"), _A("include/t20017_a.h"), "a3(int,int)")); - REQUIRE_THAT(src, - HasCall(_A("t20017.cc"), _A("include/t20017_b.h"), "b1(int,int)")); - REQUIRE_THAT(src, - HasCall( - _A("t20017.cc"), _A("include/t20017_b.h"), "b2(int,int)")); - REQUIRE_THAT(src, HasExitpoint(_A("t20017.cc"))); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } \ No newline at end of file diff --git a/tests/t20023/test_case.h b/tests/t20023/test_case.h index a7cf3371..dec644c4 100644 --- a/tests/t20023/test_case.h +++ b/tests/t20023/test_case.h @@ -32,7 +32,6 @@ TEST_CASE("t20023") {"A", "A", "a2()"}, // {"A", "A", "a3()"}, // {"A", "A", "a4()"}, // - })); }); } \ No newline at end of file diff --git a/tests/t20030/test_case.h b/tests/t20030/test_case.h index c2b8fefb..88327c5d 100644 --- a/tests/t20030/test_case.h +++ b/tests/t20030/test_case.h @@ -26,83 +26,27 @@ TEST_CASE("t20030") CHECK_SEQUENCE_DIAGRAM(config, diagram, *model, [](const auto &src) { REQUIRE(MessageOrder(src, { + // + // "clanguml::t20030::tmain(int)" // {"tmain(int)", "magic()", ""}, // {"tmain(int)", "A", "A(int)"}, // {"tmain(int)", "A", "operator+=(int)"}, // {"A", "A", "add(int)"}, // - {"tmain(bool,int)", "A", "A()"}, // - // {"A", "A", "create()"}, // - // {"tmain(bool,int)", "A", "A()"}, // - // {"A", "A", "create()"}, // - // {"tmain(bool,int)", "A", "operator+=(int)"}, - // // - // {"A", "A", "add(int)"}, // - // {"tmain(bool,int)", "A", "operator=(const A - // &)"}, // - // {"A", "A", "set(int)"}, // - // {"tmain(bool,int)", "A", "value() const"} // + + // + // "clanguml::t20030::tmain(bool,int)" + // + {"tmain(bool,int)", "A", "A()"}, // + {"A", "A", "create()"}, // + {"tmain(bool,int)", "A", "A()"}, // + {"A", "A", "create()"}, // + {"tmain(bool,int)", "A", "operator+=(int)"}, // + // + {"A", "A", "add(int)"}, // + {"tmain(bool,int)", "A", "operator=(const A &)"}, // + {"A", "A", "set(int)"}, // + {"tmain(bool,int)", "A", "value() const"} // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain(int)"), _A("magic()"), "")); - - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "create()")); - REQUIRE_THAT( - src, HasCall(_A("tmain(int)"), _A("A"), "operator+=(int)")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "add(int)")); - - REQUIRE_THAT(src, HasCall(_A("tmain(bool,int)"), _A("A"), "A()")); - REQUIRE_THAT( - src, HasCall(_A("tmain(bool,int)"), _A("A"), - "operator+=(int)")); REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), - "add(int)")); REQUIRE_THAT(src, HasCall(_A("tmain(bool,int)"), _A("A"), - "operator=(const A &)")); REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), - "set(int)")); REQUIRE_THAT(src, HasCall(_A("tmain(bool,int)"), _A("A"), - "value()")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("tmain(int)"), _A("magic()"), "")); - - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "create()")); - REQUIRE_THAT( - src, HasCall(_A("tmain(int)"), _A("A"), "operator+=(int)")); - REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), "add(int)")); - - REQUIRE_THAT(src, HasCall(_A("tmain(bool,int)"), _A("A"), "A()")); - REQUIRE_THAT( - src, HasCall(_A("tmain(bool,int)"), _A("A"), - "operator+=(int)")); REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), - "add(int)")); REQUIRE_THAT(src, HasCall(_A("tmain(bool,int)"), _A("A"), - "operator=(const A &)")); REQUIRE_THAT(src, HasCall(_A("A"), _A("A"), - "set(int)")); REQUIRE_THAT(src, HasCall(_A("tmain(bool,int)"), _A("A"), - "value()")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t20031/test_case.h b/tests/t20031/test_case.h index 4fd9c885..12232577 100644 --- a/tests/t20031/test_case.h +++ b/tests/t20031/test_case.h @@ -31,73 +31,16 @@ TEST_CASE("t20031") {"tmain(bool,int)", "execute(std::function)", ""}, // {"tmain(bool,int)", "A", "value() const"} // })); + REQUIRE(!HasMessage(src, {"A", "A", "create()"})); + REQUIRE(!HasMessage(src, {"tmain(int)", "A", "operator+=(int)"})); + REQUIRE(!HasMessage(src, {"tmain(bool,int)", "A", "A()"})); + REQUIRE(!HasMessage(src, {"tmain(bool,int)", "A", "operator+=(int)"})); + REQUIRE(!HasMessage(src, {"A", "A", "add(int)"})); + REQUIRE( + !HasMessage(src, {"tmain(bool,int)", "A", "operator=(const A &)"})); + REQUIRE(!HasMessage(src, {"A", "A", "set(int)"})); + REQUIRE(!HasMessage(src, + {"tmain(bool,int)::(lambda ../../tests/t20031/t20031.cc:47:26)", + "zero()", ""})); }); -/* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, HasCall(_A("tmain(int)"), _A("magic()"), "")); - - REQUIRE_THAT(src, !HasCall(_A("A"), _A("A"), "create()")); - REQUIRE_THAT( - src, !HasCall(_A("tmain(int)"), _A("A"), "operator+=(int)")); - REQUIRE_THAT(src, !HasCall(_A("A"), _A("A"), "add(int)")); - - REQUIRE_THAT(src, !HasCall(_A("tmain(bool,int)"), _A("A"), "A()")); - REQUIRE_THAT( - src, !HasCall(_A("tmain(bool,int)"), _A("A"), "operator+=(int)")); - REQUIRE_THAT(src, !HasCall(_A("A"), _A("A"), "add(int)")); - REQUIRE_THAT(src, - !HasCall(_A("tmain(bool,int)"), _A("A"), "operator=(const A &)")); - REQUIRE_THAT(src, !HasCall(_A("A"), _A("A"), "set(int)")); - REQUIRE_THAT(src, HasCall(_A("tmain(bool,int)"), _A("A"), "value()")); - REQUIRE_THAT(src, - !HasCall(_A("tmain(bool,int)::(lambda " - "../../tests/t20031/t20031.cc:47:26)"), - _A("zero()"), "")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("tmain(int)"), _A("magic()"), "")); - - REQUIRE_THAT(src, !HasCall(_A("A"), _A("A"), "create()")); - REQUIRE_THAT( - src, !HasCall(_A("tmain(int)"), _A("A"), "operator+=(int)")); - REQUIRE_THAT(src, !HasCall(_A("A"), _A("A"), "add(int)")); - - REQUIRE_THAT(src, !HasCall(_A("tmain(bool,int)"), _A("A"), "A()")); - REQUIRE_THAT( - src, !HasCall(_A("tmain(bool,int)"), _A("A"), "operator+=(int)")); - REQUIRE_THAT(src, !HasCall(_A("A"), _A("A"), "add(int)")); - REQUIRE_THAT(src, - !HasCall(_A("tmain(bool,int)"), _A("A"), "operator=(const A &)")); - REQUIRE_THAT(src, !HasCall(_A("A"), _A("A"), "set(int)")); - REQUIRE_THAT(src, HasCall(_A("tmain(bool,int)"), _A("A"), "value()")); - REQUIRE_THAT(src, - !HasCall(_A("tmain(bool,int)::(lambda " - "../../tests/t20031/t20031.cc:47:26)"), - _A("zero()"), "")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - } -*/ - } \ No newline at end of file +} \ No newline at end of file diff --git a/tests/t20032/test_case.h b/tests/t20032/test_case.h index 5a52d3ea..88ec1dd3 100644 --- a/tests/t20032/test_case.h +++ b/tests/t20032/test_case.h @@ -37,83 +37,10 @@ TEST_CASE("t20032") {"A", "B", "double", Response{}}, // {"B", "tmain(int,char **)", "double", Response{}}, // - {"tmain(int,char **)", "B", "b(const char *)"}, // - {"B", "A", "a3(const char *)"}, // - {"A", "B", "const char *", Response{}}, // + {"tmain(int,char **)", "B", "b(const char *)"}, // + {"B", "A", "a3(const char *)"}, // + {"A", "B", "const char *", Response{}}, // {"B", "tmain(int,char **)", "const char *", Response{}} // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain(int,char **)"), _A("B"), "b(int)")); - REQUIRE_THAT( - src, HasResponse(_A("tmain(int,char **)"), _A("B"), "int")); - - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a1(int)")); - REQUIRE_THAT(src, HasResponse(_A("B"), _A("A"), "int")); - - REQUIRE_THAT( - src, HasCall(_A("tmain(int,char **)"), _A("B"), "b(double)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2(double)")); - REQUIRE_THAT(src, HasResponse(_A("B"), _A("A"), "double")); - - REQUIRE_THAT( - src, HasCall(_A("tmain(int,char **)"), _A("B"), "b(const char *)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a3(const char *)")); - REQUIRE_THAT(src, HasResponse(_A("B"), _A("A"), "const char *")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - std::vector messages = { - FindMessage(j, "tmain(int,char **)", "B", "b(int)", "int"), - FindMessage(j, "B", "A", "a1(int)", "int"), - FindMessage(j, "tmain(int,char **)", "B", "b(double)"), - FindMessage(j, "B", "A", "a2(double)"), - FindMessage(j, "tmain(int,char **)", "B", "b(const char *)"), - FindMessage(j, "B", "A", "a3(const char *)")}; - - REQUIRE(std::is_sorted(messages.begin(), messages.end())); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - using mermaid::HasResponse; - - REQUIRE_THAT(src, HasCall(_A("tmain(int,char **)"), _A("B"), "b(int)")); - REQUIRE_THAT( - src, HasResponse(_A("tmain(int,char **)"), _A("B"), "int")); - - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a1(int)")); - REQUIRE_THAT(src, HasResponse(_A("B"), _A("A"), "int")); - - REQUIRE_THAT( - src, HasCall(_A("tmain(int,char **)"), _A("B"), "b(double)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2(double)")); - REQUIRE_THAT(src, HasResponse(_A("B"), _A("A"), "double")); - - REQUIRE_THAT( - src, HasCall(_A("tmain(int,char **)"), _A("B"), "b(const char *)")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a3(const char *)")); - REQUIRE_THAT(src, HasResponse(_A("B"), _A("A"), "const char *")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } \ No newline at end of file diff --git a/tests/t20033/test_case.h b/tests/t20033/test_case.h index 172f9076..83a483bc 100644 --- a/tests/t20033/test_case.h +++ b/tests/t20033/test_case.h @@ -52,50 +52,4 @@ TEST_CASE("t20033") {"tmain()", "A", "a4()"} // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a1()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a2()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a3()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a4()")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - using mermaid::HasCallInControlCondition; - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("A"), "a1()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a2()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a3()")); - REQUIRE_THAT( - src, HasCallInControlCondition(_A("tmain()"), _A("A"), "a4()")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t20034/test_case.h b/tests/t20034/test_case.h index 49af0319..45d8ff59 100644 --- a/tests/t20034/test_case.h +++ b/tests/t20034/test_case.h @@ -68,75 +68,7 @@ TEST_CASE("t20034") {"C", "C", "c2()"}, // {"C", "B", "b2()"}, // {"B", "A", "a2()"} // - } // + } // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("D"), _A("A"), "a2()")); - - REQUIRE_THAT(src, HasCall(_A("D"), _A("C"), "c3()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "c2()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b2()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - - REQUIRE_THAT(src, HasCall(_A("D"), _A("C"), "c4()")); - - REQUIRE_THAT(src, !HasCall(_A("C"), _A("B"), "b3()")); - - save_puml(config.output_directory(), diagram->name + - ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - REQUIRE(HasMessageChain(j, - {{"d2()", "c3()", "void"}, {"c3()", "c2()", "void"}, - {"c2()", "b2()", "void"}, {"b2()", "a2()", - "void"}})); REQUIRE(HasMessageChain(j, - {{"d2()", "c4()", "void"}, {"c4()", "b4()", "void"}, - {"b4()", "b2()", "void"}, {"b2()", "a2()", - "void"}})); REQUIRE(HasMessageChain(j, {{"d2()", "a2()", - "void"}})); REQUIRE(HasMessageChain(j, - {{"d2()", "c1()", "void"}, {"c1()", "b1()", "void"}, - {"b1()", "a2()", "void"}})); - REQUIRE(HasMessageChain(j, - {{"d2()", "c2()", "void"}, {"c2()", "b2()", "void"}, - {"b2()", "a2()", "void"}})); - - save_json(config.output_directory(), diagram->name + - ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("D"), _A("A"), "a2()")); - - REQUIRE_THAT(src, HasCall(_A("D"), _A("C"), "c3()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "c2()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b2()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - - REQUIRE_THAT(src, HasCall(_A("D"), _A("C"), "c4()")); - - REQUIRE_THAT(src, !HasCall(_A("C"), _A("B"), "b3()")); - - save_mermaid(config.output_directory(), diagram->name + - ".mmd", src); - } - */ } \ No newline at end of file diff --git a/tests/t20035/test_case.h b/tests/t20035/test_case.h index d04ce96c..0549da2a 100644 --- a/tests/t20035/test_case.h +++ b/tests/t20035/test_case.h @@ -32,46 +32,4 @@ TEST_CASE("t20035") {"b1(int)", "c(int)", ""} // }})); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, HasCall(_A("tmain(int,char **)"), _A("a(int)"), - "")); REQUIRE_THAT(src, HasCall(_A("a(int)"), _A("b1(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("b1(int)"), _A("c(int)"), "")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - REQUIRE(HasMessageChain(j, - {{"tmain(int,char **)", "a(int)", "int"}, - {"a(int)", "b1(int)", "int"}, {"b1(int)", "c(int)", - "int"}})); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("tmain(int,char **)"), _A("a(int)"), - "")); REQUIRE_THAT(src, HasCall(_A("a(int)"), _A("b1(int)"), "")); - REQUIRE_THAT(src, HasCall(_A("b1(int)"), _A("c(int)"), "")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - } - */ } \ No newline at end of file diff --git a/tests/t20036/test_case.h b/tests/t20036/test_case.h index 27819a5a..a96a06f9 100644 --- a/tests/t20036/test_case.h +++ b/tests/t20036/test_case.h @@ -67,68 +67,4 @@ TEST_CASE("t20036") }, // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "c2()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b2()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - - REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b2()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - - REQUIRE_THAT(src, HasCall(_A("D"), _A("A"), "a2()")); - - REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b1()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - REQUIRE(HasMessageChain(j, - {{"c3()", "c2()", "void"}, {"c2()", "b2()", "void"}, - {"b2()", "a2()", "void"}})); - REQUIRE(HasMessageChain( - j, {{"c4()", "b2()", "void"}, {"b2()", "a2()", "void"}})); - REQUIRE(HasMessageChain(j, {{"d3()", "a2()", "void"}})); - REQUIRE(HasMessageChain(j, - {{"d1()", "c2()", "void"}, {"c2()", "b2()", "void"}, - {"b2()", "a2()", "void"}})); - REQUIRE(HasMessageChain( - j, {{"c1()", "b1()", "void"}, {"b1()", "a2()", "void"}})); - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("C"), _A("C"), "c2()")); - REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b2()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - - REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b2()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - - REQUIRE_THAT(src, HasCall(_A("D"), _A("A"), "a2()")); - - REQUIRE_THAT(src, HasCall(_A("C"), _A("B"), "b1()")); - REQUIRE_THAT(src, HasCall(_A("B"), _A("A"), "a2()")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t20038/test_case.h b/tests/t20038/test_case.h index d5e9336c..33e01e7e 100644 --- a/tests/t20038/test_case.h +++ b/tests/t20038/test_case.h @@ -53,107 +53,4 @@ TEST_CASE("t20038") {"B", "A", "aaa()"}, // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b()")); - - REQUIRE_THAT(src, !HasCall(_A("tmain()"), _A("B"), "bb()")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "bbb()")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "bbbb()")); - - REQUIRE_THAT(src, - HasMessageComment(_A("tmain()"), - "This comment should be rendered only\\n" - "once")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("add_impl(double,double)"), - "")); - - REQUIRE_THAT( - src, HasMessageComment(_A("tmain()"), "What is 2 \\+ 2\\?")); - - REQUIRE_THAT(src, - !HasMessageComment( - _A("tmain()"), "This is specific for some_other_diagram")); - - REQUIRE_THAT( - src, HasMessageComment(_A("tmain()"), "Calling - B::bbbbb\\(\\)")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "bbbbb()")); - - REQUIRE_THAT(src, - HasMessageComment(_A("tmain()"), "This is a conditional - operator")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - using mermaid::HasCallInControlCondition; - using mermaid::HasMessageComment; - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "b()")); - - REQUIRE_THAT(src, !HasCall(_A("tmain()"), _A("B"), "bb()")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "bbb()")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "bbbb()")); - - REQUIRE_THAT(src, - HasMessageComment(_A("tmain()"), - "This comment should be rendered only
" - "once")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), _A("add_impl(double,double)"), - "")); - - REQUIRE_THAT( - src, HasMessageComment(_A("tmain()"), "What is 2 \\+ 2\\?")); - - REQUIRE_THAT(src, - !HasMessageComment( - _A("tmain()"), "This is specific for some_other_diagram")); - - REQUIRE_THAT( - src, HasMessageComment(_A("tmain()"), "Calling - B::bbbbb\\(\\)")); - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("B"), "bbbbb()")); - - REQUIRE_THAT(src, - !HasMessageComment( - _A("tmain()"), "This is specific for some_other_diagram")); - - REQUIRE_THAT( - src, HasMessageComment(_A("tmain()"), "Calling - B::bbbbb\\(\\)")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - } - */ } \ No newline at end of file diff --git a/tests/t20039/test_case.h b/tests/t20039/test_case.h index 628bef51..88a011f6 100644 --- a/tests/t20039/test_case.h +++ b/tests/t20039/test_case.h @@ -31,54 +31,8 @@ TEST_CASE("t20039") {"R", "A", "a(int)"}, // {"R", "A", "a(int_vec_t)"}, // {"R", "A", "a(string_vec_t)"}, // - {"R", "A", "a(int_map_t)"}, // + {"R", "A", "a(int_map_t)"}, // {"R", "A", "a(string_map_t)"} // })); }); -/* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - // Check if all calls exist - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("R"), "run()")); - REQUIRE_THAT(src, HasCall(_A("R"), _A("A"), "a(int)")); - REQUIRE_THAT(src, HasCall(_A("R"), _A("A"), "a(int_vec_t)")); - REQUIRE_THAT( - src, HasCall(_A("R"), _A("A"), "a(string_vec_t)")); - REQUIRE_THAT(src, HasCall(_A("R"), _A("A"), "a(int_map_t)")); - REQUIRE_THAT( - src, HasCall(_A("R"), _A("A"), "a(string_map_t)")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, HasCall(_A("tmain()"), _A("R"), "run()")); - REQUIRE_THAT(src, HasCall(_A("R"), _A("A"), "a(int)")); - REQUIRE_THAT(src, HasCall(_A("R"), _A("A"), "a(int_vec_t)")); - REQUIRE_THAT( - src, HasCall(_A("R"), _A("A"), "a(string_vec_t)")); - REQUIRE_THAT(src, HasCall(_A("R"), _A("A"), "a(int_map_t)")); - REQUIRE_THAT( - src, HasCall(_A("R"), _A("A"), "a(string_map_t)")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", src); - }*/ } \ No newline at end of file diff --git a/tests/t20040/test_case.h b/tests/t20040/test_case.h index a9297bbd..87277908 100644 --- a/tests/t20040/test_case.h +++ b/tests/t20040/test_case.h @@ -45,66 +45,4 @@ TEST_CASE("t20040") {"print(int)", "print()", ""}, // })); }); - /* - { - auto src = generate_sequence_puml(diagram, *model); - AliasMatcher _A(src); - - REQUIRE_THAT(src, StartsWith("@startuml")); - REQUIRE_THAT(src, EndsWith("@enduml\n")); - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), - _A("print(int,double,std::string)"), - "")); - - REQUIRE_THAT(src, - HasCall(_A("print(int,double,std::string)"), - _A("print(double,std::string)"), "")); - - REQUIRE_THAT(src, - HasCall(_A("print(double,std::string)"), - _A("print(std::string)"), "")); - - REQUIRE_THAT(src, - HasCall(_A("print(std::string)"), _A("print()"), - "")); - - save_puml(config.output_directory(), diagram->name + ".puml", src); - } - - { - auto j = generate_sequence_json(diagram, *model); - - using namespace json; - - save_json(config.output_directory(), diagram->name + ".json", j); - } - - { - auto src = generate_sequence_mermaid(diagram, *model); - - mermaid::SequenceDiagramAliasMatcher _A(src); - using mermaid::HasCall; - - REQUIRE_THAT(src, - HasCall(_A("tmain()"), - _A("print(int,double,std::string)"), - "")); - - REQUIRE_THAT(src, - HasCall(_A("print(int,double,std::string)"), - _A("print(double,std::string)"), "")); - - REQUIRE_THAT(src, - HasCall(_A("print(double,std::string)"), - _A("print(std::string)"), "")); - - REQUIRE_THAT(src, - HasCall(_A("print(std::string)"), _A("print()"), - "")); - - save_mermaid(config.output_directory(), diagram->name + ".mmd", - src); - }*/ } \ No newline at end of file diff --git a/tests/t20046/test_case.h b/tests/t20046/test_case.h index 89d328ff..3e7d293a 100644 --- a/tests/t20046/test_case.h +++ b/tests/t20046/test_case.h @@ -49,8 +49,7 @@ TEST_CASE("t20046") "t20046.cc:19:34)", "operator()(auto &&) const"}, // {"tmain()::(lambda t20046.cc:19:9)::(lambda t20046.cc:19:34)", - "a3(int)", ""} - + "a3(int)", ""} // })); }); } \ No newline at end of file diff --git a/tests/t20047/test_case.h b/tests/t20047/test_case.h index ab0e68f2..34b7b155 100644 --- a/tests/t20047/test_case.h +++ b/tests/t20047/test_case.h @@ -33,7 +33,6 @@ TEST_CASE("t20047") {"tmain()", "a4(int)", ""}, // {"tmain()", "a5(int)", ""}, // {"tmain()", "a6(int)", ""}, // - })); }); } \ No newline at end of file diff --git a/tests/test_cases.cc b/tests/test_cases.cc index 6ac3872e..845b3df3 100644 --- a/tests/test_cases.cc +++ b/tests/test_cases.cc @@ -121,42 +121,6 @@ auto render_diagram( return ss.str(); } } -// -// template -// auto generate_diagram_json( -// std::shared_ptr config, DiagramModel &model) -//{ -// using diagram_config = DiagramConfig; -// using diagram_model = DiagramModel; -// using diagram_generator = -// typename clanguml::common::generators::diagram_generator_t< -// DiagramConfig, -// clanguml::common::generators::json_generator_tag>::type; -// -// std::stringstream ss; -// -// ss << diagram_generator(dynamic_cast(*config), model); -// -// return nlohmann::json::parse(ss.str()); -//} -// -// template -// auto generate_diagram_mermaid( -// std::shared_ptr config, DiagramModel &model) -//{ -// using diagram_config = DiagramConfig; -// using diagram_model = DiagramModel; -// using diagram_generator = -// typename clanguml::common::generators::diagram_generator_t< -// DiagramConfig, -// clanguml::common::generators::mermaid_generator_tag>::type; -// -// std::stringstream ss; -// -// ss << diagram_generator(dynamic_cast(*config), model); -// -// return ss.str(); -//} } // namespace detail /// @@ -198,109 +162,6 @@ generate_include_diagram(clanguml::common::compilation_database &db, /// }@ -/// -/// @defgroup Diagram renderers -/// @{ -/// -/* -template -std::string render_class_diagram( - std::shared_ptr config, - clanguml::class_diagram::model::diagram &model) -{ - return detail::generate_diagram(config, model); -} - -std::string render_sequence_diagram( - std::shared_ptr config, - clanguml::sequence_diagram::model::diagram &model) -{ - return detail::generate_diagram_puml( - config, model); -} - -std::string generate_package_puml( - std::shared_ptr config, - clanguml::package_diagram::model::diagram &model) -{ - return detail::generate_diagram_puml( - config, model); -} - -std::string generate_include_puml( - std::shared_ptr config, - clanguml::include_diagram::model::diagram &model) -{ - return detail::generate_diagram_puml( - config, model); -} - -nlohmann::json generate_class_json( - std::shared_ptr config, - clanguml::class_diagram::model::diagram &model) -{ - return detail::generate_diagram_json( - config, model); -} - -nlohmann::json generate_sequence_json( - std::shared_ptr config, - clanguml::sequence_diagram::model::diagram &model) -{ - return detail::generate_diagram_json( - config, model); -} - -nlohmann::json generate_package_json( - std::shared_ptr config, - clanguml::package_diagram::model::diagram &model) -{ - return detail::generate_diagram_json( - config, model); -} - -nlohmann::json generate_include_json( - std::shared_ptr config, - clanguml::include_diagram::model::diagram &model) -{ - return detail::generate_diagram_json( - config, model); -} - -std::string generate_class_mermaid( - std::shared_ptr config, - clanguml::class_diagram::model::diagram &model) -{ - return detail::generate_diagram_mermaid( - config, model); -} - -std::string generate_sequence_mermaid( - std::shared_ptr config, - clanguml::sequence_diagram::model::diagram &model) -{ - return detail::generate_diagram_mermaid( - config, model); -} - -std::string generate_package_mermaid( - std::shared_ptr config, - clanguml::package_diagram::model::diagram &model) -{ - return detail::generate_diagram_mermaid( - config, model); -} - -std::string generate_include_mermaid( - std::shared_ptr config, - clanguml::include_diagram::model::diagram &model) -{ - return detail::generate_diagram_mermaid( - config, model); -} -*/ - template void save_diagram(const std::filesystem::path &path, const T &diagram) { @@ -592,495 +453,6 @@ void CHECK_INCLUDE_DIAGRAM(const clanguml::config::config &config, } } // namespace clanguml::test -/* -template <> -plantuml_t render_class_diagram( - std::shared_ptr c, - clanguml::class_diagram::model::diagram &d) -{ - return detail::generate_diagram_puml(c, d); -} - -template <> -mermaid_t render_class_diagram( - std::shared_ptr c, - clanguml::class_diagram::model::diagram &d) -{ - return generate_class_mermaid(c, d); -} - -template <> -json_t render_class_diagram( - std::shared_ptr c, - clanguml::class_diagram::model::diagram &d) -{ - return generate_class_json(c, d); -} - -template <> -DiagramType render_sequence_diagram( - std::shared_ptr c, - clanguml::sequence_diagram::model::diagram &model); - -template -DiagramType render_package_diagram(std::shared_ptr c, - clanguml::package_diagram::model::diagram &model); - -template -DiagramType render_include_diagram(std::shared_ptr c, - clanguml::include_diagram::model::diagram &model); - -} -*/ -// using namespace clanguml::test::matchers; - -/* - - -namespace detail { -template -auto generate_diagram_impl(clanguml::common::compilation_database &db, - std::shared_ptr diagram) -{ - LOG_INFO("All paths will be evaluated relative to {}", - diagram->root_directory().string()); - - using diagram_config = DiagramConfig; - using diagram_model = - typename clanguml::common::generators::diagram_model_t< - diagram_config>::type; - using diagram_visitor = - typename clanguml::common::generators::diagram_visitor_t< - diagram_config>::type; - - inject_diagram_options(diagram); - - auto model = clanguml::common::generators::generate(db, diagram->name, - dynamic_cast(*diagram), - diagram->get_translation_units()); - - return model; -} - -template -auto generate_diagram_puml( - std::shared_ptr config, DiagramModel &model) -{ - using diagram_config = DiagramConfig; - using diagram_model = DiagramModel; - using diagram_generator = - typename clanguml::common::generators::diagram_generator_t< - DiagramConfig, - clanguml::common::generators::plantuml_generator_tag>::type; - - std::stringstream ss; - - ss << diagram_generator(dynamic_cast(*config), model); - - return ss.str(); -} - -template -auto generate_diagram_json( - std::shared_ptr config, DiagramModel &model) -{ - using diagram_config = DiagramConfig; - using diagram_model = DiagramModel; - using diagram_generator = - typename clanguml::common::generators::diagram_generator_t< - DiagramConfig, - clanguml::common::generators::json_generator_tag>::type; - - std::stringstream ss; - - ss << diagram_generator(dynamic_cast(*config), model); - - return nlohmann::json::parse(ss.str()); -} - -template -auto generate_diagram_mermaid( - std::shared_ptr config, DiagramModel &model) -{ - using diagram_config = DiagramConfig; - using diagram_model = DiagramModel; - using diagram_generator = - typename clanguml::common::generators::diagram_generator_t< - DiagramConfig, - clanguml::common::generators::mermaid_generator_tag>::type; - - std::stringstream ss; - - ss << diagram_generator(dynamic_cast(*config), model); - - return ss.str(); -} -} - -std::unique_ptr generate_class_diagram( - clanguml::common::compilation_database &db, - std::shared_ptr diagram) -{ - return detail::generate_diagram_impl( - db, diagram); -} - -std::unique_ptr -generate_sequence_diagram(clanguml::common::compilation_database &db, - std::shared_ptr diagram) -{ - return detail::generate_diagram_impl( - db, diagram); -} - -std::unique_ptr -generate_package_diagram(clanguml::common::compilation_database &db, - std::shared_ptr diagram) -{ - return detail::generate_diagram_impl( - db, diagram); -} - -std::unique_ptr -generate_include_diagram(clanguml::common::compilation_database &db, - std::shared_ptr diagram) -{ - return detail::generate_diagram_impl( - db, diagram); -} - -std::string generate_class_puml( - std::shared_ptr config, - clanguml::class_diagram::model::diagram &model) -{ - return detail::generate_diagram_puml( - config, model); -} - -std::string generate_sequence_puml( - std::shared_ptr config, - clanguml::sequence_diagram::model::diagram &model) -{ - return detail::generate_diagram_puml( - config, model); -} - -std::string generate_package_puml( - std::shared_ptr config, - clanguml::package_diagram::model::diagram &model) -{ - return detail::generate_diagram_puml( - config, model); -} - -std::string generate_include_puml( - std::shared_ptr config, - clanguml::include_diagram::model::diagram &model) -{ - return detail::generate_diagram_puml( - config, model); -} - -nlohmann::json generate_class_json( - std::shared_ptr config, - clanguml::class_diagram::model::diagram &model) -{ - return detail::generate_diagram_json( - config, model); -} - -nlohmann::json generate_sequence_json( - std::shared_ptr config, - clanguml::sequence_diagram::model::diagram &model) -{ - return detail::generate_diagram_json( - config, model); -} - -nlohmann::json generate_package_json( - std::shared_ptr config, - clanguml::package_diagram::model::diagram &model) -{ - return detail::generate_diagram_json( - config, model); -} - -nlohmann::json generate_include_json( - std::shared_ptr config, - clanguml::include_diagram::model::diagram &model) -{ - return detail::generate_diagram_json( - config, model); -} - -std::string generate_class_mermaid( - std::shared_ptr config, - clanguml::class_diagram::model::diagram &model) -{ - return detail::generate_diagram_mermaid( - config, model); -} - -std::string generate_sequence_mermaid( - std::shared_ptr config, - clanguml::sequence_diagram::model::diagram &model) -{ - return detail::generate_diagram_mermaid( - config, model); -} - -std::string generate_package_mermaid( - std::shared_ptr config, - clanguml::package_diagram::model::diagram &model) -{ - return detail::generate_diagram_mermaid( - config, model); -} - -std::string generate_include_mermaid( - std::shared_ptr config, - clanguml::include_diagram::model::diagram &model) -{ - return detail::generate_diagram_mermaid( - config, model); -} - -template -void save_diagram(const std::filesystem::path &path, const T &diagram) -{ - static_assert( - std::is_same_v || std::is_same_v); - - std::filesystem::create_directories(path.parent_path()); - std::ofstream ofs; - ofs.open(path, std::ofstream::out | std::ofstream::trunc); - if constexpr (std::is_same_v) { - ofs << std::setw(2) << diagram; - } - else { - ofs << diagram; - } - - ofs.close(); -} - -void save_puml(const std::string &path, const std::string &filename, - const std::string &puml) -{ - std::filesystem::path p{path}; - p /= filename; - save_diagram(p, puml); -} - -void save_json(const std::string &path, const std::string &filename, - const nlohmann::json &j) -{ - std::filesystem::path p{path}; - p /= filename; - save_diagram(p, j); -} - -void save_mermaid(const std::string &path, const std::string &filename, - const std::string &mmd) -{ - std::filesystem::path p{path}; - p /= filename; - save_diagram(p, mmd); -} - -namespace clanguml::test { - -template struct test_traits; - -// function pointer -template -struct test_traits : public test_traits { }; - -template struct test_traits { - using return_type = R; - - static constexpr std::size_t arity = sizeof...(Args); - - template struct argument { - static_assert(N < arity, "error: invalid parameter index."); - using type = typename std::tuple_element>::type; - }; -}; - -struct diagram_source_storage { - diagram_source_storage(plantuml_t &&p, json_t &&j, mermaid_t &&m) - : plantuml{std::move(p)} - , json{std::move(j)} - , mermaid{std::move(m)} - { - } - - template const T &get() const; - - plantuml_t plantuml; - json_t json; - mermaid_t mermaid; -}; - -template <> const plantuml_t &diagram_source_storage::get() const -{ - return plantuml; -} - -template <> const json_t &diagram_source_storage::get() const -{ - return json; -} - -template <> const mermaid_t &diagram_source_storage::get() const -{ - return mermaid; -} - -template -void CHECK_CLASS_DIAGRAM_IMPL( - const diagram_source_storage &diagrams, TC &&tc, TCs &&...tcs) -{ - if constexpr (std::is_invocable_v) { - tc(diagrams.get()); - } - if constexpr (std::is_invocable_v) { - tc(diagrams.get()); - } - if constexpr (std::is_invocable_v) { - tc(diagrams.get()); - } - if constexpr (sizeof...(tcs) > 0) { - CHECK_CLASS_DIAGRAM_IMPL(diagrams, std::forward(tcs)...); - } -} - -template -void CHECK_CLASS_DIAGRAM( - DiagramConfig diagram, DiagramModel &model, TCs &&...tcs) -{ - diagram_source_storage diagram_sources{ - render_class_diagram(diagram, model), - render_class_diagram(diagram, model), - render_class_diagram(diagram, model)}; - - CHECK_CLASS_DIAGRAM_IMPL(diagram_sources, std::forward(tcs)...); -} - -// -// PlantUML test helpers -// -template <> -plantuml_t render_class_diagram( - std::shared_ptr c, - clanguml::class_diagram::model::diagram &d) -{ - return generate_class_puml(c, d); -} - -template <> bool IsClass(plantuml_t d, std::string name) -{ - return util::contains(d.src, fmt::format("class {}", name)); -} - -// -// MermaidJS test helpers -// -template <> -mermaid_t render_class_diagram( - std::shared_ptr c, - clanguml::class_diagram::model::diagram &d) -{ - return generate_class_mermaid(c, d); -} - -template <> bool IsClass(mermaid_t d, std::string name) -{ - return util::contains(d.src, fmt::format("class {}", name)); -} - -// -// JSON test helpers -// -struct File { - explicit File(const std::string &f) - : file{f} - { - } - - const std::string file; -}; - -std::optional get_element_by_id( - const nlohmann::json &j, const std::string &id) -{ - if (!j.contains("elements")) - return {}; - - for (const nlohmann::json &e : j["elements"]) { - if (e["id"] == id) - return {e}; - - if (e["type"] == "namespace" || e["type"] == "folder") { - auto maybe_e = get_element_by_id(e, id); - if (maybe_e) - return maybe_e; - } - } - - return {}; -} - -std::optional get_element( - const nlohmann::json &j, const std::string &name) -{ - if (!j.contains("elements")) - return {}; - - for (const nlohmann::json &e : j["elements"]) { - if (e["display_name"] == name) - return {e}; - - if (e["type"] == "namespace" || e["type"] == "folder" || - e["type"] == "directory" || e["type"] == "module") { - auto maybe_e = get_element(e, name); - if (maybe_e) - return maybe_e; - } - } - - return {}; -} - -std::optional get_element( - const json_t &src, const std::string &name) -{ - return get_element(src.src, name); -} - -std::string expand_name(const nlohmann::json &j, const std::string &name) -{ - return name; -} - -template <> -json_t render_class_diagram( - std::shared_ptr c, - clanguml::class_diagram::model::diagram &d) -{ - return generate_class_json(c, d); -} - -template <> bool IsClass(json_t d, std::string name) -{ - auto e = get_element(d.src, expand_name(d.src, name)); - return e && e->at("type") == "class"; -} -} -} - - */ /// /// Class diagram tests /// @@ -1186,7 +558,6 @@ template <> bool IsClass(json_t d, std::string name) #include "t20005/test_case.h" #endif #include "t20006/test_case.h" - #include "t20007/test_case.h" #include "t20008/test_case.h" #include "t20009/test_case.h" diff --git a/tests/test_cases.h b/tests/test_cases.h index e4d3fccd..60c2b4c0 100644 --- a/tests/test_cases.h +++ b/tests/test_cases.h @@ -51,7 +51,7 @@ using namespace clanguml::util; std::pair load_config(const std::string &test_name); -void save_puml(const std::string &path, const std::string &puml); +//void save_puml(const std::string &path, const std::string &puml); namespace clanguml::test { @@ -2562,1635 +2562,4 @@ bool IsParticipant( return p && (p->at("type") == type); } -} - -/* -namespace clanguml { -namespace test { -namespace matchers { - -using Catch::CaseSensitive; -using Catch::Matchers::StdString::CasedString; -using Catch::Matchers::StdString::ContainsMatcher; -using Catch::Matchers::StdString::RegexMatcher; - -using Catch::Matchers::Contains; -using Catch::Matchers::EndsWith; -using Catch::Matchers::Equals; -using Catch::Matchers::Matches; -using Catch::Matchers::StartsWith; -using Catch::Matchers::VectorContains; - -struct JsonMatcherBase : Catch::MatcherBase { - JsonMatcherBase( - std::string const &operation, CasedString const &comparator); - std::string describe() const override; - - CasedString m_comparator; - std::string m_operation; -}; - -template constexpr bool has_type() noexcept -{ - return (std::is_same_v || ... || false); -} - -struct Public { }; - -struct Protected { }; - -struct Private { }; - -struct Abstract { }; - -struct Static { }; - -struct Const { }; - -struct Constexpr { }; - -struct Consteval { }; - -struct Coroutine { }; - -struct Noexcept { }; - -struct Default { }; - -struct Deleted { }; - -struct HasCallWithResultMatcher : ContainsMatcher { - HasCallWithResultMatcher( - CasedString const &comparator, CasedString const &resultComparator) - : ContainsMatcher(comparator) - , m_resultComparator{resultComparator} - { - } - - bool match(std::string const &source) const override - { - return Catch::contains( - m_comparator.adjustString(source), m_comparator.m_str) && - Catch::contains( - m_comparator.adjustString(source), m_resultComparator.m_str); - } - - CasedString m_resultComparator; -}; - -template class HasCallMatcher : public Catch::MatcherBase { - T m_from, m_to, m_message; - bool m_is_response; - std::string m_call_arrow, m_return_arrow; - std::string call_pattern, response_pattern; - -public: - HasCallMatcher(T from, T to, T message, bool is_response = false, - const std::string &call_arrow = "->", - const std::string &return_arrow = "-->") - : m_from(from) - , m_to{to} - , m_message{message} - , m_is_response{is_response} - , m_call_arrow{call_arrow} - , m_return_arrow{return_arrow} - { - util::replace_all(m_message, "(", "\\("); - util::replace_all(m_message, ")", "\\)"); - util::replace_all(m_message, "*", "\\*"); - util::replace_all(m_message, "[", "\\["); - util::replace_all(m_message, "]", "\\]"); - util::replace_all(m_message, "+", "\\+"); - - call_pattern = fmt::format("{} {} {} " - "(\\[\\[.*\\]\\] )?: {}", - m_from, m_call_arrow, m_to, m_message); - - response_pattern = fmt::format( - "{} {} {} : //{}//", m_from, m_return_arrow, m_to, m_message); - } - - bool match(T const &in) const override - { - std::regex r{m_is_response ? response_pattern : call_pattern}; - std::smatch base_match; - std::regex_search(in, base_match, r); - if (base_match.size() > 0) - return true; - - return false; - } - - std::string describe() const override - { - std::ostringstream ss; - ss << "has call " - << fmt::format( - "{} {} {} : {}", m_from, m_call_arrow, m_to, m_message); - return ss.str(); - } -}; - -auto HasCall(std::string const &from, std::string const &to, - std::string const &message, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return HasCallMatcher(from, to, message, false); -} - -auto HasResponse(std::string const &from, std::string const &to, - std::string const &message, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return HasCallMatcher(to, from, message, true); -} - -auto HasCallInControlCondition(std::string const &from, std::string const &to, - std::string const &message, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return HasCallMatcher(from, to, fmt::format("**[**{}**]**", message)); -} - -auto HasCall(std::string const &from, std::string const &message, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return HasCall(from, from, message, caseSensitivity); -} - -namespace mermaid { -template class HasCallMatcher : public Catch::MatcherBase { - T m_from, m_to, m_message; - bool m_is_response; - std::string m_call_arrow, m_return_arrow; - std::string call_pattern, response_pattern; - -public: - HasCallMatcher(T from, T to, T message, bool is_response = false, - const std::string &call_arrow = "->>", - const std::string &return_arrow = "-->>") - : m_from(from) - , m_to{to} - , m_message{message} - , m_is_response{is_response} - , m_call_arrow{call_arrow} - , m_return_arrow{return_arrow} - { - util::replace_all(m_message, "(", "\\("); - util::replace_all(m_message, ")", "\\)"); - util::replace_all(m_message, "*", "\\*"); - util::replace_all(m_message, "[", "\\["); - util::replace_all(m_message, "]", "\\]"); - util::replace_all(m_message, "+", "\\+"); - - call_pattern = - fmt::format("{} {} {} : {}", m_from, m_call_arrow, m_to, m_message); - - response_pattern = fmt::format( - "{} {} {} : {}", m_from, m_return_arrow, m_to, m_message); - } - - bool match(T const &in) const override - { - std::regex r{m_is_response ? response_pattern : call_pattern}; - std::smatch base_match; - std::regex_search(in, base_match, r); - if (base_match.size() > 0) - return true; - - return false; - } - - std::string describe() const override - { - std::ostringstream ss; - ss << "has call " - << fmt::format( - "{} {} {} : {}", m_from, m_call_arrow, m_to, m_message); - return ss.str(); - } -}; - -auto HasCall(std::string const &from, std::string const &to, - std::string const &message, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return mermaid::HasCallMatcher(from, to, message, false); -} - -auto HasCallInControlCondition(std::string const &from, std::string const &to, - std::string const &message, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return mermaid::HasCallMatcher(from, to, fmt::format("[{}]", message)); -} - -auto HasResponse(std::string const &from, std::string const &to, - std::string const &message, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return HasCallMatcher(to, from, message, true, "->>", "-->>"); -} - -auto HasCall(std::string const &from, std::string const &message, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return mermaid::HasCall(from, from, message, caseSensitivity); -} -} - -ContainsMatcher HasEntrypoint(std::string const &to, std::string const &message, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher( - CasedString(fmt::format("[-> {} : {}", to, message), caseSensitivity)); -} - -namespace mermaid { -ContainsMatcher HasEntrypoint(std::string const &to, std::string const &message, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher(CasedString( - fmt::format("* ->> {} : {}", to, message), caseSensitivity)); -} -} - -ContainsMatcher HasExitpoint(std::string const &to, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher( - CasedString(fmt::format("[<-- {}", to), caseSensitivity)); -} - -namespace mermaid { -ContainsMatcher HasExitpoint(std::string const &to, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher( - CasedString(fmt::format("{} -->> *", to), caseSensitivity)); -} -} - -std::string _NS(std::string_view s) -{ - return fmt::format( - "clanguml::{}::{}", Catch::getResultCapture().getCurrentTestName(), s); -} - -class NamespaceWrapper { - -private: -}; - -struct AliasMatcher { - AliasMatcher(const std::string &puml_) - : puml{split(puml_, "\n")} - { - } - - std::string operator()(std::string name) - { - std::vector patterns; - - const std::string alias_regex("([A-Z]_[0-9]+)"); - - util::replace_all(name, "(", "\\("); - util::replace_all(name, ")", "\\)"); - util::replace_all(name, " ", "\\s"); - util::replace_all(name, "*", "\\*"); - util::replace_all(name, "[", "\\["); - util::replace_all(name, "]", "\\]"); - - patterns.push_back( - std::regex{"class\\s\"" + name + "\"\\sas\\s" + alias_regex}); - patterns.push_back( - std::regex{"abstract\\s\"" + name + "\"\\sas\\s" + alias_regex}); - patterns.push_back( - std::regex{"enum\\s\"" + name + "\"\\sas\\s" + alias_regex}); - patterns.push_back( - std::regex{"package\\s\"" + name + "\"\\sas\\s" + alias_regex}); - patterns.push_back( - std::regex{"package\\s\\[" + name + "\\]\\sas\\s" + alias_regex}); - patterns.push_back( - std::regex{"file\\s\"" + name + "\"\\sas\\s" + alias_regex}); - patterns.push_back( - std::regex{"folder\\s\"" + name + "\"\\sas\\s" + alias_regex}); - patterns.push_back( - std::regex{"participant\\s\"" + name + "\"\\sas\\s" + alias_regex}); - - std::smatch base_match; - - for (const auto &line : puml) { - for (const auto &pattern : patterns) { - if (std::regex_search(line, base_match, pattern) && - base_match.size() == 2) { - std::ssub_match base_sub_match = base_match[1]; - std::string alias = base_sub_match.str(); - return trim(alias); - } - } - } - - return fmt::format("__INVALID__ALIAS__({})", name); - } - - const std::vector puml; -}; - -namespace mermaid { -struct AliasMatcher { - AliasMatcher(const std::string &mmd_) - : mmd{split(mmd_, "\n")} - { - } - - std::string operator()(std::string name) - { - std::vector patterns; - - const std::string alias_regex("([A-Z]_[0-9]+)"); - - util::replace_all(name, "(", "("); - util::replace_all(name, ")", ")"); - util::replace_all(name, " ", "\\s"); - util::replace_all(name, "*", "\\*"); - util::replace_all(name, "[", "\\["); - util::replace_all(name, "]", "\\]"); - util::replace_all(name, "<", "<"); - util::replace_all(name, ">", ">"); - - patterns.push_back( - std::regex{"class\\s" + alias_regex + "\\[\"" + name + "\"\\]"}); - patterns.push_back( - std::regex{"subgraph\\s" + alias_regex + "\\[" + name + "\\]"}); - patterns.push_back( - std::regex{"\\s\\s" + alias_regex + "\\[" + name + "\\]"}); // file - - std::smatch base_match; - - for (const auto &line : mmd) { - for (const auto &pattern : patterns) { - if (std::regex_search(line, base_match, pattern) && - base_match.size() == 2) { - std::ssub_match base_sub_match = base_match[1]; - std::string alias = base_sub_match.str(); - return trim(alias); - } - } - } - - return "__INVALID__ALIAS__"; - } - - const std::vector mmd; -}; - -struct SequenceDiagramAliasMatcher { - SequenceDiagramAliasMatcher(const std::string &mmd_) - : mmd{split(mmd_, "\n")} - { - } - - std::string operator()(std::string name) - { - std::vector patterns; - - const std::string alias_regex("([A-Z]_[0-9]+)"); - - util::replace_all(name, "(", "\\("); - util::replace_all(name, ")", "\\)"); - util::replace_all(name, " ", "\\s"); - util::replace_all(name, "*", "\\*"); - util::replace_all(name, "[", "\\["); - util::replace_all(name, "]", "\\]"); - - patterns.push_back( - std::regex{"participant\\s" + alias_regex + "\\sas\\s" + name}); - - std::smatch base_match; - - for (const auto &line : mmd) { - for (const auto &pattern : patterns) { - if (std::regex_search(line, base_match, pattern) && - base_match.size() == 2) { - std::ssub_match base_sub_match = base_match[1]; - std::string alias = base_sub_match.str(); - return trim(alias); - } - } - } - - return "__INVALID__ALIAS__"; - } - - const std::vector mmd; -}; -} - -ContainsMatcher HasTitle(std::string const &str, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher(CasedString("title " + str, caseSensitivity)); -} - -namespace mermaid { -ContainsMatcher HasTitle(std::string const &str, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher(CasedString("title: " + str, caseSensitivity)); -} -} - -ContainsMatcher IsClass(std::string const &str, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher(CasedString("class " + str, caseSensitivity)); -} - -namespace mermaid { -auto IsClass(std::string const &str, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher(CasedString("class " + str, caseSensitivity)); -} -} - -ContainsMatcher IsUnion(std::string const &str, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher( - CasedString("class " + str + " <>", caseSensitivity)); -} - -namespace mermaid { -auto IsUnion(std::string const &alias, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return Catch::Matchers::Matches( - std::string("class ") + alias + " \\{\\n\\s+<>", - caseSensitivity); -} -} - -ContainsMatcher IsClassTemplate(std::string const &str, - std::string const &tmplt, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher(CasedString( - fmt::format("class \"{}<{}>\"", str, tmplt), caseSensitivity)); -} - -ContainsMatcher IsConcept(std::string const &str, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher( - CasedString("class " + str + " <>", caseSensitivity)); -} - -namespace mermaid { -auto IsConcept(std::string const &alias, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return Catch::Matchers::Matches( - std::string("class ") + alias + " \\{\\n\\s+<>", - caseSensitivity); -} -} - -ContainsMatcher IsEnum(std::string const &str, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher(CasedString("enum " + str, caseSensitivity)); -} - -namespace mermaid { -auto IsEnum(std::string const &alias, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return Catch::Matchers::Matches( - std::string("class ") + alias + " \\{\\n\\s+<>", - caseSensitivity); -} -} - -ContainsMatcher IsAbstractClass(std::string const &str, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher(CasedString("abstract " + str, caseSensitivity)); -} - -namespace mermaid { -auto IsAbstractClass(std::string const &alias, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return Catch::Matchers::Matches( - std::string("class ") + alias + " \\{\\n\\s+<>", - caseSensitivity); -} -} - -ContainsMatcher IsAbstractClassTemplate(std::string const &str, - std::string const &tmplt, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher(CasedString( - fmt::format("abstract \"{}<{}>\"", str, tmplt), caseSensitivity)); -} - -ContainsMatcher IsBaseClass(std::string const &base, std::string const &sub, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher(CasedString(base + " <|-- " + sub, caseSensitivity)); -} - -namespace mermaid { -ContainsMatcher IsBaseClass(std::string const &base, std::string const &sub, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher(CasedString(base + " <|-- " + sub, caseSensitivity)); -} -} - -ContainsMatcher IsInnerClass(std::string const &parent, - std::string const &inner, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher( - CasedString(inner + " --+ " + parent, caseSensitivity)); -} - -namespace mermaid { -ContainsMatcher IsInnerClass(std::string const &parent, - std::string const &inner, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher( - CasedString(parent + " ()-- " + inner + " : ", caseSensitivity)); -} -} - -ContainsMatcher IsAssociation(std::string const &from, std::string const &to, - std::string const &label = "", std::string multiplicity_source = "", - std::string multiplicity_dest = "", std::string style = "", - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - std::string format_string = "{}"; - if (!multiplicity_source.empty()) - format_string += " \"" + multiplicity_source + "\""; - - format_string += fmt::format(" -{}->", style); - - if (!multiplicity_dest.empty()) - format_string += " \"" + multiplicity_dest + "\""; - - format_string += " {}"; - - if (!label.empty()) { - format_string += " : {}"; - return ContainsMatcher(CasedString( - fmt::format(fmt::runtime(format_string), from, to, label), - caseSensitivity)); - } - else - return ContainsMatcher( - CasedString(fmt::format(fmt::runtime(format_string), from, to), - caseSensitivity)); -} - -ContainsMatcher IsComposition(std::string const &from, std::string const &to, - std::string const &label, std::string multiplicity_source = "", - std::string multiplicity_dest = "", std::string style = "", - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - std::string format_string = "{}"; - if (!multiplicity_source.empty()) - format_string += " \"" + multiplicity_source + "\""; - - format_string += fmt::format(" *-{}-", style); - - if (!multiplicity_dest.empty()) - format_string += " \"" + multiplicity_dest + "\""; - - format_string += " {} : {}"; - - return ContainsMatcher( - CasedString(fmt::format(fmt::runtime(format_string), from, to, label), - caseSensitivity)); -} - -ContainsMatcher IsAggregation(std::string const &from, std::string const &to, - std::string const &label, std::string multiplicity_source = "", - std::string multiplicity_dest = "", std::string style = "", - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - std::string format_string = "{}"; - if (!multiplicity_source.empty()) - format_string += " \"" + multiplicity_source + "\""; - - format_string += fmt::format(" o-{}-", style); - - if (!multiplicity_dest.empty()) - format_string += " \"" + multiplicity_dest + "\""; - - format_string += " {} : {}"; - - return ContainsMatcher( - CasedString(fmt::format(fmt::runtime(format_string), from, to, label), - caseSensitivity)); -} - -ContainsMatcher IsInstantiation(std::string const &from, std::string const &to, - std::string style = "", - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher(CasedString( - fmt::format("{} .{}.|> {}", to, style, from), caseSensitivity)); -} - -ContainsMatcher IsDependency(std::string const &from, std::string const &to, - std::string style = "", - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher(CasedString( - fmt::format("{} .{}.> {}", from, style, to), caseSensitivity)); -} - -namespace mermaid { -ContainsMatcher IsPackageDependency(std::string const &from, - std::string const &to, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher( - CasedString(fmt::format("{} -.-> {}", from, to), caseSensitivity)); -} -ContainsMatcher IsIncludeDependency(std::string const &from, - std::string const &to, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher( - CasedString(fmt::format("{} -.-> {}", from, to), caseSensitivity)); -} -} - -ContainsMatcher IsConstraint(std::string const &from, std::string const &to, - std::string const &label = {}, std::string style = "", - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - if (label.empty()) - return ContainsMatcher(CasedString( - fmt::format("{} .{}.> {}", from, style, to), caseSensitivity)); - else - return ContainsMatcher( - CasedString(fmt::format("{} .{}.> {} : {}", from, style, to, label), - caseSensitivity)); -} - -ContainsMatcher IsConceptRequirement(std::string const &cpt, - std::string const &requirement, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher(CasedString(requirement, caseSensitivity)); -} - -namespace mermaid { -ContainsMatcher IsConstraint(std::string const &from, std::string const &to, - std::string label = {}, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - util::replace_all(label, "<", "<"); - util::replace_all(label, ">", ">"); - util::replace_all(label, "(", "("); - util::replace_all(label, ")", ") - util::replace_all(label, "##", "::"); - util::replace_all(label, "{", "{"); - util::replace_all(label, "}", "}"); - - if (label.empty()) - return ContainsMatcher( - CasedString(fmt::format("{} ..> {}", from, to), caseSensitivity)); - else - return ContainsMatcher(CasedString( - fmt::format("{} ..> {} : {}", from, to, label), caseSensitivity)); -} - -ContainsMatcher IsConceptRequirement(std::string const &cpt, - std::string requirement, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - util::replace_all(requirement, "<", "<"); - util::replace_all(requirement, ">", ">"); - util::replace_all(requirement, "(", "("); - util::replace_all(requirement, ")", ")"); - util::replace_all(requirement, "##", "::"); - util::replace_all(requirement, "{", "{"); - util::replace_all(requirement, "}", "}"); - - return ContainsMatcher(CasedString(requirement, caseSensitivity)); -} -} - -ContainsMatcher IsLayoutHint(std::string const &from, std::string const &hint, - std::string const &to, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher(CasedString( - fmt::format("{} -[hidden]{}- {}", from, hint, to), caseSensitivity)); -} - -ContainsMatcher HasComment(std::string const &comment, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher( - CasedString(fmt::format("' {}", comment), caseSensitivity)); -} - -namespace mermaid { -ContainsMatcher HasComment(std::string const &comment, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher( - CasedString(fmt::format("%% {}", comment), caseSensitivity)); -} -} - -ContainsMatcher HasNote(std::string const &cls, std::string const &position, - std::string const ¬e = "", - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher(CasedString( - fmt::format("note {} of {}", position, cls), caseSensitivity)); -} - -auto HasMessageComment(std::string const &alias, std::string const ¬e, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return Catch::Matchers::Matches( - std::string("note over ") + alias + "\\n" + note + "\\n" + "end note", - caseSensitivity); -} - -namespace mermaid { -auto HasMessageComment(std::string const &alias, std::string const ¬e, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return Catch::Matchers::Matches( - std::string("note over ") + alias + ": " + note, caseSensitivity); -} - -ContainsMatcher HasNote(std::string const &cls, - std::string const &position = "", std::string const ¬e = "", - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher( - CasedString(fmt::format("note for {}", cls), caseSensitivity)); -} -ContainsMatcher HasPackageNote(std::string const &cls, - std::string const &position = "", std::string const ¬e = "", - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher( - CasedString(fmt::format("-.- {}", cls), caseSensitivity)); -} -} - -ContainsMatcher HasMemberNote(std::string const &cls, std::string const &member, - std::string const &position, std::string const ¬e = "", - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher( - CasedString(fmt::format("note {} of {}::{}", position, cls, member), - caseSensitivity)); -} - -ContainsMatcher HasLink(std::string const &alias, std::string const &link, - std::string const &tooltip, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher(CasedString( - fmt::format("{} [[{}{{{}}}]]", alias, link, tooltip), caseSensitivity)); -} - -namespace mermaid { -ContainsMatcher HasLink(std::string const &alias, std::string const &link, - std::string const &tooltip, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher(CasedString( - fmt::format("click {} href \"{}\" \"{}\"", alias, link, tooltip), - caseSensitivity)); -} -} - -ContainsMatcher HasMemberLink(std::string const &method, - std::string const &link, std::string const &tooltip, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher( - CasedString(fmt::format("{} [[[{}{{{}}}]]]", method, link, tooltip), - caseSensitivity)); -} - -template -ContainsMatcher IsMethod(std::string const &name, - std::string const &type = "void", std::string const ¶ms = "", - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - std::string pattern; - if constexpr (has_type()) - pattern += "{static} "; - - if constexpr (has_type()) - pattern += "{abstract} "; - - if constexpr (has_type()) - pattern = "+"; - else if constexpr (has_type()) - pattern = "#"; - else - pattern = "-"; - - pattern += name; - - pattern += "(" + params + ")"; - - if constexpr (has_type()) - pattern += " constexpr"; - - if constexpr (has_type()) - pattern += " consteval"; - - if constexpr (has_type()) - pattern += " const"; - - if constexpr (has_type()) - pattern += " = 0"; - - if constexpr (has_type()) - pattern += " = default"; - - if constexpr (has_type()) - pattern += " = deleted"; - - if constexpr (has_type()) - pattern += " [coroutine]"; - - pattern += " : " + type; - - return ContainsMatcher(CasedString(pattern, caseSensitivity)); -} - -namespace mermaid { -template -ContainsMatcher IsMethod(std::string const &name, std::string type = "void", - std::string const ¶ms = "", - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - std::string pattern; - - if constexpr (has_type()) - pattern = "+"; - else if constexpr (has_type()) - pattern = "#"; - else - pattern = "-"; - - pattern += name; - - pattern += "(" + params + ")"; - - std::vector method_mods; - if constexpr (has_type()) - method_mods.push_back("default"); - if constexpr (has_type()) - method_mods.push_back("const"); - if constexpr (has_type()) - method_mods.push_back("constexpr"); - if constexpr (has_type()) - method_mods.push_back("consteval"); - if constexpr (has_type()) - method_mods.push_back("coroutine"); - - pattern += " : "; - - if (!method_mods.empty()) { - pattern += fmt::format("[{}] ", fmt::join(method_mods, ",")); - } - - util::replace_all(type, "<", "<"); - util::replace_all(type, ">", ">"); - util::replace_all(type, "(", "("); - util::replace_all(type, ")", ")"); - util::replace_all(type, "##", "::"); - util::replace_all(type, "{", "{"); - util::replace_all(type, "}", "}"); - - pattern += type; - - if constexpr (has_type()) - pattern += "*"; - - if constexpr (has_type()) - pattern += "$"; - - return ContainsMatcher(CasedString(pattern, caseSensitivity)); -} -} - -template -ContainsMatcher IsField(std::string const &name, - std::string const &type = "void", - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - std::string pattern; - if constexpr (has_type()) - pattern += "{static} "; - - if constexpr (has_type()) - pattern = "+"; - else if constexpr (has_type()) - pattern = "#"; - else - pattern = "-"; - - pattern += name; - - return ContainsMatcher( - CasedString(pattern + " : " + type, caseSensitivity)); -} - -namespace mermaid { -template -ContainsMatcher IsField(std::string const &name, std::string type = "void", - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - std::string pattern; - if constexpr (has_type()) - pattern += "{static} "; - - if constexpr (has_type()) - pattern = "+"; - else if constexpr (has_type()) - pattern = "#"; - else - pattern = "-"; - - pattern += name; - - util::replace_all(type, "<", "<"); - util::replace_all(type, ">", ">"); - util::replace_all(type, "(", "("); - util::replace_all(type, ")", ")"); - util::replace_all(type, "##", "::"); - util::replace_all(type, "{", "{"); - util::replace_all(type, "}", "}"); - - return ContainsMatcher( - CasedString(pattern + " : " + type, caseSensitivity)); -} -} - -template -ContainsMatcher IsFriend(std::string const &from, std::string const &to, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - std::string pattern; - - if constexpr (has_type()) - pattern = "+"; - else if constexpr (has_type()) - pattern = "#"; - else - pattern = "-"; - - return ContainsMatcher( - CasedString(fmt::format("{} <.. {} : {}<>", from, to, pattern), - caseSensitivity)); -} - -namespace mermaid { -template -ContainsMatcher IsFriend(std::string const &from, std::string const &to, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - std::string pattern; - - if constexpr (has_type()) - pattern = "+"; - else if constexpr (has_type()) - pattern = "#"; - else - pattern = "-"; - - return ContainsMatcher( - CasedString(fmt::format("{} <.. {} : {}[friend]", from, to, pattern), - caseSensitivity)); -} -} - -ContainsMatcher IsPackage(std::string const &str, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher( - CasedString("package [" + str + "]", caseSensitivity)); -} - -namespace mermaid { -ContainsMatcher IsPackage(std::string const &str, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher(CasedString("subgraph " + str, caseSensitivity)); -} -} - -ContainsMatcher IsFolder(std::string const &str, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher( - CasedString("folder \"" + str + "\"", caseSensitivity)); -} - -ContainsMatcher IsFile(std::string const &str, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher( - CasedString("file \"" + str + "\"", caseSensitivity)); -} - -namespace mermaid { -ContainsMatcher IsFolder(std::string const &str, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher(CasedString("subgraph " + str, caseSensitivity)); -} - -ContainsMatcher IsFile(std::string const &str, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher(CasedString(str + "[", caseSensitivity)); -} -} - -ContainsMatcher IsDeprecated(std::string const &str, - CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes) -{ - return ContainsMatcher( - CasedString(str + " <> ", caseSensitivity)); -} - -namespace json { -struct File { - explicit File(const std::string &f) - : file{f} - { - } - - const std::string file; -}; - -std::optional get_element_by_id( - const nlohmann::json &j, const std::string &id) -{ - if (!j.contains("elements")) - return {}; - - for (const nlohmann::json &e : j["elements"]) { - if (e["id"] == id) - return {e}; - - if (e["type"] == "namespace" || e["type"] == "folder") { - auto maybe_e = get_element_by_id(e, id); - if (maybe_e) - return maybe_e; - } - } - - return {}; -} - -std::optional get_element( - const nlohmann::json &j, const std::string &name) -{ - if (!j.contains("elements")) - return {}; - - for (const nlohmann::json &e : j["elements"]) { - if (e["display_name"] == name) - return {e}; - - if (e["type"] == "namespace" || e["type"] == "folder" || - e["type"] == "directory" || e["type"] == "module") { - auto maybe_e = get_element(e, name); - if (maybe_e) - return maybe_e; - } - } - - return {}; -} - -std::optional get_participant( - const nlohmann::json &j, const std::string &name) -{ - if (!j.contains("participants")) - return {}; - - for (const nlohmann::json &e : j.at("participants")) { - if (e["display_name"] == name) - return {e}; - } - - return {}; -} - -auto get_relationship(const nlohmann::json &j, const nlohmann::json &from, - const nlohmann::json &to, const std::string &type) -{ - return std::find_if(j["relationships"].begin(), j["relationships"].end(), - [&](const auto &it) { - return (it["source"] == from) && (it["destination"] == to) && - (it["type"] == type); - }); -} - -auto get_relationship(const nlohmann::json &j, const std::string &from, - const std::string &to, const std::string &type) -{ - auto source = get_element(j, from); - auto destination = get_element(j, to); - - if (!(source && destination)) - return j["relationships"].end(); - - return get_relationship(j, source->at("id"), destination->at("id"), type); -} - -std::string expand_name(const nlohmann::json &j, const std::string &name) -{ - return name; -} - -bool HasTitle(const nlohmann::json &j, const std::string &title) -{ - return j.contains("title") && j["title"] == title; -} - -bool IsClass(const nlohmann::json &j, const std::string &name) -{ - auto e = get_element(j, expand_name(j, name)); - return e && e->at("type") == "class"; -} - -bool IsStruct(const nlohmann::json &j, const std::string &name) -{ - auto e = get_element(j, expand_name(j, name)); - return e && e->at("type") == "class" && e->at("is_struct"); -} - -bool InPublicModule(const nlohmann::json &j, const std::string &element, - const std::string &module) -{ - auto e = get_element(j, expand_name(j, element)); - return e && e->contains("module") && e->at("module")["name"] == module && - !e->at("module")["is_private"]; -} - -bool InPrivateModule(const nlohmann::json &j, const std::string &element, - const std::string &module) -{ - auto e = get_element(j, expand_name(j, element)); - return e && e->contains("module") && e->at("module")["name"] == module && - e->at("module")["is_private"]; -} - -bool IsAbstractClass(const nlohmann::json &j, const std::string &name) -{ - auto e = get_element(j, expand_name(j, name)); - return e && (e->at("type") == "class") && (e->at("is_abstract") == true); -} - -bool IsClassTemplate(const nlohmann::json &j, const std::string &name) -{ - auto e = get_element(j, expand_name(j, name)); - return e && e->at("type") == "class" && e->at("is_template") == true; -} - -bool IsConcept(const nlohmann::json &j, const std::string &name) -{ - auto e = get_element(j, expand_name(j, name)); - return e && e->at("type") == "concept"; -} - -bool IsEnum(const nlohmann::json &j, const std::string &name) -{ - auto e = get_element(j, expand_name(j, name)); - return e && e->at("type") == "enum"; -} - -bool IsPackage(const nlohmann::json &j, const std::string &name, - const std::string &type = "namespace") -{ - auto e = get_element(j, expand_name(j, name)); - return e && e->at("type") == type; -} - -struct NamespacePackage { }; -struct ModulePackage { }; -struct DirectoryPackage { }; - -template std::string package_type_name(); - -template <> std::string package_type_name() -{ - return "namespace"; -} - -template <> std::string package_type_name() { return "module"; } - -template <> std::string package_type_name() -{ - return "directory"; -} - -template -bool IsPackagePath( - const nlohmann::json &j, const std::string &head, Args... args) -{ - if constexpr (sizeof...(Args) == 0) { - auto e = get_element(j, expand_name(j, head)); - - return e && e->at("type") == package_type_name(); - } - else { - auto e = get_element(j, head); - if (!e.has_value()) - return false; - - return IsPackagePath(*e, args...); - } -} - -template -bool IsNamespacePackage( - const nlohmann::json &j, const std::string &head, Args... args) -{ - return IsPackagePath( - j, head, std::forward(args)...); -} - -template -bool IsDirectoryPackage( - const nlohmann::json &j, const std::string &head, Args... args) -{ - return IsPackagePath( - j, head, std::forward(args)...); -} - -template -bool IsModulePackage( - const nlohmann::json &j, const std::string &head, Args... args) -{ - return IsPackagePath(j, head, std::forward(args)...); -} - -bool IsFolder(const nlohmann::json &j, const std::string &name) -{ - auto e = get_element(j, name); - return e && e->at("type") == "folder"; -} - -bool IsFile(const nlohmann::json &j, const std::string &name) -{ - auto e = get_element(j, name); - return e && e->at("type") == "file"; -} - -bool IsSystemHeader(const nlohmann::json &j, const std::string &name) -{ - auto e = get_element(j, name); - return e && e->at("type") == "file" && e->at("file_kind") == "header" && - e->at("is_system"); -} - -bool IsHeader(const nlohmann::json &j, const std::string &name) -{ - auto e = get_element(j, name); - return e && e->at("type") == "file" && e->at("file_kind") == "header" && - !e->at("is_system"); -} - -bool IsDeprecated(const nlohmann::json &j, const std::string &name) -{ - auto e = get_element(j, expand_name(j, name)); - return e && e->at("is_deprecated") == true; -} - -bool IsBaseClass(const nlohmann::json &j, const std::string &base, - const std::string &subclass) -{ - auto base_el = get_element(j, expand_name(j, base)); - auto subclass_el = get_element(j, expand_name(j, subclass)); - - if (!base_el || !subclass_el) - return false; - - const nlohmann::json &bases = (*subclass_el)["bases"]; - - return std::find_if(bases.begin(), bases.end(), [&](const auto &it) { - return it["id"] == base_el.value()["id"]; - }) != bases.end(); -} - -bool IsMethod( - const nlohmann::json &j, const std::string &cls, const std::string &name) -{ - auto sc = get_element(j, expand_name(j, cls)); - - if (!sc) - return false; - - const nlohmann::json &methods = (*sc)["methods"]; - - return std::find_if(methods.begin(), methods.end(), [&](const auto &it) { - return it["name"] == name; - }) != methods.end(); -} - -bool IsField(const nlohmann::json &j, const std::string &cls, - const std::string &name, const std::string &type) -{ - auto sc = get_element(j, expand_name(j, cls)); - - if (!sc) - return false; - - const nlohmann::json &members = (*sc)["members"]; - - return std::find_if(members.begin(), members.end(), [&](const auto &it) { - return it["name"] == name && it["type"] == type; - }) != members.end(); -} - -bool IsAssociation(nlohmann::json j, const std::string &from, - const std::string &to, const std::string &label = "") -{ - auto rel = get_relationship( - j, expand_name(j, from), expand_name(j, to), "association"); - - if (rel == j["relationships"].end()) - return false; - - if (!label.empty() && rel->at("label") != label) - return false; - - return true; -} - -bool IsComposition(nlohmann::json j, const std::string &from, - const std::string &to, const std::string &label = "") -{ - auto rel = get_relationship( - j, expand_name(j, from), expand_name(j, to), "composition"); - - if (rel == j["relationships"].end()) - return false; - - if (!label.empty() && rel->at("label") != label) - return false; - - return true; -} - -bool IsAggregation(nlohmann::json j, const std::string &from, - const std::string &to, const std::string &label = "") -{ - auto rel = get_relationship( - j, expand_name(j, from), expand_name(j, to), "aggregation"); - - if (rel == j["relationships"].end()) - return false; - - if (!label.empty() && rel->at("label") != label) - return false; - - return true; -} - -namespace detail { -bool is_dependency_impl( - nlohmann::json j, const std::string &from, const std::string &to) -{ - auto rel = get_relationship(j, from, to, "dependency"); - - return rel != j["relationships"].end(); -} - -} // namespace detail - -bool IsDependency( - nlohmann::json j, const std::string &from, const std::string &to) -{ - return detail::is_dependency_impl( - j, expand_name(j, from), expand_name(j, to)); -} - -bool IsDependency(nlohmann::json j, const File &from, const File &to) -{ - return detail::is_dependency_impl(j, from.file, to.file); -} - -bool IsInstantiation( - nlohmann::json j, const std::string &from, const std::string &to) -{ - auto rel = get_relationship( - j, expand_name(j, to), expand_name(j, from), "instantiation"); - - return rel != j["relationships"].end(); -} - -bool IsFriend(nlohmann::json j, const std::string &from, const std::string &to) -{ - auto rel = get_relationship( - j, expand_name(j, from), expand_name(j, to), "friendship"); - - return rel != j["relationships"].end(); -} - -bool IsInnerClass( - nlohmann::json j, const std::string &from, const std::string &to) -{ - auto rel = get_relationship( - j, expand_name(j, to), expand_name(j, from), "containment"); - - return rel != j["relationships"].end(); -} - -bool IsParticipant( - const nlohmann::json &j, const std::string &name, const std::string &type) -{ - auto p = get_participant(j, expand_name(j, name)); - - return p && (p->at("type") == type); -} - -bool IsFunctionParticipant(const nlohmann::json &j, const std::string &name) -{ - return IsParticipant(j, name, "function"); -} - -bool IsClassParticipant(const nlohmann::json &j, const std::string &name) -{ - return IsParticipant(j, name, "class"); -} - -bool IsFileParticipant(const nlohmann::json &j, const std::string &name) -{ - return IsParticipant(j, name, "file"); -} - -namespace detail { -int find_message_nested(const nlohmann::json &j, const std::string &from, - const std::string &to, const std::string &msg, - std::optional return_type, const nlohmann::json &from_p, - const nlohmann::json &to_p, int &count) -{ - const auto &messages = j["messages"]; - - int res{-1}; - - for (const auto &m : messages) { - if (m.contains("branches")) { - for (const auto &b : m["branches"]) { - auto nested_res = find_message_nested( - b, from, to, msg, return_type, from_p, to_p, count); - - if (nested_res >= 0) - return nested_res; - } - } - else if (m.contains("messages")) { - auto nested_res = find_message_nested( - m, from, to, msg, return_type, from_p, to_p, count); - - if (nested_res >= 0) - return nested_res; - } - else { - if ((m["from"]["participant_id"] == from_p["id"]) && - (m["to"]["participant_id"] == to_p["id"]) && - (m["name"] == msg) && - (!return_type || m["return_type"] == *return_type)) - return count; - - count++; - } - } - - return res; -} - -int find_message_impl(const nlohmann::json &j, const std::string &from, - const std::string &to, const std::string &msg, - std::optional return_type) -{ - - auto from_p = get_participant(j, from); - auto to_p = get_participant(j, to); - - // TODO: support diagrams with multiple sequences... - const auto &sequence_0 = j["sequences"][0]; - - int count{0}; - - auto res = detail::find_message_nested( - sequence_0, from, to, msg, return_type, *from_p, *to_p, count); - - if (res >= 0) - return res; - - throw std::runtime_error( - fmt::format("No such message {} {} {}", from, to, msg)); -} - -} // namespace detail - -int FindMessage(const nlohmann::json &j, const File &from, const File &to, - const std::string &msg) -{ - return detail::find_message_impl(j, from.file, to.file, msg, {}); -} - -int FindMessage(const nlohmann::json &j, const std::string &from, - const std::string &to, const std::string &msg, - std::optional return_type = {}) -{ - return detail::find_message_impl( - j, expand_name(j, from), expand_name(j, to), msg, return_type); -} - -struct message_test_spec_t { - std::string from; - std::string to; - std::optional return_type; - - bool operator==(const message_test_spec_t &r) const noexcept - { - return from == r.from && to == r.to && return_type == r.return_type; - } -}; - -void from_json(const nlohmann::json &j, message_test_spec_t &p) -{ - j.at("from").at("activity_id").get_to(p.from); - j.at("to").at("activity_id").get_to(p.to); - j.at("return_type").get_to(p.return_type); -} - -std::string get_activity_id( - const nlohmann::json &j, const std::string &display_name) -{ - for (const auto &p : j["participants"]) { - if (p.contains("activities")) { - for (const auto &a : p["activities"]) { - if (a["display_name"] == display_name) { - return a["id"]; - } - } - } - else if (p["display_name"] == display_name) { - return p["id"]; - } - } - - return {}; -} - -bool HasMessageChain( - const nlohmann::json &j, std::vector msgs) -{ - std::vector full_name_messages; - std::transform(msgs.begin(), msgs.end(), - std::back_inserter(full_name_messages), - [&j](const message_test_spec_t &m) { - auto res = m; - res.from = get_activity_id(j, m.from); - res.to = get_activity_id(j, m.to); - return res; - }); - - for (const auto &seq : j.at("sequences")) - for (const auto &mc : seq.at("message_chains")) { - auto mc_msgs = - mc.at("messages").get>(); - - if (full_name_messages == mc_msgs) - return true; - } - - return false; -} - -} // namespace json -} -} -} -*/ \ No newline at end of file +} // namespace clanguml::test From 31100af689be1321c61626812d4aef36819dea8c Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Mon, 20 May 2024 22:32:10 +0200 Subject: [PATCH 10/15] Ported remaining tests from Catch to doctest (#266) --- tests/CMakeLists.txt | 4 +- tests/catch.h | 20325 ------------------ tests/test_cli_handler.cc | 20 +- tests/test_compilation_database.cc | 35 +- tests/test_config.cc | 53 +- tests/test_decorator_parser.cc | 24 +- tests/test_filters.cc | 57 +- tests/test_model.cc | 13 +- tests/test_query_driver_output_extractor.cc | 8 +- 9 files changed, 93 insertions(+), 20446 deletions(-) delete mode 100644 tests/catch.h diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b958948c..862b36cd 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -103,9 +103,9 @@ foreach(TEST_NAME ${TEST_NAMES}) ${TEST_CASE_MODULE_SOURCES}) endif(ENABLE_CXX_MODULES_TEST_CASES) target_sources(${TEST_NAME} PUBLIC ${TEST_NAME}.cc - ${TEST_CASE_SOURCES} catch.h) + ${TEST_CASE_SOURCES}) else() - target_sources(${TEST_NAME} PUBLIC ${TEST_NAME}.cc catch.h) + target_sources(${TEST_NAME} PUBLIC ${TEST_NAME}.cc) endif(TEST_NAME STREQUAL "test_cases") target_compile_features(${TEST_NAME} PRIVATE diff --git a/tests/catch.h b/tests/catch.h deleted file mode 100644 index 9cb6f4fe..00000000 --- a/tests/catch.h +++ /dev/null @@ -1,20325 +0,0 @@ -/* - * Catch v2.13.8 - * Generated: 2022-01-03 21:20:09.589503 - * ---------------------------------------------------------- - * This file has been merged from multiple headers. Please don't edit it - * directly Copyright (c) 2022 Two Blue Cubes Ltd. All rights reserved. - * - * Distributed under the Boost Software License, Version 1.0. (See accompanying - * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - */ -#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED -#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED -// start catch.hpp - -#define CATCH_VERSION_MAJOR 2 -#define CATCH_VERSION_MINOR 13 -#define CATCH_VERSION_PATCH 8 - -#ifdef __clang__ -#pragma clang system_header -#elif defined __GNUC__ -#pragma GCC system_header -#endif - -// start catch_suppress_warnings.h - -#ifdef __clang__ -#ifdef __ICC // icpc defines the __clang__ macro -#pragma warning(push) -#pragma warning(disable : 161 1682) -#else // __ICC -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpadded" -#pragma clang diagnostic ignored "-Wswitch-enum" -#pragma clang diagnostic ignored "-Wcovered-switch-default" -#endif -#elif defined __GNUC__ -// Because REQUIREs trigger GCC's -Wparentheses, and because still -// supported version of g++ have only buggy support for _Pragmas, -// Wparentheses have to be suppressed globally. -#pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-variable" -#pragma GCC diagnostic ignored "-Wpadded" -#endif -// end catch_suppress_warnings.h -#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) -#define CATCH_IMPL -#define CATCH_CONFIG_ALL_PARTS -#endif - -// In the impl file, we want to have access to all parts of the headers -// Can also be used to sanely support PCHs -#if defined(CATCH_CONFIG_ALL_PARTS) -#define CATCH_CONFIG_EXTERNAL_INTERFACES -#if defined(CATCH_CONFIG_DISABLE_MATCHERS) -#undef CATCH_CONFIG_DISABLE_MATCHERS -#endif -#if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) -#define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER -#endif -#endif - -#if !defined(CATCH_CONFIG_IMPL_ONLY) -// start catch_platform.h - -// See e.g.: -// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html -#ifdef __APPLE__ -#include -#if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \ - (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1) -#define CATCH_PLATFORM_MAC -#elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1) -#define CATCH_PLATFORM_IPHONE -#endif - -#elif defined(linux) || defined(__linux) || defined(__linux__) -#define CATCH_PLATFORM_LINUX - -#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || \ - defined(_MSC_VER) || defined(__MINGW32__) -#define CATCH_PLATFORM_WINDOWS -#endif - -// end catch_platform.h - -#ifdef CATCH_IMPL -#ifndef CLARA_CONFIG_MAIN -#define CLARA_CONFIG_MAIN_NOT_DEFINED -#define CLARA_CONFIG_MAIN -#endif -#endif - -// start catch_user_interfaces.h - -namespace Catch { -unsigned int rngSeed(); -} - -// end catch_user_interfaces.h -// start catch_tag_alias_autoregistrar.h - -// start catch_common.h - -// start catch_compiler_capabilities.h - -// Detect a number of compiler features - by compiler -// The following features are defined: -// -// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? -// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? -// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? -// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled? -// **************** -// Note to maintainers: if new toggles are added please document them -// in configuration.md, too -// **************** - -// In general each macro has a _NO_ form -// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature. -// Many features, at point of detection, define an _INTERNAL_ macro, so they -// can be combined, en-mass, with the _NO_ forms later. - -#ifdef __cplusplus - -#if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L) -#define CATCH_CPP14_OR_GREATER -#endif - -#if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) -#define CATCH_CPP17_OR_GREATER -#endif - -#endif - -// Only GCC compiler should be used in this block, so other compilers trying to -// mask themselves as GCC should be ignored. -#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && \ - !defined(__CUDACC__) && !defined(__LCC__) -#define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma("GCC diagnostic push") -#define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma("GCC diagnostic pop") - -#define CATCH_INTERNAL_IGNORE_BUT_WARN(...) \ - (void)__builtin_constant_p(__VA_ARGS__) - -#endif - -#if defined(__clang__) - -#define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ - _Pragma("clang diagnostic push") -#define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma("clang diagnostic pop") - -// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug -// which results in calls to destructors being emitted for each temporary, -// without a matching initialization. In practice, this can result in something -// like `std::string::~string` being called on an uninitialized value. -// -// For example, this code will likely segfault under IBM XL: -// ``` -// REQUIRE(std::string("12") + "34" == "1234") -// ``` -// -// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. -#if !defined(__ibmxl__) && !defined(__CUDACC__) -#define CATCH_INTERNAL_IGNORE_BUT_WARN(...) \ - (void)__builtin_constant_p( \ - __VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, \ - hicpp-vararg) */ -#endif - -#define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ - _Pragma("clang diagnostic ignored \"-Wexit-time-destructors\"") \ - _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") - -#define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ - _Pragma("clang diagnostic ignored \"-Wparentheses\"") - -#define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ - _Pragma("clang diagnostic ignored \"-Wunused-variable\"") - -#define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ - _Pragma("clang diagnostic ignored " \ - "\"-Wgnu-zero-variadic-macro-arguments\"") - -#define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ - _Pragma("clang diagnostic ignored \"-Wunused-template\"") - -#endif // __clang__ - -//////////////////////////////////////////////////////////////////////////////// -// Assume that non-Windows platforms support posix signals by default -#if !defined(CATCH_PLATFORM_WINDOWS) -#define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS -#endif - -//////////////////////////////////////////////////////////////////////////////// -// We know some environments not to support full POSIX signals -#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || \ - defined(__DJGPP__) -#define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS -#endif - -#ifdef __OS400__ -#define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS -#define CATCH_CONFIG_COLOUR_NONE -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Android somehow still does not support std::to_string -#if defined(__ANDROID__) -#define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING -#define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Not all Windows environments support SEH properly -#if defined(__MINGW32__) -#define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH -#endif - -//////////////////////////////////////////////////////////////////////////////// -// PS4 -#if defined(__ORBIS__) -#define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE -#endif - -//////////////////////////////////////////////////////////////////////////////// -// Cygwin -#ifdef __CYGWIN__ - -// Required for some versions of Cygwin to declare gettimeofday -// see: -// http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin -#define _BSD_SOURCE -// some versions of cygwin (most) do not support std::to_string. Use the libstd -// check. -// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html -// line 2812-2813 -#if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) && \ - !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) - -#define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING - -#endif -#endif // __CYGWIN__ - -//////////////////////////////////////////////////////////////////////////////// -// Visual C++ -#if defined(_MSC_VER) - -// Universal Windows platform does not support SEH -// Or console colours (or console at all...) -#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) -#define CATCH_CONFIG_COLOUR_NONE -#else -#define CATCH_INTERNAL_CONFIG_WINDOWS_SEH -#endif - -#if !defined(__clang__) // Handle Clang masquerading for msvc - -// MSVC traditional preprocessor needs some workaround for __VA_ARGS__ -// _MSVC_TRADITIONAL == 0 means new conformant preprocessor -// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor -#if !defined(_MSVC_TRADITIONAL) || \ - (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) -#define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#endif // MSVC_TRADITIONAL - -// Only do this if we're not using clang on Windows, which uses `diagnostic -// push` & `diagnostic pop` -#define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma(warning(push)) -#define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma(warning(pop)) -#endif // __clang__ - -#endif // _MSC_VER - -#if defined(_REENTRANT) || defined(_MSC_VER) -// Enable async processing, as -pthread is specified or no additional linking is -// required -#define CATCH_INTERNAL_CONFIG_USE_ASYNC -#endif // _MSC_VER - -//////////////////////////////////////////////////////////////////////////////// -// Check if we are compiled with -fno-exceptions or equivalent -#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND) -#define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED -#endif - -//////////////////////////////////////////////////////////////////////////////// -// DJGPP -#ifdef __DJGPP__ -#define CATCH_INTERNAL_CONFIG_NO_WCHAR -#endif // __DJGPP__ - -//////////////////////////////////////////////////////////////////////////////// -// Embarcadero C++Build -#if defined(__BORLANDC__) -#define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN -#endif - -//////////////////////////////////////////////////////////////////////////////// - -// Use of __COUNTER__ is suppressed during code analysis in -// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly -// handled by it. -// Otherwise all supported compilers support COUNTER macro, -// but user still might want to turn it off -#if (!defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L) -#define CATCH_INTERNAL_CONFIG_COUNTER -#endif - -//////////////////////////////////////////////////////////////////////////////// - -// RTX is a special version of Windows that is real time. -// This means that it is detected as Windows, but does not provide -// the same set of capabilities as real Windows does. -#if defined(UNDER_RTSS) || defined(RTX64_BUILD) -#define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH -#define CATCH_INTERNAL_CONFIG_NO_ASYNC -#define CATCH_CONFIG_COLOUR_NONE -#endif - -#if !defined(_GLIBCXX_USE_C99_MATH_TR1) -#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER -#endif - -// Various stdlib support checks that require __has_include -#if defined(__has_include) -// Check if string_view is available and usable -#if __has_include() && defined(CATCH_CPP17_OR_GREATER) -#define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW -#endif - -// Check if optional is available and usable -#if __has_include() && defined(CATCH_CPP17_OR_GREATER) -#define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL -#endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) - -// Check if byte is available and usable -#if __has_include() && defined(CATCH_CPP17_OR_GREATER) -#include -#if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0) -#define CATCH_INTERNAL_CONFIG_CPP17_BYTE -#endif -#endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) - -// Check if variant is available and usable -#if __has_include() && defined(CATCH_CPP17_OR_GREATER) -#if defined(__clang__) && (__clang_major__ < 8) -// work around clang bug with libstdc++ -// https://bugs.llvm.org/show_bug.cgi?id=31852 fix should be in clang 8, -// workaround in libstdc++ 8.2 -#include -#if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) -#define CATCH_CONFIG_NO_CPP17_VARIANT -#else -#define CATCH_INTERNAL_CONFIG_CPP17_VARIANT -#endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE - // < 9) -#else -#define CATCH_INTERNAL_CONFIG_CPP17_VARIANT -#endif // defined(__clang__) && (__clang_major__ < 8) -#endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) -#endif // defined(__has_include) - -#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && \ - !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) -#define CATCH_CONFIG_COUNTER -#endif -#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && \ - !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && \ - !defined(CATCH_CONFIG_WINDOWS_SEH) && \ - !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH) -#define CATCH_CONFIG_WINDOWS_SEH -#endif -// This is set by default, because we assume that unix compilers are -// posix-signal-compatible by default. -#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && \ - !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && \ - !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && \ - !defined(CATCH_CONFIG_POSIX_SIGNALS) -#define CATCH_CONFIG_POSIX_SIGNALS -#endif -// This is set by default, because we assume that compilers with no wchar_t -// support are just rare exceptions. -#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && \ - !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR) -#define CATCH_CONFIG_WCHAR -#endif - -#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && \ - !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && \ - !defined(CATCH_CONFIG_CPP11_TO_STRING) -#define CATCH_CONFIG_CPP11_TO_STRING -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && \ - !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && \ - !defined(CATCH_CONFIG_CPP17_OPTIONAL) -#define CATCH_CONFIG_CPP17_OPTIONAL -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && \ - !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && \ - !defined(CATCH_CONFIG_CPP17_STRING_VIEW) -#define CATCH_CONFIG_CPP17_STRING_VIEW -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && \ - !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && \ - !defined(CATCH_CONFIG_CPP17_VARIANT) -#define CATCH_CONFIG_CPP17_VARIANT -#endif - -#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && \ - !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE) -#define CATCH_CONFIG_CPP17_BYTE -#endif - -#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) -#define CATCH_INTERNAL_CONFIG_NEW_CAPTURE -#endif - -#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && \ - !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && \ - !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && \ - !defined(CATCH_CONFIG_NEW_CAPTURE) -#define CATCH_CONFIG_NEW_CAPTURE -#endif - -#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && \ - !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) -#define CATCH_CONFIG_DISABLE_EXCEPTIONS -#endif - -#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && \ - !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && \ - !defined(CATCH_CONFIG_POLYFILL_ISNAN) -#define CATCH_CONFIG_POLYFILL_ISNAN -#endif - -#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && \ - !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && \ - !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) -#define CATCH_CONFIG_USE_ASYNC -#endif - -#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && \ - !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && \ - !defined(CATCH_CONFIG_ANDROID_LOGWRITE) -#define CATCH_CONFIG_ANDROID_LOGWRITE -#endif - -#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && \ - !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && \ - !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) -#define CATCH_CONFIG_GLOBAL_NEXTAFTER -#endif - -// Even if we do not think the compiler has that warning, we still have -// to provide a macro that can be used by the code. -#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION) -#define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION -#endif -#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION) -#define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) -#define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) -#define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS) -#define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS) -#define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS -#endif - -// The goal of this macro is to avoid evaluation of the arguments, but -// still have the compiler warn on problems inside... -#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN) -#define CATCH_INTERNAL_IGNORE_BUT_WARN(...) -#endif - -#if defined(__APPLE__) && defined(__apple_build_version__) && \ - (__clang_major__ < 10) -#undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS -#elif defined(__clang__) && (__clang_major__ < 5) -#undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS -#endif - -#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS) -#define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS -#endif - -#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) -#define CATCH_TRY if ((true)) -#define CATCH_CATCH_ALL if ((false)) -#define CATCH_CATCH_ANON(type) if ((false)) -#else -#define CATCH_TRY try -#define CATCH_CATCH_ALL catch (...) -#define CATCH_CATCH_ANON(type) catch (type) -#endif - -#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && \ - !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && \ - !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) -#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#endif - -// end catch_compiler_capabilities.h -#define INTERNAL_CATCH_UNIQUE_NAME_LINE2(name, line) name##line -#define INTERNAL_CATCH_UNIQUE_NAME_LINE(name, line) \ - INTERNAL_CATCH_UNIQUE_NAME_LINE2(name, line) -#ifdef CATCH_CONFIG_COUNTER -#define INTERNAL_CATCH_UNIQUE_NAME(name) \ - INTERNAL_CATCH_UNIQUE_NAME_LINE(name, __COUNTER__) -#else -#define INTERNAL_CATCH_UNIQUE_NAME(name) \ - INTERNAL_CATCH_UNIQUE_NAME_LINE(name, __LINE__) -#endif - -#include -#include -#include - -// We need a dummy global operator<< so we can bring it into Catch namespace -// later -struct Catch_global_namespace_dummy { }; -std::ostream &operator<<(std::ostream &, Catch_global_namespace_dummy); - -namespace Catch { - -struct CaseSensitive { - enum Choice { Yes, No }; -}; - -class NonCopyable { - NonCopyable(NonCopyable const &) = delete; - NonCopyable(NonCopyable &&) = delete; - NonCopyable &operator=(NonCopyable const &) = delete; - NonCopyable &operator=(NonCopyable &&) = delete; - -protected: - NonCopyable(); - virtual ~NonCopyable(); -}; - -struct SourceLineInfo { - - SourceLineInfo() = delete; - SourceLineInfo(char const *_file, std::size_t _line) noexcept - : file(_file) - , line(_line) - { - } - - SourceLineInfo(SourceLineInfo const &other) = default; - SourceLineInfo &operator=(SourceLineInfo const &) = default; - SourceLineInfo(SourceLineInfo &&) noexcept = default; - SourceLineInfo &operator=(SourceLineInfo &&) noexcept = default; - - bool empty() const noexcept { return file[0] == '\0'; } - bool operator==(SourceLineInfo const &other) const noexcept; - bool operator<(SourceLineInfo const &other) const noexcept; - - char const *file; - std::size_t line; -}; - -std::ostream &operator<<(std::ostream &os, SourceLineInfo const &info); - -// Bring in operator<< from global namespace into Catch namespace -// This is necessary because the overload of operator<< above makes -// lookup stop at namespace Catch -using ::operator<<; - -// Use this in variadic streaming macros to allow -// >> +StreamEndStop -// as well as -// >> stuff +StreamEndStop -struct StreamEndStop { - std::string operator+() const; -}; -template T const &operator+(T const &value, StreamEndStop) -{ - return value; -} -} - -#define CATCH_INTERNAL_LINEINFO \ - ::Catch::SourceLineInfo(__FILE__, static_cast(__LINE__)) - -// end catch_common.h -namespace Catch { - -struct RegistrarForTagAliases { - RegistrarForTagAliases( - char const *alias, char const *tag, SourceLineInfo const &lineInfo); -}; - -} // end namespace Catch - -#define CATCH_REGISTER_TAG_ALIAS(alias, spec) \ - CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ - CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ - namespace { \ - Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( \ - AutoRegisterTagAlias)(alias, spec, CATCH_INTERNAL_LINEINFO); \ - } \ - CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION - -// end catch_tag_alias_autoregistrar.h -// start catch_test_registry.h - -// start catch_interfaces_testcase.h - -#include - -namespace Catch { - -class TestSpec; - -struct ITestInvoker { - virtual void invoke() const = 0; - virtual ~ITestInvoker(); -}; - -class TestCase; -struct IConfig; - -struct ITestCaseRegistry { - virtual ~ITestCaseRegistry(); - virtual std::vector const &getAllTests() const = 0; - virtual std::vector const &getAllTestsSorted( - IConfig const &config) const = 0; -}; - -bool isThrowSafe(TestCase const &testCase, IConfig const &config); -bool matchTest( - TestCase const &testCase, TestSpec const &testSpec, IConfig const &config); -std::vector filterTests(std::vector const &testCases, - TestSpec const &testSpec, IConfig const &config); -std::vector const &getAllTestCasesSorted(IConfig const &config); - -} - -// end catch_interfaces_testcase.h -// start catch_stringref.h - -#include -#include -#include -#include - -namespace Catch { - -/// A non-owning string class (similar to the forthcoming std::string_view) -/// Note that, because a StringRef may be a substring of another string, -/// it may not be null terminated. -class StringRef { -public: - using size_type = std::size_t; - using const_iterator = const char *; - -private: - static constexpr char const *const s_empty = ""; - - char const *m_start = s_empty; - size_type m_size = 0; - -public: // construction - constexpr StringRef() noexcept = default; - - StringRef(char const *rawChars) noexcept; - - constexpr StringRef(char const *rawChars, size_type size) noexcept - : m_start(rawChars) - , m_size(size) - { - } - - StringRef(std::string const &stdString) noexcept - : m_start(stdString.c_str()) - , m_size(stdString.size()) - { - } - - explicit operator std::string() const - { - return std::string(m_start, m_size); - } - -public: // operators - auto operator==(StringRef const &other) const noexcept -> bool; - auto operator!=(StringRef const &other) const noexcept -> bool - { - return !(*this == other); - } - - auto operator[](size_type index) const noexcept -> char - { - assert(index < m_size); - return m_start[index]; - } - -public: // named queries - constexpr auto empty() const noexcept -> bool { return m_size == 0; } - constexpr auto size() const noexcept -> size_type { return m_size; } - - // Returns the current start pointer. If the StringRef is not - // null-terminated, throws std::domain_exception - auto c_str() const -> char const *; - -public: // substrings and searches - // Returns a substring of [start, start + length). - // If start + length > size(), then the substring is [start, size()). - // If start > size(), then the substring is empty. - auto substr(size_type start, size_type length) const noexcept -> StringRef; - - // Returns the current start pointer. May not be null-terminated. - auto data() const noexcept -> char const *; - - constexpr auto isNullTerminated() const noexcept -> bool - { - return m_start[m_size] == '\0'; - } - -public: // iterators - constexpr const_iterator begin() const { return m_start; } - constexpr const_iterator end() const { return m_start + m_size; } -}; - -auto operator+=(std::string &lhs, StringRef const &sr) -> std::string &; -auto operator<<(std::ostream &os, StringRef const &sr) -> std::ostream &; - -constexpr auto operator"" _sr(char const *rawChars, std::size_t size) noexcept - -> StringRef -{ - return StringRef(rawChars, size); -} -} // namespace Catch - -constexpr auto operator"" _catch_sr( - char const *rawChars, std::size_t size) noexcept -> Catch::StringRef -{ - return Catch::StringRef(rawChars, size); -} - -// end catch_stringref.h -// start catch_preprocessor.hpp - -#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__ -#define CATCH_RECURSION_LEVEL1(...) \ - CATCH_RECURSION_LEVEL0( \ - CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__))) -#define CATCH_RECURSION_LEVEL2(...) \ - CATCH_RECURSION_LEVEL1( \ - CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__))) -#define CATCH_RECURSION_LEVEL3(...) \ - CATCH_RECURSION_LEVEL2( \ - CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__))) -#define CATCH_RECURSION_LEVEL4(...) \ - CATCH_RECURSION_LEVEL3( \ - CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__))) -#define CATCH_RECURSION_LEVEL5(...) \ - CATCH_RECURSION_LEVEL4( \ - CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__))) - -#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__ -// MSVC needs more evaluations -#define CATCH_RECURSION_LEVEL6(...) \ - CATCH_RECURSION_LEVEL5( \ - CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__))) -#define CATCH_RECURSE(...) \ - CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__)) -#else -#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__) -#endif - -#define CATCH_REC_END(...) -#define CATCH_REC_OUT - -#define CATCH_EMPTY() -#define CATCH_DEFER(id) id CATCH_EMPTY() - -#define CATCH_REC_GET_END2() 0, CATCH_REC_END -#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2 -#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1 -#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT -#define CATCH_REC_NEXT1(test, next) CATCH_DEFER(CATCH_REC_NEXT0)(test, next, 0) -#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next) - -#define CATCH_REC_LIST0(f, x, peek, ...) \ - , \ - f(x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST1))( \ - f, peek, __VA_ARGS__) -#define CATCH_REC_LIST1(f, x, peek, ...) \ - , \ - f(x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST0))( \ - f, peek, __VA_ARGS__) -#define CATCH_REC_LIST2(f, x, peek, ...) \ - f(x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST1))( \ - f, peek, __VA_ARGS__) - -#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) \ - , \ - f(userdata, x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD))( \ - f, userdata, peek, __VA_ARGS__) -#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) \ - , \ - f(userdata, x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD))( \ - f, userdata, peek, __VA_ARGS__) -#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) \ - f(userdata, x) CATCH_DEFER(CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD))( \ - f, userdata, peek, __VA_ARGS__) - -// Applies the function macro `f` to each of the remaining parameters, inserts -// commas between the results, and passes userdata as the first parameter to -// each invocation, e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), -// f(x, b), f(x, c) -#define CATCH_REC_LIST_UD(f, userdata, ...) \ - CATCH_RECURSE(CATCH_REC_LIST2_UD( \ - f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) - -#define CATCH_REC_LIST(f, ...) \ - CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) - -#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) -#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO##__VA_ARGS__ -#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ -#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF -#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__) -#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__ -#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) \ - INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) -#else -// MSVC is adding extra space and needs another indirection to expand -// INTERNAL_CATCH_NOINTERNAL_CATCH_DEF -#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__) -#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__ -#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) \ - (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1) -#endif - -#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__ -#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name) - -#define INTERNAL_CATCH_REMOVE_PARENS(...) \ - INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__) - -#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR -#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) \ - decltype(get_wrapper()) -#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) \ - INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)) -#else -#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) \ - INTERNAL_CATCH_EXPAND_VARGS( \ - decltype(get_wrapper())) -#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) \ - INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2( \ - INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) -#endif - -#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...) \ - CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST, __VA_ARGS__) - -#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0) -#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) \ - INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1) -#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) \ - INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2) -#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) \ - INTERNAL_CATCH_REMOVE_PARENS(_0), \ - INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3) -#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) \ - INTERNAL_CATCH_REMOVE_PARENS(_0), \ - INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4) -#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) \ - INTERNAL_CATCH_REMOVE_PARENS(_0), \ - INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5) -#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) \ - INTERNAL_CATCH_REMOVE_PARENS(_0), \ - INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6) -#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) \ - INTERNAL_CATCH_REMOVE_PARENS(_0), \ - INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7) -#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) \ - INTERNAL_CATCH_REMOVE_PARENS(_0), \ - INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8) -#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG( \ - _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ - INTERNAL_CATCH_REMOVE_PARENS(_0), \ - INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9) -#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG( \ - _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ - INTERNAL_CATCH_REMOVE_PARENS(_0), \ - INTERNAL_CATCH_REMOVE_PARENS_10_ARG( \ - _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) - -#define INTERNAL_CATCH_VA_NARGS_IMPL( \ - _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) \ - N - -#define INTERNAL_CATCH_TYPE_GEN \ - template struct TypeList { }; \ - template \ - constexpr auto get_wrapper() noexcept -> TypeList \ - { \ - return {}; \ - } \ - template