From c8c4325b5bcfa3468c8f8adde5c52fb52b0562e0 Mon Sep 17 00:00:00 2001 From: Denis Blank Date: Fri, 3 Apr 2020 19:57:46 +0200 Subject: [PATCH] Fix the unit tests by providing an ASSERT_ASYNC_CANCELLATION --- include/continuable/detail/other/testing.hpp | 60 ++++++++++++------- include/continuable/external/gtest.hpp | 8 +++ .../multi/test-continuable-base-destruct.cpp | 18 +++--- 3 files changed, 59 insertions(+), 27 deletions(-) diff --git a/include/continuable/detail/other/testing.hpp b/include/continuable/detail/other/testing.hpp index 130222e..cd7d39c 100644 --- a/include/continuable/detail/other/testing.hpp +++ b/include/continuable/detail/other/testing.hpp @@ -73,7 +73,28 @@ void assert_async_exception_completion(C&& continuable) { // ... FAIL(); }) - .fail([called](cti::exception_t /*error*/) { + .fail([called](cti::exception_t error) { + ASSERT_TRUE(bool(error)); + ASSERT_FALSE(*called); + *called = true; + }); + + ASSERT_TRUE(*called); +} + +template +void assert_async_cancellation(C&& continuable) { + auto called = std::make_shared(false); + std::forward(continuable) + .then([](auto&&... args) { + // Workaround for our known GCC bug. + util::unused(std::forward(args)...); + + // ... + FAIL(); + }) + .fail([called](cti::exception_t error) { + ASSERT_FALSE(bool(error)); ASSERT_FALSE(*called); *called = true; }); @@ -90,7 +111,7 @@ void assert_async_never_completed(C&& continuable) { FAIL(); }) - .fail([](cti::exception_t /*error*/) { + .fail([](cti::exception_t error) { // ... FAIL(); }); @@ -100,10 +121,10 @@ template void assert_async_validation(C&& continuable, V&& validator) { assert_async_completion( std::forward(continuable) - .then([validator = - std::forward(validator)](auto&&... args) mutable { - validator(std::forward(args)...); - })); + .then( + [validator = std::forward(validator)](auto&&... args) mutable { + validator(std::forward(args)...); + })); } /// Expects that the continuable is finished with the given arguments @@ -113,17 +134,17 @@ void assert_async_binary_validation(V&& validator, C&& continuable, using size = std::integral_constant; - assert_async_validation(std::forward(continuable), [ - expected_pack = std::make_tuple(std::forward(expected)...), - validator = std::forward(validator) - ](auto&&... args) mutable { - static_assert(size::value == sizeof...(args), - "Async completion handler called with a different count " - "of arguments!"); + assert_async_validation( + std::forward(continuable), + [expected_pack = std::make_tuple(std::forward(expected)...), + validator = std::forward(validator)](auto&&... args) mutable { + static_assert(size::value == sizeof...(args), + "Async completion handler called with a different count " + "of arguments!"); - validator(std::make_tuple(std::forward(args)...), - expected_pack); - }); + validator(std::make_tuple(std::forward(args)...), + expected_pack); + }); } /// Expects that the continuable is finished with the given arguments @@ -139,10 +160,9 @@ void assert_async_binary_exception_validation(V&& validator, C&& continuable, // The exception was not thrown! FAIL(); }) - .fail([ - called, validator = std::forward(validator), - expected = std::forward(expected) - ](exception_t error) { + .fail([called, validator = std::forward(validator), + expected = std::forward(expected)]( + exception_t error) { ASSERT_FALSE(*called); *called = true; diff --git a/include/continuable/external/gtest.hpp b/include/continuable/external/gtest.hpp index 7a2bc67..35afb67 100644 --- a/include/continuable/external/gtest.hpp +++ b/include/continuable/external/gtest.hpp @@ -53,6 +53,14 @@ #define ASSERT_ASYNC_EXCEPTION_COMPLETION(CONTINUABLE) \ cti::detail::testing::assert_async_exception_completion(CONTINUABLE); +/// Asserts that the final callback of the given continuable is called +/// with a cancelled result which is represented by a default constructed +/// exception_t. +/// +/// \since 4.0.0 +#define ASSERT_ASYNC_CANCELLATION(CONTINUABLE) \ + cti::detail::testing::assert_async_cancellation(CONTINUABLE); + /// Asserts that the final callback of the given continuable is never called /// with any result. /// diff --git a/test/unit-test/multi/test-continuable-base-destruct.cpp b/test/unit-test/multi/test-continuable-base-destruct.cpp index c0cc1c0..aa4c8b5 100644 --- a/test/unit-test/multi/test-continuable-base-destruct.cpp +++ b/test/unit-test/multi/test-continuable-base-destruct.cpp @@ -31,7 +31,9 @@ TYPED_TEST(single_dimension_tests, are_called_on_destruct) { auto allowed = false; // Are not supplyd until destruction - auto continuable = this->supply().then([&] { ASSERT_TRUE(allowed); }); + auto continuable = this->supply().then([&] { + ASSERT_TRUE(allowed); + }); ASSERT_FALSE(allowed); allowed = true; @@ -56,7 +58,7 @@ auto create_incomplete(T* me) { } template -auto create_incomplete_cancelling(T* me) { +auto create_cancellation(T* me) { return me->make(identity<>{}, identity{}, [](auto&& callback) mutable { EXPECT_TRUE(callback); make_cancelling_continuable().next( @@ -106,19 +108,21 @@ TYPED_TEST(single_dimension_tests, are_not_finished_when_not_continued) { TYPED_TEST(single_dimension_tests, are_not_finished_when_cancelling) { { - auto chain = create_incomplete_cancelling(this); - ASSERT_ASYNC_INCOMPLETION(std::move(chain)); + auto chain = create_cancellation(this); + ASSERT_ASYNC_CANCELLATION(std::move(chain)); } { - auto chain = create_incomplete_cancelling(this); - ASSERT_ASYNC_INCOMPLETION(std::move(chain).then(this->supply())); + auto chain = create_cancellation(this); + ASSERT_ASYNC_CANCELLATION(std::move(chain).then(this->supply())); } } TYPED_TEST(single_dimension_tests, freeze_is_kept_across_the_chain) { { - auto chain = this->supply().freeze().then([=] { return this->supply(); }); + auto chain = this->supply().freeze().then([=] { + return this->supply(); + }); ASSERT_TRUE(chain.is_frozen()); }