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