Handle take(-1) better
[folly.git] / folly / gen / test / BaseTest.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 <glog/logging.h>
18 #include <gtest/gtest.h>
19 #include <iosfwd>
20 #include <random>
21 #include <set>
22 #include <vector>
23
24 #include <folly/FBVector.h>
25 #include <folly/MapUtil.h>
26 #include <folly/Memory.h>
27 #include <folly/dynamic.h>
28 #include <folly/gen/Base.h>
29 #include <folly/experimental/TestUtil.h>
30
31 using namespace folly::gen;
32 using namespace folly;
33 using std::make_tuple;
34 using std::ostream;
35 using std::pair;
36 using std::set;
37 using std::string;
38 using std::tuple;
39 using std::unique_ptr;
40 using std::vector;
41
42 #define EXPECT_SAME(A, B) \
43   static_assert(std::is_same<A, B>::value, "Mismatched: " #A ", " #B)
44 EXPECT_SAME(int&&, typename ArgumentReference<int>::type);
45 EXPECT_SAME(int&, typename ArgumentReference<int&>::type);
46 EXPECT_SAME(const int&, typename ArgumentReference<const int&>::type);
47 EXPECT_SAME(const int&, typename ArgumentReference<const int>::type);
48
49 template<typename T>
50 ostream& operator<<(ostream& os, const set<T>& values) {
51   return os << from(values);
52 }
53
54 template<typename T>
55 ostream& operator<<(ostream& os, const vector<T>& values) {
56   os << "[";
57   for (auto& value : values) {
58     if (&value != &values.front()) {
59       os << " ";
60     }
61     os << value;
62   }
63   return os << "]";
64 }
65
66 auto square = [](int x) { return x * x; };
67 auto add = [](int a, int b) { return a + b; };
68 auto multiply = [](int a, int b) { return a * b; };
69
70 auto product = foldl(1, multiply);
71
72 template<typename A, typename B>
73 ostream& operator<<(ostream& os, const pair<A, B>& pair) {
74   return os << "(" << pair.first << ", " << pair.second << ")";
75 }
76
77 TEST(Gen, Count) {
78   auto gen = seq(1, 10);
79   EXPECT_EQ(10, gen | count);
80   EXPECT_EQ(5, gen | take(5) | count);
81 }
82
83 TEST(Gen, Sum) {
84   auto gen = seq(1, 10);
85   EXPECT_EQ((1 + 10) * 10 / 2, gen | sum);
86   EXPECT_EQ((1 + 5) * 5 / 2, gen | take(5) | sum);
87 }
88
89 TEST(Gen, Foreach) {
90   auto gen = seq(1, 4);
91   int accum = 0;
92   gen | [&](int x) { accum += x; };
93   EXPECT_EQ(10, accum);
94   int accum2 = 0;
95   gen | take(3) | [&](int x) { accum2 += x; };
96   EXPECT_EQ(6, accum2);
97 }
98
99 TEST(Gen, Map) {
100   auto expected = vector<int>{4, 9, 16};
101   auto gen = from({2, 3, 4}) | map(square);
102   EXPECT_EQ((vector<int>{4, 9, 16}), gen | as<vector>());
103   EXPECT_EQ((vector<int>{4, 9}), gen | take(2) | as<vector>());
104 }
105
106 TEST(Gen, Member) {
107   struct Counter {
108     Counter(int start = 0)
109       : c(start)
110     {}
111
112     int count() const { return c; }
113     int incr() { return ++c; }
114
115     int& ref() { return c; }
116     const int& ref() const { return c; }
117    private:
118     int c;
119   };
120   auto counters = seq(1, 10) | eachAs<Counter>() | as<vector>();
121   EXPECT_EQ(10 * (1 + 10) / 2,
122             from(counters)
123           | member(&Counter::count)
124           | sum);
125   EXPECT_EQ(10 * (1 + 10) / 2,
126             from(counters)
127           | indirect
128           | member(&Counter::count)
129           | sum);
130   EXPECT_EQ(10 * (2 + 11) / 2,
131             from(counters)
132           | member(&Counter::incr)
133           | sum);
134   EXPECT_EQ(10 * (3 + 12) / 2,
135             from(counters)
136           | indirect
137           | member(&Counter::incr)
138           | sum);
139   EXPECT_EQ(10 * (3 + 12) / 2,
140             from(counters)
141           | member(&Counter::count)
142           | sum);
143
144   // type-verifications
145   auto m = empty<Counter&>();
146   auto c = empty<const Counter&>();
147   m | member(&Counter::incr) | assert_type<int&&>();
148   m | member(&Counter::count) | assert_type<int&&>();
149   m | member(&Counter::count) | assert_type<int&&>();
150   m | member<Const>(&Counter::ref) | assert_type<const int&>();
151   m | member<Mutable>(&Counter::ref) | assert_type<int&>();
152   c | member<Const>(&Counter::ref) | assert_type<const int&>();
153 }
154
155 TEST(Gen, Field) {
156   struct X {
157     X() : a(2), b(3), c(4), d(b) {}
158
159     const int a;
160     int b;
161     mutable int c;
162     int& d; // can't access this with a field pointer.
163   };
164
165   std::vector<X> xs(1);
166   EXPECT_EQ(2, from(xs)
167              | field(&X::a)
168              | sum);
169   EXPECT_EQ(3, from(xs)
170              | field(&X::b)
171              | sum);
172   EXPECT_EQ(4, from(xs)
173              | field(&X::c)
174              | sum);
175   EXPECT_EQ(2, seq(&xs[0], &xs[0])
176              | field(&X::a)
177              | sum);
178   // type-verification
179   empty<X&>() | field(&X::a) | assert_type<const int&>();
180   empty<X*>() | field(&X::a) | assert_type<const int&>();
181   empty<X&>() | field(&X::b) | assert_type<int&>();
182   empty<X*>() | field(&X::b) | assert_type<int&>();
183   empty<X&>() | field(&X::c) | assert_type<int&>();
184   empty<X*>() | field(&X::c) | assert_type<int&>();
185
186   empty<X&&>() | field(&X::a) | assert_type<const int&&>();
187   empty<X&&>() | field(&X::b) | assert_type<int&&>();
188   empty<X&&>() | field(&X::c) | assert_type<int&&>();
189   // references don't imply ownership so they're not moved
190
191   empty<const X&>() | field(&X::a) | assert_type<const int&>();
192   empty<const X*>() | field(&X::a) | assert_type<const int&>();
193   empty<const X&>() | field(&X::b) | assert_type<const int&>();
194   empty<const X*>() | field(&X::b) | assert_type<const int&>();
195   // 'mutable' has no effect on field pointers, by C++ spec
196   empty<const X&>() | field(&X::c) | assert_type<const int&>();
197   empty<const X*>() | field(&X::c) | assert_type<const int&>();
198
199   // can't form pointer-to-reference field: empty<X&>() | field(&X::d)
200 }
201
202 TEST(Gen, Seq) {
203   // cover the fenceposts of the loop unrolling
204   for (int n = 1; n < 100; ++n) {
205     EXPECT_EQ(n, seq(1, n) | count);
206     EXPECT_EQ(n + 1, seq(1) | take(n + 1) | count);
207   }
208 }
209
210 TEST(Gen, SeqWithStep) {
211   EXPECT_EQ(75, seq(5, 25, 5) | sum);
212 }
213
214 TEST(Gen, SeqWithStepArray) {
215   const std::array<int, 6> arr{{1, 2, 3, 4, 5, 6}};
216   EXPECT_EQ(9, seq(&arr[0], &arr[5], 2)
217              | map([](const int *i) { return *i; })
218              | sum);
219 }
220
221 TEST(Gen, Range) {
222   // cover the fenceposts of the loop unrolling
223   for (int n = 1; n < 100; ++n) {
224     EXPECT_EQ(gen::range(0, n) | count, n);
225   }
226 }
227
228 TEST(Gen, RangeWithStep) {
229   EXPECT_EQ(50, range(5, 25, 5) | sum);
230 }
231
232 TEST(Gen, FromIterators) {
233   vector<int> source {2, 3, 5, 7, 11};
234   auto gen = from(folly::range(source.begin() + 1, source.end() - 1));
235   EXPECT_EQ(3 * 5 * 7, gen | product);
236 }
237
238 TEST(Gen, FromMap) {
239   auto source = seq(0, 10)
240               | map([](int i) { return std::make_pair(i, i * i); })
241               | as<std::map<int, int>>();
242   auto gen = fromConst(source)
243            | map([&](const std::pair<const int, int>& p) {
244                return p.second - p.first;
245              });
246   EXPECT_EQ(330, gen | sum);
247 }
248
249 TEST(Gen, Filter) {
250   const auto expected = vector<int>{1, 2, 4, 5, 7, 8};
251   auto actual =
252       seq(1, 9)
253     | filter([](int x) { return x % 3; })
254     | as<vector<int>>();
255   EXPECT_EQ(expected, actual);
256 }
257
258 TEST(Gen, FilterDefault) {
259   {
260     // Default filter should remove 0s
261     const auto expected = vector<int>{1, 1, 2, 3};
262     auto actual =
263         from({0, 1, 1, 0, 2, 3, 0})
264       | filter()
265       | as<vector>();
266     EXPECT_EQ(expected, actual);
267   }
268   {
269     // Default filter should remove nullptrs
270     int a = 5;
271     int b = 3;
272     int c = 0;
273     const auto expected = vector<int*>{&a, &b, &c};
274     auto actual =
275         from({(int*)nullptr, &a, &b, &c, (int*)nullptr})
276       | filter()
277       | as<vector>();
278     EXPECT_EQ(expected, actual);
279   }
280   {
281     // Default filter on Optionals should remove folly::null
282     const auto expected =
283         vector<Optional<int>>{Optional<int>(5), Optional<int>(0)};
284     const auto actual =
285         from({Optional<int>(5), Optional<int>(), Optional<int>(0)})
286       | filter()
287       | as<vector>();
288     EXPECT_EQ(expected, actual);
289   }
290 }
291
292 TEST(Gen, FilterSink) {
293   auto actual
294     = seq(1, 2)
295     | map([](int x) { return vector<int>{x}; })
296     | filter([](vector<int> v) { return !v.empty(); })
297     | as<vector>();
298   EXPECT_FALSE(from(actual) | rconcat | isEmpty);
299 }
300
301 TEST(Gen, Contains) {
302   {
303     auto gen =
304         seq(1, 9)
305       | map(square);
306     EXPECT_TRUE(gen | contains(49));
307     EXPECT_FALSE(gen | contains(50));
308   }
309   {
310     auto gen =
311         seq(1) // infinite, to prove laziness
312       | map(square)
313       | eachTo<std::string>();
314
315     // std::string gen, const char* needle
316     EXPECT_TRUE(gen | take(9999) | contains("49"));
317   }
318 }
319
320 TEST(Gen, Take) {
321   {
322     auto expected = vector<int>{1, 4, 9, 16};
323     auto actual =
324       seq(1, 1000)
325       | mapped([](int x) { return x * x; })
326       | take(4)
327       | as<vector<int>>();
328     EXPECT_EQ(expected, actual);
329   }
330   {
331     auto expected = vector<int>{ 0, 1, 4, 5, 8 };
332     auto actual
333       = ((seq(0) | take(2)) +
334          (seq(4) | take(2)) +
335          (seq(8) | take(2)))
336       | take(5)
337       | as<vector>();
338     EXPECT_EQ(expected, actual);
339   }
340   {
341     auto expected = vector<int>{ 0, 1, 4, 5, 8 };
342     auto actual
343       = seq(0)
344       | mapped([](int i) {
345           return seq(i * 4) | take(2);
346         })
347       | concat
348       | take(5)
349       | as<vector>();
350     EXPECT_EQ(expected, actual);
351   }
352   {
353     int64_t limit = 5;
354     take(limit - 5);
355     EXPECT_THROW(take(limit - 6), std::invalid_argument);
356   }
357 }
358
359
360 TEST(Gen, Stride) {
361   {
362     EXPECT_THROW(stride(0), std::invalid_argument);
363   }
364   {
365     auto expected = vector<int>{1, 2, 3, 4};
366     auto actual
367       = seq(1, 4)
368       | stride(1)
369       | as<vector<int>>();
370     EXPECT_EQ(expected, actual);
371   }
372   {
373     auto expected = vector<int>{1, 3, 5, 7};
374     auto actual
375       = seq(1, 8)
376       | stride(2)
377       | as<vector<int>>();
378     EXPECT_EQ(expected, actual);
379   }
380   {
381     auto expected = vector<int>{1, 4, 7, 10};
382     auto actual
383       = seq(1, 12)
384       | stride(3)
385       | as<vector<int>>();
386     EXPECT_EQ(expected, actual);
387   }
388   {
389     auto expected = vector<int>{1, 3, 5, 7, 9, 1, 4, 7, 10};
390     auto actual
391       = ((seq(1, 10) | stride(2)) +
392          (seq(1, 10) | stride(3)))
393       | as<vector<int>>();
394     EXPECT_EQ(expected, actual);
395   }
396   EXPECT_EQ(500, seq(1) | take(1000) | stride(2) | count);
397   EXPECT_EQ(10, seq(1) | take(1000) | stride(2) | take(10) | count);
398 }
399
400 TEST(Gen, Sample) {
401   std::mt19937 rnd(42);
402
403   auto sampler =
404       seq(1, 100)
405     | sample(50, rnd);
406   std::unordered_map<int,int> hits;
407   const int kNumIters = 80;
408   for (int i = 0; i < kNumIters; i++) {
409     auto vec = sampler | as<vector<int>>();
410     EXPECT_EQ(vec.size(), 50);
411     auto uniq = fromConst(vec) | as<set<int>>();
412     EXPECT_EQ(uniq.size(), vec.size());  // sampling without replacement
413     for (auto v: vec) {
414       ++hits[v];
415     }
416   }
417
418   // In 80 separate samples of our range, we should have seen every value
419   // at least once and no value all 80 times. (The odds of either of those
420   // events is 1/2^80).
421   EXPECT_EQ(hits.size(), 100);
422   for (auto hit: hits) {
423     EXPECT_GT(hit.second, 0);
424     EXPECT_LT(hit.second, kNumIters);
425   }
426
427   auto small =
428       seq(1, 5)
429     | sample(10);
430   EXPECT_EQ((small | sum), 15);
431   EXPECT_EQ((small | take(3) | count), 3);
432 }
433
434 TEST(Gen, Skip) {
435   auto gen =
436       seq(1, 1000)
437     | mapped([](int x) { return x * x; })
438     | skip(4)
439     | take(4);
440   EXPECT_EQ((vector<int>{25, 36, 49, 64}), gen | as<vector>());
441 }
442
443 TEST(Gen, Until) {
444   {
445     auto expected = vector<int>{1, 4, 9, 16};
446     auto actual
447       = seq(1, 1000)
448       | mapped([](int x) { return x * x; })
449       | until([](int x) { return x > 20; })
450       | as<vector<int>>();
451     EXPECT_EQ(expected, actual);
452   }
453   {
454     auto expected = vector<int>{ 0, 1, 4, 5, 8 };
455     auto actual
456       = ((seq(0) | until([](int i) { return i > 1; })) +
457          (seq(4) | until([](int i) { return i > 5; })) +
458          (seq(8) | until([](int i) { return i > 9; })))
459       | until([](int i) { return i > 8; })
460       | as<vector<int>>();
461     EXPECT_EQ(expected, actual);
462   }
463   /*
464   {
465     auto expected = vector<int>{ 0, 1, 5, 6, 10 };
466     auto actual
467       = seq(0)
468       | mapped([](int i) {
469           return seq(i * 5) | until([=](int j) { return j > i * 5 + 1; });
470         })
471       | concat
472       | until([](int i) { return i > 10; })
473       | as<vector<int>>();
474     EXPECT_EQ(expected, actual);
475   }
476   */
477 }
478
479 TEST(Gen, Composed) {
480   // Operator, Operator
481   auto valuesOf =
482       filter([](Optional<int>& o) { return o.hasValue(); })
483     | map([](Optional<int>& o) -> int& { return o.value(); });
484   std::vector<Optional<int>> opts {
485     none, 4, none, 6, none
486   };
487   EXPECT_EQ(4 * 4 + 6 * 6, from(opts) | valuesOf | map(square) | sum);
488   // Operator, Sink
489   auto sumOpt = valuesOf | sum;
490   EXPECT_EQ(10, from(opts) | sumOpt);
491 }
492
493 TEST(Gen, Chain) {
494   std::vector<int> nums {2, 3, 5, 7};
495   std::map<int, int> mappings { { 3, 9}, {5, 25} };
496   auto gen = from(nums) + (from(mappings) | get<1>());
497   EXPECT_EQ(51, gen | sum);
498   EXPECT_EQ(5, gen | take(2) | sum);
499   EXPECT_EQ(26, gen | take(5) | sum);
500 }
501
502 TEST(Gen, Concat) {
503   std::vector<std::vector<int>> nums {{2, 3}, {5, 7}};
504   auto gen = from(nums) | rconcat;
505   EXPECT_EQ(17, gen | sum);
506   EXPECT_EQ(10, gen | take(3) | sum);
507 }
508
509 TEST(Gen, ConcatGen) {
510   auto gen = seq(1, 10)
511            | map([](int i) { return seq(1, i); })
512            | concat;
513   EXPECT_EQ(220, gen | sum);
514   EXPECT_EQ(10, gen | take(6) | sum);
515 }
516
517 TEST(Gen, ConcatAlt) {
518   std::vector<std::vector<int>> nums {{2, 3}, {5, 7}};
519   auto actual = from(nums)
520               | map([](std::vector<int>& v) { return from(v); })
521               | concat
522               | sum;
523   auto expected = 17;
524   EXPECT_EQ(expected, actual);
525 }
526
527 TEST(Gen, Order) {
528   auto expected = vector<int>{0, 3, 5, 6, 7, 8, 9};
529   auto actual =
530       from({8, 6, 7, 5, 3, 0, 9})
531     | order
532     | as<vector>();
533   EXPECT_EQ(expected, actual);
534 }
535
536 TEST(Gen, OrderMoved) {
537   auto expected = vector<int>{0, 9, 25, 36, 49, 64, 81};
538   auto actual =
539       from({8, 6, 7, 5, 3, 0, 9})
540     | move
541     | order
542     | map(square)
543     | as<vector>();
544   EXPECT_EQ(expected, actual);
545 }
546
547 TEST(Gen, OrderTake) {
548   auto expected = vector<int>{9, 8, 7};
549   auto actual =
550       from({8, 6, 7, 5, 3, 0, 9})
551     | orderByDescending(square)
552     | take(3)
553     | as<vector>();
554   EXPECT_EQ(expected, actual);
555 }
556
557 TEST(Gen, Distinct) {
558   auto expected = vector<int>{3, 1, 2};
559   auto actual =
560       from({3, 1, 3, 2, 1, 2, 3})
561     | distinct
562     | as<vector>();
563   EXPECT_EQ(expected, actual);
564 }
565
566 TEST(Gen, DistinctBy) {   //  0  1  4  9  6  5  6  9  4  1  0
567   auto expected = vector<int>{0, 1, 2, 3, 4, 5};
568   auto actual =
569       seq(0, 100)
570     | distinctBy([](int i) { return i * i % 10; })
571     | as<vector>();
572   EXPECT_EQ(expected, actual);
573 }
574
575 TEST(Gen, DistinctMove) {   //  0  1  4  9  6  5  6  9  4  1  0
576   auto expected = vector<int>{0, 1, 2, 3, 4, 5};
577   auto actual =
578       seq(0, 100)
579     | mapped([](int i) { return std::unique_ptr<int>(new int(i)); })
580       // see comment below about selector parameters for Distinct
581     | distinctBy([](const std::unique_ptr<int>& pi) { return *pi * *pi % 10; })
582     | mapped([](std::unique_ptr<int> pi) { return *pi; })
583     | as<vector>();
584
585   // NOTE(tjackson): the following line intentionally doesn't work:
586   //  | distinctBy([](std::unique_ptr<int> pi) { return *pi * *pi % 10; })
587   // This is because distinctBy because the selector intentionally requires a
588   // const reference.  If it required a move-reference, the value might get
589   // gutted by the selector before said value could be passed to downstream
590   // operators.
591   EXPECT_EQ(expected, actual);
592 }
593
594 TEST(Gen, DistinctInfinite) {
595   // distinct should be able to handle an infinite sequence, provided that, of
596   // of cource, is it eventually made finite before returning the result.
597   auto expected = seq(0) | take(5) | as<vector>(); // 0 1 2 3 4
598
599   auto actual =
600       seq(0)                              // 0 1 2 3 4 5 6 7 ...
601     | mapped([](int i) { return i / 2; }) // 0 0 1 1 2 2 3 3 ...
602     | distinct                            // 0 1 2 3 4 5 6 7 ...
603     | take(5)                             // 0 1 2 3 4
604     | as<vector>();
605
606   EXPECT_EQ(expected, actual);
607 }
608
609 TEST(Gen, DistinctByInfinite) {
610   // Similarly to the DistinctInfinite test case, distinct by should be able to
611   // handle infinite sequences. Note that depending on how many values we take()
612   // at the end, the sequence may infinite loop. This is fine becasue we cannot
613   // solve the halting problem.
614   auto expected = vector<int>{1, 2};
615   auto actual =
616       seq(1)                                    // 1 2 3 4 5 6 7 8 ...
617     | distinctBy([](int i) { return i % 2; })   // 1 2 (but might by infinite)
618     | take(2)                                   // 1 2
619     | as<vector>();
620   // Note that if we had take(3), this would infinite loop
621
622   EXPECT_EQ(expected, actual);
623 }
624
625 TEST(Gen, MinBy) {
626   EXPECT_EQ(7, seq(1, 10)
627              | minBy([](int i) -> double {
628                  double d = i - 6.8;
629                  return d * d;
630                })
631              | unwrap);
632 }
633
634 TEST(Gen, MaxBy) {
635   auto gen = from({"three", "eleven", "four"});
636
637   EXPECT_EQ("eleven", gen | maxBy(&strlen) | unwrap);
638 }
639
640 TEST(Gen, Min) {
641   auto odds = seq(2,10) | filter([](int i){ return i % 2; });
642
643   EXPECT_EQ(3, odds | min);
644 }
645
646 TEST(Gen, Max) {
647   auto odds = seq(2,10) | filter([](int i){ return i % 2; });
648
649   EXPECT_EQ(9, odds | max);
650 }
651
652 TEST(Gen, Append) {
653   string expected = "facebook";
654   string actual = "face";
655   from(StringPiece("book")) | appendTo(actual);
656   EXPECT_EQ(expected, actual);
657 }
658
659 TEST(Gen, FromRValue) {
660   {
661     // AFAICT The C++ Standard does not specify what happens to the rvalue
662     // reference of a std::vector when it is used as the 'other' for an rvalue
663     // constructor.  Use fbvector because we're sure its size will be zero in
664     // this case.
665     fbvector<int> v({1,2,3,4});
666     auto q1 = from(v);
667     EXPECT_EQ(v.size(), 4);  // ensure that the lvalue version was called!
668     auto expected = 1 * 2 * 3 * 4;
669     EXPECT_EQ(expected, q1 | product);
670
671     auto q2 = from(std::move(v));
672     EXPECT_EQ(v.size(), 0);  // ensure that rvalue version was called
673     EXPECT_EQ(expected, q2 | product);
674   }
675   {
676     auto expected = 7;
677     auto q = from([] {return vector<int>({3,7,5}); }());
678     EXPECT_EQ(expected, q | max);
679   }
680   {
681     for (auto size: {5, 1024, 16384, 1<<20}) {
682       auto q1 = from(vector<int>(size, 2));
683       auto q2 = from(vector<int>(size, 3));
684       // If the rvalue specialization is broken/gone, then the compiler will
685       // (disgustingly!) just store a *reference* to the temporary object,
686       // which is bad.  Try to catch this by allocating two temporary vectors
687       // of the same size, so that they'll probably use the same underlying
688       // buffer if q1's vector is destructed before q2's vector is constructed.
689       EXPECT_EQ(size * 2 + size * 3, (q1 | sum) + (q2 | sum));
690     }
691   }
692   {
693     auto q = from(set<int>{1,2,3,2,1});
694     EXPECT_EQ(q | sum, 6);
695   }
696 }
697
698 TEST(Gen, OrderBy) {
699   auto expected = vector<int>{5, 6, 4, 7, 3, 8, 2, 9, 1, 10};
700   auto actual =
701       seq(1, 10)
702     | orderBy([](int x) { return (5.1 - x) * (5.1 - x); })
703     | as<vector>();
704   EXPECT_EQ(expected, actual);
705
706   expected = seq(1, 10) | as<vector>();
707   actual =
708       from(expected)
709     | map([] (int x) { return 11 - x; })
710     | orderBy()
711     | as<vector>();
712   EXPECT_EQ(expected, actual);
713 }
714
715 TEST(Gen, Foldl) {
716   int expected = 2 * 3 * 4 * 5;
717   auto actual =
718       seq(2, 5)
719     | foldl(1, multiply);
720   EXPECT_EQ(expected, actual);
721 }
722
723 TEST(Gen, Reduce) {
724   int expected = 2 + 3 + 4 + 5;
725   auto actual = seq(2, 5) | reduce(add);
726   EXPECT_EQ(expected, actual | unwrap);
727 }
728
729 TEST(Gen, ReduceBad) {
730   auto gen = seq(1) | take(0);
731   auto actual = gen | reduce(add);
732   EXPECT_FALSE(actual); // Empty sequences are okay, they just yeild 'none'
733 }
734
735 TEST(Gen, Moves) {
736   std::vector<unique_ptr<int>> ptrs;
737   ptrs.emplace_back(new int(1));
738   EXPECT_NE(ptrs.front().get(), nullptr);
739   auto ptrs2 = from(ptrs) | move | as<vector>();
740   EXPECT_EQ(ptrs.front().get(), nullptr);
741   EXPECT_EQ(**ptrs2.data(), 1);
742 }
743
744 TEST(Gen, First) {
745   auto gen = seq(0) | filter([](int x) { return x > 3; });
746   EXPECT_EQ(4, gen | first | unwrap);
747 }
748
749 TEST(Gen, FromCopy) {
750   vector<int> v {3, 5};
751   auto src = from(v);
752   auto copy = fromCopy(v);
753   EXPECT_EQ(8, src | sum);
754   EXPECT_EQ(8, copy | sum);
755   v[1] = 7;
756   EXPECT_EQ(10, src | sum);
757   EXPECT_EQ(8, copy | sum);
758 }
759
760 TEST(Gen, Get) {
761   std::map<int, int> pairs {
762     {1, 1},
763     {2, 4},
764     {3, 9},
765     {4, 16},
766   };
767   auto pairSrc = from(pairs);
768   auto keys = pairSrc | get<0>();
769   auto values = pairSrc | get<1>();
770   EXPECT_EQ(10, keys | sum);
771   EXPECT_EQ(30, values | sum);
772   EXPECT_EQ(30, keys | map(square) | sum);
773   pairs[5] = 25;
774   EXPECT_EQ(15, keys | sum);
775   EXPECT_EQ(55, values | sum);
776
777   vector<tuple<int, int, int>> tuples {
778     make_tuple(1, 1, 1),
779     make_tuple(2, 4, 8),
780     make_tuple(3, 9, 27),
781   };
782   EXPECT_EQ(36, from(tuples) | get<2>() | sum);
783 }
784
785 TEST(Gen, notEmpty) {
786   EXPECT_TRUE(seq(0, 1) | notEmpty);
787   EXPECT_TRUE(just(1) | notEmpty);
788   EXPECT_FALSE(gen::range(0, 0) | notEmpty);
789   EXPECT_FALSE(from({1}) | take(0) | notEmpty);
790 }
791
792 TEST(Gen, isEmpty) {
793   EXPECT_FALSE(seq(0, 1) | isEmpty);
794   EXPECT_FALSE(just(1) | isEmpty);
795   EXPECT_TRUE(gen::range(0, 0) | isEmpty);
796   EXPECT_TRUE(from({1}) | take(0) | isEmpty);
797 }
798
799 TEST(Gen, Any) {
800   EXPECT_TRUE(seq(0, 10) | any([](int i) { return i == 7; }));
801   EXPECT_FALSE(seq(0, 10) | any([](int i) { return i == 11; }));
802 }
803
804 TEST(Gen, All) {
805   EXPECT_TRUE(seq(0, 10) | all([](int i) { return i < 11; }));
806   EXPECT_FALSE(seq(0, 10) | all([](int i) { return i < 5; }));
807   EXPECT_FALSE(seq(0) | take(9999) | all([](int i) { return i < 10; }));
808
809   // empty lists satisfies all
810   EXPECT_TRUE(seq(0) | take(0) | all([](int i) { return i < 50; }));
811   EXPECT_TRUE(seq(0) | take(0) | all([](int i) { return i > 50; }));
812 }
813
814 TEST(Gen, Yielders) {
815   auto gen = GENERATOR(int) {
816     for (int i = 1; i <= 5; ++i) {
817       yield(i);
818     }
819     yield(7);
820     for (int i = 3; ; ++i) {
821       yield(i * i);
822     }
823   };
824   vector<int> expected {
825     1, 2, 3, 4, 5, 7, 9, 16, 25
826   };
827   EXPECT_EQ(expected, gen | take(9) | as<vector>());
828 }
829
830 TEST(Gen, NestedYield) {
831   auto nums = GENERATOR(int) {
832     for (int i = 1; ; ++i) {
833       yield(i);
834     }
835   };
836   auto gen = GENERATOR(int) {
837     nums | take(10) | yield;
838     seq(1, 5) | [&](int i) {
839       yield(i);
840     };
841   };
842   EXPECT_EQ(70, gen | sum);
843 }
844
845 TEST(Gen, MapYielders) {
846   auto gen = seq(1, 5)
847            | map([](int n) {
848                return GENERATOR(int) {
849                  int i;
850                  for (i = 1; i < n; ++i)
851                    yield(i);
852                  for (; i >= 1; --i)
853                    yield(i);
854                };
855              })
856            | concat;
857   vector<int> expected {
858                 1,
859              1, 2, 1,
860           1, 2, 3, 2, 1,
861        1, 2, 3, 4, 3, 2, 1,
862     1, 2, 3, 4, 5, 4, 3, 2, 1,
863   };
864   EXPECT_EQ(expected, gen | as<vector>());
865 }
866
867 TEST(Gen, VirtualGen) {
868   VirtualGen<int> v(seq(1, 10));
869   EXPECT_EQ(55, v | sum);
870   v = v | map(square);
871   EXPECT_EQ(385, v | sum);
872   v = v | take(5);
873   EXPECT_EQ(55, v | sum);
874   EXPECT_EQ(30, v | take(4) | sum);
875 }
876
877
878 TEST(Gen, CustomType) {
879   struct Foo{
880     int y;
881   };
882   auto gen = from({Foo{2}, Foo{3}})
883            | map([](const Foo& f) { return f.y; });
884   EXPECT_EQ(5, gen | sum);
885 }
886
887 TEST(Gen, NoNeedlessCopies) {
888   auto gen = seq(1, 5)
889            | map([](int x) { return unique_ptr<int>(new int(x)); })
890            | map([](unique_ptr<int> p) { return p; })
891            | map([](unique_ptr<int>&& p) { return std::move(p); })
892            | map([](const unique_ptr<int>& p) { return *p; });
893   EXPECT_EQ(15, gen | sum);
894   EXPECT_EQ(6, gen | take(3) | sum);
895 }
896
897 namespace {
898
899 class TestIntSeq : public GenImpl<int, TestIntSeq> {
900  public:
901   TestIntSeq() { }
902
903   template <class Body>
904   bool apply(Body&& body) const {
905     for (int i = 1; i < 6; ++i) {
906       if (!body(i)) {
907         return false;
908       }
909     }
910     return true;
911   }
912
913   TestIntSeq(TestIntSeq&&) noexcept = default;
914   TestIntSeq& operator=(TestIntSeq&&) noexcept = default;
915   TestIntSeq(const TestIntSeq&) = delete;
916   TestIntSeq& operator=(const TestIntSeq&) = delete;
917 };
918
919 }  // namespace
920
921 TEST(Gen, NoGeneratorCopies) {
922   EXPECT_EQ(15, TestIntSeq() | sum);
923   auto x = TestIntSeq() | take(3);
924   EXPECT_EQ(6, std::move(x) | sum);
925 }
926
927 TEST(Gen, FromArray) {
928   int source[] = {2, 3, 5, 7};
929   auto gen = from(source);
930   EXPECT_EQ(2 * 3 * 5 * 7, gen | product);
931 }
932
933 TEST(Gen, FromStdArray) {
934   std::array<int,4> source {{2, 3, 5, 7}};
935   auto gen = from(source);
936   EXPECT_EQ(2 * 3 * 5 * 7, gen | product);
937 }
938
939 TEST(Gen, StringConcat) {
940   auto gen = seq(1, 10)
941            | eachTo<string>()
942            | rconcat;
943   EXPECT_EQ("12345678910", gen | as<string>());
944 }
945
946 struct CopyCounter {
947   static int alive;
948   int copies;
949   int moves;
950
951   CopyCounter() : copies(0), moves(0) {
952     ++alive;
953   }
954
955   CopyCounter(CopyCounter&& source) noexcept {
956     *this = std::move(source);
957     ++alive;
958   }
959
960   CopyCounter(const CopyCounter& source) {
961     *this = source;
962     ++alive;
963   }
964
965   ~CopyCounter() {
966     --alive;
967   }
968
969   CopyCounter& operator=(const CopyCounter& source) {
970     this->copies = source.copies + 1;
971     this->moves = source.moves;
972     return *this;
973   }
974
975   CopyCounter& operator=(CopyCounter&& source) {
976     this->copies = source.copies;
977     this->moves = source.moves + 1;
978     return *this;
979   }
980 };
981
982 int CopyCounter::alive = 0;
983
984 TEST(Gen, CopyCount) {
985   vector<CopyCounter> originals;
986   originals.emplace_back();
987   EXPECT_EQ(1, originals.size());
988   EXPECT_EQ(0, originals.back().copies);
989
990   vector<CopyCounter> copies = from(originals) | as<vector>();
991   EXPECT_EQ(1, copies.back().copies);
992   EXPECT_EQ(0, copies.back().moves);
993
994   vector<CopyCounter> moves = from(originals) | move | as<vector>();
995   EXPECT_EQ(0, moves.back().copies);
996   EXPECT_EQ(1, moves.back().moves);
997 }
998
999 // test dynamics with various layers of nested arrays.
1000 TEST(Gen, Dynamic) {
1001   dynamic array1 = {1, 2};
1002   EXPECT_EQ(dynamic(3), from(array1) | sum);
1003   dynamic array2 = {{1}, {1, 2}};
1004   EXPECT_EQ(dynamic(4), from(array2) | rconcat | sum);
1005   dynamic array3 = {{{1}}, {{1}, {1, 2}}};
1006   EXPECT_EQ(dynamic(5), from(array3) | rconcat | rconcat | sum);
1007 }
1008
1009 TEST(Gen, DynamicObject) {
1010   const dynamic obj = dynamic::object(1, 2)(3, 4);
1011   EXPECT_EQ(dynamic(4), from(obj.keys()) | sum);
1012   EXPECT_EQ(dynamic(6), from(obj.values()) | sum);
1013   EXPECT_EQ(dynamic(4), from(obj.items()) | get<0>() | sum);
1014   EXPECT_EQ(dynamic(6), from(obj.items()) | get<1>() | sum);
1015 }
1016
1017 TEST(Gen, Collect) {
1018   auto s = from({7, 6, 5, 4, 3}) | as<set<int>>();
1019   EXPECT_EQ(s.size(), 5);
1020 }
1021
1022
1023 TEST(Gen, Cycle) {
1024   {
1025     auto s = from({1, 2});
1026     EXPECT_EQ((vector<int> { 1, 2, 1, 2, 1 }),
1027               s | cycle | take(5) | as<vector>());
1028   }
1029   {
1030     auto s = from({1, 2});
1031     EXPECT_EQ((vector<int> { 1, 2, 1, 2 }),
1032               s | cycle(2) | as<vector>());
1033   }
1034   {
1035     auto s = from({1, 2, 3});
1036     EXPECT_EQ((vector<int> { 1, 2, 1, 2, 1 }),
1037               s | take(2) | cycle | take(5) | as<vector>());
1038   }
1039   {
1040     auto s = empty<int>();
1041     EXPECT_EQ((vector<int> { }),
1042               s | cycle | take(4) | as<vector>());
1043   }
1044   {
1045     int count = 3;
1046     int* pcount = &count;
1047     auto countdown = GENERATOR(int) {
1048       ASSERT_GE(*pcount, 0)
1049         << "Cycle should have stopped when it didnt' get values!";
1050       for (int i = 1; i <= *pcount; ++i) {
1051         yield(i);
1052       }
1053       --*pcount;
1054     };
1055     auto s = countdown;
1056     EXPECT_EQ((vector<int> { 1, 2, 3, 1, 2, 1}),
1057               s | cycle | take(7) | as<vector>());
1058     // take necessary as cycle returns an infinite generator
1059   }
1060 }
1061
1062 TEST(Gen, Dereference) {
1063   {
1064     const int x = 4, y = 2;
1065     auto s = from(std::initializer_list<const int*>({&x, nullptr, &y}));
1066     EXPECT_EQ(6, s | dereference | sum);
1067   }
1068   {
1069     vector<int> a { 1, 2 };
1070     vector<int> b { 3, 4 };
1071     vector<vector<int>*> pv { &a, nullptr, &b };
1072     from(pv)
1073       | dereference
1074       | [&](vector<int>& v) {
1075           v.push_back(5);
1076         };
1077     EXPECT_EQ(3, a.size());
1078     EXPECT_EQ(3, b.size());
1079     EXPECT_EQ(5, a.back());
1080     EXPECT_EQ(5, b.back());
1081   }
1082   {
1083     vector<std::map<int, int>> maps {
1084       {
1085         { 2, 31 },
1086         { 3, 41 },
1087       },
1088       {
1089         { 3, 52 },
1090         { 4, 62 },
1091       },
1092       {
1093         { 4, 73 },
1094         { 5, 83 },
1095       },
1096     };
1097     EXPECT_EQ(
1098       93,
1099       from(maps)
1100       | map([](std::map<int, int>& m) {
1101           return get_ptr(m, 3);
1102         })
1103       | dereference
1104       | sum);
1105   }
1106   {
1107     vector<unique_ptr<int>> ups;
1108     ups.emplace_back(new int(3));
1109     ups.emplace_back();
1110     ups.emplace_back(new int(7));
1111     EXPECT_EQ(10, from(ups) | dereference | sum);
1112     EXPECT_EQ(10, from(ups) | move | dereference | sum);
1113   }
1114 }
1115
1116 TEST(Gen, Indirect) {
1117   vector<int> vs{1};
1118   EXPECT_EQ(&vs[0], from(vs) | indirect | first | unwrap);
1119 }
1120
1121 TEST(Gen, Guard) {
1122   using std::runtime_error;
1123   EXPECT_THROW(from({"1", "a", "3"})
1124                | eachTo<int>()
1125                | sum,
1126                runtime_error);
1127   EXPECT_EQ(4,
1128             from({"1", "a", "3"})
1129             | guard<runtime_error>([](runtime_error&, const char*) {
1130                 return true; // continue
1131               })
1132             | eachTo<int>()
1133             | sum);
1134   EXPECT_EQ(1,
1135             from({"1", "a", "3"})
1136             | guard<runtime_error>([](runtime_error&, const char*) {
1137                 return false; // break
1138               })
1139             | eachTo<int>()
1140             | sum);
1141   EXPECT_THROW(from({"1", "a", "3"})
1142                 | guard<runtime_error>([](runtime_error&, const char* v) {
1143                     if (v[0] == 'a') {
1144                       throw;
1145                     }
1146                     return true;
1147                   })
1148                | eachTo<int>()
1149                | sum,
1150                runtime_error);
1151 }
1152
1153 TEST(Gen, Batch) {
1154   EXPECT_EQ((vector<vector<int>> { {1} }),
1155             seq(1, 1) | batch(5) | as<vector>());
1156   EXPECT_EQ((vector<vector<int>> { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11} }),
1157             seq(1, 11) | batch(3) | as<vector>());
1158   EXPECT_THROW(seq(1, 1) | batch(0) | as<vector>(),
1159                std::invalid_argument);
1160 }
1161
1162 TEST(Gen, BatchMove) {
1163   auto expected = vector<vector<int>>{ {0, 1}, {2, 3}, {4} };
1164   auto actual =
1165       seq(0, 4)
1166     | mapped([](int i) { return std::unique_ptr<int>(new int(i)); })
1167     | batch(2)
1168     | mapped([](std::vector<std::unique_ptr<int>>& pVector) {
1169         std::vector<int> iVector;
1170         for (const auto& p : pVector) {
1171           iVector.push_back(*p);
1172         };
1173         return iVector;
1174       })
1175     | as<vector>();
1176   EXPECT_EQ(expected, actual);
1177 }
1178
1179 TEST(Gen, Just) {
1180   {
1181     int x = 3;
1182     auto j = just(x);
1183     EXPECT_EQ(&x, j | indirect | first | unwrap);
1184     x = 4;
1185     EXPECT_EQ(4, j | sum);
1186   }
1187   {
1188     int x = 3;
1189     const int& cx = x;
1190     auto j = just(cx);
1191     EXPECT_EQ(&x, j | indirect | first | unwrap);
1192     x = 5;
1193     EXPECT_EQ(5, j | sum);
1194   }
1195   {
1196     int x = 3;
1197     auto j = just(std::move(x));
1198     EXPECT_NE(&x, j | indirect | first | unwrap);
1199     x = 5;
1200     EXPECT_EQ(3, j | sum);
1201   }
1202 }
1203
1204 TEST(Gen, GroupBy) {
1205   vector<string> strs{"zero", "one", "two",   "three", "four",
1206                       "five", "six", "seven", "eight", "nine"};
1207
1208   auto gb = from(strs) | groupBy([](const string& str) { return str.size(); });
1209
1210   EXPECT_EQ(10, gb | mapOp(count) | sum);
1211   EXPECT_EQ(3, gb | count);
1212
1213   vector<string> mode{"zero", "four", "five", "nine"};
1214   EXPECT_EQ(mode,
1215             gb | maxBy([](const Group<size_t, string>& g) { return g.size(); })
1216                | unwrap
1217                | as<vector>());
1218
1219   vector<string> largest{"three", "seven", "eight"};
1220   EXPECT_EQ(largest,
1221             gb | maxBy([](const Group<size_t, string>& g) { return g.key(); })
1222                | unwrap
1223                | as<vector>());
1224 }
1225
1226 TEST(Gen, Unwrap) {
1227   Optional<int> o(4);
1228   Optional<int> e;
1229   EXPECT_EQ(4, o | unwrap);
1230   EXPECT_THROW(e | unwrap, OptionalEmptyException);
1231
1232   auto oup = folly::make_optional(folly::make_unique<int>(5));
1233   // optional has a value, and that value is non-null
1234   EXPECT_TRUE(oup | unwrap);
1235   EXPECT_EQ(5, *(oup | unwrap));
1236   EXPECT_TRUE(oup.hasValue()); // still has a pointer (null or not)
1237   EXPECT_TRUE(oup.value()); // that value isn't null
1238
1239   auto moved1 = std::move(oup) | unwrapOr(folly::make_unique<int>(6));
1240   // oup still has a value, but now it's now nullptr since the pointer was moved
1241   // into moved1
1242   EXPECT_TRUE(oup.hasValue());
1243   EXPECT_FALSE(oup.value());
1244   EXPECT_TRUE(moved1);
1245   EXPECT_EQ(5, *moved1);
1246
1247   auto moved2 = std::move(oup) | unwrapOr(folly::make_unique<int>(7));
1248   // oup's still-valid nullptr value wins here, the pointer to 7 doesn't apply
1249   EXPECT_FALSE(moved2);
1250
1251   oup.clear();
1252   auto moved3 = std::move(oup) | unwrapOr(folly::make_unique<int>(8));
1253   // oup is empty now, so the unwrapOr comes into play.
1254   EXPECT_TRUE(moved3);
1255   EXPECT_EQ(8, *moved3);
1256
1257   {
1258   // mixed types, with common type matching optional
1259     Optional<double> full(3.3);
1260     decltype(full) empty;
1261     auto fallback = unwrapOr(4);
1262     EXPECT_EQ(3.3, full | fallback);
1263     EXPECT_EQ(3.3, std::move(full) | fallback);
1264     EXPECT_EQ(3.3, full | std::move(fallback));
1265     EXPECT_EQ(3.3, std::move(full) | std::move(fallback));
1266     EXPECT_EQ(4.0, empty | fallback);
1267     EXPECT_EQ(4.0, std::move(empty) | fallback);
1268     EXPECT_EQ(4.0, empty | std::move(fallback));
1269     EXPECT_EQ(4.0, std::move(empty) | std::move(fallback));
1270   }
1271
1272   {
1273   // mixed types, with common type matching fallback
1274     Optional<int> full(3);
1275     decltype(full) empty;
1276     auto fallback = unwrapOr(5.0); // type: double
1277     // if we chose 'int' as the common type, we'd see truncation here
1278     EXPECT_EQ(1.5, (full | fallback) / 2);
1279     EXPECT_EQ(1.5, (std::move(full) | fallback) / 2);
1280     EXPECT_EQ(1.5, (full | std::move(fallback)) / 2);
1281     EXPECT_EQ(1.5, (std::move(full) | std::move(fallback)) / 2);
1282     EXPECT_EQ(2.5, (empty | fallback) / 2);
1283     EXPECT_EQ(2.5, (std::move(empty) | fallback) / 2);
1284     EXPECT_EQ(2.5, (empty | std::move(fallback)) / 2);
1285     EXPECT_EQ(2.5, (std::move(empty) | std::move(fallback)) / 2);
1286   }
1287
1288   {
1289     auto opt = folly::make_optional(std::make_shared<int>(8));
1290     auto fallback = unwrapOr(folly::make_unique<int>(9));
1291     // fallback must be std::move'd to be used
1292     EXPECT_EQ(8, *(opt | std::move(fallback)));
1293     EXPECT_TRUE(opt.value()); // shared_ptr copied out, not moved
1294     EXPECT_TRUE(opt); // value still present
1295     EXPECT_TRUE(fallback.value()); // fallback value not needed
1296
1297     EXPECT_EQ(8, *(std::move(opt) | std::move(fallback)));
1298     EXPECT_FALSE(opt.value()); // shared_ptr moved out
1299     EXPECT_TRUE(opt); // gutted value still present
1300     EXPECT_TRUE(fallback.value()); // fallback value not needed
1301
1302     opt.clear();
1303
1304     EXPECT_FALSE(opt); // opt is empty now
1305     EXPECT_EQ(9, *(std::move(opt) | std::move(fallback)));
1306     EXPECT_FALSE(fallback.value()); // fallback moved out!
1307   }
1308
1309   {
1310     // test with nullptr
1311     vector<int> v{1, 2};
1312     EXPECT_EQ(&v[1], from(v) | indirect | max | unwrap);
1313     v.clear();
1314     EXPECT_FALSE(from(v) | indirect | max | unwrapOr(nullptr));
1315   }
1316
1317   {
1318     // mixed type determined by fallback
1319     Optional<std::nullptr_t> empty;
1320     int x = 3;
1321     EXPECT_EQ(&x, empty | unwrapOr(&x));
1322   }
1323 }
1324
1325 int main(int argc, char *argv[]) {
1326   testing::InitGoogleTest(&argc, argv);
1327   gflags::ParseCommandLineFlags(&argc, &argv, true);
1328   return RUN_ALL_TESTS();
1329 }