Commit 9c47cb9c authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook GitHub Bot

Prefer to nest helper functions in coro tests

Summary: [Folly] Prefer to nest helper functions in coro tests within the specific tests which use them.

Reviewed By: ispeters, Orvid

Differential Revision: D20324066

fbshipit-source-id: 4134145c406f2d1fdeaddf9a7d244c1bd25ec60b
parent 4f5128bb
This diff is collapsed.
......@@ -107,28 +107,13 @@ TEST_F(InlineTaskTest, SimpleRefTask) {
EXPECT_EQ(&hasRun, &result);
}
struct MoveOnlyType {
int value_;
explicit MoveOnlyType(int value) noexcept : value_(value) {}
MoveOnlyType(MoveOnlyType&& other) noexcept
: value_(std::exchange(other.value_, -1)) {}
MoveOnlyType& operator=(MoveOnlyType&& other) noexcept {
value_ = std::exchange(other.value_, -1);
return *this;
}
~MoveOnlyType() { value_ = -2; }
};
struct TypeWithImplicitSingleValueConstructor {
float value_;
/* implicit */ TypeWithImplicitSingleValueConstructor(float x) : value_(x) {}
};
TEST_F(InlineTaskTest, ReturnValueWithInitializerListSyntax) {
struct TypeWithImplicitSingleValueConstructor {
float value_;
/* implicit */ TypeWithImplicitSingleValueConstructor(float x)
: value_(x) {}
};
auto f = []() -> InlineTask<TypeWithImplicitSingleValueConstructor> {
co_return {1.23f};
};
......@@ -137,15 +122,15 @@ TEST_F(InlineTaskTest, ReturnValueWithInitializerListSyntax) {
EXPECT_EQ(1.23f, result.value_);
}
struct TypeWithImplicitMultiValueConstructor {
std::string s_;
float x_;
/* implicit */ TypeWithImplicitMultiValueConstructor(
std::string s, float x) noexcept
: s_(s), x_(x) {}
};
TEST_F(InlineTaskTest, ReturnValueWithInitializerListSyntax2) {
struct TypeWithImplicitMultiValueConstructor {
std::string s_;
float x_;
/* implicit */ TypeWithImplicitMultiValueConstructor(
std::string s, float x) noexcept
: s_(s), x_(x) {}
};
auto f = []() -> InlineTask<TypeWithImplicitMultiValueConstructor> {
co_return {"hello", 3.1415f};
};
......@@ -155,6 +140,26 @@ TEST_F(InlineTaskTest, ReturnValueWithInitializerListSyntax2) {
EXPECT_EQ(3.1415f, result.x_);
}
namespace {
struct MoveOnlyType {
int value_;
explicit MoveOnlyType(int value) noexcept : value_(value) {}
MoveOnlyType(MoveOnlyType&& other) noexcept
: value_(std::exchange(other.value_, -1)) {}
FOLLY_MAYBE_UNUSED MoveOnlyType& operator=(MoveOnlyType&& other) noexcept {
value_ = std::exchange(other.value_, -1);
return *this;
}
~MoveOnlyType() { value_ = -2; }
};
} // namespace
TEST_F(InlineTaskTest, TaskOfMoveOnlyType) {
auto f = []() -> InlineTask<MoveOnlyType> { co_return MoveOnlyType{42}; };
......@@ -191,9 +196,9 @@ TEST_F(InlineTaskTest, ReturnLvalueReference) {
EXPECT_EQ(&value, &x);
}
struct MyException : std::exception {};
TEST_F(InlineTaskTest, ExceptionsPropagateFromVoidTask) {
struct MyException : std::exception {};
auto f = []() -> InlineTask<void> {
co_await std::experimental::suspend_never{};
throw MyException{};
......@@ -202,6 +207,8 @@ TEST_F(InlineTaskTest, ExceptionsPropagateFromVoidTask) {
}
TEST_F(InlineTaskTest, ExceptionsPropagateFromValueTask) {
struct MyException : std::exception {};
auto f = []() -> InlineTask<int> {
co_await std::experimental::suspend_never{};
throw MyException{};
......@@ -210,6 +217,8 @@ TEST_F(InlineTaskTest, ExceptionsPropagateFromValueTask) {
}
TEST_F(InlineTaskTest, ExceptionsPropagateFromRefTask) {
struct MyException : std::exception {};
auto f = []() -> InlineTask<int&> {
co_await std::experimental::suspend_never{};
throw MyException{};
......@@ -217,54 +226,64 @@ TEST_F(InlineTaskTest, ExceptionsPropagateFromRefTask) {
EXPECT_THROW(folly::coro::blockingWait(f()), MyException);
}
struct ThrowingCopyConstructor {
ThrowingCopyConstructor() noexcept = default;
TEST_F(InlineTaskTest, ExceptionsPropagateFromReturnValueConstructor) {
struct MyException : std::exception {};
[[noreturn]] ThrowingCopyConstructor(const ThrowingCopyConstructor&) noexcept(
false) {
throw MyException{};
}
struct ThrowingCopyConstructor {
FOLLY_MAYBE_UNUSED ThrowingCopyConstructor() noexcept = default;
ThrowingCopyConstructor& operator=(const ThrowingCopyConstructor&) = delete;
};
[[noreturn]] ThrowingCopyConstructor(
const ThrowingCopyConstructor&) noexcept(false) {
throw MyException{};
}
ThrowingCopyConstructor& operator=(const ThrowingCopyConstructor&) = delete;
};
TEST_F(InlineTaskTest, ExceptionsPropagateFromReturnValueConstructor) {
auto f = []() -> InlineTask<ThrowingCopyConstructor> { co_return {}; };
EXPECT_THROW(folly::coro::blockingWait(f()), MyException);
}
InlineTask<void> recursiveTask(int depth) {
if (depth > 0) {
co_await recursiveTask(depth - 1);
}
}
TEST_F(InlineTaskTest, DeepRecursionDoesntStackOverflow) {
folly::coro::blockingWait(recursiveTask(500000));
}
struct RecursiveTask {
InlineTask<void> operator()(int depth) {
if (depth > 0) {
co_await operator()(depth - 1);
}
}
};
InlineTask<int> recursiveValueTask(int depth) {
if (depth > 0) {
co_return co_await recursiveValueTask(depth - 1) + 1;
}
co_return 0;
folly::coro::blockingWait(RecursiveTask{}(500000));
}
TEST_F(InlineTaskTest, DeepRecursionOfValueTaskDoesntStackOverflow) {
EXPECT_EQ(500000, folly::coro::blockingWait(recursiveValueTask(500000)));
}
InlineTask<void> recursiveThrowingTask(int depth) {
if (depth > 0) {
co_await recursiveThrowingTask(depth - 1);
}
struct RecursiveValueTask {
InlineTask<int> operator()(int depth) {
if (depth > 0) {
co_return co_await operator()(depth - 1) + 1;
}
co_return 0;
}
};
throw MyException{};
EXPECT_EQ(500000, folly::coro::blockingWait(RecursiveValueTask{}(500000)));
}
TEST_F(InlineTaskTest, DeepRecursionOfExceptions) {
struct MyException : std::exception {};
struct RecursiveThrowingTask {
static InlineTask<void> go(int depth) {
if (depth > 0) {
co_await go(depth - 1);
}
throw MyException{};
}
};
EXPECT_THROW(
folly::coro::blockingWait(recursiveThrowingTask(50000)), MyException);
folly::coro::blockingWait(RecursiveThrowingTask::go(50000)), MyException);
}
#endif
......@@ -362,9 +362,10 @@ TEST_F(TaskTest, FutureRoundtrip) {
std::runtime_error);
}
// NOTE: This function is unused.
namespace {
// We just want to make sure this compiles without errors or warnings.
folly::coro::Task<void>
FOLLY_MAYBE_UNUSED folly::coro::Task<void>
checkAwaitingFutureOfUnitDoesntWarnAboutDiscardedResult() {
co_await folly::makeSemiFuture();
......@@ -372,11 +373,13 @@ checkAwaitingFutureOfUnitDoesntWarnAboutDiscardedResult() {
co_await folly::futures::sleep(1ms);
}
folly::coro::Task<int&> returnIntRef(int& value) {
co_return value;
}
} // namespace
TEST_F(TaskTest, TaskOfLvalueReference) {
auto returnIntRef = [](int& value) -> folly::coro::Task<int&> {
co_return value;
};
int value = 123;
auto&& result = folly::coro::blockingWait(returnIntRef(value));
static_assert(std::is_same_v<decltype(result), int&>);
......@@ -385,6 +388,10 @@ TEST_F(TaskTest, TaskOfLvalueReference) {
TEST_F(TaskTest, TaskOfLvalueReferenceAsTry) {
folly::coro::blockingWait([]() -> folly::coro::Task<void> {
auto returnIntRef = [](int& value) -> folly::coro::Task<int&> {
co_return value;
};
int value = 123;
auto&& result = co_await co_awaitTry(returnIntRef(value));
CHECK(result.hasValue());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment