aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@gmail.com>2023-06-07 22:49:03 +0200
committerFelix Morgner <felix.morgner@gmail.com>2023-06-07 22:49:03 +0200
commiteead590762ec67cff200a65d02a6a12c6d0a40f8 (patch)
treec13b8981741a56e1dbc5c4ff348761e9c02beef1
parentfc033418a95d0eae238a4e2718b6429cdc160d0d (diff)
downloadnewtype-eead590762ec67cff200a65d02a6a12c6d0a40f8.tar.xz
newtype-eead590762ec67cff200a65d02a6a12c6d0a40f8.zip
tests: port conversion suite to catch2
-rw-r--r--.conan/profiles/default4
-rw-r--r--.vscode/settings.json12
-rw-r--r--conanfile.py4
-rw-r--r--source/tests/CMakeLists.txt2
-rw-r--r--source/tests/src/conversion.cpp135
-rw-r--r--source/tests/src/conversion_suite.cpp201
6 files changed, 150 insertions, 208 deletions
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 <catch2/catch_template_test_macros.hpp>
+#include <catch2/catch_test_macros.hpp>
+#include <catch2/generators/catch_generators_all.hpp>
+
+#include <string>
+#include <type_traits>
+#include <vector>
+
+using test_types = std::tuple<bool, char, int, double, std::string>;
+
+TEMPLATE_LIST_TEST_CASE("Scenario: Implicit Conversions", "[conversion]", test_types)
+{
+ GIVEN("A new_type not deriving nt::ImplicitConversion")
+ {
+ using type_alias = nt::new_type<TestType, struct conversion_test>;
+
+ THEN("it is not implicitly convertible to the base type")
+ {
+ REQUIRE(!std::is_convertible_v<type_alias, TestType>);
+ }
+ }
+
+ GIVEN("A new_type deriving nt::ImplicitConversion")
+ {
+ using type_alias = nt::new_type<TestType, struct conversion_test, deriving(nt::ImplicitConversion)>;
+
+ THEN("it is implicitly convertible to the base type")
+ {
+ REQUIRE(std::is_convertible_v<type_alias, TestType>);
+ }
+ }
+}
+
+TEMPLATE_LIST_TEST_CASE("Scenario: Decay", "[conversion]", test_types)
+{
+ GIVEN("Any new_type")
+ {
+ using type_alias = nt::new_type<TestType, struct conversion_test>;
+
+ THEN("it's decay() member function returns a value of the base type")
+ {
+ REQUIRE(std::is_same_v<TestType, decltype(std::declval<type_alias>().decay())>);
+ }
+ }
+
+ GIVEN("Any new_type")
+ {
+ using type_alias = nt::new_type<TestType, struct conversion_test>;
+
+ 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<std::string, TestType>)
+ {
+ return std::to_string(integral_value);
+ }
+ else
+ {
+ return static_cast<TestType>(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<int, struct conversion_test>;
+
+ THEN("the decay member function is nothrow-invokable")
+ {
+ REQUIRE(noexcept(std::declval<type_alias>().decay()));
+ }
+ }
+
+ GIVEN("A new_type over a non-nothrow-copyable type")
+ {
+ using type_alias = nt::new_type<strange_type, struct conversion_test>;
+
+ THEN("the decay member function is not nothrow-invokable")
+ {
+ REQUIRE(!noexcept(std::declval<type_alias>().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<int, struct conversion_test>;
+
+ THEN("the decay member function is nothrow-invokable")
+ {
+ REQUIRE(noexcept(std::declval<type_alias>().operator int()));
+ }
+ }
+
+ GIVEN("A new_type over a non-nothrow-copy-constructible type")
+ {
+ using type_alias = nt::new_type<strange_type, struct conversion_test>;
+
+ THEN("the decay member function is not nothrow-invokable")
+ {
+ REQUIRE(!noexcept(std::declval<type_alias>().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 <cute/cute.h>
-
-#include <algorithm>
-#include <iterator>
-#include <limits>
-#include <random>
-#include <string>
-#include <type_traits>
-#include <vector>
-
-inline namespace traits_extensions
-{
-
- template<typename To, typename From, typename = void>
- struct is_implicitly_convertible : std::false_type
- {
- };
-
- template<typename To, typename From>
- struct is_implicitly_convertible<To, From, std::void_t<decltype(std::declval<To &>() = std::declval<From &>())>> : std::true_type
- {
- };
-
- template<typename To, typename From>
- auto constexpr is_implicitly_convertible_v = is_implicitly_convertible<To, From>::value;
-
-} // namespace traits_extensions
-
-inline namespace ddt_support
-{
-
- template<typename T>
- struct datum
- {
- T value;
- cute::test_failure failure;
- };
-
- template<typename ValueType>
- auto generate_test_set(std::size_t size) -> std::vector<datum<ValueType>>
- {
- auto device = std::random_device{};
- auto generator = std::mt19937{device()};
- auto distribution = [&] {
- auto min = std::numeric_limits<ValueType>::min();
- auto max = std::numeric_limits<ValueType>::max();
- if constexpr (std::is_floating_point_v<ValueType>)
- {
- return std::uniform_real_distribution<ValueType>(min, max);
- }
- else
- {
- return std::uniform_int_distribution<ValueType>(min, max);
- }
- }();
-
- auto data = std::vector<datum<ValueType>>{};
- generate_n(std::back_inserter(data), size, [&] {
- auto point = distribution(generator);
- return datum<ValueType>{point, DDT()};
- });
- return data;
- }
-
-} // namespace ddt_support
-
-inline namespace implicit_conversion_tests
-{
-
- template<typename T>
- auto a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type() -> void
- {
- using type_alias = nt::new_type<T, struct conversion_test_1_tag>;
- ASSERT(!(is_implicitly_convertible_v<T, type_alias>));
- }
-
- template<typename T>
- auto a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type() -> void
- {
- using type_alias = nt::new_type<T, struct conversion_test_2_tag, deriving(nt::ImplicitConversion)>;
- ASSERT((is_implicitly_convertible_v<T, type_alias>));
- }
-
-} // namespace implicit_conversion_tests
-
-inline namespace decay_tests
-{
-
- template<typename T>
- auto decay_on_a_new__type_has_a_return_type_equal_to_the_base_type() -> void
- {
- using type_alias = nt::new_type<T, struct conversion_test_3_tag>;
- ASSERT((std::is_same_v<T, decltype(std::declval<type_alias &>().decay())>));
- }
-
- template<typename T>
- auto decay_on_a_new__type_returns_the_underlying_value() -> void
- {
- using type_alias = nt::new_type<T, struct conversion_test_4_tag>;
- auto data = generate_test_set<T>(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<int>, "Sanity check");
- using type_alias = nt::new_type<int, struct conversion_test_5_tag>;
- 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<strange_type>, "Sanity check");
- using type_alias = nt::new_type<strange_type, struct conversion_test_6_tag>;
- 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<int>, "Sanity check");
- using type_alias = nt::new_type<int, struct conversion_test_5_tag>;
- ASSERT(noexcept(static_cast<int>(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<strange_type>, "Sanity check");
- using type_alias = nt::new_type<strange_type, struct conversion_test_5_tag>;
- ASSERT(!noexcept(static_cast<strange_type>(type_alias{})));
- }
-
-} // namespace conversion_operator_noexcept_tests
-
-auto conversion_suite() -> std::pair<cute::suite, std::string>
-{
- return {{
- /// Implicit Conversion Tests
- KAWAII(a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type<bool>),
- KAWAII(a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type<char>),
- KAWAII(a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type<int>),
- KAWAII(a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type<double>),
- KAWAII(a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type<std::string>),
- KAWAII(a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type<bool>),
- KAWAII(a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type<char>),
- KAWAII(a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type<int>),
- KAWAII(a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type<double>),
- KAWAII(a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type<std::string>),
-
- /// Decay Tests
- KAWAII(decay_on_a_new__type_has_a_return_type_equal_to_the_base_type<bool>),
- KAWAII(decay_on_a_new__type_has_a_return_type_equal_to_the_base_type<char>),
- KAWAII(decay_on_a_new__type_has_a_return_type_equal_to_the_base_type<int>),
- KAWAII(decay_on_a_new__type_has_a_return_type_equal_to_the_base_type<double>),
- KAWAII(decay_on_a_new__type_has_a_return_type_equal_to_the_base_type<std::string>),
- KAWAII(decay_on_a_new__type_returns_the_underlying_value<char>),
- KAWAII(decay_on_a_new__type_returns_the_underlying_value<int>),
- KAWAII(decay_on_a_new__type_returns_the_underlying_value<double>),
-
- /// 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