From eead590762ec67cff200a65d02a6a12c6d0a40f8 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 7 Jun 2023 22:49:03 +0200 Subject: tests: port conversion suite to catch2 --- .conan/profiles/default | 4 + .vscode/settings.json | 12 +- conanfile.py | 4 +- source/tests/CMakeLists.txt | 2 +- source/tests/src/conversion.cpp | 135 +++++++++++++++++++++++ source/tests/src/conversion_suite.cpp | 201 ---------------------------------- 6 files changed, 150 insertions(+), 208 deletions(-) create mode 100644 .conan/profiles/default create mode 100644 source/tests/src/conversion.cpp delete mode 100644 source/tests/src/conversion_suite.cpp diff --git a/.conan/profiles/default b/.conan/profiles/default new file mode 100644 index 0000000..dedc2a6 --- /dev/null +++ b/.conan/profiles/default @@ -0,0 +1,4 @@ +include(default) + +[settings] +compiler.cppstd=20 \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 24f5d88..1636210 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,14 +1,18 @@ { // CMake Configuration - "cmake.configureArguments": "-DCMAKE_EXPORT_COMPILE_COMMANDS=YES", - "cmake.cpptools.intelliSenseMode": "gcc-x64", - "cmake.cpptools.guessSourceFileConfigurations": true, + "cmake.configureOnOpen": false, + "cmake.useCMakePresets": "always", + "cmake.sourceDirectory": "${workspaceFolder}/source", + "cmake.skipConfigureIfCachePresent": true, // C++ Configuration "[cpp]": { "editor.formatOnSave": true }, "C_Cpp.autoAddFileAssociations": false, + "C_Cpp.intelliSenseEngine": "default", + "C_Cpp.errorSquiggles": "enabledIfIncludesResolve", + "C_Cpp.autocomplete": "default", // RST Configuration "restructuredtext.confPath": "${workspaceFolder}/doc/src", @@ -16,4 +20,4 @@ "editor.defaultFormatter": "ms-python.black-formatter" }, "python.formatting.provider": "none" -} \ No newline at end of file +} diff --git a/conanfile.py b/conanfile.py index 618073b..7322849 100644 --- a/conanfile.py +++ b/conanfile.py @@ -43,7 +43,7 @@ class NewtypeConan(ConanFile): cmake.test() def build_requirements(self): - self.tool_requires("cmake/[~3.25]") + self.tool_requires("cmake/[>3.25]") self.tool_requires("ninja/[~1.11]") self.test_requires("catch2/[~3.3]") @@ -55,7 +55,7 @@ class NewtypeConan(ConanFile): toolchain.generate() def layout(self): - cmake_layout(self, src_folder="source") + cmake_layout(self, generator="Ninja Multi-Config", src_folder="source") def package(self): cmake = CMake(self) diff --git a/source/tests/CMakeLists.txt b/source/tests/CMakeLists.txt index 2287a91..7840739 100644 --- a/source/tests/CMakeLists.txt +++ b/source/tests/CMakeLists.txt @@ -8,7 +8,7 @@ include("Catch") add_executable("${PROJECT_NAME}_tests" "src/arithmetic.cpp" - # "src/conversion_suite.cpp" + "src/conversion.cpp" # "src/derivation_clause_suite.cpp" # "src/equality_comparison_suite.cpp" # "src/hash_suite.cpp" diff --git a/source/tests/src/conversion.cpp b/source/tests/src/conversion.cpp new file mode 100644 index 0000000..436d951 --- /dev/null +++ b/source/tests/src/conversion.cpp @@ -0,0 +1,135 @@ +#include "newtype/derivable.hpp" +#include "newtype/deriving.hpp" +#include "newtype/newtype.hpp" + +#include +#include +#include + +#include +#include +#include + +using test_types = std::tuple; + +TEMPLATE_LIST_TEST_CASE("Scenario: Implicit Conversions", "[conversion]", test_types) +{ + GIVEN("A new_type not deriving nt::ImplicitConversion") + { + using type_alias = nt::new_type; + + THEN("it is not implicitly convertible to the base type") + { + REQUIRE(!std::is_convertible_v); + } + } + + GIVEN("A new_type deriving nt::ImplicitConversion") + { + using type_alias = nt::new_type; + + THEN("it is implicitly convertible to the base type") + { + REQUIRE(std::is_convertible_v); + } + } +} + +TEMPLATE_LIST_TEST_CASE("Scenario: Decay", "[conversion]", test_types) +{ + GIVEN("Any new_type") + { + using type_alias = nt::new_type; + + THEN("it's decay() member function returns a value of the base type") + { + REQUIRE(std::is_same_v().decay())>); + } + } + + GIVEN("Any new_type") + { + using type_alias = nt::new_type; + + WHEN("an object of that type is constructed") + { + auto integral_value = GENERATE(take(64, random(0, 127))); + auto value = [integral_value] { + if constexpr (std::is_same_v) + { + return std::to_string(integral_value); + } + else + { + return static_cast(integral_value); + } + }(); + auto obj = type_alias{value}; + + THEN("it's decay() member function return the underlying value") + { + REQUIRE(obj.decay() == value); + } + } + } +} + +SCENARIO("Nothrow Decay") +{ + struct strange_type + { + strange_type(strange_type const &) noexcept(false) + { + } + }; + + GIVEN("A new_type over a nothrow-copyable type") + { + using type_alias = nt::new_type; + + THEN("the decay member function is nothrow-invokable") + { + REQUIRE(noexcept(std::declval().decay())); + } + } + + GIVEN("A new_type over a non-nothrow-copyable type") + { + using type_alias = nt::new_type; + + THEN("the decay member function is not nothrow-invokable") + { + REQUIRE(!noexcept(std::declval().decay())); + } + } +} + +SCENARIO("Nothrow Conversion") +{ + struct strange_type + { + strange_type(strange_type const &) noexcept(false) + { + } + }; + + GIVEN("A new_type over a nothrow-copy-constructible type") + { + using type_alias = nt::new_type; + + THEN("the decay member function is nothrow-invokable") + { + REQUIRE(noexcept(std::declval().operator int())); + } + } + + GIVEN("A new_type over a non-nothrow-copy-constructible type") + { + using type_alias = nt::new_type; + + THEN("the decay member function is not nothrow-invokable") + { + REQUIRE(!noexcept(std::declval().operator strange_type())); + } + } +} diff --git a/source/tests/src/conversion_suite.cpp b/source/tests/src/conversion_suite.cpp deleted file mode 100644 index cbe2463..0000000 --- a/source/tests/src/conversion_suite.cpp +++ /dev/null @@ -1,201 +0,0 @@ -#include "conversion_suite.hpp" - -#include "kawaii.hpp" -#include "newtype/derivable.hpp" -#include "newtype/deriving.hpp" -#include "newtype/newtype.hpp" - -#include - -#include -#include -#include -#include -#include -#include -#include - -inline namespace traits_extensions -{ - - template - struct is_implicitly_convertible : std::false_type - { - }; - - template - struct is_implicitly_convertible() = std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_implicitly_convertible_v = is_implicitly_convertible::value; - -} // namespace traits_extensions - -inline namespace ddt_support -{ - - template - struct datum - { - T value; - cute::test_failure failure; - }; - - template - auto generate_test_set(std::size_t size) -> std::vector> - { - auto device = std::random_device{}; - auto generator = std::mt19937{device()}; - auto distribution = [&] { - auto min = std::numeric_limits::min(); - auto max = std::numeric_limits::max(); - if constexpr (std::is_floating_point_v) - { - return std::uniform_real_distribution(min, max); - } - else - { - return std::uniform_int_distribution(min, max); - } - }(); - - auto data = std::vector>{}; - generate_n(std::back_inserter(data), size, [&] { - auto point = distribution(generator); - return datum{point, DDT()}; - }); - return data; - } - -} // namespace ddt_support - -inline namespace implicit_conversion_tests -{ - - template - auto a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type() -> void - { - using type_alias = nt::new_type; - ASSERT(!(is_implicitly_convertible_v)); - } - - template - auto a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type() -> void - { - using type_alias = nt::new_type; - ASSERT((is_implicitly_convertible_v)); - } - -} // namespace implicit_conversion_tests - -inline namespace decay_tests -{ - - template - auto decay_on_a_new__type_has_a_return_type_equal_to_the_base_type() -> void - { - using type_alias = nt::new_type; - ASSERT((std::is_same_v().decay())>)); - } - - template - auto decay_on_a_new__type_returns_the_underlying_value() -> void - { - using type_alias = nt::new_type; - auto data = generate_test_set(2 << 16); - for_each(begin(data), end(data), [](auto & test) { ASSERT_EQUAL_DDT(test.value, type_alias{test.value}.decay(), test.failure); }); - } - -} // namespace decay_tests - -inline namespace decay_noexcept_tests -{ - - auto decay_on_a_new__type_is_noexcept_if_the_base_type_can_be_copied_without_throwing() -> void - { - static_assert(std::is_nothrow_copy_constructible_v, "Sanity check"); - using type_alias = nt::new_type; - ASSERT(noexcept(type_alias{}.decay())); - } - - auto decay_on_a_new__type_is_not_noexcept_if_the_base_type_can_be_not_copied_without_throwing() -> void - { - struct strange_type - { - strange_type() = default; - strange_type(strange_type const &) noexcept(false) - { - } - }; - - static_assert(!std::is_nothrow_copy_constructible_v, "Sanity check"); - using type_alias = nt::new_type; - ASSERT(!noexcept(type_alias{}.decay())); - } - -} // namespace decay_noexcept_tests - -inline namespace conversion_operator_noexcept_tests -{ - - auto new__type_conversion_operator_is_noexcept_if_the_base_type_can_be_copied_without_throwing() -> void - { - static_assert(std::is_nothrow_copy_constructible_v, "Sanity check"); - using type_alias = nt::new_type; - ASSERT(noexcept(static_cast(type_alias{}))); - } - - auto new__type_conversion_operator_is_not_noexcept_if_the_base_type_can_not_be_copied_without_throwing() -> void - { - struct strange_type - { - strange_type() = default; - strange_type(strange_type const &) noexcept(false) - { - } - }; - - static_assert(!std::is_nothrow_copy_constructible_v, "Sanity check"); - using type_alias = nt::new_type; - ASSERT(!noexcept(static_cast(type_alias{}))); - } - -} // namespace conversion_operator_noexcept_tests - -auto conversion_suite() -> std::pair -{ - return {{ - /// Implicit Conversion Tests - KAWAII(a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type), - KAWAII(a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type), - KAWAII(a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type), - KAWAII(a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type), - KAWAII(a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type), - KAWAII(a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type), - KAWAII(a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type), - KAWAII(a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type), - KAWAII(a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type), - KAWAII(a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type), - - /// Decay Tests - KAWAII(decay_on_a_new__type_has_a_return_type_equal_to_the_base_type), - KAWAII(decay_on_a_new__type_has_a_return_type_equal_to_the_base_type), - KAWAII(decay_on_a_new__type_has_a_return_type_equal_to_the_base_type), - KAWAII(decay_on_a_new__type_has_a_return_type_equal_to_the_base_type), - KAWAII(decay_on_a_new__type_has_a_return_type_equal_to_the_base_type), - KAWAII(decay_on_a_new__type_returns_the_underlying_value), - KAWAII(decay_on_a_new__type_returns_the_underlying_value), - KAWAII(decay_on_a_new__type_returns_the_underlying_value), - - /// Decay noexcept Tests - KAWAII(decay_on_a_new__type_is_noexcept_if_the_base_type_can_be_copied_without_throwing), - KAWAII(decay_on_a_new__type_is_not_noexcept_if_the_base_type_can_be_not_copied_without_throwing), - - /// Conversion Operator noexcept Tests - KAWAII(new__type_conversion_operator_is_noexcept_if_the_base_type_can_be_copied_without_throwing), - KAWAII(new__type_conversion_operator_is_not_noexcept_if_the_base_type_can_not_be_copied_without_throwing), - }, - "Conversion Tests"}; -} \ No newline at end of file -- cgit v1.2.3