mirror of
https://github.com/Naios/continuable.git
synced 2026-01-01 03:12:12 +08:00
Add the unit tests for the failure handlers recovering and rethrowing
This commit is contained in:
parent
afe1a3298e
commit
c5663bf1ad
@ -899,17 +899,20 @@ constexpr auto make_exceptional_continuable(Exception&& exception) {
|
||||
|
||||
template <typename... Args>
|
||||
auto recover(Args&&... args) {
|
||||
return make_expected(std::forward<Args>(args)...);
|
||||
return make_result(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/// Returns a new exceptional result from the given exception
|
||||
// NOLINTNEXTLINE(performance-unnecessary-value-param)
|
||||
inline auto rethrow(exception_t exception) {
|
||||
// NOLINTNEXTLINE(hicpp-move-const-arg, performance-move-const-arg)
|
||||
return make_exceptional_result(std::move(exception));
|
||||
return exceptional_result{std::move(exception)};
|
||||
}
|
||||
|
||||
inline auto cancel() {
|
||||
return make_empty_result();
|
||||
return empty_result{};
|
||||
}
|
||||
|
||||
/// \}
|
||||
} // namespace cti
|
||||
|
||||
|
||||
@ -52,11 +52,6 @@ namespace cti {
|
||||
/// value so the real result gets invalidated when this object is passed to it.
|
||||
struct empty_result {};
|
||||
|
||||
/// Returns a new empty result
|
||||
inline empty_result make_empty_result() {
|
||||
return {};
|
||||
}
|
||||
|
||||
/// A class which is convertible to any result and that definitly holds
|
||||
/// an exception which is then passed to the converted result object.
|
||||
class exceptional_result {
|
||||
@ -101,13 +96,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// Returns a new exceptional result from the given exception
|
||||
// NOLINTNEXTLINE(performance-unnecessary-value-param)
|
||||
inline exceptional_result make_exceptional_result(exception_t exception) {
|
||||
// NOLINTNEXTLINE(hicpp-move-const-arg, performance-move-const-arg)
|
||||
return exceptional_result{std::move(exception)};
|
||||
}
|
||||
|
||||
/// The result class can carry the three kinds of results an asynchronous
|
||||
/// operation can return: no result, a value or an exception.
|
||||
/// - *no result*: If the operation didn't finish
|
||||
|
||||
@ -409,7 +409,7 @@ struct result_handler_base<handle_results::yes, Base,
|
||||
}
|
||||
};
|
||||
|
||||
inline auto make_error_invoker(
|
||||
inline auto make_exception_invoker(
|
||||
std::integral_constant<handle_errors, handle_errors::plain>) noexcept {
|
||||
return [](auto&& callback, exception_t&& error) {
|
||||
// Errors are not partial invoked
|
||||
@ -417,7 +417,7 @@ inline auto make_error_invoker(
|
||||
std::forward<decltype(callback)>(callback)(std::move(error));
|
||||
};
|
||||
}
|
||||
inline auto make_error_invoker(
|
||||
inline auto make_exception_invoker(
|
||||
std::integral_constant<handle_errors, handle_errors::forward>) noexcept {
|
||||
return [](auto&& callback, exception_t&& error) {
|
||||
// Errors are not partial invoked
|
||||
@ -432,7 +432,7 @@ template <handle_errors HandleErrors /* = plain or forward*/, typename Base>
|
||||
struct error_handler_base {
|
||||
void operator()(exception_arg_t, exception_t error) && {
|
||||
// Just invoke the error handler, cancel the calling hierarchy after
|
||||
auto invoker = make_error_invoker(
|
||||
auto invoker = make_exception_invoker(
|
||||
std::integral_constant<handle_errors, HandleErrors>{});
|
||||
|
||||
// Invoke the error handler
|
||||
@ -578,7 +578,6 @@ constexpr auto
|
||||
next_hint_of(std::integral_constant<handle_results, handle_results::no>,
|
||||
traits::identity<T> /*callback*/,
|
||||
hints::signature_hint_tag<Args...> current) {
|
||||
// TODO
|
||||
return current;
|
||||
}
|
||||
|
||||
|
||||
@ -30,13 +30,13 @@ static int const CANARY = 382947;
|
||||
TYPED_TEST(single_dimension_tests, multipath_result_is_forwardable) {
|
||||
EXPECT_ASYNC_RESULT(this->supply().then([](auto&&... canaries) -> result<> {
|
||||
//
|
||||
return make_result(std::forward<decltype(canaries)>(canaries)...);
|
||||
return recover(std::forward<decltype(canaries)>(canaries)...);
|
||||
}));
|
||||
|
||||
EXPECT_ASYNC_RESULT(
|
||||
this->supply(CANARY).then([](auto&&... canaries) -> result<int> {
|
||||
//
|
||||
return make_result(std::forward<decltype(canaries)>(canaries)...);
|
||||
return recover(std::forward<decltype(canaries)>(canaries)...);
|
||||
}),
|
||||
CANARY);
|
||||
|
||||
@ -44,7 +44,7 @@ TYPED_TEST(single_dimension_tests, multipath_result_is_forwardable) {
|
||||
this->supply(1, CANARY, 3)
|
||||
.then([](auto&&... canaries) -> result<int, int, int> {
|
||||
//
|
||||
return make_result(std::forward<decltype(canaries)>(canaries)...);
|
||||
return recover(std::forward<decltype(canaries)>(canaries)...);
|
||||
}),
|
||||
1, CANARY, 3);
|
||||
}
|
||||
@ -53,53 +53,106 @@ TYPED_TEST(single_dimension_tests, multipath_result_is_throwable) {
|
||||
ASSERT_ASYNC_EXCEPTION_COMPLETION(
|
||||
this->supply().then([]() -> exceptional_result {
|
||||
//
|
||||
return make_exceptional_result(supply_test_exception());
|
||||
return rethrow(supply_test_exception());
|
||||
}));
|
||||
|
||||
ASSERT_ASYNC_EXCEPTION_COMPLETION(this->supply().then([]() -> result<> {
|
||||
//
|
||||
return make_exceptional_result(supply_test_exception());
|
||||
return rethrow(supply_test_exception());
|
||||
}));
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests, multipath_result_is_cancelable) {
|
||||
ASSERT_ASYNC_INCOMPLETION(this->supply().then([]() -> empty_result {
|
||||
//
|
||||
return make_empty_result();
|
||||
return cancel();
|
||||
}));
|
||||
|
||||
ASSERT_ASYNC_INCOMPLETION(this->supply().then([]() -> result<> {
|
||||
//
|
||||
return make_empty_result();
|
||||
return cancel();
|
||||
}));
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests, multipath_exception_is_recoverable) {
|
||||
/*EXPECT_ASYNC_RESULT(this->supply_exception(supply_test_exception())
|
||||
.fail([](exception_t) -> result<> {
|
||||
//
|
||||
return make_result();
|
||||
}));
|
||||
EXPECT_ASYNC_RESULT(
|
||||
this->supply_exception(supply_test_exception(), identity<>{})
|
||||
.fail([](exception_t) -> result<> {
|
||||
//
|
||||
return recover();
|
||||
}));
|
||||
|
||||
EXPECT_ASYNC_RESULT(this->supply_exception(supply_test_exception())
|
||||
.fail([](exception_t) -> result<int> {
|
||||
//
|
||||
return make_result(CANARY);
|
||||
}),
|
||||
CANARY);
|
||||
EXPECT_ASYNC_RESULT(
|
||||
this->supply_exception(supply_test_exception(), identity<int>{})
|
||||
.fail([](exception_t) -> result<int> {
|
||||
//
|
||||
return recover(CANARY);
|
||||
}),
|
||||
CANARY);
|
||||
|
||||
EXPECT_ASYNC_RESULT(this->supply_exception(supply_test_exception())
|
||||
.fail([](exception_t) -> result<int, int, int> {
|
||||
//
|
||||
return make_result(1, CANARY, 3);
|
||||
}),
|
||||
1, CANARY, 3);*/
|
||||
EXPECT_ASYNC_RESULT(
|
||||
this->supply_exception(supply_test_exception(), identity<int, int, int>{})
|
||||
.fail([](exception_t) -> result<int, int, int> {
|
||||
//
|
||||
return recover(1, CANARY, 3);
|
||||
}),
|
||||
1, CANARY, 3);
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests, multipath_exception_is_forwardable) {
|
||||
// TODO
|
||||
ASSERT_ASYNC_EXCEPTION_COMPLETION(
|
||||
this->supply_exception(supply_test_exception(), identity<int>{})
|
||||
.fail([](exception_t exception) -> exceptional_result {
|
||||
//
|
||||
return rethrow(exception);
|
||||
}));
|
||||
|
||||
ASSERT_ASYNC_EXCEPTION_COMPLETION(
|
||||
this->supply_exception(supply_test_exception(), identity<int>{})
|
||||
.fail([](exception_t exception) -> result<int> {
|
||||
//
|
||||
return rethrow(exception);
|
||||
}));
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests, multipath_exception_is_cancelable) {
|
||||
// TODO
|
||||
ASSERT_ASYNC_INCOMPLETION(
|
||||
this->supply_exception(supply_test_exception(), identity<int>{})
|
||||
.fail([](exception_t) -> empty_result {
|
||||
//
|
||||
return cancel();
|
||||
})
|
||||
.fail([] {
|
||||
//
|
||||
FAIL();
|
||||
}));
|
||||
|
||||
ASSERT_ASYNC_INCOMPLETION(
|
||||
this->supply_exception(supply_test_exception(), identity<int>{})
|
||||
.fail([](exception_t) -> result<int> {
|
||||
//
|
||||
return cancel();
|
||||
})
|
||||
.fail([] {
|
||||
//
|
||||
FAIL();
|
||||
}));
|
||||
}
|
||||
|
||||
TYPED_TEST(single_dimension_tests, multipath_exception_is_autocanceled) {
|
||||
bool caught = false;
|
||||
ASSERT_ASYNC_INCOMPLETION(this->supply_exception(supply_test_exception())
|
||||
.fail([&](exception_t) {
|
||||
EXPECT_FALSE(caught);
|
||||
caught = true;
|
||||
})
|
||||
.then([] {
|
||||
// ...
|
||||
FAIL();
|
||||
})
|
||||
.fail([](exception_t) {
|
||||
// ...
|
||||
FAIL();
|
||||
}));
|
||||
ASSERT_TRUE(caught);
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ auto to_hint(identity<Args...> hint) {
|
||||
template <typename... Args>
|
||||
auto supplier_of(Args&&... args) {
|
||||
return [values = std::make_tuple(std::forward<Args>(args)...)](
|
||||
auto&& promise) mutable {
|
||||
auto&& promise) mutable {
|
||||
cti::detail::traits::unpack(
|
||||
[&](auto&&... passed) {
|
||||
promise.set_value(std::forward<decltype(passed)>(passed)...);
|
||||
@ -84,12 +84,9 @@ public:
|
||||
supplier_of(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
template <typename Arg>
|
||||
auto supply_exception(Arg&& arg) {
|
||||
identity<> arg_types;
|
||||
auto hint_types = to_hint(arg_types);
|
||||
|
||||
return this->make(arg_types, hint_types,
|
||||
template <typename Arg, typename Hint = identity<>>
|
||||
auto supply_exception(Arg&& arg, Hint hint = {}) {
|
||||
return this->make(hint, to_hint(hint),
|
||||
exception_supplier_of(std::forward<Arg>(arg)));
|
||||
}
|
||||
};
|
||||
@ -112,12 +109,12 @@ struct provide_copyable {
|
||||
struct provide_unique {
|
||||
template <typename... Args, typename... Hint, typename T>
|
||||
auto make(identity<Args...>, identity<Hint...>, T&& callback) {
|
||||
return cti::make_continuable<Hint...>([
|
||||
callback = std::forward<T>(callback), guard = std::make_unique<int>(0)
|
||||
](auto&&... args) mutable {
|
||||
(void)(*guard);
|
||||
return std::move(callback)(std::forward<decltype(args)>(args)...);
|
||||
});
|
||||
return cti::make_continuable<Hint...>(
|
||||
[callback = std::forward<T>(callback),
|
||||
guard = std::make_unique<int>(0)](auto&&... args) mutable {
|
||||
(void)(*guard);
|
||||
return std::move(callback)(std::forward<decltype(args)>(args)...);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user