(Wangle) Then Magic
[folly.git] / folly / futures / test / ThenTest.cpp
1 /*
2  * Copyright 2015 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 #include <thread>
19
20 #include <folly/futures/Future.h>
21
22 using namespace folly;
23
24 struct Widget {
25   int v_, copied_, moved_;
26   /* implicit */ Widget(int v) : v_(v), copied_(0), moved_(0) {}
27   Widget(const Widget& other)
28     : v_(other.v_), copied_(other.copied_ + 1), moved_(other.moved_) {}
29   Widget(Widget&& other) noexcept
30     : v_(other.v_), copied_(other.copied_), moved_(other.moved_ + 1) {}
31   Widget& operator=(const Widget& other)
32     { throw std::logic_error("unexpected copy assignment"); }
33   Widget& operator=(Widget&& other)
34     { throw std::logic_error("unexpected move assignment"); }
35 };
36
37 TEST(Then, tryConstructor) {
38   auto t = Try<Widget>(23);
39   EXPECT_EQ(t.value().v_, 23);
40   EXPECT_EQ(t.value().copied_, 0);
41   EXPECT_EQ(t.value().moved_, 1);
42 }
43
44 TEST(Then, makeFuture) {
45   auto future = makeFuture<Widget>(23);
46   EXPECT_EQ(future.value().v_, 23);
47   EXPECT_EQ(future.value().copied_, 0);
48   EXPECT_EQ(future.value().moved_, 2);
49 }
50
51 TEST(Then, TryConstRValueReference) {
52   auto future = makeFuture<Widget>(23).then(
53     [](const Try<Widget>&& t) {
54       EXPECT_EQ(t.value().copied_, 0);
55       EXPECT_EQ(t.value().moved_, 2);
56       return t.value().v_;
57     });
58   EXPECT_EQ(future.value(), 23);
59 }
60
61 TEST(Then, TryRValueReference) {
62   auto future = makeFuture<Widget>(23).then(
63     [](Try<Widget>&& t) {
64       EXPECT_EQ(t.value().copied_, 0);
65       EXPECT_EQ(t.value().moved_, 2);
66       return t.value().v_;
67     });
68   EXPECT_EQ(future.value(), 23);
69 }
70
71 TEST(Then, TryLValueReference) {
72   auto future = makeFuture<Widget>(23).then(
73     [](Try<Widget>& t) {
74       EXPECT_EQ(t.value().copied_, 0);
75       EXPECT_EQ(t.value().moved_, 2);
76       return t.value().v_;
77     });
78   EXPECT_EQ(future.value(), 23);
79 }
80
81 TEST(Then, TryConstLValueReference) {
82   auto future = makeFuture<Widget>(23).then(
83     [](const Try<Widget>& t) {
84       EXPECT_EQ(t.value().copied_, 0);
85       EXPECT_EQ(t.value().moved_, 2);
86       return t.value().v_;
87     });
88   EXPECT_EQ(future.value(), 23);
89 }
90
91 TEST(Then, TryValue) {
92   auto future = makeFuture<Widget>(23).then(
93     [](Try<Widget> t) {
94       EXPECT_EQ(t.value().copied_, 0);
95       EXPECT_EQ(t.value().moved_, 3);
96       return t.value().v_;
97     });
98   EXPECT_EQ(future.value(), 23);
99 }
100
101 TEST(Then, TryConstValue) {
102   auto future = makeFuture<Widget>(23).then(
103     [](const Try<Widget> t) {
104       EXPECT_EQ(t.value().copied_, 0);
105       EXPECT_EQ(t.value().moved_, 3);
106       return t.value().v_;
107     });
108   EXPECT_EQ(future.value(), 23);
109 }
110
111 TEST(Then, ConstRValueReference) {
112   auto future = makeFuture<Widget>(23).then(
113     [](const Widget&& w) {
114       EXPECT_EQ(w.copied_, 0);
115       EXPECT_EQ(w.moved_, 2);
116       return w.v_;
117     });
118   EXPECT_EQ(future.value(), 23);
119 }
120
121 TEST(Then, RValueReference) {
122   auto future = makeFuture<Widget>(23).then(
123     [](Widget&& w) {
124       EXPECT_EQ(w.copied_, 0);
125       EXPECT_EQ(w.moved_, 2);
126       return w.v_;
127     });
128   EXPECT_EQ(future.value(), 23);
129 }
130
131 TEST(Then, LValueReference) {
132   auto future = makeFuture<Widget>(23).then(
133     [](Widget& w) {
134       EXPECT_EQ(w.copied_, 0);
135       EXPECT_EQ(w.moved_, 2);
136       return w.v_;
137     });
138   EXPECT_EQ(future.value(), 23);
139 }
140
141 TEST(Then, ConstLValueReference) {
142   auto future = makeFuture<Widget>(23).then(
143     [](const Widget& w) {
144       EXPECT_EQ(w.copied_, 0);
145       EXPECT_EQ(w.moved_, 2);
146       return w.v_;
147     });
148   EXPECT_EQ(future.value(), 23);
149 }
150
151 TEST(Then, Value) {
152   auto future = makeFuture<Widget>(23).then(
153     [](Widget w) {
154       EXPECT_EQ(w.copied_, 0);
155       EXPECT_EQ(w.moved_, 3);
156       return w.v_;
157     });
158   EXPECT_EQ(future.value(), 23);
159 }
160
161 TEST(Then, ConstValue) {
162   auto future = makeFuture<Widget>(23).then(
163     [](const Widget w) {
164       EXPECT_EQ(w.copied_, 0);
165       EXPECT_EQ(w.moved_, 3);
166       return w.v_;
167     });
168   EXPECT_EQ(future.value(), 23);
169 }