2 * Copyright 2017 Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include <folly/Range.h>
21 #include <folly/FBVector.h>
22 #include <folly/experimental/TestUtil.h>
23 #include <folly/gen/Base.h>
24 #include <folly/gen/Combine.h>
25 #include <folly/portability/GTest.h>
27 using namespace folly::gen;
28 using namespace folly;
33 const folly::gen::detail::Map<
34 folly::gen::detail::MergeTuples> gTupleFlatten{};
36 auto even = [](int i) -> bool { return i % 2 == 0; };
37 auto odd = [](int i) -> bool { return i % 2 == 1; };
39 TEST(CombineGen, Interleave) {
40 { // large (infinite) base, small container
41 auto base = seq(1) | filter(odd);
42 auto toInterleave = seq(1, 6) | filter(even);
43 auto interleaved = base | interleave(toInterleave | as<vector>());
44 EXPECT_EQ(interleaved | as<vector>(), vector<int>({1, 2, 3, 4, 5, 6}));
46 { // small base, large container
47 auto base = seq(1) | filter(odd) | take(3);
48 auto toInterleave = seq(1) | filter(even) | take(50);
49 auto interleaved = base | interleave(toInterleave | as<vector>());
50 EXPECT_EQ(interleaved | as<vector>(),
51 vector<int>({1, 2, 3, 4, 5, 6}));
55 TEST(CombineGen, Zip) {
57 // We rely on std::move(fbvector) emptying the source vector
58 auto zippee = fbvector<string>{"one", "two", "three"};
63 ASSERT_EQ(combined.size(), 3);
64 EXPECT_EQ(std::get<0>(combined[0]), 1);
65 EXPECT_EQ(std::get<1>(combined[0]), "one");
66 EXPECT_EQ(std::get<0>(combined[1]), 2);
67 EXPECT_EQ(std::get<1>(combined[1]), "two");
68 EXPECT_EQ(std::get<0>(combined[2]), 3);
69 EXPECT_EQ(std::get<1>(combined[2]), "three");
70 ASSERT_FALSE(zippee.empty());
71 EXPECT_FALSE(zippee.front().empty()); // shouldn't have been move'd
74 { // same as top, but using std::move.
76 | zip(std::move(zippee))
78 ASSERT_EQ(combined.size(), 3);
79 EXPECT_EQ(std::get<0>(combined[0]), 1);
80 EXPECT_TRUE(zippee.empty());
83 { // same as top, but base is truncated
84 auto baseFinite = seq(1) | take(1);
85 auto combined = baseFinite
86 | zip(vector<string>{"one", "two", "three"})
88 ASSERT_EQ(combined.size(), 1);
89 EXPECT_EQ(std::get<0>(combined[0]), 1);
90 EXPECT_EQ(std::get<1>(combined[0]), "one");
94 TEST(CombineGen, TupleFlatten) {
95 vector<tuple<int,string>> intStringTupleVec{
96 tuple<int,string>{1, "1"},
97 tuple<int,string>{2, "2"},
98 tuple<int,string>{3, "3"},
101 vector<tuple<char>> charTupleVec{
108 vector<double> doubleVec{
116 auto zipped1 = from(intStringTupleVec)
118 | assert_type<tuple<tuple<int, string>, tuple<char>>>()
120 EXPECT_EQ(std::get<0>(zipped1[0]), std::make_tuple(1, "1"));
121 EXPECT_EQ(std::get<1>(zipped1[0]), std::make_tuple('A'));
123 auto zipped2 = from(zipped1)
125 | assert_type<tuple<int, string, char>&&>()
127 ASSERT_EQ(zipped2.size(), 3);
128 EXPECT_EQ(zipped2[0], std::make_tuple(1, "1", 'A'));
130 auto zipped3 = from(charTupleVec)
131 | zip(intStringTupleVec)
133 | assert_type<tuple<char, int, string>&&>()
135 ASSERT_EQ(zipped3.size(), 3);
136 EXPECT_EQ(zipped3[0], std::make_tuple('A', 1, "1"));
138 auto zipped4 = from(intStringTupleVec)
141 | assert_type<tuple<int, string, double>&&>()
143 ASSERT_EQ(zipped4.size(), 3);
144 EXPECT_EQ(zipped4[0], std::make_tuple(1, "1", 1.0));
146 auto zipped5 = from(doubleVec)
148 | assert_type<tuple<double, double>>()
149 | gTupleFlatten // essentially a no-op
150 | assert_type<tuple<double, double>&&>()
152 ASSERT_EQ(zipped5.size(), 5);
153 EXPECT_EQ(zipped5[0], std::make_tuple(1.0, 1.0));
155 auto zipped6 = from(intStringTupleVec)
160 | assert_type<tuple<int, string, char, double>&&>()
162 ASSERT_EQ(zipped6.size(), 3);
163 EXPECT_EQ(zipped6[0], std::make_tuple(1, "1", 'A', 1.0));
166 int main(int argc, char *argv[]) {
167 testing::InitGoogleTest(&argc, argv);
168 gflags::ParseCommandLineFlags(&argc, &argv, true);
169 return RUN_ALL_TESTS();