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