Fix the unit tests by providing an ASSERT_ASYNC_CANCELLATION

This commit is contained in:
Denis Blank 2020-04-03 19:57:46 +02:00
parent f1e9255eb9
commit c8c4325b5b
3 changed files with 59 additions and 27 deletions

View File

@ -73,7 +73,28 @@ void assert_async_exception_completion(C&& continuable) {
// ... // ...
FAIL(); 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 <typename C>
void assert_async_cancellation(C&& continuable) {
auto called = std::make_shared<bool>(false);
std::forward<C>(continuable)
.then([](auto&&... args) {
// Workaround for our known GCC bug.
util::unused(std::forward<decltype(args)>(args)...);
// ...
FAIL();
})
.fail([called](cti::exception_t error) {
ASSERT_FALSE(bool(error));
ASSERT_FALSE(*called); ASSERT_FALSE(*called);
*called = true; *called = true;
}); });
@ -90,7 +111,7 @@ void assert_async_never_completed(C&& continuable) {
FAIL(); FAIL();
}) })
.fail([](cti::exception_t /*error*/) { .fail([](cti::exception_t error) {
// ... // ...
FAIL(); FAIL();
}); });
@ -100,8 +121,8 @@ template <typename C, typename V>
void assert_async_validation(C&& continuable, V&& validator) { void assert_async_validation(C&& continuable, V&& validator) {
assert_async_completion( assert_async_completion(
std::forward<C>(continuable) std::forward<C>(continuable)
.then([validator = .then(
std::forward<V>(validator)](auto&&... args) mutable { [validator = std::forward<V>(validator)](auto&&... args) mutable {
validator(std::forward<decltype(args)>(args)...); validator(std::forward<decltype(args)>(args)...);
})); }));
} }
@ -113,10 +134,10 @@ void assert_async_binary_validation(V&& validator, C&& continuable,
using size = std::integral_constant<std::size_t, sizeof...(expected)>; using size = std::integral_constant<std::size_t, sizeof...(expected)>;
assert_async_validation(std::forward<C>(continuable), [ assert_async_validation(
expected_pack = std::make_tuple(std::forward<Args>(expected)...), std::forward<C>(continuable),
validator = std::forward<V>(validator) [expected_pack = std::make_tuple(std::forward<Args>(expected)...),
](auto&&... args) mutable { validator = std::forward<V>(validator)](auto&&... args) mutable {
static_assert(size::value == sizeof...(args), static_assert(size::value == sizeof...(args),
"Async completion handler called with a different count " "Async completion handler called with a different count "
"of arguments!"); "of arguments!");
@ -139,10 +160,9 @@ void assert_async_binary_exception_validation(V&& validator, C&& continuable,
// The exception was not thrown! // The exception was not thrown!
FAIL(); FAIL();
}) })
.fail([ .fail([called, validator = std::forward<decltype(validator)>(validator),
called, validator = std::forward<decltype(validator)>(validator), expected = std::forward<decltype(expected)>(expected)](
expected = std::forward<decltype(expected)>(expected) exception_t error) {
](exception_t error) {
ASSERT_FALSE(*called); ASSERT_FALSE(*called);
*called = true; *called = true;

View File

@ -53,6 +53,14 @@
#define ASSERT_ASYNC_EXCEPTION_COMPLETION(CONTINUABLE) \ #define ASSERT_ASYNC_EXCEPTION_COMPLETION(CONTINUABLE) \
cti::detail::testing::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 /// Asserts that the final callback of the given continuable is never called
/// with any result. /// with any result.
/// ///

View File

@ -31,7 +31,9 @@ TYPED_TEST(single_dimension_tests, are_called_on_destruct) {
auto allowed = false; auto allowed = false;
// Are not supplyd until destruction // Are not supplyd until destruction
auto continuable = this->supply().then([&] { ASSERT_TRUE(allowed); }); auto continuable = this->supply().then([&] {
ASSERT_TRUE(allowed);
});
ASSERT_FALSE(allowed); ASSERT_FALSE(allowed);
allowed = true; allowed = true;
@ -56,7 +58,7 @@ auto create_incomplete(T* me) {
} }
template <typename T> template <typename T>
auto create_incomplete_cancelling(T* me) { auto create_cancellation(T* me) {
return me->make(identity<>{}, identity<void>{}, [](auto&& callback) mutable { return me->make(identity<>{}, identity<void>{}, [](auto&& callback) mutable {
EXPECT_TRUE(callback); EXPECT_TRUE(callback);
make_cancelling_continuable<void>().next( make_cancelling_continuable<void>().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) { TYPED_TEST(single_dimension_tests, are_not_finished_when_cancelling) {
{ {
auto chain = create_incomplete_cancelling(this); auto chain = create_cancellation(this);
ASSERT_ASYNC_INCOMPLETION(std::move(chain)); ASSERT_ASYNC_CANCELLATION(std::move(chain));
} }
{ {
auto chain = create_incomplete_cancelling(this); auto chain = create_cancellation(this);
ASSERT_ASYNC_INCOMPLETION(std::move(chain).then(this->supply())); ASSERT_ASYNC_CANCELLATION(std::move(chain).then(this->supply()));
} }
} }
TYPED_TEST(single_dimension_tests, freeze_is_kept_across_the_chain) { 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()); ASSERT_TRUE(chain.is_frozen());
} }