Promise<T>::makeEmpty() and Future<T>::makeEmpty()
[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, makeEmpty) {
28   auto p = Promise<int>::makeEmpty();
29   EXPECT_TRUE(p.isFulfilled());
30 }
31
32 TEST(Promise, special) {
33   EXPECT_FALSE(std::is_copy_constructible<Promise<int>>::value);
34   EXPECT_FALSE(std::is_copy_assignable<Promise<int>>::value);
35   EXPECT_TRUE(std::is_move_constructible<Promise<int>>::value);
36   EXPECT_TRUE(std::is_move_assignable<Promise<int>>::value);
37 }
38
39 TEST(Promise, getFuture) {
40   Promise<int> p;
41   Future<int> f = p.getFuture();
42   EXPECT_FALSE(f.isReady());
43 }
44
45 TEST(Promise, setValueUnit) {
46   Promise<Unit> p;
47   p.setValue();
48 }
49
50 TEST(Promise, setValue) {
51   Promise<int> fund;
52   auto ffund = fund.getFuture();
53   fund.setValue(42);
54   EXPECT_EQ(42, ffund.value());
55
56   struct Foo {
57     string name;
58     int value;
59   };
60
61   Promise<Foo> pod;
62   auto fpod = pod.getFuture();
63   Foo f = {"the answer", 42};
64   pod.setValue(f);
65   Foo f2 = fpod.value();
66   EXPECT_EQ(f.name, f2.name);
67   EXPECT_EQ(f.value, f2.value);
68
69   pod = Promise<Foo>();
70   fpod = pod.getFuture();
71   pod.setValue(std::move(f2));
72   Foo f3 = fpod.value();
73   EXPECT_EQ(f.name, f3.name);
74   EXPECT_EQ(f.value, f3.value);
75
76   Promise<unique_ptr<int>> mov;
77   auto fmov = mov.getFuture();
78   mov.setValue(unique_ptr<int>(new int(42)));
79   unique_ptr<int> ptr = std::move(fmov.value());
80   EXPECT_EQ(42, *ptr);
81
82   Promise<Unit> v;
83   auto fv = v.getFuture();
84   v.setValue();
85   EXPECT_TRUE(fv.isReady());
86 }
87
88 TEST(Promise, setException) {
89   {
90     Promise<Unit> p;
91     auto f = p.getFuture();
92     p.setException(eggs);
93     EXPECT_THROW(f.value(), eggs_t);
94   }
95   {
96     Promise<Unit> p;
97     auto f = p.getFuture();
98     try {
99       throw eggs;
100     } catch (const std::exception& e) {
101       p.setException(exception_wrapper(std::current_exception(), e));
102     } catch (...) {
103       p.setException(exception_wrapper(std::current_exception()));
104     }
105     EXPECT_THROW(f.value(), eggs_t);
106   }
107 }
108
109 TEST(Promise, setWith) {
110   {
111     Promise<int> p;
112     auto f = p.getFuture();
113     p.setWith([] { return 42; });
114     EXPECT_EQ(42, f.value());
115   }
116   {
117     Promise<int> p;
118     auto f = p.getFuture();
119     p.setWith([]() -> int { throw eggs; });
120     EXPECT_THROW(f.value(), eggs_t);
121   }
122 }
123
124 TEST(Promise, isFulfilled) {
125   Promise<int> p;
126
127   EXPECT_FALSE(p.isFulfilled());
128   p.setValue(42);
129   EXPECT_TRUE(p.isFulfilled());
130 }
131
132 TEST(Promise, isFulfilledWithFuture) {
133   Promise<int> p;
134   auto f = p.getFuture(); // so core_ will become null
135
136   EXPECT_FALSE(p.isFulfilled());
137   p.setValue(42); // after here
138   EXPECT_TRUE(p.isFulfilled());
139 }
140
141 TEST(Promise, brokenOnDelete) {
142   auto p = std::make_unique<Promise<int>>();
143   auto f = p->getFuture();
144
145   EXPECT_FALSE(f.isReady());
146
147   p.reset();
148
149   EXPECT_TRUE(f.isReady());
150
151   auto t = f.getTry();
152
153   EXPECT_TRUE(t.hasException<BrokenPromise>());
154 }
155
156 TEST(Promise, brokenPromiseHasTypeInfo) {
157   auto pInt = std::make_unique<Promise<int>>();
158   auto fInt = pInt->getFuture();
159
160   auto pFloat = std::make_unique<Promise<float>>();
161   auto fFloat = pFloat->getFuture();
162
163   pInt.reset();
164   pFloat.reset();
165
166   auto whatInt = fInt.getTry().exception().what();
167   auto whatFloat = fFloat.getTry().exception().what();
168
169   EXPECT_NE(whatInt, whatFloat);
170 }