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

Side by Side Diff: mojo/public/cpp/bindings/tests/array_common_test.h

Issue 2607063002: Remove mojo::Array. (Closed)
Patch Set: rebase Created 3 years, 11 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 2016 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 <stddef.h>
6 #include <stdint.h>
7 #include <utility>
8
9 #include "mojo/public/cpp/bindings/lib/array_internal.h"
10 #include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
11 #include "mojo/public/cpp/bindings/lib/serialization.h"
12 #include "mojo/public/cpp/bindings/tests/container_test_util.h"
13 #include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace mojo {
17 namespace test {
18
19 // Common tests for both mojo::Array and mojo::WTFArray.
20 template <template <typename...> class ArrayType>
21 class ArrayCommonTest {
22 public:
23 // Tests null and empty arrays.
24 static void NullAndEmpty() {
25 ArrayType<char> array0;
26 EXPECT_TRUE(array0.empty());
27 EXPECT_FALSE(array0.is_null());
28 array0 = nullptr;
29 EXPECT_TRUE(array0.is_null());
30 EXPECT_FALSE(array0.empty());
31
32 ArrayType<char> array1(nullptr);
33 EXPECT_TRUE(array1.is_null());
34 EXPECT_FALSE(array1.empty());
35 array1.SetToEmpty();
36 EXPECT_TRUE(array1.empty());
37 EXPECT_FALSE(array1.is_null());
38 }
39
40 // Tests that basic array operations work.
41 static void Basic() {
42 ArrayType<char> array(8);
43 for (size_t i = 0; i < array.size(); ++i) {
44 char val = static_cast<char>(i * 2);
45 array[i] = val;
46 EXPECT_EQ(val, array.at(i));
47 }
48 }
49
50 // Tests that basic ArrayType<bool> operations work.
51 static void Bool() {
52 ArrayType<bool> array(64);
53 for (size_t i = 0; i < array.size(); ++i) {
54 bool val = i % 3 == 0;
55 array[i] = val;
56 EXPECT_EQ(val, array.at(i));
57 }
58 }
59
60 // Tests that ArrayType<ScopedMessagePipeHandle> supports transferring
61 // handles.
62 static void Handle() {
63 MessagePipe pipe;
64 ArrayType<ScopedMessagePipeHandle> handles(2);
65 handles[0] = std::move(pipe.handle0);
66 handles[1].reset(pipe.handle1.release());
67
68 EXPECT_FALSE(pipe.handle0.is_valid());
69 EXPECT_FALSE(pipe.handle1.is_valid());
70
71 ArrayType<ScopedMessagePipeHandle> handles2 = std::move(handles);
72 EXPECT_TRUE(handles2[0].is_valid());
73 EXPECT_TRUE(handles2[1].is_valid());
74
75 ScopedMessagePipeHandle pipe_handle = std::move(handles2[0]);
76 EXPECT_TRUE(pipe_handle.is_valid());
77 EXPECT_FALSE(handles2[0].is_valid());
78 }
79
80 // Tests that ArrayType<ScopedMessagePipeHandle> supports closing handles.
81 static void HandlesAreClosed() {
82 MessagePipe pipe;
83 MojoHandle pipe0_value = pipe.handle0.get().value();
84 MojoHandle pipe1_value = pipe.handle0.get().value();
85
86 {
87 ArrayType<ScopedMessagePipeHandle> handles(2);
88 handles[0] = std::move(pipe.handle0);
89 handles[1].reset(pipe.handle0.release());
90 }
91
92 // We expect the pipes to have been closed.
93 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe0_value));
94 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe1_value));
95 }
96
97 static void Clone() {
98 {
99 // Test POD.
100 ArrayType<int32_t> array(3);
101 for (size_t i = 0; i < array.size(); ++i)
102 array[i] = static_cast<int32_t>(i);
103
104 ArrayType<int32_t> clone_array = array.Clone();
105 EXPECT_EQ(array.size(), clone_array.size());
106 for (size_t i = 0; i < array.size(); ++i)
107 EXPECT_EQ(array[i], clone_array[i]);
108 }
109
110 {
111 // Test copyable object.
112 ArrayType<std::string> array(2);
113 array[0] = "hello";
114 array[1] = "world";
115
116 ArrayType<std::string> clone_array = array.Clone();
117 EXPECT_EQ(array.size(), clone_array.size());
118 for (size_t i = 0; i < array.size(); ++i)
119 EXPECT_EQ(array[i], clone_array[i]);
120 }
121
122 {
123 // Test struct.
124 ArrayType<RectPtr> array(2);
125 array[1] = Rect::New();
126 array[1]->x = 1;
127 array[1]->y = 2;
128 array[1]->width = 3;
129 array[1]->height = 4;
130
131 ArrayType<RectPtr> clone_array = array.Clone();
132 EXPECT_EQ(array.size(), clone_array.size());
133 EXPECT_TRUE(clone_array[0].is_null());
134 EXPECT_EQ(array[1]->x, clone_array[1]->x);
135 EXPECT_EQ(array[1]->y, clone_array[1]->y);
136 EXPECT_EQ(array[1]->width, clone_array[1]->width);
137 EXPECT_EQ(array[1]->height, clone_array[1]->height);
138 }
139
140 {
141 // Test array of array.
142 ArrayType<ArrayType<int8_t>> array(2);
143 array[0] = nullptr;
144 array[1] = ArrayType<int8_t>(2);
145 array[1][0] = 0;
146 array[1][1] = 1;
147
148 ArrayType<ArrayType<int8_t>> clone_array = array.Clone();
149 EXPECT_EQ(array.size(), clone_array.size());
150 EXPECT_TRUE(clone_array[0].is_null());
151 EXPECT_EQ(array[1].size(), clone_array[1].size());
152 EXPECT_EQ(array[1][0], clone_array[1][0]);
153 EXPECT_EQ(array[1][1], clone_array[1][1]);
154 }
155
156 {
157 // Test that array of handles still works although Clone() is not
158 // available.
159 ArrayType<ScopedMessagePipeHandle> array(10);
160 EXPECT_FALSE(array[0].is_valid());
161 }
162 }
163
164 static void Serialization_ArrayOfPOD() {
165 ArrayType<int32_t> array(4);
166 for (size_t i = 0; i < array.size(); ++i)
167 array[i] = static_cast<int32_t>(i);
168
169 size_t size = mojo::internal::PrepareToSerialize<ArrayDataView<int32_t>>(
170 array, nullptr);
171 EXPECT_EQ(8U + 4 * 4U, size);
172
173 mojo::internal::FixedBufferForTesting buf(size);
174 mojo::internal::Array_Data<int32_t>* data;
175 mojo::internal::ContainerValidateParams validate_params(0, false, nullptr);
176 mojo::internal::Serialize<ArrayDataView<int32_t>>(
177 array, &buf, &data, &validate_params, nullptr);
178
179 ArrayType<int32_t> array2;
180 mojo::internal::Deserialize<ArrayDataView<int32_t>>(data, &array2, nullptr);
181
182 EXPECT_EQ(4U, array2.size());
183 for (size_t i = 0; i < array2.size(); ++i)
184 EXPECT_EQ(static_cast<int32_t>(i), array2[i]);
185 }
186
187 static void Serialization_EmptyArrayOfPOD() {
188 ArrayType<int32_t> array;
189 size_t size = mojo::internal::PrepareToSerialize<ArrayDataView<int32_t>>(
190 array, nullptr);
191 EXPECT_EQ(8U, size);
192
193 mojo::internal::FixedBufferForTesting buf(size);
194 mojo::internal::Array_Data<int32_t>* data;
195 mojo::internal::ContainerValidateParams validate_params(0, false, nullptr);
196 mojo::internal::Serialize<ArrayDataView<int32_t>>(
197 array, &buf, &data, &validate_params, nullptr);
198
199 ArrayType<int32_t> array2;
200 mojo::internal::Deserialize<ArrayDataView<int32_t>>(data, &array2, nullptr);
201 EXPECT_EQ(0U, array2.size());
202 }
203
204 static void Serialization_ArrayOfArrayOfPOD() {
205 using MojomType = ArrayDataView<ArrayDataView<int32_t>>;
206 ArrayType<ArrayType<int32_t>> array(2);
207 for (size_t j = 0; j < array.size(); ++j) {
208 ArrayType<int32_t> inner(4);
209 for (size_t i = 0; i < inner.size(); ++i)
210 inner[i] = static_cast<int32_t>(i + (j * 10));
211 array[j] = std::move(inner);
212 }
213
214 size_t size = mojo::internal::PrepareToSerialize<MojomType>(array, nullptr);
215 EXPECT_EQ(8U + 2 * 8U + 2 * (8U + 4 * 4U), size);
216
217 mojo::internal::FixedBufferForTesting buf(size);
218 typename mojo::internal::MojomTypeTraits<MojomType>::Data* data;
219 mojo::internal::ContainerValidateParams validate_params(
220 0, false,
221 new mojo::internal::ContainerValidateParams(0, false, nullptr));
222 mojo::internal::Serialize<MojomType>(array, &buf, &data, &validate_params,
223 nullptr);
224
225 ArrayType<ArrayType<int32_t>> array2;
226 mojo::internal::Deserialize<MojomType>(data, &array2, nullptr);
227
228 EXPECT_EQ(2U, array2.size());
229 for (size_t j = 0; j < array2.size(); ++j) {
230 const ArrayType<int32_t>& inner = array2[j];
231 EXPECT_EQ(4U, inner.size());
232 for (size_t i = 0; i < inner.size(); ++i)
233 EXPECT_EQ(static_cast<int32_t>(i + (j * 10)), inner[i]);
234 }
235 }
236
237 static void Serialization_ArrayOfBool() {
238 ArrayType<bool> array(10);
239 for (size_t i = 0; i < array.size(); ++i)
240 array[i] = i % 2 ? true : false;
241
242 size_t size =
243 mojo::internal::PrepareToSerialize<ArrayDataView<bool>>(array, nullptr);
244 EXPECT_EQ(8U + 8U, size);
245
246 mojo::internal::FixedBufferForTesting buf(size);
247 mojo::internal::Array_Data<bool>* data;
248 mojo::internal::ContainerValidateParams validate_params(0, false, nullptr);
249 mojo::internal::Serialize<ArrayDataView<bool>>(array, &buf, &data,
250 &validate_params, nullptr);
251
252 ArrayType<bool> array2;
253 mojo::internal::Deserialize<ArrayDataView<bool>>(data, &array2, nullptr);
254
255 EXPECT_EQ(10U, array2.size());
256 for (size_t i = 0; i < array2.size(); ++i)
257 EXPECT_EQ(i % 2 ? true : false, array2[i]);
258 }
259
260 static void Serialization_ArrayOfString() {
261 using MojomType = ArrayDataView<StringDataView>;
262 ArrayType<std::string> array(10);
263 for (size_t i = 0; i < array.size(); ++i) {
264 char c = 'A' + static_cast<char>(i);
265 array[i] = std::string(&c, 1);
266 }
267
268 size_t size = mojo::internal::PrepareToSerialize<MojomType>(array, nullptr);
269 EXPECT_EQ(8U + // array header
270 10 * 8U + // array payload (10 pointers)
271 10 * (8U + // string header
272 8U), // string length of 1 padded to 8
273 size);
274
275 mojo::internal::FixedBufferForTesting buf(size);
276 typename mojo::internal::MojomTypeTraits<MojomType>::Data* data;
277 mojo::internal::ContainerValidateParams validate_params(
278 0, false,
279 new mojo::internal::ContainerValidateParams(0, false, nullptr));
280 mojo::internal::Serialize<MojomType>(array, &buf, &data, &validate_params,
281 nullptr);
282
283 ArrayType<std::string> array2;
284 mojo::internal::Deserialize<MojomType>(data, &array2, nullptr);
285
286 EXPECT_EQ(10U, array2.size());
287 for (size_t i = 0; i < array2.size(); ++i) {
288 char c = 'A' + static_cast<char>(i);
289 EXPECT_EQ(std::string(&c, 1), array2[i]);
290 }
291 }
292
293 static void Resize_Copyable() {
294 ASSERT_EQ(0u, CopyableType::num_instances());
295 ArrayType<CopyableType> array(3);
296 std::vector<CopyableType*> value_ptrs;
297 value_ptrs.push_back(array[0].ptr());
298 value_ptrs.push_back(array[1].ptr());
299
300 for (size_t i = 0; i < array.size(); i++)
301 array[i].ResetCopied();
302
303 array.resize(2);
304 ASSERT_EQ(2u, array.size());
305 EXPECT_EQ(array.size(), CopyableType::num_instances());
306 for (size_t i = 0; i < array.size(); i++) {
307 EXPECT_FALSE(array[i].copied());
308 EXPECT_EQ(value_ptrs[i], array[i].ptr());
309 }
310
311 array.resize(3);
312 array[2].ResetCopied();
313 ASSERT_EQ(3u, array.size());
314 EXPECT_EQ(array.size(), CopyableType::num_instances());
315 for (size_t i = 0; i < array.size(); i++)
316 EXPECT_FALSE(array[i].copied());
317 value_ptrs.push_back(array[2].ptr());
318
319 size_t capacity = array.storage().capacity();
320 array.resize(capacity);
321 ASSERT_EQ(capacity, array.size());
322 EXPECT_EQ(array.size(), CopyableType::num_instances());
323 for (size_t i = 0; i < 3; i++)
324 EXPECT_FALSE(array[i].copied());
325 for (size_t i = 3; i < array.size(); i++) {
326 array[i].ResetCopied();
327 value_ptrs.push_back(array[i].ptr());
328 }
329
330 array.resize(capacity + 2);
331 ASSERT_EQ(capacity + 2, array.size());
332 EXPECT_EQ(array.size(), CopyableType::num_instances());
333 for (size_t i = 0; i < capacity; i++) {
334 EXPECT_TRUE(array[i].copied());
335 EXPECT_EQ(value_ptrs[i], array[i].ptr());
336 }
337 array = nullptr;
338 EXPECT_EQ(0u, CopyableType::num_instances());
339 EXPECT_FALSE(array);
340 array.resize(0);
341 EXPECT_EQ(0u, CopyableType::num_instances());
342 EXPECT_TRUE(array);
343 }
344
345 static void Resize_MoveOnly() {
346 ASSERT_EQ(0u, MoveOnlyType::num_instances());
347 ArrayType<MoveOnlyType> array(3);
348 std::vector<MoveOnlyType*> value_ptrs;
349 value_ptrs.push_back(array[0].ptr());
350 value_ptrs.push_back(array[1].ptr());
351
352 for (size_t i = 0; i < array.size(); i++)
353 EXPECT_FALSE(array[i].moved());
354
355 array.resize(2);
356 ASSERT_EQ(2u, array.size());
357 EXPECT_EQ(array.size(), MoveOnlyType::num_instances());
358 for (size_t i = 0; i < array.size(); i++) {
359 EXPECT_FALSE(array[i].moved());
360 EXPECT_EQ(value_ptrs[i], array[i].ptr());
361 }
362
363 array.resize(3);
364 ASSERT_EQ(3u, array.size());
365 EXPECT_EQ(array.size(), MoveOnlyType::num_instances());
366 for (size_t i = 0; i < array.size(); i++)
367 EXPECT_FALSE(array[i].moved());
368 value_ptrs.push_back(array[2].ptr());
369
370 size_t capacity = array.storage().capacity();
371 array.resize(capacity);
372 ASSERT_EQ(capacity, array.size());
373 EXPECT_EQ(array.size(), MoveOnlyType::num_instances());
374 for (size_t i = 0; i < array.size(); i++)
375 EXPECT_FALSE(array[i].moved());
376 for (size_t i = 3; i < array.size(); i++)
377 value_ptrs.push_back(array[i].ptr());
378
379 array.resize(capacity + 2);
380 ASSERT_EQ(capacity + 2, array.size());
381 EXPECT_EQ(array.size(), MoveOnlyType::num_instances());
382 for (size_t i = 0; i < capacity; i++) {
383 EXPECT_TRUE(array[i].moved());
384 EXPECT_EQ(value_ptrs[i], array[i].ptr());
385 }
386 for (size_t i = capacity; i < array.size(); i++)
387 EXPECT_FALSE(array[i].moved());
388
389 array = nullptr;
390 EXPECT_EQ(0u, MoveOnlyType::num_instances());
391 EXPECT_FALSE(array);
392 array.resize(0);
393 EXPECT_EQ(0u, MoveOnlyType::num_instances());
394 EXPECT_TRUE(array);
395 }
396 };
397
398 #define ARRAY_COMMON_TEST(ArrayType, test_name) \
399 TEST_F(ArrayType##Test, test_name) { \
400 ArrayCommonTest<ArrayType>::test_name(); \
401 }
402
403 } // namespace test
404 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698