1/*
2 * Copyright 2015-present 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
20using namespace folly;
21
22TEST(Map, basic) {
23 Promise<int> p1;
24 Promise<int> p2;
25 Promise<int> p3;
26
27 std::vector<Future<int>> fs;
28 fs.push_back(p1.getFuture());
29 fs.push_back(p2.getFuture());
30 fs.push_back(p3.getFuture());
31
32 int c = 0;
33 std::vector<Future<Unit>> fs2 = futures::mapValue(fs, [&](int i) { c += i; });
34
35 // Ensure we call the callbacks as the futures complete regardless of order
36 p2.setValue(1);
37 EXPECT_EQ(1, c);
38 p3.setValue(1);
39 EXPECT_EQ(2, c);
40 p1.setValue(1);
41 EXPECT_EQ(3, c);
42
43 EXPECT_TRUE(collect(fs2).isReady());
44}
45
46TEST(Map, basic_try) {
47 Promise<int> p1;
48 Promise<int> p2;
49 Promise<int> p3;
50
51 std::vector<Future<int>> fs;
52 fs.push_back(p1.getFuture());
53 fs.push_back(p2.getFuture());
54 fs.push_back(p3.getFuture());
55
56 int c = 0;
57 std::vector<Future<Unit>> fs2 =
58 futures::mapTry(fs, [&](folly::Try<int> i) { c += i.value(); });
59
60 // Ensure we call the callbacks as the futures complete regardless of order
61 p2.setValue(1);
62 EXPECT_EQ(1, c);
63 p3.setValue(1);
64 EXPECT_EQ(2, c);
65 p1.setValue(1);
66 EXPECT_EQ(3, c);
67
68 EXPECT_TRUE(collect(fs2).isReady());
69}
70
71TEST(Map, executor) {
72 Promise<int> p1;
73 Promise<int> p2;
74 Promise<int> p3;
75 folly::InlineExecutor exec;
76
77 std::vector<Future<int>> fs;
78 fs.push_back(p1.getFuture());
79 fs.push_back(p2.getFuture());
80 fs.push_back(p3.getFuture());
81
82 int c = 0;
83 std::vector<Future<Unit>> fs2 =
84 futures::mapValue(exec, fs, [&](int i) { c += i; });
85
86 // Ensure we call the callbacks as the futures complete regardless of order
87 p2.setValue(1);
88 EXPECT_EQ(1, c);
89 p3.setValue(1);
90 EXPECT_EQ(2, c);
91 p1.setValue(1);
92 EXPECT_EQ(3, c);
93
94 EXPECT_TRUE(collect(fs2).isReady());
95}
96
97TEST(Map, executor_try) {
98 Promise<int> p1;
99 Promise<int> p2;
100 Promise<int> p3;
101 folly::InlineExecutor exec;
102
103 std::vector<Future<int>> fs;
104 fs.push_back(p1.getFuture());
105 fs.push_back(p2.getFuture());
106 fs.push_back(p3.getFuture());
107
108 int c = 0;
109 std::vector<Future<Unit>> fs2 =
110 futures::mapTry(exec, fs, [&](folly::Try<int> i) { c += i.value(); });
111
112 // Ensure we call the callbacks as the futures complete regardless of order
113 p2.setValue(1);
114 EXPECT_EQ(1, c);
115 p3.setValue(1);
116 EXPECT_EQ(2, c);
117 p1.setValue(1);
118 EXPECT_EQ(3, c);
119
120 EXPECT_TRUE(collect(fs2).isReady());
121}
122
123TEST(Map, semifuture) {
124 Promise<int> p1;
125 Promise<int> p2;
126 Promise<int> p3;
127 folly::InlineExecutor exec;
128
129 std::vector<SemiFuture<int>> fs;
130 fs.push_back(p1.getSemiFuture());
131 fs.push_back(p2.getSemiFuture());
132 fs.push_back(p3.getSemiFuture());
133
134 int c = 0;
135 std::vector<Future<Unit>> fs2 =
136 futures::mapValue(exec, fs, [&](int i) { c += i; });
137
138 // Ensure we call the callbacks as the futures complete regardless of order
139 p2.setValue(1);
140 EXPECT_EQ(1, c);
141 p3.setValue(1);
142 EXPECT_EQ(2, c);
143 p1.setValue(1);
144 EXPECT_EQ(3, c);
145
146 EXPECT_TRUE(collect(fs2).isReady());
147}
148