ff9cef9cdc117016de938ecb37796272189e0461
[folly.git] / folly / futures / test / PromiseTest.cpp
1 /*
2  * Copyright 2017 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <folly/futures/Future.h>
18 #include <folly/portability/GTest.h>
19
20 using namespace folly;
21 using std::unique_ptr;
22 using std::string;
23
24 typedef FutureException eggs_t;
25 static eggs_t eggs("eggs");
26
27 TEST(Promise, special) {
28   EXPECT_FALSE(std::is_copy_constructible<Promise<int>>::value);
29   EXPECT_FALSE(std::is_copy_assignable<Promise<int>>::value);
30   EXPECT_TRUE(std::is_move_constructible<Promise<int>>::value);
31   EXPECT_TRUE(std::is_move_assignable<Promise<int>>::value);
32 }
33
34 TEST(Promise, getFuture) {
35   Promise<int> p;
36   Future<int> f = p.getFuture();
37   EXPECT_FALSE(f.isReady());
38 }
39
40 TEST(Promise, setValueUnit) {
41   Promise<Unit> p;
42   p.setValue();
43 }
44
45 TEST(Promise, setValue) {
46   Promise<int> fund;
47   auto ffund = fund.getFuture();
48   fund.setValue(42);
49   EXPECT_EQ(42, ffund.value());
50
51   struct Foo {
52     string name;
53     int value;
54   };
55
56   Promise<Foo> pod;
57   auto fpod = pod.getFuture();
58   Foo f = {"the answer", 42};
59   pod.setValue(f);
60   Foo f2 = fpod.value();
61   EXPECT_EQ(f.name, f2.name);
62   EXPECT_EQ(f.value, f2.value);
63
64   pod = Promise<Foo>();
65   fpod = pod.getFuture();
66   pod.setValue(std::move(f2));
67   Foo f3 = fpod.value();
68   EXPECT_EQ(f.name, f3.name);
69   EXPECT_EQ(f.value, f3.value);
70
71   Promise<unique_ptr<int>> mov;
72   auto fmov = mov.getFuture();
73   mov.setValue(unique_ptr<int>(new int(42)));
74   unique_ptr<int> ptr = std::move(fmov.value());
75   EXPECT_EQ(42, *ptr);
76
77   Promise<Unit> v;
78   auto fv = v.getFuture();
79   v.setValue();
80   EXPECT_TRUE(fv.isReady());
81 }
82
83 TEST(Promise, setException) {
84   {
85     Promise<Unit> p;
86     auto f = p.getFuture();
87     p.setException(eggs);
88     EXPECT_THROW(f.value(), eggs_t);
89   }
90   {
91     Promise<Unit> p;
92     auto f = p.getFuture();
93     try {
94       throw eggs;
95     } catch (const std::exception& e) {
96       p.setException(exception_wrapper(std::current_exception(), e));
97     } catch (...) {
98       p.setException(exception_wrapper(std::current_exception()));
99     }
100     EXPECT_THROW(f.value(), eggs_t);
101   }
102 }
103
104 TEST(Promise, setWith) {
105   {
106     Promise<int> p;
107     auto f = p.getFuture();
108     p.setWith([] { return 42; });
109     EXPECT_EQ(42, f.value());
110   }
111   {
112     Promise<int> p;
113     auto f = p.getFuture();
114     p.setWith([]() -> int { throw eggs; });
115     EXPECT_THROW(f.value(), eggs_t);
116   }
117 }
118
119 TEST(Promise, isFulfilled) {
120   Promise<int> p;
121
122   EXPECT_FALSE(p.isFulfilled());
123   p.setValue(42);
124   EXPECT_TRUE(p.isFulfilled());
125 }
126
127 TEST(Promise, isFulfilledWithFuture) {
128   Promise<int> p;
129   auto f = p.getFuture(); // so core_ will become null
130
131   EXPECT_FALSE(p.isFulfilled());
132   p.setValue(42); // after here
133   EXPECT_TRUE(p.isFulfilled());
134 }
135
136 TEST(Promise, brokenOnDelete) {
137   auto p = folly::make_unique<Promise<int>>();
138   auto f = p->getFuture();
139
140   EXPECT_FALSE(f.isReady());
141
142   p.reset();
143
144   EXPECT_TRUE(f.isReady());
145
146   auto t = f.getTry();
147
148   EXPECT_TRUE(t.hasException<BrokenPromise>());
149 }
150
151 TEST(Promise, brokenPromiseHasTypeInfo) {
152   auto pInt = folly::make_unique<Promise<int>>();
153   auto fInt = pInt->getFuture();
154
155   auto pFloat = folly::make_unique<Promise<float>>();
156   auto fFloat = pFloat->getFuture();
157
158   pInt.reset();
159   pFloat.reset();
160
161   auto whatInt = fInt.getTry().exception().what();
162   auto whatFloat = fFloat.getTry().exception().what();
163
164   EXPECT_NE(whatInt, whatFloat);
165 }