diff --git a/include/continuable/continuable-testing.hpp b/include/continuable/continuable-testing.hpp index 4dcaebf..77bcb17 100644 --- a/include/continuable/continuable-testing.hpp +++ b/include/continuable/continuable-testing.hpp @@ -53,7 +53,7 @@ /// with any result. /// /// \since version 1.0.0 -#define ASSERT_ASYNC_NEVER_COMPLETED(CONTINUABLE) \ +#define ASSERT_ASYNC_INCOMPLETION(CONTINUABLE) \ cti::detail::testing::assert_async_never_completed(CONTINUABLE); /// Expects the continuation to be called and forwards it's arguments to diff --git a/include/continuable/detail/testing.hpp b/include/continuable/detail/testing.hpp index d504aad..50b1086 100644 --- a/include/continuable/detail/testing.hpp +++ b/include/continuable/detail/testing.hpp @@ -153,7 +153,7 @@ void assert_async_binary_exception_validation(V&& validator, C&& continuable, !defined(CONTINUABLE_WITH_NO_EXCEPTIONS) try { std::rethrow_exception(error); - } catch (std::decay_t const& exception) { + } catch (std::decay_t& exception) { validator(exception, expected); } catch (...) { FAIL(); diff --git a/test/unit-test/test-continuable-base-destruct.cpp b/test/unit-test/test-continuable-base-destruct.cpp index 6f413c7..943ea2e 100644 --- a/test/unit-test/test-continuable-base-destruct.cpp +++ b/test/unit-test/test-continuable-base-destruct.cpp @@ -62,31 +62,31 @@ TYPED_TEST(single_dimension_tests, are_incomplete_when_frozen) { { auto chain = this->supply(); chain.freeze(); - ASSERT_ASYNC_NEVER_COMPLETED(std::move(chain)); + ASSERT_ASYNC_INCOMPLETION(std::move(chain)); } { auto chain = this->supply(); chain.freeze(); - ASSERT_ASYNC_NEVER_COMPLETED(std::move(chain).then(this->supply())); + ASSERT_ASYNC_INCOMPLETION(std::move(chain).then(this->supply())); } } TYPED_TEST(single_dimension_tests, are_not_dispatched_when_frozen) { auto chain = assert_invocation(this); chain.freeze(); - ASSERT_ASYNC_NEVER_COMPLETED(std::move(chain)); + ASSERT_ASYNC_INCOMPLETION(std::move(chain)); } TYPED_TEST(single_dimension_tests, are_not_finished_when_not_continued) { { auto chain = create_incomplete(this); - ASSERT_ASYNC_NEVER_COMPLETED(std::move(chain)); + ASSERT_ASYNC_INCOMPLETION(std::move(chain)); } { auto chain = create_incomplete(this); - ASSERT_ASYNC_NEVER_COMPLETED(std::move(chain).then(this->supply())); + ASSERT_ASYNC_INCOMPLETION(std::move(chain).then(this->supply())); } } diff --git a/test/unit-test/test-continuable-base-errors.cpp b/test/unit-test/test-continuable-base-errors.cpp index 1758fff..8ca33df 100644 --- a/test/unit-test/test-continuable-base-errors.cpp +++ b/test/unit-test/test-continuable-base-errors.cpp @@ -69,7 +69,72 @@ static auto supply_test_exception() { } #endif -TYPED_TEST(single_dimension_tests, are_using_errors) { +TYPED_TEST(single_dimension_tests, are_completing_errors) { ASSERT_ASYNC_EXCEPTION_COMPLETION( this->supply_exception(supply_test_exception())); } + +TYPED_TEST(single_dimension_tests, are_yielding_error_result) { + ASSERT_ASYNC_EXCEPTION_RESULT(this->supply_exception(supply_test_exception()), + get_test_exception_proto()); +} + +TYPED_TEST(single_dimension_tests, are_never_completed_after_error_handled) { + auto handled = std::make_shared(false); + auto continuation = this->supply_exception(supply_test_exception()) + .fail([handled](cti::error_type) { + ASSERT_FALSE(*handled); + *handled = true; + }); + + ASSERT_ASYNC_INCOMPLETION(std::move(continuation)); + ASSERT_TRUE(*handled); +} + +#if !defined(CONTINUABLE_WITH_NO_EXCEPTIONS) +// Enable this test only if we support exceptions +TYPED_TEST(single_dimension_tests, are_yielding_errors_from_handlers) { + auto continuation = this->supply().then([] { + // Throw an error from inside the handler + throw test_exception(); + }); + + ASSERT_ASYNC_EXCEPTION_RESULT(std::move(continuation), + get_test_exception_proto()); +} +#endif + +TYPED_TEST(single_dimension_tests, are_result_error_accepting) { + auto handled = std::make_shared(false); + auto continuation = this->supply(supply_test_exception()) + .flow(fu2::overload( + [handled] { + ASSERT_FALSE(*handled); + *handled = true; + }, + [](cti::dispatch_error_tag, cti::error_type) { + // ... + FAIL(); + })); + + ASSERT_ASYNC_COMPLETION(std::move(continuation)); + ASSERT_TRUE(*handled); +} + +TYPED_TEST(single_dimension_tests, are_flow_error_accepting) { + auto handled = std::make_shared(false); + auto continuation = + this->supply_exception(supply_test_exception()) + .flow(fu2::overload( + [] { + // ... + FAIL(); + }, + [handled](cti::dispatch_error_tag, cti::error_type) { + ASSERT_FALSE(*handled); + *handled = true; + })); + + ASSERT_ASYNC_INCOMPLETION(std::move(continuation)); + ASSERT_TRUE(*handled); +}