Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(683)

Side by Side Diff: mojo/public/cpp/bindings/tests/pointer_deque_unittest.cc

Issue 2900543002: Mojo C++ bindings: introduce mojo::internal::deque and use it in MultiplexRouter. (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "mojo/public/cpp/bindings/lib/pointer_deque.h"
6 #include "base/memory/ptr_util.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8
9 namespace mojo {
10 namespace internal {
11
12 template <typename T, bool owned>
13 class PointerDequeAccessor {
14 public:
15 explicit PointerDequeAccessor(PointerDeque<T, owned>* deque)
16 : deque_(deque) {}
17
18 size_t front() { return deque_->front_; }
19
20 size_t back() { return deque_->back_; }
21
22 std::vector<typename PointerDeque<T, owned>::ElementType>& buffer() {
23 return deque_->buffer_;
24 }
25
26 private:
27 PointerDeque<T, owned>* deque_;
28 };
29
30 } // namespace internal
31
32 namespace test {
33 namespace {
34
35 using mojo::internal::PointerDeque;
36 using mojo::internal::PointerDequeAccessor;
37
38 struct Element {
39 explicit Element(int32_t in_value) : value(in_value) {}
40 int32_t value = 0;
41 };
42
43 struct RawPointerCase {
44 static constexpr bool kOwned = false;
45
46 struct ElementWrapper {
47 explicit ElementWrapper(int32_t value) : element_(value) {}
48 Element* ToPointer() { return &element_; }
49
50 private:
51 Element element_;
52 DISALLOW_COPY_AND_ASSIGN(ElementWrapper);
53 };
54
55 using Deque = PointerDeque<Element, kOwned>;
56 using Accessor = PointerDequeAccessor<Element, kOwned>;
57 };
58
59 struct OwnedPointerCase {
60 static constexpr bool kOwned = true;
61
62 struct ElementWrapper {
63 explicit ElementWrapper(int32_t value)
64 : element_(base::MakeUnique<Element>(value)) {}
65 std::unique_ptr<Element> ToPointer() { return std::move(element_); }
66
67 private:
68 std::unique_ptr<Element> element_;
69 DISALLOW_COPY_AND_ASSIGN(ElementWrapper);
70 };
71
72 using Deque = PointerDeque<Element, kOwned>;
73 using Accessor = PointerDequeAccessor<Element, kOwned>;
74 };
75
76 template <typename T>
77 class PointerDequeTest : public ::testing::Test {
78 public:
79 };
80
81 using CaseList = ::testing::Types<RawPointerCase, OwnedPointerCase>;
82
83 TYPED_TEST_CASE(PointerDequeTest, CaseList);
84
85 TYPED_TEST(PointerDequeTest, PushPop) {
86 using ElementWrapper = typename TypeParam::ElementWrapper;
87
88 typename TypeParam::Deque deque(2);
89 EXPECT_TRUE(deque.empty());
90
91 ElementWrapper e0(123);
92 deque.push_front(e0.ToPointer());
93 EXPECT_FALSE(deque.empty());
94
95 EXPECT_EQ(123, deque.front()->value);
96 EXPECT_EQ(123, deque.back()->value);
97
98 ElementWrapper e1(456);
99 deque.push_back(e1.ToPointer());
100
101 EXPECT_EQ(123, deque.front()->value);
102 EXPECT_EQ(456, deque.back()->value);
103
104 ElementWrapper e2(789);
105 deque.push_front(e2.ToPointer());
106
107 EXPECT_EQ(789, deque.front()->value);
108 EXPECT_EQ(456, deque.back()->value);
109
110 deque.pop_back();
111 EXPECT_EQ(789, deque.front()->value);
112 EXPECT_EQ(123, deque.back()->value);
113
114 deque.pop_front();
115 EXPECT_EQ(123, deque.front()->value);
116 EXPECT_EQ(123, deque.back()->value);
117
118 deque.pop_front();
119 EXPECT_TRUE(deque.empty());
120 }
121
122 TYPED_TEST(PointerDequeTest, Clear) {
123 using ElementWrapper = typename TypeParam::ElementWrapper;
124
125 typename TypeParam::Deque deque;
126 EXPECT_TRUE(deque.empty());
127
128 deque.clear();
129 EXPECT_TRUE(deque.empty());
130
131 ElementWrapper e0(123);
132 deque.push_front(e0.ToPointer());
133 ElementWrapper e1(456);
134 deque.push_back(e1.ToPointer());
135 ElementWrapper e2(789);
136 deque.push_front(e2.ToPointer());
137
138 deque.clear();
139
140 EXPECT_TRUE(deque.empty());
141 }
142
143 TYPED_TEST(PointerDequeTest, Move) {
144 using ElementWrapper = typename TypeParam::ElementWrapper;
145
146 {
147 typename TypeParam::Deque deque;
148 ElementWrapper e0(123);
149 deque.push_back(e0.ToPointer());
150 ElementWrapper e1(456);
151 deque.push_back(e1.ToPointer());
152 ElementWrapper e2(789);
153 deque.push_back(e2.ToPointer());
154
155 typename TypeParam::Deque deque2(std::move(deque));
156
157 EXPECT_TRUE(deque.empty());
158
159 EXPECT_EQ(123, deque2.front()->value);
160 deque2.pop_front();
161 EXPECT_EQ(456, deque2.front()->value);
162 deque2.pop_front();
163 EXPECT_EQ(789, deque2.front()->value);
164
165 // |deque| is still in valid state and could be reused.
166 ElementWrapper e4(321);
167 deque.push_back(e4.ToPointer());
168 EXPECT_EQ(321, deque.front()->value);
169 EXPECT_EQ(321, deque.back()->value);
170 }
171
172 {
173 typename TypeParam::Deque deque;
174 ElementWrapper e0(123);
175 deque.push_back(e0.ToPointer());
176 ElementWrapper e1(456);
177 deque.push_back(e1.ToPointer());
178 ElementWrapper e2(789);
179 deque.push_back(e2.ToPointer());
180
181 typename TypeParam::Deque deque2;
182 deque2 = std::move(deque);
183
184 EXPECT_TRUE(deque.empty());
185
186 EXPECT_EQ(123, deque2.front()->value);
187 deque2.pop_front();
188 EXPECT_EQ(456, deque2.front()->value);
189 deque2.pop_front();
190 EXPECT_EQ(789, deque2.front()->value);
191
192 // |deque| is still in valid state and could be reused.
193 ElementWrapper e4(321);
194 deque.push_back(e4.ToPointer());
195 EXPECT_EQ(321, deque.front()->value);
196 EXPECT_EQ(321, deque.back()->value);
197 }
198 }
199
200 // Constructs a deque with a fully occupied ring buffer.
201 // |front_index| is the position of the front element in the ring buffer.
202 // |values| stores the values from front to back.
203 template <typename Deque, typename ElementWrapper>
204 void ConstructFullDeque(
205 const std::vector<int32_t>& values,
206 size_t front_index,
207 Deque* deque,
208 std::vector<std::unique_ptr<ElementWrapper>>* wrappers) {
209 DCHECK_LT(front_index, values.size());
210 *deque = Deque(values.size());
211
212 // Push some temp elements to make sure the desired front element starts at
213 // |front_index|.
214 std::vector<std::unique_ptr<ElementWrapper>> temp_storage;
215 for (size_t i = 0; i < front_index; ++i) {
216 temp_storage.emplace_back(base::MakeUnique<ElementWrapper>(0));
217 deque->push_back(temp_storage.back()->ToPointer());
218 }
219
220 wrappers->emplace_back(base::MakeUnique<ElementWrapper>(values[0]));
221 deque->push_back(wrappers->back()->ToPointer());
222
223 for (size_t i = 0; i < front_index; ++i)
224 deque->pop_front();
225
226 for (size_t i = 1; i < values.size(); ++i) {
227 wrappers->emplace_back(base::MakeUnique<ElementWrapper>(values[i]));
228 deque->push_back(wrappers->back()->ToPointer());
229 }
230 }
231
232 template <typename Accessor, typename Deque>
233 void VerifyDequeInternalState(Deque* deque,
234 size_t expected_front,
235 size_t expected_back,
236 const std::vector<int32_t>& expected_values,
237 size_t expected_ring_buffer_size) {
238 Accessor accessor(deque);
239
240 EXPECT_EQ(expected_front, accessor.front());
241 EXPECT_EQ(expected_back, accessor.back());
242 EXPECT_EQ(expected_ring_buffer_size, accessor.buffer().size());
243
244 size_t index = expected_front;
245 for (size_t i = 0; i < expected_values.size(); ++i) {
246 EXPECT_EQ(expected_values[i], accessor.buffer()[index]->value);
247 index++;
248 if (index == accessor.buffer().size())
249 index = 0;
250 }
251 }
252
253 TYPED_TEST(PointerDequeTest, ExpandWhiteBox) {
254 using Deque = typename TypeParam::Deque;
255 using ElementWrapper = typename TypeParam::ElementWrapper;
256 using Accessor = typename TypeParam::Accessor;
257
258 // Test ConstructFullDeque() and VerifyDequeInternalState().
259 {
260 Deque deque;
261 std::vector<std::unique_ptr<ElementWrapper>> wrappers;
262 ConstructFullDeque({1, 2, 3}, 0, &deque, &wrappers);
263 VerifyDequeInternalState<Accessor>(&deque, 0, 2, {1, 2, 3}, 3);
264
265 Deque deque1;
266 std::vector<std::unique_ptr<ElementWrapper>> wrappers1;
267 ConstructFullDeque({1, 2, 3}, 1, &deque1, &wrappers1);
268 VerifyDequeInternalState<Accessor>(&deque1, 1, 0, {1, 2, 3}, 3);
269 }
270
271 // Test that ring buffer [1(front), 2, 3(back)] becomes
272 // [1(front), 2, 3, 4(back), _, _] after push_back(4).
273 {
274 Deque deque;
275 std::vector<std::unique_ptr<ElementWrapper>> wrappers;
276 ConstructFullDeque({1, 2, 3}, 0, &deque, &wrappers);
277
278 ElementWrapper e(4);
279 deque.push_back(e.ToPointer());
280 VerifyDequeInternalState<Accessor>(&deque, 0, 3, {1, 2, 3, 4}, 6);
281 }
282
283 // Test that ring buffer [1(front), 2, 3(back)] becomes
284 // [1, 2, 3(back), _, _, 4(front)] after push_front(4).
285 {
286 Deque deque;
287 std::vector<std::unique_ptr<ElementWrapper>> wrappers;
288 ConstructFullDeque({1, 2, 3}, 0, &deque, &wrappers);
289
290 ElementWrapper e(4);
291 deque.push_front(e.ToPointer());
292 VerifyDequeInternalState<Accessor>(&deque, 5, 2, {4, 1, 2, 3}, 6);
293 }
294
295 // Test that ring buffer [3(back), 1(front), 2] becomes
296 // [_, 1(front), 2, 3, 4(back), _] after push_back(4).
297 {
298 Deque deque;
299 std::vector<std::unique_ptr<ElementWrapper>> wrappers;
300 ConstructFullDeque({1, 2, 3}, 1, &deque, &wrappers);
301
302 ElementWrapper e(4);
303 deque.push_back(e.ToPointer());
304 VerifyDequeInternalState<Accessor>(&deque, 1, 4, {1, 2, 3, 4}, 6);
305 }
306
307 // Test that ring buffer [2, 3(back), 1(front)] becomes
308 // [2, 3, 4(back), _, _, 1(front)] after push_back(4).
309 {
310 Deque deque;
311 std::vector<std::unique_ptr<ElementWrapper>> wrappers;
312 ConstructFullDeque({1, 2, 3}, 2, &deque, &wrappers);
313
314 ElementWrapper e(4);
315 deque.push_back(e.ToPointer());
316 VerifyDequeInternalState<Accessor>(&deque, 5, 2, {1, 2, 3, 4}, 6);
317 }
318 }
319
320 } // namespace
321 } // namespace test
322 } // namespace mojo
OLDNEW
« mojo/public/cpp/bindings/lib/pointer_deque.h ('K') | « mojo/public/cpp/bindings/tests/BUILD.gn ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698