mirror of
https://github.com/Naios/continuable.git
synced 2025-12-06 08:46:44 +08:00
Add tests for checking the correct invalidation on destruction
This commit is contained in:
parent
4271f59348
commit
df0fd2f2da
@ -53,6 +53,15 @@ template <typename C> void expect_async_completion(C&& continuable) {
|
||||
EXPECT_TRUE(called);
|
||||
}
|
||||
|
||||
template <typename C> void expect_async_incomplete(C&& continuable) {
|
||||
std::forward<C>(continuable).then([](auto&&... args) {
|
||||
// Workaround for our known GCC bug.
|
||||
util::unused(std::forward<decltype(args)>(args)...);
|
||||
|
||||
FAIL();
|
||||
});
|
||||
}
|
||||
|
||||
template <typename C, typename V>
|
||||
void expect_async_validation(C&& continuable, V&& validator) {
|
||||
expect_async_completion(
|
||||
@ -128,6 +137,13 @@ void assert_async_types(C&& continuable, util::identity<Args...> expected) {
|
||||
#define EXPECT_ASYNC_COMPLETION(CONTINUABLE) \
|
||||
cti::detail::testing::expect_async_completion(CONTINUABLE);
|
||||
|
||||
/// Expects the final callback of the given continuable is never called
|
||||
/// with any result.
|
||||
///
|
||||
/// \since version 1.0.0
|
||||
#define EXPECT_ASYNC_INCOMPLETE(CONTINUABLE) \
|
||||
cti::detail::testing::expect_async_incomplete(CONTINUABLE);
|
||||
|
||||
/// Expects the continuation to be called and forwards it's arguments to
|
||||
/// the given validator which can then do assertions on the result.
|
||||
#define EXPECT_ASYNC_VALIDATION(CONTINUABLE, VALIDATOR) \
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
foreach(STEP RANGE 5)
|
||||
foreach(STEP RANGE 4)
|
||||
set(PROJECT_NAME test-continuable-${STEP})
|
||||
set(TEST_NAME continuable-unit-tests-${STEP})
|
||||
|
||||
@ -9,7 +9,7 @@ foreach(STEP RANGE 5)
|
||||
${CMAKE_CURRENT_LIST_DIR}/test-continuable-connection-any.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/test-continuable-connection-seq.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/test-continuable-erasure.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/test-continuable-recursion.cpp)
|
||||
${CMAKE_CURRENT_LIST_DIR}/test-continuable-regression.cpp)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
using namespace cti;
|
||||
using namespace cti::detail;
|
||||
|
||||
TYPED_TEST(single_dimension_tests, are_supplyd_on_destruct) {
|
||||
TYPED_TEST(single_dimension_tests, are_called_on_destruct) {
|
||||
{
|
||||
auto allowed = false;
|
||||
|
||||
@ -45,6 +45,38 @@ TYPED_TEST(single_dimension_tests, are_supplyd_on_destruct) {
|
||||
ASSERT_ASYNC_TYPES(this->supply(tag1{}), tag1);
|
||||
}
|
||||
|
||||
template <typename T> auto create_incomplete(T* me) {
|
||||
return me->make(identity<>{}, identity<void>{}, [](auto&& callback) mutable {
|
||||
// Destruct the callback here
|
||||
auto destroy = std::forward<decltype(callback)>(callback);
|
||||
(void)destroy;
|
||||
});
|
||||
}
|
||||
|
||||
template <typename T> auto assert_invocation(T* me) {
|
||||
return me->make(identity<>{}, identity<void>{},
|
||||
[](auto&& /*callback*/) mutable { FAIL(); });
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests, are_incomplete_when_released) {
|
||||
auto chain = this->supply().then([] {
|
||||
int i = 0;
|
||||
});
|
||||
chain.release();
|
||||
EXPECT_ASYNC_INCOMPLETE(std::move(chain));
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests, are_not_dispatched_when_released) {
|
||||
auto chain = assert_invocation(this);
|
||||
chain.release();
|
||||
EXPECT_ASYNC_INCOMPLETE(std::move(chain));
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests, are_not_finished_when_not_continued) {
|
||||
auto chain = create_incomplete(this);
|
||||
EXPECT_ASYNC_INCOMPLETE(std::move(chain));
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests, are_chainable) {
|
||||
EXPECT_ASYNC_RESULT(this->supply().then([] {
|
||||
return; // void
|
||||
@ -88,7 +120,7 @@ TYPED_TEST(single_dimension_tests, are_chainable) {
|
||||
}
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests, are_executable_through_dispatchers) {
|
||||
TYPED_TEST(single_dimension_tests, are_convertible_to_futures) {
|
||||
auto is_ready = [](auto& future) {
|
||||
// Check that the future is ready
|
||||
return future.wait_for(std::chrono::seconds(0)) ==
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
using namespace cti;
|
||||
using namespace cti::detail;
|
||||
|
||||
TEST(recursion_tests, are_multiple_args_mergeable) {
|
||||
TEST(regression_tests, are_multiple_args_mergeable) {
|
||||
{
|
||||
auto tp = std::make_tuple(1, 2, 3);
|
||||
util::merge(tp, tp, tp, tp, tp);
|
||||
@ -148,24 +148,24 @@ template <typename Provider> struct provide_continuation_seq_right {
|
||||
// Feel free to uncomment more tests, however this will increase the
|
||||
// build time significantly.
|
||||
using single_types = ::testing::Types<
|
||||
#if UNIT_TEST_STEP == 1
|
||||
#if UNIT_TEST_STEP == 0
|
||||
provide_copyable,
|
||||
// provide_unique,
|
||||
// provide_copyable_erasure,
|
||||
provide_unique_erasure
|
||||
#elif UNIT_TEST_STEP == 2
|
||||
#elif UNIT_TEST_STEP == 1
|
||||
// Some instantiations out commented for compilation speed reasons
|
||||
// provide_continuation_and_left<provide_copyable>,
|
||||
provide_continuation_and_left<provide_unique>
|
||||
// provide_continuation_and_left<provide_copyable_erasure>,
|
||||
// provide_continuation_and_left<provide_unique_erasure>,
|
||||
// provide_continuation_and_right<provide_copyable>,
|
||||
#elif UNIT_TEST_STEP == 3
|
||||
#elif UNIT_TEST_STEP == 2
|
||||
provide_continuation_and_right<provide_unique>
|
||||
// provide_continuation_and_left<provide_copyable_erasure>,
|
||||
#elif UNIT_TEST_STEP == 4
|
||||
#elif UNIT_TEST_STEP == 3
|
||||
provide_continuation_and_left<provide_unique_erasure>
|
||||
#elif UNIT_TEST_STEP == 5
|
||||
#elif UNIT_TEST_STEP == 4
|
||||
provide_continuation_seq_right<provide_unique>
|
||||
#endif
|
||||
>;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user