Commit 9df5dacf authored by Chad Austin's avatar Chad Austin Committed by Facebook Github Bot

test that the value remains alive even if the .then callback takes no arguments

Summary:
It was not clear to me, if a callback takes no arguments, the
underlying value is guaranteed to be alive during the execution of the
callback, so I wrote these tests.

Reviewed By: yfeldblum

Differential Revision: D6594921

fbshipit-source-id: 6a658afc1bf4d29eaa9c62269ddc21c7f897ad01
parent 8091d719
...@@ -36,6 +36,40 @@ struct Widget { ...@@ -36,6 +36,40 @@ struct Widget {
throw std::logic_error("unexpected move assignment"); throw std::logic_error("unexpected move assignment");
} }
}; };
struct CountedWidget : Widget {
static std::vector<Widget*> instances_;
bool alive = true;
/* implicit */ CountedWidget(int v) : Widget(v) {
instances_.push_back(this);
}
CountedWidget(const CountedWidget& other) : Widget(other) {
instances_.push_back(this);
}
CountedWidget(CountedWidget&& other) noexcept(false)
: Widget(std::move(other)) {
other.alive = false;
other.remove();
instances_.push_back(this);
}
~CountedWidget() {
if (alive) {
remove();
}
}
private:
CountedWidget& operator=(const CountedWidget&) = delete;
CountedWidget& operator=(CountedWidget&&) = delete;
void remove() {
auto iter = std::find(instances_.begin(), instances_.end(), this);
EXPECT_TRUE(iter != instances_.end());
instances_.erase(iter);
}
};
std::vector<Widget*> CountedWidget::instances_;
} // namespace } // namespace
TEST(Then, tryConstructor) { TEST(Then, tryConstructor) {
...@@ -172,6 +206,29 @@ TEST(Then, constValue) { ...@@ -172,6 +206,29 @@ TEST(Then, constValue) {
EXPECT_EQ(future.value(), 23); EXPECT_EQ(future.value(), 23);
} }
TEST(Then, objectAliveDuringImmediateNoParamContinuation) {
auto f = makeFuture<CountedWidget>(23);
auto called = false;
f.then([&] {
EXPECT_EQ(CountedWidget::instances_.size(), 1u);
EXPECT_EQ(CountedWidget::instances_[0]->v_, 23);
called = true;
});
EXPECT_EQ(true, called);
}
TEST(Then, objectAliveDuringDeferredNoParamContinuation) {
auto p = Promise<CountedWidget>{};
bool called = false;
p.getFuture().then([&] {
EXPECT_EQ(CountedWidget::instances_.size(), 1u);
EXPECT_EQ(CountedWidget::instances_[0]->v_, 23);
called = true;
});
p.setValue(CountedWidget{23});
EXPECT_EQ(true, called);
}
TEST(Then, voidThenShouldPropagateExceptions) { TEST(Then, voidThenShouldPropagateExceptions) {
EXPECT_FALSE(makeFuture(42).then().hasException()); EXPECT_FALSE(makeFuture(42).then().hasException());
EXPECT_TRUE(makeFuture<int>(std::runtime_error("err")) EXPECT_TRUE(makeFuture<int>(std::runtime_error("err"))
......
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