1 // Copyright 2021 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "src/core/lib/promise/seq.h"
16
17 #include <memory>
18 #include <string>
19 #include <vector>
20
21 #include "gtest/gtest.h"
22
23 namespace grpc_core {
24
TEST(SeqTest,Immediate)25 TEST(SeqTest, Immediate) {
26 EXPECT_EQ(Seq([] { return 3; })(), 3);
27 }
28
TEST(SeqTest,OneThen)29 TEST(SeqTest, OneThen) {
30 auto initial = [a = std::make_unique<int>(0)] { return 3; };
31 auto then = [a = std::make_unique<int>(1)](int i) {
32 return [i, b = std::make_unique<int>(2)]() { return i + 4; };
33 };
34 EXPECT_EQ(Seq(std::move(initial), std::move(then))(), Poll<int>(7));
35 }
36
TEST(SeqTest,OneThenIncomplete)37 TEST(SeqTest, OneThenIncomplete) {
38 auto initial = [a = std::make_unique<int>(0)]() -> Poll<int> {
39 return Pending{};
40 };
41 auto then = [a = std::make_unique<int>(1)](int i) {
42 return [i, b = std::make_unique<int>(2)]() { return i + 4; };
43 };
44 EXPECT_EQ(Seq(std::move(initial), std::move(then))(), Poll<int>(Pending{}));
45 }
46
TEST(SeqTest,TwoTypedThens)47 TEST(SeqTest, TwoTypedThens) {
48 struct A {};
49 struct B {};
50 struct C {};
51 auto initial = [] { return A{}; };
52 auto next1 = [](A) { return []() { return B{}; }; };
53 auto next2 = [](B) { return []() { return C{}; }; };
54 EXPECT_FALSE(Seq(initial, next1, next2)().pending());
55 }
56
57 // This does not compile, but is useful for testing error messages generated
58 // TEST(SeqTest, MisTypedThen) {
59 // struct A {};
60 // struct B {};
61 // auto initial = [] { return A{}; };
62 // auto next = [](B) { return []() { return B{}; }; };
63 // Seq(initial, next)().take();
64 //}
65 //
66
TEST(SeqTest,TwoThens)67 TEST(SeqTest, TwoThens) {
68 auto initial = [] { return std::string("a"); };
69 auto next1 = [](std::string i) { return [i]() { return i + "b"; }; };
70 auto next2 = [](std::string i) { return [i]() { return i + "c"; }; };
71 EXPECT_EQ(Seq(initial, next1, next2)(), Poll<std::string>("abc"));
72 }
73
TEST(SeqTest,ThreeThens)74 TEST(SeqTest, ThreeThens) {
75 EXPECT_EQ(
76 Seq([x = std::make_unique<int>(1)] { return std::string("a"); },
77 [x = std::make_unique<int>(1)](std::string i) {
78 return [i, y = std::make_unique<int>(2)]() { return i + "b"; };
79 },
80 [x = std::make_unique<int>(1)](std::string i) {
81 return [i, y = std::make_unique<int>(2)]() { return i + "c"; };
82 },
83 [x = std::make_unique<int>(1)](std::string i) {
84 return [i, y = std::make_unique<int>(2)]() { return i + "d"; };
85 })(),
86 Poll<std::string>("abcd"));
87 }
88
89 struct Big {
90 int x[256];
YesItIsUnusedgrpc_core::Big91 void YesItIsUnused() const {}
92 };
93
TEST(SeqTest,SaneSizes)94 TEST(SeqTest, SaneSizes) {
95 auto x = Big();
96 auto p1 = Seq(
97 [x] {
98 x.YesItIsUnused();
99 return 1;
100 },
101 [](int) {
102 auto y = Big();
103 return [y]() {
104 y.YesItIsUnused();
105 return 2;
106 };
107 });
108 EXPECT_GE(sizeof(p1), sizeof(Big));
109 EXPECT_LT(sizeof(p1), 2 * sizeof(Big));
110 }
111
TEST(SeqIterTest,Accumulate)112 TEST(SeqIterTest, Accumulate) {
113 std::vector<int> v{1, 2, 3, 4, 5};
114 EXPECT_EQ(SeqIter(v.begin(), v.end(), 0,
115 [](int cur, int next) {
116 return [cur, next]() { return cur + next; };
117 })(),
118 Poll<int>(15));
119 }
120
121 } // namespace grpc_core
122
main(int argc,char ** argv)123 int main(int argc, char** argv) {
124 ::testing::InitGoogleTest(&argc, argv);
125 return RUN_ALL_TESTS();
126 }
127