proxygen
PushmiTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2018-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 <type_traits>
18 
19 #include <chrono>
20 using namespace std::literals;
21 
31 
34 
35 using namespace folly::pushmi::aliases;
36 
39 
40 using namespace testing;
41 
42 TEST(EmptyNoArgSingleSender, TapAndSubmit) {
43  auto e = op::empty();
44  using E = decltype(e);
45 
46  EXPECT_THAT((v::SenderTo<E, v::any_receiver<>, v::is_single<>>), Eq(true))
47  << "expected empty to return a single sender that can take an any_receiver";
48 
49  int signals = 0;
50  e |
51  op::tap(
52  [&]() { signals += 100; },
53  [&](auto) noexcept { signals += 1000; },
54  [&]() { signals += 10; }) |
55  op::submit(
56  [&]() { signals += 100; },
57  [&](auto) noexcept { signals += 1000; },
58  [&]() { signals += 10; });
59 
60  EXPECT_THAT(signals, Eq(20))
61  << "expected the done signal to be recorded twice";
62 
63  EXPECT_THROW(v::future_from(e).get(), std::future_error)
64  << "expected future_error when future_from is applied";
65 
67  (std::is_same<std::future<void>, decltype(v::future_from(e))>::value),
68  Eq(true))
69  << "expected future_from(e) to return std::future<void>";
70 }
71 
72 TEST(EmptyIntSingleSender, TapAndSubmit) {
73  auto e = op::empty<int>();
74  using E = decltype(e);
75 
77  (v::SenderTo<
78  E,
81  Eq(true))
82  << "expected empty to return a single sender that can take an any_receiver<int>";
83 
84  int signals = 0;
85  e |
86  op::tap(
87  [&](auto) { signals += 100; },
88  [&](auto) noexcept { signals += 1000; },
89  [&]() { signals += 10; }) |
90  op::submit(
91  [&](auto) { signals += 100; },
92  [&](auto) noexcept { signals += 1000; },
93  [&]() { signals += 10; });
94 
95  EXPECT_THAT(signals, Eq(20))
96  << "expected the done signal to be recorded twice";
97 
98  EXPECT_THROW(v::future_from<int>(e).get(), std::future_error)
99  << "expected future_error when future_from is applied";
100 
101  EXPECT_THAT(
102  (std::is_same<std::future<int>, decltype(v::future_from<int>(e))>::value),
103  Eq(true))
104  << "expected future_from(e) to return std::future<void>";
105 }
106 
107 TEST(JustIntSingleSender, TransformAndSubmit) {
108  auto j = op::just(20);
109  using J = decltype(j);
110 
111  EXPECT_THAT(
112  (v::SenderTo<
113  J,
115  v::is_single<>>),
116  Eq(true))
117  << "expected empty to return a single sender that can take an any_receiver<int>";
118 
119  int signals = 0;
120  int value = 0;
121  j |
123  [&](int v) {
124  signals += 10000;
125  return v + 1;
126  },
127  [&](auto v) {
128  std::abort();
129  return v;
130  }) |
131  op::transform([&](int v) {
132  signals += 10000;
133  return v * 2;
134  }) |
135  op::submit(
136  [&](auto v) {
137  value = v;
138  signals += 100;
139  },
140  [&](auto) noexcept { signals += 1000; },
141  [&]() { signals += 10; });
142 
143  EXPECT_THAT(signals, Eq(20110))
144  << "expected that the transform signal is recorded twice and that the value and done signals once each";
145 
146  EXPECT_THAT(value, Eq(42)) << "expected a different result";
147 
148  auto twenty = v::future_from<int>(j).get();
149 
150  EXPECT_THAT(twenty, Eq(20))
151  << "expected a different result from future_from(e).get()";
152 
153  EXPECT_THAT(
154  (std::is_same<std::future<int>, decltype(v::future_from<int>(j))>::value),
155  Eq(true))
156  << "expected future_from(e) to return std::future<int>";
157 }
158 
159 TEST(FromIntManySender, TransformAndSubmit) {
160  std::array<int, 3> arr{0, 9, 99};
161  auto m = op::from(arr);
162  using M = decltype(m);
163 
164  EXPECT_THAT(
166  Eq(true))
167  << "expected empty to return a many sender that can take an any_receiver<int>";
168 
169  int signals = 0;
170  int value = 0;
171  m |
173  [&](int v) {
174  signals += 10000;
175  return v + 1;
176  },
177  [&](auto v) {
178  std::abort();
179  return v;
180  }) |
181  op::transform([&](int v) {
182  signals += 10000;
183  return v * 2;
184  }) |
185  op::submit(
186  [&](auto v) {
187  value += v;
188  signals += 100;
189  },
190  [&](auto) noexcept { signals += 1000; },
191  [&]() { signals += 10; });
192 
193  EXPECT_THAT(signals, Eq(60310))
194  << "expected that the transform signal is recorded six times and that the value signal three times and done signal once";
195 
196  EXPECT_THAT(value, Eq(222)) << "expected a different result";
197 }
auto v
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
internal::EqMatcher< T > Eq(T x)
PUSHMI_INLINE_VAR constexpr detail::tap_fn tap
Definition: tap.h:126
TEST(EmptyNoArgSingleSender, TapAndSubmit)
Definition: PushmiTest.cpp:42
requires E e noexcept(noexcept(s.error(std::move(e))))
PUSHMI_INLINE_VAR constexpr detail::transform_fn transform
Definition: transform.h:158
constexpr auto empty(C const &c) -> decltype(c.empty())
Definition: Access.h:55
requires SenderTo< In, std::promise< T >, is_single<> > std::future< T > future_from(In in)
Definition: receiver.h:500
static map< string, int > m
static const char *const value
Definition: Conv.cpp:50
**Optimized Holders **The template hazptr_array< M > provides most of the functionality *of M hazptr_holder s but with faster construction destruction *for M
Definition: Hazptr.h:104
PUSHMI_INLINE_VAR constexpr struct folly::pushmi::operators::from_fn from
#define EXPECT_THAT(value, matcher)
PUSHMI_INLINE_VAR constexpr struct folly::pushmi::operators::just_fn just