From f135ee19925f5e1afffcf20366f9056f88d866e9 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Sat, 28 Dec 2019 14:36:08 +0100 Subject: new_type: add conversion tests --- CMakeLists.txt | 1 + include/newtype/new_type.hpp | 4 +- test/include/conversion_suite.hpp | 11 +++ test/include/kawaii.hpp | 5 +- test/src/conversion_suite.cpp | 201 ++++++++++++++++++++++++++++++++++++++ test/src/driver.cpp | 6 +- 6 files changed, 221 insertions(+), 7 deletions(-) create mode 100644 test/include/conversion_suite.hpp create mode 100644 test/src/conversion_suite.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 070fdb6..9977012 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,7 @@ if(BUILD_TESTING) "${PROJECT_SOURCE_DIR}/test/src/driver.cpp" "${PROJECT_SOURCE_DIR}/test/src/derivation_clause_suite.cpp" + "${PROJECT_SOURCE_DIR}/test/src/conversion_suite.cpp" "${PROJECT_SOURCE_DIR}/test/src/new_type_constructor_suite.cpp" ) diff --git a/include/newtype/new_type.hpp b/include/newtype/new_type.hpp index 68a22dd..67e29c3 100644 --- a/include/newtype/new_type.hpp +++ b/include/newtype/new_type.hpp @@ -39,7 +39,7 @@ namespace nt /** * Retrieve the base type value contained in this @p new_type */ - auto constexpr decay() const noexcept -> BaseType + auto constexpr decay() const noexcept(std::is_nothrow_copy_constructible_v) -> BaseType { return m_value; } @@ -75,7 +75,7 @@ namespace nt /** * Retrieve the base type value contained in this @p new_type */ - auto constexpr decay() const noexcept -> BaseType + auto constexpr decay() const noexcept(std::is_nothrow_copy_constructible_v) -> BaseType { return m_value; } diff --git a/test/include/conversion_suite.hpp b/test/include/conversion_suite.hpp new file mode 100644 index 0000000..8b9c337 --- /dev/null +++ b/test/include/conversion_suite.hpp @@ -0,0 +1,11 @@ +#ifndef NEWTYPE_TEST_CONVERSION_SUITE_HPP +#define NEWTYPE_TEST_CONVERSION_SUITE_HPP + +#include + +#include +#include + +auto conversion_suite() -> std::pair; + +#endif \ No newline at end of file diff --git a/test/include/kawaii.hpp b/test/include/kawaii.hpp index 787f38a..69da012 100644 --- a/test/include/kawaii.hpp +++ b/test/include/kawaii.hpp @@ -17,7 +17,7 @@ namespace nt::test namespace impl { auto constexpr prepositions = std::array{"a", "an", "and", "as", "at", "by", "for", "in", "of", "on", "or", "the", "to"}; - + auto constexpr keywords = std::array{"noexcept"}; auto constexpr type_names = std::array{"new_type", "derivation_clause"}; auto inline replace_template_argument_syntax(std::string const & name) -> std::string @@ -103,8 +103,9 @@ namespace nt::test while (stream >> word && word != "[") { auto is_preposition = std::find(cbegin(prepositions), cend(prepositions), word) != cend(prepositions); + auto is_keyword = std::find(cbegin(keywords), cend(keywords), word) != cend(keywords); auto is_type_name = std::find(cbegin(type_names), cend(type_names), word) != cend(type_names); - if ((!is_preposition || buffer.empty()) && !is_type_name) + if ((!(is_preposition || is_keyword) || buffer.empty()) && !is_type_name) { word.front() = std::toupper(word.front()); } diff --git a/test/src/conversion_suite.cpp b/test/src/conversion_suite.cpp new file mode 100644 index 0000000..b60a611 --- /dev/null +++ b/test/src/conversion_suite.cpp @@ -0,0 +1,201 @@ +#include "conversion_suite.hpp" + +#include "kawaii.hpp" +#include "newtype/derivable.hpp" +#include "newtype/deriving.hpp" +#include "newtype/new_type.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 diff --git a/test/src/driver.cpp b/test/src/driver.cpp index 22e1ab9..6c1ae7d 100644 --- a/test/src/driver.cpp +++ b/test/src/driver.cpp @@ -1,3 +1,4 @@ +#include "conversion_suite.hpp" #include "derivation_clause_suite.hpp" #include "new_type_constructor_suite.hpp" @@ -27,9 +28,7 @@ auto get_test_selectors(suite_list const & suites) -> std::vector for_each(cbegin(suites), cend(suites), [&](auto descriptor) { auto const & [suite, name] = descriptor; - transform(cbegin(suite), cend(suite), std::back_inserter(selectors), [&, name = name](auto test) { - return name + "#" + test.name(); - }); + transform(cbegin(suite), cend(suite), std::back_inserter(selectors), [&, name = name](auto test) { return name + "#" + test.name(); }); }); return selectors; @@ -51,6 +50,7 @@ int main(int argc, char ** argv) auto suites = std::vector{ derivation_clause_suite(), new_type_constructor_suite(), + conversion_suite(), }; auto selectors = get_test_selectors(suites); -- cgit v1.2.3