From 040403382a0f47e3c1df8f2ea76c85ba349c83b1 Mon Sep 17 00:00:00 2001 From: Bartek Kryza Date: Wed, 15 Feb 2023 22:13:38 +0100 Subject: [PATCH] Added basic framework for creating cxx20 test cases --- src/util/util.h | 45 +++++++++++++++------------ tests/CMakeLists.txt | 26 ++++++++++++++-- tests/t00056/.clang-uml | 12 ++++++++ tests/t00056/t00056.cc | 10 ++++++ tests/t00056/test_case.h | 66 ++++++++++++++++++++++++++++++++++++++++ tests/t20006/t20006.cc | 4 +-- tests/test_cases.cc | 5 ++- tests/test_cases.h | 16 ++++++---- 8 files changed, 153 insertions(+), 31 deletions(-) create mode 100644 tests/t00056/.clang-uml create mode 100644 tests/t00056/t00056.cc create mode 100644 tests/t00056/test_case.h diff --git a/src/util/util.h b/src/util/util.h index 96e39fbf..1cddf3a4 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -27,6 +27,31 @@ #include #include +#define LOG_ERROR(fmt__, ...) \ + spdlog::get("console")->error( \ + fmt::runtime(std::string("[{}:{}] ") + fmt__), FILENAME_, __LINE__, \ + ##__VA_ARGS__) + +#define LOG_WARN(fmt__, ...) \ + spdlog::get("console")->warn( \ + fmt::runtime(std::string("[{}:{}] ") + fmt__), FILENAME_, __LINE__, \ + ##__VA_ARGS__) + +#define LOG_INFO(fmt__, ...) \ + spdlog::get("console")->info( \ + fmt::runtime(std::string("[{}:{}] ") + fmt__), FILENAME_, __LINE__, \ + ##__VA_ARGS__) + +#define LOG_DBG(fmt__, ...) \ + spdlog::get("console")->debug( \ + fmt::runtime(std::string("[{}:{}] ") + fmt__), FILENAME_, __LINE__, \ + ##__VA_ARGS__) + +#define LOG_TRACE(fmt__, ...) \ + spdlog::get("console")->trace( \ + fmt::runtime(std::string("[{}:{}] ") + fmt__), FILENAME_, __LINE__, \ + ##__VA_ARGS__) + namespace clanguml::util { std::string ltrim(const std::string &s); @@ -36,26 +61,6 @@ std::string trim(const std::string &s); #define FILENAME_ \ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) -#define LOG_ERROR(fmt__, ...) \ - spdlog::get("console")->error( \ - std::string("[{}:{}] ") + fmt__, FILENAME_, __LINE__, ##__VA_ARGS__) - -#define LOG_WARN(fmt__, ...) \ - spdlog::get("console")->warn( \ - std::string("[{}:{}] ") + fmt__, FILENAME_, __LINE__, ##__VA_ARGS__) - -#define LOG_INFO(fmt__, ...) \ - spdlog::get("console")->info( \ - std::string("[{}:{}] ") + fmt__, FILENAME_, __LINE__, ##__VA_ARGS__) - -#define LOG_DBG(fmt__, ...) \ - spdlog::get("console")->debug( \ - std::string("[{}:{}] ") + fmt__, FILENAME_, __LINE__, ##__VA_ARGS__) - -#define LOG_TRACE(fmt__, ...) \ - spdlog::get("console")->trace( \ - std::string("[{}:{}] ") + fmt__, FILENAME_, __LINE__, ##__VA_ARGS__) - /** * @brief Setup spdlog logger. * diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f9bf22c5..26f64965 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -3,6 +3,8 @@ file(GLOB_RECURSE TEST_CASE_SOURCES t*/*.cc t*/*.c t*/src/*.c) file(GLOB_RECURSE TEST_CASE_CONFIGS t*/.clang-uml) file(GLOB_RECURSE TEST_CONFIG_YMLS test_config_data/*.yml) +set(TEST_CASES_REQUIRING_CXX20 t00056) + set(CLANG_UML_TEST_LIBRARIES clang-umllib ${YAML_CPP_LIBRARIES} @@ -13,6 +15,23 @@ if(MSVC) list(APPEND CLANG_UML_TEST_LIBRARIES "Version.lib") endif(MSVC) +list(FIND CMAKE_CXX_COMPILE_FEATURES cxx_std_20 SUPPORTS_CXX_STD_20) + +if(SUPPORTS_CXX_STD_20 EQUAL -1 + OR ${LLVM_PACKAGE_VERSION} VERSION_LESS "15.0") + set(ENABLE_CXX_STD_20_TEST_CASES 0) + foreach(CXX20_TC ${TEST_CASES_REQUIRING_CXX20}) + list(FILTER TEST_CASE_SOURCES + EXCLUDE + REGEX ".*${CXX20_TC}.*") + list(FILTER TEST_CASE_CONFIGS + EXCLUDE + REGEX ".*${CXX20_TC}.*") + endforeach() +else() + set(ENABLE_CXX_STD_20_TEST_CASES 1) +endif() + set(TEST_CASES test_util test_model @@ -27,11 +46,14 @@ foreach(TEST_NAME ${TEST_CASES}) ${TEST_NAME}.cc $<$:${TEST_CASE_SOURCES}> catch.h) - target_compile_features(${TEST_NAME} PRIVATE cxx_std_17) + target_compile_features(${TEST_NAME} PRIVATE + $) + target_compile_definitions(${TEST_NAME} PRIVATE + $<$:ENABLE_CXX_STD_20_TEST_CASES>) target_compile_options(${TEST_NAME} PRIVATE $<$,$>: -Wno-unused-parameter -Wno-unused-private-field -Wno-unused-variable - -Wno-attributes -Wno-nonnull> + -Wno-attributes -Wno-nonnull -Wno-deprecated-enum-enum-conversion> $<$:/MP /W1 /bigobj /wd4624>) target_link_libraries(${TEST_NAME} PRIVATE ${CLANG_UML_TEST_LIBRARIES}) endforeach() diff --git a/tests/t00056/.clang-uml b/tests/t00056/.clang-uml new file mode 100644 index 00000000..64345fc7 --- /dev/null +++ b/tests/t00056/.clang-uml @@ -0,0 +1,12 @@ +compilation_database_dir: .. +output_directory: puml +diagrams: + t00056_class: + type: class + glob: + - ../../tests/t00056/t00056.cc + include: + namespaces: + - clanguml::t00056 + using_namespace: + - clanguml::t00056 \ No newline at end of file diff --git a/tests/t00056/t00056.cc b/tests/t00056/t00056.cc new file mode 100644 index 00000000..63cccf08 --- /dev/null +++ b/tests/t00056/t00056.cc @@ -0,0 +1,10 @@ +namespace clanguml { +namespace t00056 { +template +concept MaxFourBytes = sizeof(T) <= 4; + +template struct A { + T a; +}; +} +} \ No newline at end of file diff --git a/tests/t00056/test_case.h b/tests/t00056/test_case.h new file mode 100644 index 00000000..48260920 --- /dev/null +++ b/tests/t00056/test_case.h @@ -0,0 +1,66 @@ +/** + * tests/t00056/test_case.h + * + * Copyright (c) 2021-2023 Bartek Kryza + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +TEST_CASE("t00056", "[test-case][class]") +{ + 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 puml = generate_class_puml(diagram, *model); + AliasMatcher _A(puml); + + REQUIRE_THAT(puml, StartsWith("@startuml")); + REQUIRE_THAT(puml, EndsWith("@enduml\n")); + + // Check if all classes exist + // REQUIRE_THAT(puml, IsClass(_A("A"))); + + // Check if class templates exist + // REQUIRE_THAT(puml, IsClassTemplate("A", "T,P,CMP,int N")); + + // Check if all enums exist + // REQUIRE_THAT(puml, IsEnum(_A("Lights"))); + + // Check if all inner classes exist + // REQUIRE_THAT(puml, IsInnerClass(_A("A"), _A("AA"))); + + // Check if all inheritance relationships exist + // REQUIRE_THAT(puml, IsBaseClass(_A("Base"), _A("Child"))); + + // Check if all methods exist + // REQUIRE_THAT(puml, (IsMethod("foo"))); + + // Check if all fields exist + // REQUIRE_THAT(puml, (IsField("private_member", "int"))); + + // Check if all relationships exist + // REQUIRE_THAT(puml, IsAssociation(_A("D"), _A("A"), "-as")); + // REQUIRE_THAT(puml, IsDependency(_A("R"), _A("B"))); + // REQUIRE_THAT(puml, IsAggregation(_A("R"), _A("D"))); + // REQUIRE_THAT(puml, IsComposition(_A("R"), _A("D"))); + // REQUIRE_THAT(puml, IsInstantiation(_A("ABCD::F"), _A("F"))); + + save_puml(config.output_directory() + "/" + diagram->name + ".puml", puml); +} \ No newline at end of file diff --git a/tests/t20006/t20006.cc b/tests/t20006/t20006.cc index f76e9d54..0ea7d8c2 100644 --- a/tests/t20006/t20006.cc +++ b/tests/t20006/t20006.cc @@ -34,7 +34,7 @@ template struct BB { void bb1(T t, std::string f) { aa_->aa2(t); } void bb2(T t, std::string f) { aa_->aa1(t); } - BB(AA *aa) + BB(AA *aa) : aa_{aa} { } @@ -46,7 +46,7 @@ template struct BB { void bb1(T t, float f) { bb2(t, f); } void bb2(T t, float f) { aa_.aa2(t); } - BB(AA &aa) + BB(AA &aa) : aa_{aa} { } diff --git a/tests/test_cases.cc b/tests/test_cases.cc index a1d4d618..8412df53 100644 --- a/tests/test_cases.cc +++ b/tests/test_cases.cc @@ -255,6 +255,9 @@ using namespace clanguml::test::matchers; #include "t00053/test_case.h" #include "t00054/test_case.h" #include "t00055/test_case.h" +#if defined(ENABLE_CXX_STD_20_TEST_CASES) +#include "t00056/test_case.h" +#endif #include "t00057/test_case.h" /// @@ -340,4 +343,4 @@ int main(int argc, char *argv[]) clanguml::util::setup_logging(debug_log ? 3 : 1); return session.run(); -} \ No newline at end of file +} diff --git a/tests/test_cases.h b/tests/test_cases.h index 99894176..d3e4351f 100644 --- a/tests/test_cases.h +++ b/tests/test_cases.h @@ -334,11 +334,13 @@ ContainsMatcher IsAssociation(std::string const &from, std::string const &to, if (!label.empty()) { format_string += " : {}"; return ContainsMatcher(CasedString( - fmt::format(format_string, from, to, label), caseSensitivity)); + fmt::format(fmt::runtime(format_string), from, to, label), + caseSensitivity)); } else return ContainsMatcher( - CasedString(fmt::format(format_string, from, to), caseSensitivity)); + CasedString(fmt::format(fmt::runtime(format_string), from, to), + caseSensitivity)); } ContainsMatcher IsComposition(std::string const &from, std::string const &to, @@ -357,8 +359,9 @@ ContainsMatcher IsComposition(std::string const &from, std::string const &to, format_string += " {} : {}"; - return ContainsMatcher(CasedString( - fmt::format(format_string, from, to, label), caseSensitivity)); + return ContainsMatcher( + CasedString(fmt::format(fmt::runtime(format_string), from, to, label), + caseSensitivity)); } ContainsMatcher IsAggregation(std::string const &from, std::string const &to, @@ -377,8 +380,9 @@ ContainsMatcher IsAggregation(std::string const &from, std::string const &to, format_string += " {} : {}"; - return ContainsMatcher(CasedString( - fmt::format(format_string, from, to, label), caseSensitivity)); + return ContainsMatcher( + CasedString(fmt::format(fmt::runtime(format_string), from, to, label), + caseSensitivity)); } ContainsMatcher IsAggregationWithStyle(std::string const &from,