Add tests for checking the correct invalidation on destruction

This commit is contained in:
Denis Blank 2017-03-02 23:35:49 +01:00
parent 4271f59348
commit df0fd2f2da
5 changed files with 58 additions and 10 deletions

View File

@ -53,6 +53,15 @@ template <typename C> void expect_async_completion(C&& continuable) {
EXPECT_TRUE(called); 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> template <typename C, typename V>
void expect_async_validation(C&& continuable, V&& validator) { void expect_async_validation(C&& continuable, V&& validator) {
expect_async_completion( expect_async_completion(
@ -128,6 +137,13 @@ void assert_async_types(C&& continuable, util::identity<Args...> expected) {
#define EXPECT_ASYNC_COMPLETION(CONTINUABLE) \ #define EXPECT_ASYNC_COMPLETION(CONTINUABLE) \
cti::detail::testing::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 /// Expects the continuation to be called and forwards it's arguments to
/// the given validator which can then do assertions on the result. /// the given validator which can then do assertions on the result.
#define EXPECT_ASYNC_VALIDATION(CONTINUABLE, VALIDATOR) \ #define EXPECT_ASYNC_VALIDATION(CONTINUABLE, VALIDATOR) \

View File

@ -1,4 +1,4 @@
foreach(STEP RANGE 5) foreach(STEP RANGE 4)
set(PROJECT_NAME test-continuable-${STEP}) set(PROJECT_NAME test-continuable-${STEP})
set(TEST_NAME continuable-unit-tests-${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-any.cpp
${CMAKE_CURRENT_LIST_DIR}/test-continuable-connection-seq.cpp ${CMAKE_CURRENT_LIST_DIR}/test-continuable-connection-seq.cpp
${CMAKE_CURRENT_LIST_DIR}/test-continuable-erasure.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} target_link_libraries(${PROJECT_NAME}
PRIVATE PRIVATE

View File

@ -26,7 +26,7 @@
using namespace cti; using namespace cti;
using namespace cti::detail; 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; auto allowed = false;
@ -45,6 +45,38 @@ TYPED_TEST(single_dimension_tests, are_supplyd_on_destruct) {
ASSERT_ASYNC_TYPES(this->supply(tag1{}), tag1); 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) { TYPED_TEST(single_dimension_tests, are_chainable) {
EXPECT_ASYNC_RESULT(this->supply().then([] { EXPECT_ASYNC_RESULT(this->supply().then([] {
return; // void 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) { auto is_ready = [](auto& future) {
// Check that the future is ready // Check that the future is ready
return future.wait_for(std::chrono::seconds(0)) == return future.wait_for(std::chrono::seconds(0)) ==

View File

@ -28,7 +28,7 @@
using namespace cti; using namespace cti;
using namespace cti::detail; 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); auto tp = std::make_tuple(1, 2, 3);
util::merge(tp, tp, tp, tp, tp); util::merge(tp, tp, tp, tp, tp);

View File

@ -148,24 +148,24 @@ template <typename Provider> struct provide_continuation_seq_right {
// Feel free to uncomment more tests, however this will increase the // Feel free to uncomment more tests, however this will increase the
// build time significantly. // build time significantly.
using single_types = ::testing::Types< using single_types = ::testing::Types<
#if UNIT_TEST_STEP == 1 #if UNIT_TEST_STEP == 0
provide_copyable, provide_copyable,
// provide_unique, // provide_unique,
// provide_copyable_erasure, // provide_copyable_erasure,
provide_unique_erasure provide_unique_erasure
#elif UNIT_TEST_STEP == 2 #elif UNIT_TEST_STEP == 1
// Some instantiations out commented for compilation speed reasons // Some instantiations out commented for compilation speed reasons
// provide_continuation_and_left<provide_copyable>, // provide_continuation_and_left<provide_copyable>,
provide_continuation_and_left<provide_unique> provide_continuation_and_left<provide_unique>
// provide_continuation_and_left<provide_copyable_erasure>, // provide_continuation_and_left<provide_copyable_erasure>,
// provide_continuation_and_left<provide_unique_erasure>, // provide_continuation_and_left<provide_unique_erasure>,
// provide_continuation_and_right<provide_copyable>, // 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_right<provide_unique>
// provide_continuation_and_left<provide_copyable_erasure>, // provide_continuation_and_left<provide_copyable_erasure>,
#elif UNIT_TEST_STEP == 4 #elif UNIT_TEST_STEP == 3
provide_continuation_and_left<provide_unique_erasure> provide_continuation_and_left<provide_unique_erasure>
#elif UNIT_TEST_STEP == 5 #elif UNIT_TEST_STEP == 4
provide_continuation_seq_right<provide_unique> provide_continuation_seq_right<provide_unique>
#endif #endif
>; >;