/*
- * Copyright 2015 Facebook, Inc.
+ * Copyright 2015-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* limitations under the License.
*/
-#include <gtest/gtest.h>
-
#include <folly/futures/Future.h>
+#include <folly/portability/GTest.h>
+
+#include <memory>
using namespace folly;
-using std::unique_ptr;
using std::string;
+using std::unique_ptr;
typedef FutureException eggs_t;
static eggs_t eggs("eggs");
+TEST(Promise, makeEmpty) {
+ auto p = Promise<int>::makeEmpty();
+ EXPECT_TRUE(p.isFulfilled());
+}
+
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_assignable<Promise<int>>::value);
}
+TEST(Promise, getSemiFuture) {
+ Promise<int> p;
+ SemiFuture<int> f = p.getSemiFuture();
+ EXPECT_FALSE(f.isReady());
+}
+
TEST(Promise, getFuture) {
Promise<int> p;
Future<int> f = p.getFuture();
EXPECT_FALSE(f.isReady());
}
+TEST(Promise, setValueUnit) {
+ Promise<Unit> p;
+ p.setValue();
+}
+
+TEST(Promise, setValueSemiFuture) {
+ Promise<int> fund;
+ auto ffund = fund.getSemiFuture();
+ fund.setValue(42);
+ EXPECT_EQ(42, ffund.value());
+
+ struct Foo {
+ string name;
+ int value;
+ };
+
+ Promise<Foo> pod;
+ auto fpod = pod.getSemiFuture();
+ 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.getSemiFuture();
+ 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.getSemiFuture();
+ mov.setValue(std::make_unique<int>(42));
+ unique_ptr<int> ptr = std::move(fmov.value());
+ EXPECT_EQ(42, *ptr);
+
+ Promise<Unit> v;
+ auto fv = v.getSemiFuture();
+ v.setValue();
+ EXPECT_TRUE(fv.isReady());
+}
+
TEST(Promise, setValue) {
Promise<int> fund;
auto ffund = fund.getFuture();
Promise<unique_ptr<int>> mov;
auto fmov = mov.getFuture();
- mov.setValue(unique_ptr<int>(new int(42)));
+ mov.setValue(std::make_unique<int>(42));
unique_ptr<int> ptr = std::move(fmov.value());
EXPECT_EQ(42, *ptr);
- Promise<void> v;
+ Promise<Unit> v;
auto fv = v.getFuture();
v.setValue();
EXPECT_TRUE(fv.isReady());
TEST(Promise, setException) {
{
- Promise<void> p;
+ Promise<Unit> p;
auto f = p.getFuture();
p.setException(eggs);
EXPECT_THROW(f.value(), eggs_t);
}
{
- Promise<void> p;
+ Promise<Unit> p;
+ auto f = p.getFuture();
+ // Calling setException() with an exception_ptr is deprecated,
+ // but don't complain about this in the test for this function.
+ FOLLY_PUSH_WARNING
+ FOLLY_GCC_DISABLE_WARNING("-Wdeprecated-declarations")
+ p.setException(std::make_exception_ptr(eggs));
+ FOLLY_POP_WARNING
+ EXPECT_THROW(f.value(), eggs_t);
+ }
+ {
+ Promise<Unit> p;
auto f = p.getFuture();
- try {
- throw eggs;
- } catch (...) {
- p.setException(exception_wrapper(std::current_exception()));
- }
+ p.setException(exception_wrapper(eggs));
EXPECT_THROW(f.value(), eggs_t);
}
}
p.setValue(42); // after here
EXPECT_TRUE(p.isFulfilled());
}
+
+TEST(Promise, brokenOnDelete) {
+ auto p = std::make_unique<Promise<int>>();
+ auto f = p->getFuture();
+
+ EXPECT_FALSE(f.isReady());
+
+ p.reset();
+
+ EXPECT_TRUE(f.isReady());
+
+ auto t = f.getTry();
+
+ EXPECT_TRUE(t.hasException<BrokenPromise>());
+}
+
+TEST(Promise, brokenPromiseHasTypeInfo) {
+ auto pInt = std::make_unique<Promise<int>>();
+ auto fInt = pInt->getFuture();
+
+ auto pFloat = std::make_unique<Promise<float>>();
+ auto fFloat = pFloat->getFuture();
+
+ pInt.reset();
+ pFloat.reset();
+
+ auto whatInt = fInt.getTry().exception().what();
+ auto whatFloat = fFloat.getTry().exception().what();
+
+ EXPECT_NE(whatInt, whatFloat);
+}