Commit 5180b662 authored by Hannes Roth's avatar Hannes Roth Committed by Sara Golemon

(Wangle) Clean up tests

Summary:
This always bothered me. Now:

1) Separate tests for each feature
2) `XTest.cpp` contains `TEST(X, lowerCaseCamelCase)`

Also cleaned up some header files and using statements.

Shamelessly trying to increase the number of lines that blame to me.

Test Plan:
Run all the tests.

`git grep 'TEST' -- 'folly/futures/test/*Test.cpp' | cut -d ',' -f 1 | cut -d '/' -f 4 | sort -u`

`diff <(git ls-files -- 'folly/futures/test/*Test.cpp' | cut -d '/' -f 4 | sort) <(git grep 'Test.cpp' -- folly/futures/TARGETS | cut -d '/' -f 4 | cut -d "'" -f 1 | sort)`

Reviewed By: jsedgwick@fb.com

Subscribers: trunkagent, folly-diffs@, jsedgwick, yfeldblum, chalfant

FB internal diff: D2127359

Tasks: 6019442

Signature: t1:2127359:1433459532:54a91ae83d7fb2d0b3f3769f673fefea20f35435
parent 66476fc9
......@@ -15,15 +15,16 @@
*/
#include <gflags/gflags.h>
#include <folly/Baton.h>
#include <folly/Benchmark.h>
#include <folly/futures/Future.h>
#include <folly/futures/Promise.h>
#include <semaphore.h>
#include <vector>
using namespace folly;
using namespace std;
namespace {
......@@ -89,8 +90,8 @@ BENCHMARK_RELATIVE(hundredThens) {
BENCHMARK_DRAW_LINE()
BENCHMARK(no_contention) {
vector<Promise<int>> promises(10000);
vector<Future<int>> futures;
std::vector<Promise<int>> promises(10000);
std::vector<Future<int>> futures;
std::thread producer, consumer;
BENCHMARK_SUSPEND {
......@@ -118,8 +119,8 @@ BENCHMARK(no_contention) {
}
BENCHMARK_RELATIVE(contention) {
vector<Promise<int>> promises(10000);
vector<Future<int>> futures;
std::vector<Promise<int>> promises(10000);
std::vector<Future<int>> futures;
std::thread producer, consumer;
sem_t sem;
sem_init(&sem, 0, 0);
......
This diff is collapsed.
/*
* Copyright 2015 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include <folly/futures/Future.h>
using namespace folly;
class TestData : public RequestData {
public:
explicit TestData(int data) : data_(data) {}
virtual ~TestData() {}
int data_;
};
TEST(Context, basic) {
// Start a new context
RequestContext::create();
EXPECT_EQ(nullptr, RequestContext::get()->getContextData("test"));
// Set some test data
RequestContext::get()->setContextData(
"test",
std::unique_ptr<TestData>(new TestData(10)));
// Start a future
Promise<void> p;
auto future = p.getFuture().then([&]{
// Check that the context followed the future
EXPECT_TRUE(RequestContext::get() != nullptr);
auto a = dynamic_cast<TestData*>(
RequestContext::get()->getContextData("test"));
auto data = a->data_;
EXPECT_EQ(10, data);
});
// Clear the context
RequestContext::setContext(nullptr);
EXPECT_EQ(nullptr, RequestContext::get()->getContextData("test"));
// Fulfill the promise
p.setValue();
}
......@@ -15,11 +15,14 @@
*/
#include <gtest/gtest.h>
#include <gflags/gflags.h>
#include <folly/Portability.h>
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
::gflags::ParseCommandLineFlags(&argc, &argv, true);
return RUN_ALL_TESTS();
#include <folly/futures/Future.h>
#include <folly/futures/detail/Core.h>
using namespace folly;
TEST(Core, size) {
// If this number goes down, it's fine!
// If it goes up, please seek professional advice ;-)
EXPECT_EQ(192, sizeof(detail::Core<void>));
}
/*
* Copyright 2015 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include <folly/futures/Future.h>
using namespace folly;
TEST(Ensure, basic) {
size_t count = 0;
auto cob = [&]{ count++; };
auto f = makeFuture(42)
.ensure(cob)
.then([](int) { throw std::runtime_error("ensure"); })
.ensure(cob);
EXPECT_THROW(f.get(), std::runtime_error);
EXPECT_EQ(2, count);
}
......@@ -15,15 +15,14 @@
*/
#include <gtest/gtest.h>
#include <folly/futures/Future.h>
#include <folly/futures/InlineExecutor.h>
#include <folly/futures/ManualExecutor.h>
#include <folly/futures/QueuedImmediateExecutor.h>
#include <folly/futures/Future.h>
#include <folly/Baton.h>
using namespace folly;
using namespace std::chrono;
using namespace testing;
TEST(ManualExecutor, runIsStable) {
ManualExecutor x;
......@@ -37,7 +36,7 @@ TEST(ManualExecutor, runIsStable) {
TEST(ManualExecutor, scheduleDur) {
ManualExecutor x;
size_t count = 0;
milliseconds dur {10};
std::chrono::milliseconds dur {10};
x.schedule([&]{ count++; }, dur);
EXPECT_EQ(count, 0);
x.run();
......@@ -56,38 +55,38 @@ TEST(ManualExecutor, clockStartsAt0) {
TEST(ManualExecutor, scheduleAbs) {
ManualExecutor x;
size_t count = 0;
x.scheduleAt([&]{ count++; }, x.now() + milliseconds(10));
x.scheduleAt([&]{ count++; }, x.now() + std::chrono::milliseconds(10));
EXPECT_EQ(count, 0);
x.advance(milliseconds(10));
x.advance(std::chrono::milliseconds(10));
EXPECT_EQ(count, 1);
}
TEST(ManualExecutor, advanceTo) {
ManualExecutor x;
size_t count = 0;
x.scheduleAt([&]{ count++; }, steady_clock::now());
x.scheduleAt([&]{ count++; }, std::chrono::steady_clock::now());
EXPECT_EQ(count, 0);
x.advanceTo(steady_clock::now());
x.advanceTo(std::chrono::steady_clock::now());
EXPECT_EQ(count, 1);
}
TEST(ManualExecutor, advanceBack) {
ManualExecutor x;
size_t count = 0;
x.advance(microseconds(5));
x.schedule([&]{ count++; }, microseconds(6));
x.advance(std::chrono::microseconds(5));
x.schedule([&]{ count++; }, std::chrono::microseconds(6));
EXPECT_EQ(count, 0);
x.advanceTo(x.now() - microseconds(1));
x.advanceTo(x.now() - std::chrono::microseconds(1));
EXPECT_EQ(count, 0);
}
TEST(ManualExecutor, advanceNeg) {
ManualExecutor x;
size_t count = 0;
x.advance(microseconds(5));
x.schedule([&]{ count++; }, microseconds(6));
x.advance(std::chrono::microseconds(5));
x.schedule([&]{ count++; }, std::chrono::microseconds(6));
EXPECT_EQ(count, 0);
x.advance(microseconds(-1));
x.advance(std::chrono::microseconds(-1));
EXPECT_EQ(count, 0);
}
......
......@@ -15,6 +15,7 @@
*/
#include <gtest/gtest.h>
#include <folly/futures/detail/FSM.h>
using namespace folly::detail;
......
/*
* Copyright 2015 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include <folly/futures/Future.h>
using namespace folly;
TEST(Filter, alwaysTrye) {
EXPECT_EQ(42, makeFuture(42).filter([](int){ return true; }).get());
}
TEST(Filter, alwaysFalse) {
EXPECT_THROW(makeFuture(42).filter([](int){ return false; }).get(),
folly::PredicateDoesNotObtain);
}
TEST(Filter, moveOnlyValue) {
EXPECT_EQ(42,
*makeFuture(folly::make_unique<int>(42))
.filter([](std::unique_ptr<int> const&) { return true; })
.get());
}
This diff is collapsed.
......@@ -14,9 +14,14 @@
* limitations under the License.
*/
#include <gtest/gtest.h>
// amazing what things can go wrong if you include things in an unexpected
// order.
#include <folly/futures/Try.h>
#include <folly/futures/Promise.h>
#include <folly/futures/Future.h>
int main() { return 0; }
TEST(Basic, compiles) {
EXPECT_TRUE(true);
}
......@@ -20,9 +20,8 @@
#include <folly/futures/Promise.h>
using namespace folly;
using folly::exception_wrapper;
TEST(Interrupts, raise) {
TEST(Interrupt, raise) {
std::runtime_error eggs("eggs");
Promise<void> p;
p.setInterruptHandler([&](const exception_wrapper& e) {
......@@ -31,7 +30,7 @@ TEST(Interrupts, raise) {
p.getFuture().raise(eggs);
}
TEST(Interrupts, cancel) {
TEST(Interrupt, cancel) {
Promise<void> p;
p.setInterruptHandler([&](const exception_wrapper& e) {
EXPECT_THROW(e.throwException(), FutureCancellation);
......@@ -39,7 +38,7 @@ TEST(Interrupts, cancel) {
p.getFuture().cancel();
}
TEST(Interrupts, handleThenInterrupt) {
TEST(Interrupt, handleThenInterrupt) {
Promise<int> p;
bool flag = false;
p.setInterruptHandler([&](const exception_wrapper& e) { flag = true; });
......@@ -47,7 +46,7 @@ TEST(Interrupts, handleThenInterrupt) {
EXPECT_TRUE(flag);
}
TEST(Interrupts, interruptThenHandle) {
TEST(Interrupt, interruptThenHandle) {
Promise<int> p;
bool flag = false;
p.getFuture().cancel();
......@@ -55,7 +54,7 @@ TEST(Interrupts, interruptThenHandle) {
EXPECT_TRUE(flag);
}
TEST(Interrupts, interruptAfterFulfilNoop) {
TEST(Interrupt, interruptAfterFulfilNoop) {
Promise<void> p;
bool flag = false;
p.setInterruptHandler([&](const exception_wrapper& e) { flag = true; });
......@@ -64,7 +63,7 @@ TEST(Interrupts, interruptAfterFulfilNoop) {
EXPECT_FALSE(flag);
}
TEST(Interrupts, secondInterruptNoop) {
TEST(Interrupt, secondInterruptNoop) {
Promise<void> p;
int count = 0;
p.setInterruptHandler([&](const exception_wrapper& e) { count++; });
......
/*
* Copyright 2015 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include <folly/futures/Future.h>
using namespace folly;
TEST(Map, basic) {
Promise<int> p1;
Promise<int> p2;
Promise<int> p3;
std::vector<Future<int>> fs;
fs.push_back(p1.getFuture());
fs.push_back(p2.getFuture());
fs.push_back(p3.getFuture());
int c = 0;
std::vector<Future<void>> fs2 = futures::map(fs, [&](int i){
c += i;
});
// Ensure we call the callbacks as the futures complete regardless of order
p2.setValue(1);
EXPECT_EQ(1, c);
p3.setValue(1);
EXPECT_EQ(2, c);
p1.setValue(1);
EXPECT_EQ(3, c);
EXPECT_TRUE(collect(fs2).isReady());
}
......@@ -20,38 +20,22 @@
using namespace folly;
TEST(Sugar, pollReady) {
TEST(Poll, ready) {
Promise<int> p;
auto f = p.getFuture();
p.setValue(42);
EXPECT_EQ(42, f.poll().value().value());
}
TEST(Sugar, pollNotReady) {
TEST(Poll, notReady) {
Promise<int> p;
auto f = p.getFuture();
EXPECT_FALSE(f.poll().hasValue());
}
TEST(Sugar, pollException) {
TEST(Poll, exception) {
Promise<void> p;
auto f = p.getFuture();
p.setWith([] { throw std::runtime_error("Runtime"); });
EXPECT_TRUE(f.poll().value().hasException());
}
TEST(Sugar, filterTrue) {
EXPECT_EQ(42, makeFuture(42).filter([](int){ return true; }).get());
}
TEST(Sugar, filterFalse) {
EXPECT_THROW(makeFuture(42).filter([](int){ return false; }).get(),
folly::PredicateDoesNotObtain);
}
TEST(Sugar, filterMoveonly) {
EXPECT_EQ(42,
*makeFuture(folly::make_unique<int>(42))
.filter([](std::unique_ptr<int> const&) { return true; })
.get());
}
/*
* Copyright 2015 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include <folly/futures/Future.h>
using namespace folly;
using std::unique_ptr;
using std::string;
typedef FutureException eggs_t;
static eggs_t eggs("eggs");
TEST(Promise, special) {
EXPECT_FALSE(std::is_copy_constructible<Promise<int>>::value);
EXPECT_FALSE(std::is_copy_assignable<Promise<int>>::value);
EXPECT_TRUE(std::is_move_constructible<Promise<int>>::value);
EXPECT_TRUE(std::is_move_assignable<Promise<int>>::value);
}
TEST(Promise, getFuture) {
Promise<int> p;
Future<int> f = p.getFuture();
EXPECT_FALSE(f.isReady());
}
TEST(Promise, setValue) {
Promise<int> fund;
auto ffund = fund.getFuture();
fund.setValue(42);
EXPECT_EQ(42, ffund.value());
struct Foo {
string name;
int value;
};
Promise<Foo> pod;
auto fpod = pod.getFuture();
Foo f = {"the answer", 42};
pod.setValue(f);
Foo f2 = fpod.value();
EXPECT_EQ(f.name, f2.name);
EXPECT_EQ(f.value, f2.value);
pod = Promise<Foo>();
fpod = pod.getFuture();
pod.setValue(std::move(f2));
Foo f3 = fpod.value();
EXPECT_EQ(f.name, f3.name);
EXPECT_EQ(f.value, f3.value);
Promise<unique_ptr<int>> mov;
auto fmov = mov.getFuture();
mov.setValue(unique_ptr<int>(new int(42)));
unique_ptr<int> ptr = std::move(fmov.value());
EXPECT_EQ(42, *ptr);
Promise<void> v;
auto fv = v.getFuture();
v.setValue();
EXPECT_TRUE(fv.isReady());
}
TEST(Promise, setException) {
{
Promise<void> p;
auto f = p.getFuture();
p.setException(eggs);
EXPECT_THROW(f.value(), eggs_t);
}
{
Promise<void> p;
auto f = p.getFuture();
try {
throw eggs;
} catch (...) {
p.setException(exception_wrapper(std::current_exception()));
}
EXPECT_THROW(f.value(), eggs_t);
}
}
TEST(Promise, setWith) {
{
Promise<int> p;
auto f = p.getFuture();
p.setWith([] { return 42; });
EXPECT_EQ(42, f.value());
}
{
Promise<int> p;
auto f = p.getFuture();
p.setWith([]() -> int { throw eggs; });
EXPECT_THROW(f.value(), eggs_t);
}
}
TEST(Promise, isFulfilled) {
Promise<int> p;
EXPECT_FALSE(p.isFulfilled());
p.setValue(42);
EXPECT_TRUE(p.isFulfilled());
}
TEST(Promise, isFulfilledWithFuture) {
Promise<int> p;
auto f = p.getFuture(); // so core_ will become null
EXPECT_FALSE(p.isFulfilled());
p.setValue(42); // after here
EXPECT_TRUE(p.isFulfilled());
}
/*
* Copyright 2015 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include <folly/futures/Future.h>
using namespace folly;
TEST(Reduce, basic) {
auto makeFutures = [](int count) {
std::vector<Future<int>> fs;
for (int i = 1; i <= count; ++i) {
fs.emplace_back(makeFuture(i));
}
return fs;
};
// Empty (Try)
{
auto fs = makeFutures(0);
Future<double> f1 = reduce(fs, 1.2,
[](double a, Try<int>&& b){
return a + *b + 0.1;
});
EXPECT_EQ(1.2, f1.get());
}
// One (Try)
{
auto fs = makeFutures(1);
Future<double> f1 = reduce(fs, 0.0,
[](double a, Try<int>&& b){
return a + *b + 0.1;
});
EXPECT_EQ(1.1, f1.get());
}
// Returning values (Try)
{
auto fs = makeFutures(3);
Future<double> f1 = reduce(fs, 0.0,
[](double a, Try<int>&& b){
return a + *b + 0.1;
});
EXPECT_EQ(6.3, f1.get());
}
// Returning values
{
auto fs = makeFutures(3);
Future<double> f1 = reduce(fs, 0.0,
[](double a, int&& b){
return a + b + 0.1;
});
EXPECT_EQ(6.3, f1.get());
}
// Returning futures (Try)
{
auto fs = makeFutures(3);
Future<double> f2 = reduce(fs, 0.0,
[](double a, Try<int>&& b){
return makeFuture<double>(a + *b + 0.1);
});
EXPECT_EQ(6.3, f2.get());
}
// Returning futures
{
auto fs = makeFutures(3);
Future<double> f2 = reduce(fs, 0.0,
[](double a, int&& b){
return makeFuture<double>(a + b + 0.1);
});
EXPECT_EQ(6.3, f2.get());
}
}
TEST(Reduce, chain) {
auto makeFutures = [](int count) {
std::vector<Future<int>> fs;
for (int i = 1; i <= count; ++i) {
fs.emplace_back(makeFuture(i));
}
return fs;
};
{
auto f = collectAll(makeFutures(3)).reduce(0, [](int a, Try<int>&& b){
return a + *b;
});
EXPECT_EQ(6, f.get());
}
{
auto f = collect(makeFutures(3)).reduce(0, [](int a, int&& b){
return a + b;
});
EXPECT_EQ(6, f.get());
}
}
TEST(Reduce, unorderedReduce) {
{
std::vector<Future<int>> fs;
fs.push_back(makeFuture(1));
fs.push_back(makeFuture(2));
fs.push_back(makeFuture(3));
Future<double> f = unorderedReduce(fs.begin(), fs.end(), 0.0,
[](double a, int&& b){
return double(b);
});
EXPECT_EQ(3.0, f.get());
}
{
Promise<int> p1;
Promise<int> p2;
Promise<int> p3;
std::vector<Future<int>> fs;
fs.push_back(p1.getFuture());
fs.push_back(p2.getFuture());
fs.push_back(p3.getFuture());
Future<double> f = unorderedReduce(fs.begin(), fs.end(), 0.0,
[](double a, int&& b){
return double(b);
});
p3.setValue(3);
p2.setValue(2);
p1.setValue(1);
EXPECT_EQ(1.0, f.get());
}
}
TEST(Reduce, unorderedReduceException) {
Promise<int> p1;
Promise<int> p2;
Promise<int> p3;
std::vector<Future<int>> fs;
fs.push_back(p1.getFuture());
fs.push_back(p2.getFuture());
fs.push_back(p3.getFuture());
Future<double> f = unorderedReduce(fs.begin(), fs.end(), 0.0,
[](double a, int&& b){
return b + 0.0;
});
p3.setValue(3);
p2.setException(exception_wrapper(std::runtime_error("blah")));
p1.setValue(1);
EXPECT_THROW(f.get(), std::runtime_error);
}
......@@ -13,12 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <folly/futures/SharedPromise.h>
#include <gtest/gtest.h>
#include <folly/futures/SharedPromise.h>
using namespace folly;
TEST(SharedPromise, SetGet) {
TEST(SharedPromise, setGet) {
SharedPromise<int> p;
p.setValue(1);
auto f1 = p.getFuture();
......@@ -26,7 +28,7 @@ TEST(SharedPromise, SetGet) {
EXPECT_EQ(1, f1.value());
EXPECT_EQ(1, f2.value());
}
TEST(SharedPromise, GetSet) {
TEST(SharedPromise, getSet) {
SharedPromise<int> p;
auto f1 = p.getFuture();
auto f2 = p.getFuture();
......@@ -35,7 +37,7 @@ TEST(SharedPromise, GetSet) {
EXPECT_EQ(1, f2.value());
}
TEST(SharedPromise, GetSetGet) {
TEST(SharedPromise, getSetGet) {
SharedPromise<int> p;
auto f1 = p.getFuture();
p.setValue(1);
......@@ -44,7 +46,7 @@ TEST(SharedPromise, GetSetGet) {
EXPECT_EQ(1, f2.value());
}
TEST(SharedPromise, Reset) {
TEST(SharedPromise, reset) {
SharedPromise<int> p;
auto f1 = p.getFuture();
......@@ -58,7 +60,7 @@ TEST(SharedPromise, Reset) {
EXPECT_EQ(2, f2.value());
}
TEST(SharedPromise, GetMoveSet) {
TEST(SharedPromise, getMoveSet) {
SharedPromise<int> p;
auto f = p.getFuture();
auto p2 = std::move(p);
......@@ -66,7 +68,7 @@ TEST(SharedPromise, GetMoveSet) {
EXPECT_EQ(1, f.value());
}
TEST(SharedPromise, SetMoveGet) {
TEST(SharedPromise, setMoveGet) {
SharedPromise<int> p;
p.setValue(1);
auto p2 = std::move(p);
......@@ -74,7 +76,7 @@ TEST(SharedPromise, SetMoveGet) {
EXPECT_EQ(1, f.value());
}
TEST(SharedPromise, MoveSetGet) {
TEST(SharedPromise, moveSetGet) {
SharedPromise<int> p;
auto p2 = std::move(p);
p2.setValue(1);
......@@ -82,7 +84,7 @@ TEST(SharedPromise, MoveSetGet) {
EXPECT_EQ(1, f.value());
}
TEST(SharedPromise, MoveGetSet) {
TEST(SharedPromise, moveGetSet) {
SharedPromise<int> p;
auto p2 = std::move(p);
auto f = p2.getFuture();
......@@ -90,7 +92,7 @@ TEST(SharedPromise, MoveGetSet) {
EXPECT_EQ(1, f.value());
}
TEST(SharedPromise, MoveMove) {
TEST(SharedPromise, moveMove) {
SharedPromise<std::shared_ptr<int>> p;
auto f1 = p.getFuture();
auto f2 = p.getFuture();
......
// This file is @generated by thens.rb. Do not edit directly.
// This file is @generated by then_compile_test.rb. Do not edit directly.
#include <folly/futures/test/Thens.h>
#include <folly/futures/test/ThenCompileTest.h>
TEST(Future, thenVariants) {
using namespace folly;
TEST(Basic, thenVariants) {
SomeClass anObject;
folly::Executor* anExecutor;
{Future<B> f = someFuture<A>().then(&aFunction<Future<B>, Try<A>&&>);}
{Future<B> f = someFuture<A>().then(&SomeClass::aStaticMethod<Future<B>, Try<A>&&>);}
......@@ -89,4 +90,3 @@ TEST(Future, thenVariants) {
{Future<B> f = someFuture<A>().then([&](A&){return B();});}
{Future<B> f = someFuture<A>().then([&](){return B();});}
}
......@@ -15,16 +15,16 @@
*/
#pragma once
#include <gtest/gtest.h>
#include <memory>
#include <folly/futures/Future.h>
#include <folly/Executor.h>
using namespace folly;
using namespace std;
using namespace testing;
#include <memory>
typedef unique_ptr<int> A;
namespace folly {
typedef std::unique_ptr<int> A;
struct B {};
template <class T>
......@@ -95,3 +95,5 @@ public:
return makeFuture(T());
}
};
}
......@@ -15,10 +15,11 @@
*/
#include <gtest/gtest.h>
#include <thread>
#include <folly/futures/Future.h>
#include <thread>
using namespace folly;
struct Widget {
......@@ -48,7 +49,7 @@ TEST(Then, makeFuture) {
EXPECT_EQ(future.value().moved_, 2);
}
TEST(Then, TryConstRValueReference) {
TEST(Then, tryConstRValueReference) {
auto future = makeFuture<Widget>(23).then(
[](const Try<Widget>&& t) {
EXPECT_EQ(t.value().copied_, 0);
......@@ -58,7 +59,7 @@ TEST(Then, TryConstRValueReference) {
EXPECT_EQ(future.value(), 23);
}
TEST(Then, TryRValueReference) {
TEST(Then, tryRValueReference) {
auto future = makeFuture<Widget>(23).then(
[](Try<Widget>&& t) {
EXPECT_EQ(t.value().copied_, 0);
......@@ -68,7 +69,7 @@ TEST(Then, TryRValueReference) {
EXPECT_EQ(future.value(), 23);
}
TEST(Then, TryLValueReference) {
TEST(Then, tryLValueReference) {
auto future = makeFuture<Widget>(23).then(
[](Try<Widget>& t) {
EXPECT_EQ(t.value().copied_, 0);
......@@ -78,7 +79,7 @@ TEST(Then, TryLValueReference) {
EXPECT_EQ(future.value(), 23);
}
TEST(Then, TryConstLValueReference) {
TEST(Then, tryConstLValueReference) {
auto future = makeFuture<Widget>(23).then(
[](const Try<Widget>& t) {
EXPECT_EQ(t.value().copied_, 0);
......@@ -88,7 +89,7 @@ TEST(Then, TryConstLValueReference) {
EXPECT_EQ(future.value(), 23);
}
TEST(Then, TryValue) {
TEST(Then, tryValue) {
auto future = makeFuture<Widget>(23).then(
[](Try<Widget> t) {
EXPECT_EQ(t.value().copied_, 0);
......@@ -98,7 +99,7 @@ TEST(Then, TryValue) {
EXPECT_EQ(future.value(), 23);
}
TEST(Then, TryConstValue) {
TEST(Then, tryConstValue) {
auto future = makeFuture<Widget>(23).then(
[](const Try<Widget> t) {
EXPECT_EQ(t.value().copied_, 0);
......@@ -108,7 +109,7 @@ TEST(Then, TryConstValue) {
EXPECT_EQ(future.value(), 23);
}
TEST(Then, ConstRValueReference) {
TEST(Then, constRValueReference) {
auto future = makeFuture<Widget>(23).then(
[](const Widget&& w) {
EXPECT_EQ(w.copied_, 0);
......@@ -118,7 +119,7 @@ TEST(Then, ConstRValueReference) {
EXPECT_EQ(future.value(), 23);
}
TEST(Then, RValueReference) {
TEST(Then, rValueReference) {
auto future = makeFuture<Widget>(23).then(
[](Widget&& w) {
EXPECT_EQ(w.copied_, 0);
......@@ -128,7 +129,7 @@ TEST(Then, RValueReference) {
EXPECT_EQ(future.value(), 23);
}
TEST(Then, LValueReference) {
TEST(Then, lValueReference) {
auto future = makeFuture<Widget>(23).then(
[](Widget& w) {
EXPECT_EQ(w.copied_, 0);
......@@ -138,7 +139,7 @@ TEST(Then, LValueReference) {
EXPECT_EQ(future.value(), 23);
}
TEST(Then, ConstLValueReference) {
TEST(Then, constLValueReference) {
auto future = makeFuture<Widget>(23).then(
[](const Widget& w) {
EXPECT_EQ(w.copied_, 0);
......@@ -148,7 +149,7 @@ TEST(Then, ConstLValueReference) {
EXPECT_EQ(future.value(), 23);
}
TEST(Then, Value) {
TEST(Then, value) {
auto future = makeFuture<Widget>(23).then(
[](Widget w) {
EXPECT_EQ(w.copied_, 0);
......@@ -158,7 +159,7 @@ TEST(Then, Value) {
EXPECT_EQ(future.value(), 23);
}
TEST(Then, ConstValue) {
TEST(Then, constValue) {
auto future = makeFuture<Widget>(23).then(
[](const Widget w) {
EXPECT_EQ(w.copied_, 0);
......
......@@ -13,15 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include <folly/futures/Timekeeper.h>
#include <unistd.h>
using namespace folly;
using namespace std::chrono;
using folly::Timekeeper;
using Duration = folly::Duration;
std::chrono::milliseconds const one_ms(1);
std::chrono::milliseconds const awhile(10);
......@@ -66,7 +65,7 @@ TEST(Timekeeper, futureGetBeforeTimeout) {
// runs it by hand they're not sitting there forever wondering why it's
// blocked, and get a useful error message instead. If it does get flaky,
// empirically increase the timeout to the point where it's very improbable.
EXPECT_EQ(42, p.getFuture().get(seconds(2)));
EXPECT_EQ(42, p.getFuture().get(std::chrono::seconds(2)));
t.join();
}
......
......@@ -21,6 +21,26 @@
using namespace folly;
TEST(Try, basic) {
class A {
public:
A(int x) : x_(x) {}
int x() const {
return x_;
}
private:
int x_;
};
A a(5);
Try<A> t_a(std::move(a));
Try<void> t_void;
EXPECT_EQ(5, t_a.value().x());
}
// Make sure we can copy Trys for copyable types
TEST(Try, copy) {
Try<int> t;
......
......@@ -14,12 +14,13 @@
* limitations under the License.
*/
#include <folly/futures/Future.h>
#include <gtest/gtest.h>
#include <folly/futures/Future.h>
using namespace folly;
TEST(Unit, FutureDefaultCtor) {
TEST(Unit, futureDefaultCtor) {
Future<Unit>();
}
......@@ -29,19 +30,19 @@ TEST(Unit, voidOrUnit) {
EXPECT_FALSE(is_void_or_unit<int>::value);
}
TEST(Unit, PromiseSetValue) {
TEST(Unit, promiseSetValue) {
Promise<Unit> p;
p.setValue();
}
TEST(Unit, LiftInt) {
TEST(Unit, liftInt) {
using Lifted = Unit::Lift<int>;
EXPECT_FALSE(Lifted::value);
auto v = std::is_same<int, Lifted::type>::value;
EXPECT_TRUE(v);
}
TEST(Unit, LiftVoid) {
TEST(Unit, liftVoid) {
using Lifted = Unit::Lift<void>;
EXPECT_TRUE(Lifted::value);
auto v = std::is_same<Unit, Lifted::type>::value;
......
/*
* Copyright 2015 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include <folly/futures/Future.h>
using namespace folly;
// A simple scenario for the unwrap call, when the promise was fulfilled
// before calling to unwrap.
TEST(Unwrap, simpleScenario) {
Future<int> encapsulated_future = makeFuture(5484);
Future<Future<int>> future = makeFuture(std::move(encapsulated_future));
EXPECT_EQ(5484, future.unwrap().value());
}
// Makes sure that unwrap() works when chaning Future's commands.
TEST(Unwrap, chainCommands) {
Future<Future<int>> future = makeFuture(makeFuture(5484));
auto unwrapped = future.unwrap().then([](int i){ return i; });
EXPECT_EQ(5484, unwrapped.value());
}
// Makes sure that the unwrap call also works when the promise was not yet
// fulfilled, and that the returned Future<T> becomes ready once the promise
// is fulfilled.
TEST(Unwrap, futureNotReady) {
Promise<Future<int>> p;
Future<Future<int>> future = p.getFuture();
Future<int> unwrapped = future.unwrap();
// Sanity - should not be ready before the promise is fulfilled.
ASSERT_FALSE(unwrapped.isReady());
// Fulfill the promise and make sure the unwrapped future is now ready.
p.setValue(makeFuture(5484));
ASSERT_TRUE(unwrapped.isReady());
EXPECT_EQ(5484, unwrapped.value());
}
......@@ -15,12 +15,15 @@
*/
#include <gtest/gtest.h>
#include <thread>
#include <folly/futures/Future.h>
#include <folly/futures/InlineExecutor.h>
#include <folly/futures/ManualExecutor.h>
#include <folly/futures/DrivableExecutor.h>
#include <folly/Baton.h>
#include <folly/MPMCQueue.h>
#include <thread>
using namespace folly;
......@@ -73,12 +76,12 @@ struct ViaFixture : public testing::Test {
std::thread t;
};
TEST(Via, exception_on_launch) {
TEST(Via, exceptionOnLaunch) {
auto future = makeFuture<int>(std::runtime_error("E"));
EXPECT_THROW(future.value(), std::runtime_error);
}
TEST(Via, then_value) {
TEST(Via, thenValue) {
auto future = makeFuture(std::move(1))
.then([](Try<int>&& t) {
return t.value() == 1;
......@@ -88,7 +91,7 @@ TEST(Via, then_value) {
EXPECT_TRUE(future.value());
}
TEST(Via, then_future) {
TEST(Via, thenFuture) {
auto future = makeFuture(1)
.then([](Try<int>&& t) {
return makeFuture(t.value() == 1);
......@@ -100,7 +103,7 @@ static Future<std::string> doWorkStatic(Try<std::string>&& t) {
return makeFuture(t.value() + ";static");
}
TEST(Via, then_function) {
TEST(Via, thenFunction) {
struct Worker {
Future<std::string> doWork(Try<std::string>&& t) {
return makeFuture(t.value() + ";class");
......@@ -119,7 +122,7 @@ TEST(Via, then_function) {
EXPECT_EQ(f.value(), "start;static;class-static;class");
}
TEST_F(ViaFixture, thread_hops) {
TEST_F(ViaFixture, threadHops) {
auto westThreadId = std::this_thread::get_id();
auto f = via(eastExecutor.get()).then([=](Try<void>&& t) {
EXPECT_NE(std::this_thread::get_id(), westThreadId);
......@@ -132,7 +135,7 @@ TEST_F(ViaFixture, thread_hops) {
EXPECT_EQ(f.getVia(waiter.get()), 1);
}
TEST_F(ViaFixture, chain_vias) {
TEST_F(ViaFixture, chainVias) {
auto westThreadId = std::this_thread::get_id();
auto f = via(eastExecutor.get()).then([=]() {
EXPECT_NE(std::this_thread::get_id(), westThreadId);
......@@ -287,3 +290,127 @@ TEST(Via, then2Variadic) {
x.run();
EXPECT_TRUE(f.a);
}
/// Simple executor that does work in another thread
class ThreadExecutor : public Executor {
folly::MPMCQueue<Func> funcs;
std::atomic<bool> done {false};
std::thread worker;
folly::Baton<> baton;
void work() {
baton.post();
Func fn;
while (!done) {
while (!funcs.isEmpty()) {
funcs.blockingRead(fn);
fn();
}
}
}
public:
explicit ThreadExecutor(size_t n = 1024)
: funcs(n) {
worker = std::thread(std::bind(&ThreadExecutor::work, this));
}
~ThreadExecutor() {
done = true;
funcs.write([]{});
worker.join();
}
void add(Func fn) override {
funcs.blockingWrite(std::move(fn));
}
void waitForStartup() {
baton.wait();
}
};
TEST(Via, viaThenGetWasRacy) {
ThreadExecutor x;
std::unique_ptr<int> val = folly::via(&x)
.then([] { return folly::make_unique<int>(42); })
.get();
ASSERT_TRUE(!!val);
EXPECT_EQ(42, *val);
}
class DummyDrivableExecutor : public DrivableExecutor {
public:
void add(Func f) override {}
void drive() override { ran = true; }
bool ran{false};
};
TEST(Via, getVia) {
{
// non-void
ManualExecutor x;
auto f = via(&x).then([]{ return true; });
EXPECT_TRUE(f.getVia(&x));
}
{
// void
ManualExecutor x;
auto f = via(&x).then();
f.getVia(&x);
}
{
DummyDrivableExecutor x;
auto f = makeFuture(true);
EXPECT_TRUE(f.getVia(&x));
EXPECT_FALSE(x.ran);
}
}
TEST(Via, waitVia) {
{
ManualExecutor x;
auto f = via(&x).then();
EXPECT_FALSE(f.isReady());
f.waitVia(&x);
EXPECT_TRUE(f.isReady());
}
{
// try rvalue as well
ManualExecutor x;
auto f = via(&x).then().waitVia(&x);
EXPECT_TRUE(f.isReady());
}
{
DummyDrivableExecutor x;
makeFuture(true).waitVia(&x);
EXPECT_FALSE(x.ran);
}
}
TEST(Via, viaRaces) {
ManualExecutor x;
Promise<void> p;
auto tid = std::this_thread::get_id();
bool done = false;
std::thread t1([&] {
p.getFuture()
.via(&x)
.then([&](Try<void>&&) { EXPECT_EQ(tid, std::this_thread::get_id()); })
.then([&](Try<void>&&) { EXPECT_EQ(tid, std::this_thread::get_id()); })
.then([&](Try<void>&&) { done = true; });
});
std::thread t2([&] {
p.setValue();
});
while (!done) x.run();
t1.join();
t2.join();
}
/*
* Copyright 2015 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include <folly/futures/Future.h>
#include <folly/io/async/EventBase.h>
#include <folly/Baton.h>
using namespace folly;
using std::vector;
using std::chrono::milliseconds;
TEST(Wait, waitImmediate) {
makeFuture().wait();
auto done = makeFuture(42).wait().value();
EXPECT_EQ(42, done);
vector<int> v{1,2,3};
auto done_v = makeFuture(v).wait().value();
EXPECT_EQ(v.size(), done_v.size());
EXPECT_EQ(v, done_v);
vector<Future<void>> v_f;
v_f.push_back(makeFuture());
v_f.push_back(makeFuture());
auto done_v_f = collectAll(v_f).wait().value();
EXPECT_EQ(2, done_v_f.size());
vector<Future<bool>> v_fb;
v_fb.push_back(makeFuture(true));
v_fb.push_back(makeFuture(false));
auto fut = collectAll(v_fb);
auto done_v_fb = std::move(fut.wait().value());
EXPECT_EQ(2, done_v_fb.size());
}
TEST(Wait, wait) {
Promise<int> p;
Future<int> f = p.getFuture();
std::atomic<bool> flag{false};
std::atomic<int> result{1};
std::atomic<std::thread::id> id;
std::thread t([&](Future<int>&& tf){
auto n = tf.then([&](Try<int> && t) {
id = std::this_thread::get_id();
return t.value();
});
flag = true;
result.store(n.wait().value());
},
std::move(f)
);
while(!flag){}
EXPECT_EQ(result.load(), 1);
p.setValue(42);
t.join();
// validate that the callback ended up executing in this thread, which
// is more to ensure that this test actually tests what it should
EXPECT_EQ(id, std::this_thread::get_id());
EXPECT_EQ(result.load(), 42);
}
struct MoveFlag {
MoveFlag() = default;
MoveFlag& operator=(const MoveFlag&) = delete;
MoveFlag(const MoveFlag&) = delete;
MoveFlag(MoveFlag&& other) noexcept {
other.moved = true;
}
bool moved{false};
};
TEST(Wait, waitReplacesSelf) {
// wait
{
// lvalue
auto f1 = makeFuture(MoveFlag());
f1.wait();
EXPECT_FALSE(f1.value().moved);
// rvalue
auto f2 = makeFuture(MoveFlag()).wait();
EXPECT_FALSE(f2.value().moved);
}
// wait(Duration)
{
// lvalue
auto f1 = makeFuture(MoveFlag());
f1.wait(milliseconds(1));
EXPECT_FALSE(f1.value().moved);
// rvalue
auto f2 = makeFuture(MoveFlag()).wait(milliseconds(1));
EXPECT_FALSE(f2.value().moved);
}
// waitVia
{
folly::EventBase eb;
// lvalue
auto f1 = makeFuture(MoveFlag());
f1.waitVia(&eb);
EXPECT_FALSE(f1.value().moved);
// rvalue
auto f2 = makeFuture(MoveFlag()).waitVia(&eb);
EXPECT_FALSE(f2.value().moved);
}
}
TEST(Wait, waitWithDuration) {
{
Promise<int> p;
Future<int> f = p.getFuture();
f.wait(milliseconds(1));
EXPECT_FALSE(f.isReady());
p.setValue(1);
EXPECT_TRUE(f.isReady());
}
{
Promise<int> p;
Future<int> f = p.getFuture();
p.setValue(1);
f.wait(milliseconds(1));
EXPECT_TRUE(f.isReady());
}
{
vector<Future<bool>> v_fb;
v_fb.push_back(makeFuture(true));
v_fb.push_back(makeFuture(false));
auto f = collectAll(v_fb);
f.wait(milliseconds(1));
EXPECT_TRUE(f.isReady());
EXPECT_EQ(2, f.value().size());
}
{
vector<Future<bool>> v_fb;
Promise<bool> p1;
Promise<bool> p2;
v_fb.push_back(p1.getFuture());
v_fb.push_back(p2.getFuture());
auto f = collectAll(v_fb);
f.wait(milliseconds(1));
EXPECT_FALSE(f.isReady());
p1.setValue(true);
EXPECT_FALSE(f.isReady());
p2.setValue(true);
EXPECT_TRUE(f.isReady());
}
{
auto f = makeFuture().wait(milliseconds(1));
EXPECT_TRUE(f.isReady());
}
{
Promise<void> p;
auto start = std::chrono::steady_clock::now();
auto f = p.getFuture().wait(milliseconds(100));
auto elapsed = std::chrono::steady_clock::now() - start;
EXPECT_GE(elapsed, milliseconds(100));
EXPECT_FALSE(f.isReady());
p.setValue();
EXPECT_TRUE(f.isReady());
}
{
// Try to trigger the race where the resultant Future is not yet complete
// even if we didn't hit the timeout, and make sure we deal with it properly
Promise<void> p;
folly::Baton<> b;
auto t = std::thread([&]{
b.post();
/* sleep override */ std::this_thread::sleep_for(milliseconds(100));
p.setValue();
});
b.wait();
auto f = p.getFuture().wait(std::chrono::seconds(3600));
EXPECT_TRUE(f.isReady());
t.join();
}
}
/*
* Copyright 2015 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include <folly/futures/Future.h>
using namespace folly;
TEST(WillEqual, basic) {
// both p1 and p2 already fulfilled
{
Promise<int> p1;
Promise<int> p2;
p1.setValue(27);
p2.setValue(27);
auto f1 = p1.getFuture();
auto f2 = p2.getFuture();
EXPECT_TRUE(f1.willEqual(f2).get());
}
{
Promise<int> p1;
Promise<int> p2;
p1.setValue(27);
p2.setValue(36);
auto f1 = p1.getFuture();
auto f2 = p2.getFuture();
EXPECT_FALSE(f1.willEqual(f2).get());
}
// both p1 and p2 not yet fulfilled
{
Promise<int> p1;
Promise<int> p2;
auto f1 = p1.getFuture();
auto f2 = p2.getFuture();
auto f3 = f1.willEqual(f2);
p1.setValue(27);
p2.setValue(27);
EXPECT_TRUE(f3.get());
}
{
Promise<int> p1;
Promise<int> p2;
auto f1 = p1.getFuture();
auto f2 = p2.getFuture();
auto f3 = f1.willEqual(f2);
p1.setValue(27);
p2.setValue(36);
EXPECT_FALSE(f3.get());
}
// p1 already fulfilled, p2 not yet fulfilled
{
Promise<int> p1;
Promise<int> p2;
p1.setValue(27);
auto f1 = p1.getFuture();
auto f2 = p2.getFuture();
auto f3 = f1.willEqual(f2);
p2.setValue(27);
EXPECT_TRUE(f3.get());
}
{
Promise<int> p1;
Promise<int> p2;
p1.setValue(27);
auto f1 = p1.getFuture();
auto f2 = p2.getFuture();
auto f3 = f1.willEqual(f2);
p2.setValue(36);
EXPECT_FALSE(f3.get());
}
// p2 already fulfilled, p1 not yet fulfilled
{
Promise<int> p1;
Promise<int> p2;
p2.setValue(27);
auto f1 = p1.getFuture();
auto f2 = p2.getFuture();
auto f3 = f1.willEqual(f2);
p1.setValue(27);
EXPECT_TRUE(f3.get());
}
{
Promise<int> p1;
Promise<int> p2;
p2.setValue(36);
auto f1 = p1.getFuture();
auto f2 = p2.getFuture();
auto f3 = f1.willEqual(f2);
p1.setValue(27);
EXPECT_FALSE(f3.get());
}
}
/*
* Copyright 2015 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include <folly/futures/Future.h>
#include <vector>
using namespace folly;
TEST(Window, basic) {
// int -> Future<int>
auto fn = [](std::vector<int> input, size_t window_size, size_t expect) {
auto res = reduce(
window(
input,
[](int i) { return makeFuture(i); },
2),
0,
[](int sum, const Try<int>& b) {
return sum + *b;
}).get();
EXPECT_EQ(expect, res);
};
{
// 2 in-flight at a time
std::vector<int> input = {1, 2, 3};
fn(input, 2, 6);
}
{
// 4 in-flight at a time
std::vector<int> input = {1, 2, 3};
fn(input, 4, 6);
}
{
// empty inpt
std::vector<int> input;
fn(input, 1, 0);
}
{
// int -> Future<void>
auto res = reduce(
window(
std::vector<int>({1, 2, 3}),
[](int i) { return makeFuture(); },
2),
0,
[](int sum, const Try<void>& b) {
EXPECT_TRUE(b.hasValue());
return sum + 1;
}).get();
EXPECT_EQ(3, res);
}
{
// string -> return Future<int>
auto res = reduce(
window(
std::vector<std::string>{"1", "2", "3"},
[](std::string s) { return makeFuture<int>(folly::to<int>(s)); },
2),
0,
[](int sum, const Try<int>& b) {
return sum + *b;
}).get();
EXPECT_EQ(6, res);
}
}
#!/usr/bin/env ruby
# ruby folly/futures/test/thens.rb > folly/futures/test/Thens.cpp
# cd folly/futures/test && ruby then_compile_test.rb > ThenCompileTest.cpp
# An exercise in combinatorics.
# (ordinary/static function, member function, std::function, lambda)
......@@ -62,15 +62,15 @@ tests = (
).map {|a| test(a)}.flatten
print <<EOF
// This file is #{"@"}generated by thens.rb. Do not edit directly.
// This file is #{"@"}generated by then_compile_test.rb. Do not edit directly.
#include <folly/futures/test/Thens.h>
#include <folly/futures/test/ThenCompileTest.h>
TEST(Future, thenVariants) {
using namespace folly;
TEST(Basic, thenVariants) {
SomeClass anObject;
folly::Executor* anExecutor;
#{tests.join("\n ")}
}
EOF
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