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

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

Issue 2250183003: Make the fuchsia mojo/public repo the source of truth. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 4 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 2014 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 "gtest/gtest.h"
6 #include "mojo/public/cpp/bindings/array.h"
7 #include "mojo/public/cpp/bindings/lib/array_internal.h"
8 #include "mojo/public/cpp/bindings/lib/array_serialization.h"
9 #include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
10 #include "mojo/public/cpp/bindings/tests/container_test_util.h"
11 #include "mojo/public/cpp/bindings/tests/iterator_test_util.h"
12 #include "mojo/public/interfaces/bindings/tests/test_arrays.mojom.h"
13 #include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h"
14
15 namespace mojo {
16 namespace test {
17 namespace {
18
19 using mojo::internal::Array_Data;
20 using mojo::internal::ArrayValidateParams;
21 using mojo::internal::FixedBufferForTesting;
22 using mojo::internal::String_Data;
23
24 // Tests that basic Array operations work.
25 TEST(ArrayTest, Basic) {
26 auto array = Array<uint8_t>::New(8);
27 for (size_t i = 0u; i < array.size(); ++i) {
28 uint8_t val = static_cast<uint8_t>(i * 2);
29 array[i] = val;
30 EXPECT_EQ(val, array.at(i));
31 }
32
33 EXPECT_EQ(0u, *array.data());
34 EXPECT_EQ(2u, *(array.data() + 1));
35 EXPECT_EQ(4u, *(array.data() + 2));
36 }
37
38 TEST(ArrayTest, Testability) {
39 Array<int32_t> array;
40 EXPECT_FALSE(array);
41 EXPECT_TRUE(array.is_null());
42
43 array.push_back(123);
44 EXPECT_TRUE(array);
45 EXPECT_FALSE(array.is_null());
46 }
47
48 void NullptrConstructorTestHelper(Array<int32_t> array) {
49 EXPECT_FALSE(array);
50 EXPECT_TRUE(array.is_null());
51 EXPECT_EQ(0u, array.size());
52 }
53
54 TEST(ArrayTest, NullptrConstructor) {
55 Array<int32_t> array(nullptr);
56 EXPECT_FALSE(array);
57 EXPECT_TRUE(array.is_null());
58 EXPECT_EQ(0u, array.size());
59
60 array.push_back(123);
61 EXPECT_TRUE(array);
62 EXPECT_FALSE(array.is_null());
63 EXPECT_EQ(1u, array.size());
64
65 // Test some implicit constructions of |Array<int32_t>| from a |nullptr|.
66 array = nullptr;
67 NullptrConstructorTestHelper(nullptr);
68 }
69
70 // Tests that basic Array<bool> operations work.
71 TEST(ArrayTest, Bool) {
72 auto array = Array<bool>::New(64);
73 for (size_t i = 0; i < array.size(); ++i) {
74 bool val = i % 3 == 0;
75 array[i] = val;
76 EXPECT_EQ(val, array.at(i));
77 }
78 }
79
80 // Tests that Array<ScopedMessagePipeHandle> supports transferring handles.
81 TEST(ArrayTest, Handle) {
82 MessagePipe pipe;
83 auto handles = Array<ScopedMessagePipeHandle>::New(2);
84 handles[0] = pipe.handle0.Pass();
85 handles[1].reset(pipe.handle1.release());
86
87 EXPECT_FALSE(pipe.handle0.is_valid());
88 EXPECT_FALSE(pipe.handle1.is_valid());
89
90 Array<ScopedMessagePipeHandle> handles2 = handles.Pass();
91 EXPECT_TRUE(handles2[0].is_valid());
92 EXPECT_TRUE(handles2[1].is_valid());
93
94 ScopedMessagePipeHandle pipe_handle = handles2[0].Pass();
95 EXPECT_TRUE(pipe_handle.is_valid());
96 EXPECT_FALSE(handles2[0].is_valid());
97 }
98
99 // Tests that Array<ScopedMessagePipeHandle> supports closing handles.
100 TEST(ArrayTest, HandlesAreClosed) {
101 MessagePipe pipe;
102 MojoHandle pipe0_value = pipe.handle0.get().value();
103 MojoHandle pipe1_value = pipe.handle0.get().value();
104
105 {
106 auto handles = Array<ScopedMessagePipeHandle>::New(2);
107 handles[0] = pipe.handle0.Pass();
108 handles[1].reset(pipe.handle0.release());
109 }
110
111 // We expect the pipes to have been closed.
112 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe0_value));
113 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe1_value));
114 }
115
116 TEST(ArrayTest, Clone) {
117 {
118 // Test POD.
119 auto array = Array<int32_t>::New(3);
120 for (size_t i = 0; i < array.size(); ++i)
121 array[i] = static_cast<int32_t>(i);
122
123 Array<int32_t> clone_array = array.Clone();
124 EXPECT_EQ(array.size(), clone_array.size());
125 for (size_t i = 0; i < array.size(); ++i)
126 EXPECT_EQ(array[i], clone_array[i]);
127 }
128
129 {
130 // Test copyable object.
131 auto array = Array<String>::New(2);
132 array[0] = "hello";
133 array[1] = "world";
134
135 Array<String> clone_array = array.Clone();
136 EXPECT_EQ(array.size(), clone_array.size());
137 for (size_t i = 0; i < array.size(); ++i)
138 EXPECT_EQ(array[i], clone_array[i]);
139 }
140
141 {
142 // Test struct.
143 auto array = Array<RectPtr>::New(2);
144 array[1] = Rect::New();
145 array[1]->x = 1;
146 array[1]->y = 2;
147 array[1]->width = 3;
148 array[1]->height = 4;
149
150 Array<RectPtr> clone_array = array.Clone();
151 EXPECT_EQ(array.size(), clone_array.size());
152 EXPECT_TRUE(clone_array[0].is_null());
153 EXPECT_EQ(array[1]->x, clone_array[1]->x);
154 EXPECT_EQ(array[1]->y, clone_array[1]->y);
155 EXPECT_EQ(array[1]->width, clone_array[1]->width);
156 EXPECT_EQ(array[1]->height, clone_array[1]->height);
157 }
158
159 {
160 // Test array of array.
161 auto array = Array<Array<int8_t>>::New(2);
162 array[1] = Array<int8_t>::New(2);
163 array[1][0] = 0;
164 array[1][1] = 1;
165
166 Array<Array<int8_t>> clone_array = array.Clone();
167 EXPECT_EQ(array.size(), clone_array.size());
168 EXPECT_TRUE(clone_array[0].is_null());
169 EXPECT_EQ(array[1].size(), clone_array[1].size());
170 EXPECT_EQ(array[1][0], clone_array[1][0]);
171 EXPECT_EQ(array[1][1], clone_array[1][1]);
172 }
173
174 {
175 // Test that array of handles still works although Clone() is not available.
176 auto array = Array<ScopedMessagePipeHandle>::New(10);
177 EXPECT_FALSE(array[0].is_valid());
178 }
179 }
180
181 TEST(ArrayTest, Serialization_ArrayOfPOD) {
182 auto array = Array<int32_t>::New(4);
183 for (size_t i = 0; i < array.size(); ++i)
184 array[i] = static_cast<int32_t>(i);
185
186 size_t size = GetSerializedSize_(array);
187 EXPECT_EQ(8U + 4 * 4U, size);
188
189 FixedBufferForTesting buf(size);
190 Array_Data<int32_t>* data = nullptr;
191 ArrayValidateParams validate_params(0, false, nullptr);
192 EXPECT_EQ(mojo::internal::ValidationError::NONE,
193 SerializeArray_(&array, &buf, &data, &validate_params));
194
195 Array<int32_t> array2;
196 Deserialize_(data, &array2);
197
198 EXPECT_EQ(4U, array2.size());
199 for (size_t i = 0; i < array2.size(); ++i)
200 EXPECT_EQ(static_cast<int32_t>(i), array2[i]);
201 }
202
203 TEST(ArrayTest, Serialization_EmptyArrayOfPOD) {
204 auto array = Array<int32_t>::New(0);
205 size_t size = GetSerializedSize_(array);
206 EXPECT_EQ(8U, size);
207
208 FixedBufferForTesting buf(size);
209 Array_Data<int32_t>* data = nullptr;
210 ArrayValidateParams validate_params(0, false, nullptr);
211 EXPECT_EQ(mojo::internal::ValidationError::NONE,
212 SerializeArray_(&array, &buf, &data, &validate_params));
213
214 Array<int32_t> array2;
215 Deserialize_(data, &array2);
216 EXPECT_EQ(0U, array2.size());
217 }
218
219 TEST(ArrayTest, Serialization_ArrayOfArrayOfPOD) {
220 auto array = Array<Array<int32_t>>::New(2);
221 for (size_t j = 0; j < array.size(); ++j) {
222 auto inner = Array<int32_t>::New(4);
223 for (size_t i = 0; i < inner.size(); ++i)
224 inner[i] = static_cast<int32_t>(i + (j * 10));
225 array[j] = inner.Pass();
226 }
227
228 size_t size = GetSerializedSize_(array);
229 EXPECT_EQ(8U + 2 * 8U + 2 * (8U + 4 * 4U), size);
230
231 FixedBufferForTesting buf(size);
232 Array_Data<Array_Data<int32_t>*>* data = nullptr;
233 ArrayValidateParams validate_params(
234 0, false, new ArrayValidateParams(0, false, nullptr));
235 EXPECT_EQ(mojo::internal::ValidationError::NONE,
236 SerializeArray_(&array, &buf, &data, &validate_params));
237
238 Array<Array<int32_t>> array2;
239 Deserialize_(data, &array2);
240
241 EXPECT_EQ(2U, array2.size());
242 for (size_t j = 0; j < array2.size(); ++j) {
243 const Array<int32_t>& inner = array2[j];
244 EXPECT_EQ(4U, inner.size());
245 for (size_t i = 0; i < inner.size(); ++i)
246 EXPECT_EQ(static_cast<int32_t>(i + (j * 10)), inner[i]);
247 }
248 }
249
250 TEST(ArrayTest, Serialization_ArrayOfScopedEnum) {
251 enum class TestEnum : int32_t {
252 E0,
253 E1,
254 E2,
255 E3,
256 };
257 static const TestEnum TEST_VALS[] = {
258 TestEnum::E0, TestEnum::E2, TestEnum::E1, TestEnum::E3,
259 TestEnum::E2, TestEnum::E2, TestEnum::E2, TestEnum::E0,
260 };
261
262 auto array = Array<TestEnum>::New(MOJO_ARRAYSIZE(TEST_VALS));
263 for (size_t i = 0; i < array.size(); ++i)
264 array[i] = TEST_VALS[i];
265
266 size_t size = GetSerializedSize_(array);
267 EXPECT_EQ(8U + (MOJO_ARRAYSIZE(TEST_VALS) * sizeof(int32_t)), size);
268
269 FixedBufferForTesting buf(size);
270 Array_Data<int32_t>* data = nullptr;
271 ArrayValidateParams validate_params(0, false, nullptr);
272 SerializeArray_(&array, &buf, &data, &validate_params);
273
274 Array<TestEnum> array2;
275 Deserialize_(data, &array2);
276
277 EXPECT_EQ(MOJO_ARRAYSIZE(TEST_VALS), array2.size());
278 for (size_t i = 0; i < array2.size(); ++i)
279 EXPECT_EQ(TEST_VALS[i], array2[i]);
280 }
281
282 TEST(ArrayTest, Serialization_ArrayOfBool) {
283 auto array = Array<bool>::New(10);
284 for (size_t i = 0; i < array.size(); ++i)
285 array[i] = i % 2 ? true : false;
286
287 size_t size = GetSerializedSize_(array);
288 EXPECT_EQ(8U + 8U, size);
289
290 FixedBufferForTesting buf(size);
291 Array_Data<bool>* data = nullptr;
292 ArrayValidateParams validate_params(0, false, nullptr);
293 EXPECT_EQ(mojo::internal::ValidationError::NONE,
294 SerializeArray_(&array, &buf, &data, &validate_params));
295
296 Array<bool> array2;
297 Deserialize_(data, &array2);
298
299 EXPECT_EQ(10U, array2.size());
300 for (size_t i = 0; i < array2.size(); ++i)
301 EXPECT_EQ(i % 2 ? true : false, array2[i]);
302 }
303
304 TEST(ArrayTest, Serialization_ArrayOfString) {
305 auto array = Array<String>::New(10);
306 for (size_t i = 0; i < array.size(); ++i) {
307 char c = 'A' + static_cast<char>(i);
308 array[i] = String(&c, 1);
309 }
310
311 size_t size = GetSerializedSize_(array);
312 EXPECT_EQ(8U + // array header
313 10 * 8U + // array payload (10 pointers)
314 10 * (8U + // string header
315 8U), // string length of 1 padded to 8
316 size);
317
318 FixedBufferForTesting buf(size);
319 Array_Data<String_Data*>* data = nullptr;
320 ArrayValidateParams validate_params(
321 0, false, new ArrayValidateParams(0, false, nullptr));
322 EXPECT_EQ(mojo::internal::ValidationError::NONE,
323 SerializeArray_(&array, &buf, &data, &validate_params));
324
325 Array<String> array2;
326 Deserialize_(data, &array2);
327
328 EXPECT_EQ(10U, array2.size());
329 for (size_t i = 0; i < array2.size(); ++i) {
330 char c = 'A' + static_cast<char>(i);
331 EXPECT_EQ(String(&c, 1), array2[i]);
332 }
333 }
334
335 // Tests serializing and deserializing an Array<Handle>.
336 TEST(ArrayTest, Serialization_ArrayOfHandle) {
337 auto array = Array<ScopedHandleBase<MessagePipeHandle>>::New(4);
338 MessagePipe p0;
339 MessagePipe p1;
340 // array[0] is left invalid.
341 array[1] = p0.handle1.Pass();
342 array[2] = p1.handle0.Pass();
343 array[3] = p1.handle1.Pass();
344
345 size_t size = GetSerializedSize_(array);
346 EXPECT_EQ(8U // array header
347 + (4U * 4), // 4 handles
348 size);
349
350 // We're going to reuse this buffer.. twice.
351 FixedBufferForTesting buf(size * 3);
352 Array_Data<MessagePipeHandle>* data = nullptr;
353
354 // 1. Serialization should fail on non-nullable invalid Handle.
355 ArrayValidateParams validate_params(4, false, nullptr);
356 EXPECT_EQ(mojo::internal::ValidationError::UNEXPECTED_INVALID_HANDLE,
357 SerializeArray_(&array, &buf, &data, &validate_params));
358
359 // We failed trying to transfer the first handle, so the rest are left valid.
360 EXPECT_FALSE(array[0].is_valid());
361 EXPECT_TRUE(array[1].is_valid());
362 EXPECT_TRUE(array[2].is_valid());
363 EXPECT_TRUE(array[3].is_valid());
364
365 // 2. Serialization should pass on nullable invalid Handle.
366 ArrayValidateParams validate_params_nullable(4, true, nullptr);
367 EXPECT_EQ(mojo::internal::ValidationError::NONE,
368 SerializeArray_(&array, &buf, &data, &validate_params_nullable));
369
370 EXPECT_FALSE(array[0].is_valid());
371 EXPECT_FALSE(array[1].is_valid());
372 EXPECT_FALSE(array[2].is_valid());
373 EXPECT_FALSE(array[3].is_valid());
374
375 Deserialize_(data, &array);
376 EXPECT_FALSE(array[0].is_valid());
377 EXPECT_TRUE(array[1].is_valid());
378 EXPECT_TRUE(array[2].is_valid());
379 EXPECT_TRUE(array[3].is_valid());
380 }
381
382 TEST(ArrayTest, Serialization_StructWithArraysOfHandles) {
383 StructWithHandles handles_struct;
384 MessagePipe handle_pair_0;
385 }
386
387 // Test serializing and deserializing an Array<InterfacePtr>.
388 TEST(ArrayTest, Serialization_ArrayOfInterfacePtr) {
389 auto iface_array = Array<mojo::InterfaceHandle<TestInterface>>::New(1);
390 size_t size = GetSerializedSize_(iface_array);
391 EXPECT_EQ(8U // array header
392 + (8U * 1), // Interface_Data * number of elements
393 size);
394
395 FixedBufferForTesting buf(size * 3);
396 Array_Data<mojo::internal::Interface_Data>* output = nullptr;
397
398 // 1. Invalid InterfacePtr should fail serialization.
399 ArrayValidateParams validate_non_nullable(1, false, nullptr);
400 EXPECT_EQ(
401 mojo::internal::ValidationError::UNEXPECTED_INVALID_HANDLE,
402 SerializeArray_(&iface_array, &buf, &output, &validate_non_nullable));
403 EXPECT_FALSE(iface_array[0].is_valid());
404
405 // 2. Invalid InterfacePtr should pass if array elements are nullable.
406 ArrayValidateParams validate_nullable(1, true, nullptr);
407 EXPECT_EQ(mojo::internal::ValidationError::NONE,
408 SerializeArray_(&iface_array, &buf, &output, &validate_nullable));
409 EXPECT_FALSE(iface_array[0].is_valid());
410
411 // 3. Should serialize successfully if InterfacePtr is valid.
412 TestInterfacePtr iface_ptr;
413 auto iface_req = GetProxy(&iface_ptr);
414
415 iface_array[0] = iface_ptr.Pass();
416 EXPECT_TRUE(iface_array[0].is_valid());
417
418 EXPECT_EQ(
419 mojo::internal::ValidationError::NONE,
420 SerializeArray_(&iface_array, &buf, &output, &validate_non_nullable));
421 EXPECT_FALSE(iface_array[0].is_valid());
422
423 Deserialize_(output, &iface_array);
424 EXPECT_TRUE(iface_array[0].is_valid());
425 }
426
427 // Test serializing and deserializing a struct with an Array<> of another struct
428 // which has an InterfacePtr.
429 TEST(ArrayTest, Serialization_StructWithArrayOfInterfacePtr) {
430 StructWithInterfaceArray struct_arr_iface;
431 struct_arr_iface.structs_array = Array<StructWithInterfacePtr>::New(1);
432 struct_arr_iface.nullable_structs_array =
433 Array<StructWithInterfacePtr>::New(1);
434
435 size_t size = GetSerializedSize_(struct_arr_iface);
436 EXPECT_EQ(8U // struct header
437 + 8U // offset to |structs_array|
438 + (8U // array header
439 + 8U) // offset to StructWithInterface (nullptr)
440 + 8U // offset to |structs_nullable_array|
441 + 8U // offset to |nullable_structs_array|
442 + (8U // array header
443 + 8U) // offset to StructWithinInterface (nullptr)
444 + 8U, // offset to |nullable_structs_nullable_array|
445 size);
446
447 FixedBufferForTesting buf(size * 2);
448 StructWithInterfaceArray::Data_* struct_arr_iface_data = nullptr;
449 // 1. This should fail because |structs_array| has an invalid InterfacePtr<>
450 // and it is not nullable.
451 EXPECT_EQ(mojo::internal::ValidationError::UNEXPECTED_NULL_POINTER,
452 Serialize_(&struct_arr_iface, &buf, &struct_arr_iface_data));
453
454 // 2. Adding in a struct with a valid InterfacePtr<> will let it serialize.
455 TestInterfacePtr iface_ptr;
456 auto iface_req = GetProxy(&iface_ptr);
457
458 StructWithInterfacePtr iface_struct(StructWithInterface::New());
459 iface_struct->iptr = iface_ptr.Pass();
460
461 struct_arr_iface.structs_array[0] = iface_struct.Pass();
462 ASSERT_TRUE(struct_arr_iface.structs_array[0]->iptr.is_valid());
463 EXPECT_EQ(mojo::internal::ValidationError::NONE,
464 Serialize_(&struct_arr_iface, &buf, &struct_arr_iface_data));
465
466 EXPECT_FALSE(struct_arr_iface.structs_array[0]->iptr.is_valid());
467
468 Deserialize_(struct_arr_iface_data, &struct_arr_iface);
469 EXPECT_TRUE(struct_arr_iface.structs_array[0]->iptr.is_valid());
470 }
471
472 // Test serializing and deserializing a struct with an Array<> of interface
473 // requests.
474 TEST(ArrayTest, Serialization_StructWithArrayOfIntefaceRequest) {
475 StructWithInterfaceRequests struct_arr_iface_req;
476 struct_arr_iface_req.req_array =
477 Array<InterfaceRequest<TestInterface>>::New(1);
478 struct_arr_iface_req.nullable_req_array =
479 Array<InterfaceRequest<TestInterface>>::New(1);
480
481 size_t size = GetSerializedSize_(struct_arr_iface_req);
482 EXPECT_EQ(8U // struct header
483 + 8U // offset to |req_array|
484 + (8U // array header for |req_array|
485 + 4U // InterfaceRequest
486 + 4U) // alignment padding
487 + 8U // offset to |req_nullable_array|
488 + 8U // offset to |nullable_req_array|
489 + (8U // array header for |nullable_req_array|
490 + 4U // InterfaceRequest
491 + 4U) // alignment padding
492 + 8U, // offset to |nullable_req_nullable_array|
493 size);
494
495 FixedBufferForTesting buf(size * 2);
496 StructWithInterfaceRequests::Data_* struct_arr_iface_req_data;
497 // 1. This should fail because |req_array| has an invalid InterfaceRequest<>
498 // and it is not nullable.
499 EXPECT_EQ(
500 mojo::internal::ValidationError::UNEXPECTED_INVALID_HANDLE,
501 Serialize_(&struct_arr_iface_req, &buf, &struct_arr_iface_req_data));
502
503 // 2. Adding in a valid InterfacePtr<> will let it serialize.
504 TestInterfacePtr iface_ptr;
505 struct_arr_iface_req.req_array[0] = GetProxy(&iface_ptr);
506 EXPECT_TRUE(struct_arr_iface_req.req_array[0].is_pending());
507
508 EXPECT_EQ(
509 mojo::internal::ValidationError::NONE,
510 Serialize_(&struct_arr_iface_req, &buf, &struct_arr_iface_req_data));
511
512 EXPECT_FALSE(struct_arr_iface_req.req_array[0].is_pending());
513
514 Deserialize_(struct_arr_iface_req_data, &struct_arr_iface_req);
515 EXPECT_TRUE(struct_arr_iface_req.req_array[0].is_pending());
516 }
517
518 TEST(ArrayTest, Resize_Copyable) {
519 ASSERT_EQ(0u, CopyableType::num_instances());
520 auto array = mojo::Array<CopyableType>::New(3);
521 std::vector<CopyableType*> value_ptrs;
522 value_ptrs.push_back(array[0].ptr());
523 value_ptrs.push_back(array[1].ptr());
524
525 for (size_t i = 0; i < array.size(); i++)
526 array[i].ResetCopied();
527
528 array.resize(2);
529 ASSERT_EQ(2u, array.size());
530 EXPECT_EQ(array.size(), CopyableType::num_instances());
531 for (size_t i = 0; i < array.size(); i++) {
532 EXPECT_FALSE(array[i].copied());
533 EXPECT_EQ(value_ptrs[i], array[i].ptr());
534 }
535
536 array.resize(3);
537 array[2].ResetCopied();
538 ASSERT_EQ(3u, array.size());
539 EXPECT_EQ(array.size(), CopyableType::num_instances());
540 for (size_t i = 0; i < array.size(); i++)
541 EXPECT_FALSE(array[i].copied());
542 value_ptrs.push_back(array[2].ptr());
543
544 size_t capacity = array.storage().capacity();
545 array.resize(capacity);
546 ASSERT_EQ(capacity, array.size());
547 EXPECT_EQ(array.size(), CopyableType::num_instances());
548 for (size_t i = 0; i < 3; i++)
549 EXPECT_FALSE(array[i].copied());
550 for (size_t i = 3; i < array.size(); i++) {
551 array[i].ResetCopied();
552 value_ptrs.push_back(array[i].ptr());
553 }
554
555 array.resize(capacity + 2);
556 ASSERT_EQ(capacity + 2, array.size());
557 EXPECT_EQ(array.size(), CopyableType::num_instances());
558 for (size_t i = 0; i < capacity; i++) {
559 EXPECT_TRUE(array[i].copied());
560 EXPECT_EQ(value_ptrs[i], array[i].ptr());
561 }
562 array.reset();
563 EXPECT_EQ(0u, CopyableType::num_instances());
564 EXPECT_FALSE(array);
565 array.resize(0);
566 EXPECT_EQ(0u, CopyableType::num_instances());
567 EXPECT_TRUE(array);
568 }
569
570 TEST(ArrayTest, Resize_MoveOnly) {
571 ASSERT_EQ(0u, MoveOnlyType::num_instances());
572 auto array = mojo::Array<MoveOnlyType>::New(3);
573 std::vector<MoveOnlyType*> value_ptrs;
574 value_ptrs.push_back(array[0].ptr());
575 value_ptrs.push_back(array[1].ptr());
576
577 for (size_t i = 0; i < array.size(); i++)
578 EXPECT_FALSE(array[i].moved());
579
580 array.resize(2);
581 ASSERT_EQ(2u, array.size());
582 EXPECT_EQ(array.size(), MoveOnlyType::num_instances());
583 for (size_t i = 0; i < array.size(); i++) {
584 EXPECT_FALSE(array[i].moved());
585 EXPECT_EQ(value_ptrs[i], array[i].ptr());
586 }
587
588 array.resize(3);
589 ASSERT_EQ(3u, array.size());
590 EXPECT_EQ(array.size(), MoveOnlyType::num_instances());
591 for (size_t i = 0; i < array.size(); i++)
592 EXPECT_FALSE(array[i].moved());
593 value_ptrs.push_back(array[2].ptr());
594
595 size_t capacity = array.storage().capacity();
596 array.resize(capacity);
597 ASSERT_EQ(capacity, array.size());
598 EXPECT_EQ(array.size(), MoveOnlyType::num_instances());
599 for (size_t i = 0; i < array.size(); i++)
600 EXPECT_FALSE(array[i].moved());
601 for (size_t i = 3; i < array.size(); i++)
602 value_ptrs.push_back(array[i].ptr());
603
604 array.resize(capacity + 2);
605 ASSERT_EQ(capacity + 2, array.size());
606 EXPECT_EQ(array.size(), MoveOnlyType::num_instances());
607 for (size_t i = 0; i < capacity; i++) {
608 EXPECT_TRUE(array[i].moved());
609 EXPECT_EQ(value_ptrs[i], array[i].ptr());
610 }
611 for (size_t i = capacity; i < array.size(); i++)
612 EXPECT_FALSE(array[i].moved());
613
614 array.reset();
615 EXPECT_EQ(0u, MoveOnlyType::num_instances());
616 EXPECT_FALSE(array);
617 array.resize(0);
618 EXPECT_EQ(0u, MoveOnlyType::num_instances());
619 EXPECT_TRUE(array);
620 }
621
622 TEST(ArrayTest, PushBack_Copyable) {
623 ASSERT_EQ(0u, CopyableType::num_instances());
624 auto array = mojo::Array<CopyableType>::New(2);
625 array.reset();
626 std::vector<CopyableType*> value_ptrs;
627 size_t capacity = array.storage().capacity();
628 for (size_t i = 0; i < capacity; i++) {
629 CopyableType value;
630 value_ptrs.push_back(value.ptr());
631 array.push_back(value);
632 ASSERT_EQ(i + 1, array.size());
633 ASSERT_EQ(i + 1, value_ptrs.size());
634 EXPECT_EQ(array.size() + 1, CopyableType::num_instances());
635 EXPECT_TRUE(array[i].copied());
636 EXPECT_EQ(value_ptrs[i], array[i].ptr());
637 array[i].ResetCopied();
638 EXPECT_TRUE(array);
639 }
640 {
641 CopyableType value;
642 value_ptrs.push_back(value.ptr());
643 array.push_back(value);
644 EXPECT_EQ(array.size() + 1, CopyableType::num_instances());
645 }
646 ASSERT_EQ(capacity + 1, array.size());
647 EXPECT_EQ(array.size(), CopyableType::num_instances());
648
649 for (size_t i = 0; i < array.size(); i++) {
650 EXPECT_TRUE(array[i].copied());
651 EXPECT_EQ(value_ptrs[i], array[i].ptr());
652 }
653 array.reset();
654 EXPECT_EQ(0u, CopyableType::num_instances());
655 }
656
657 TEST(ArrayTest, PushBack_MoveOnly) {
658 ASSERT_EQ(0u, MoveOnlyType::num_instances());
659 auto array = mojo::Array<MoveOnlyType>::New(2);
660 array.reset();
661 std::vector<MoveOnlyType*> value_ptrs;
662 size_t capacity = array.storage().capacity();
663 for (size_t i = 0; i < capacity; i++) {
664 MoveOnlyType value;
665 value_ptrs.push_back(value.ptr());
666 array.push_back(value.Pass());
667 ASSERT_EQ(i + 1, array.size());
668 ASSERT_EQ(i + 1, value_ptrs.size());
669 EXPECT_EQ(array.size() + 1, MoveOnlyType::num_instances());
670 EXPECT_TRUE(array[i].moved());
671 EXPECT_EQ(value_ptrs[i], array[i].ptr());
672 array[i].ResetMoved();
673 EXPECT_TRUE(array);
674 }
675 {
676 MoveOnlyType value;
677 value_ptrs.push_back(value.ptr());
678 array.push_back(value.Pass());
679 EXPECT_EQ(array.size() + 1, MoveOnlyType::num_instances());
680 }
681 ASSERT_EQ(capacity + 1, array.size());
682 EXPECT_EQ(array.size(), MoveOnlyType::num_instances());
683
684 for (size_t i = 0; i < array.size(); i++) {
685 EXPECT_TRUE(array[i].moved());
686 EXPECT_EQ(value_ptrs[i], array[i].ptr());
687 }
688 array.reset();
689 EXPECT_EQ(0u, MoveOnlyType::num_instances());
690 }
691
692 TEST(ArrayTest, Iterator) {
693 std::vector<int> values;
694 values.push_back(0);
695 values.push_back(1);
696 values.push_back(2);
697 values.push_back(3);
698 Array<int> arr = Array<int>::From(values);
699
700 // Test RandomAcessIterator traits.
701 {
702 // Test +,-,+=,-=.
703 auto i1 = arr.begin();
704 i1 += 2;
705 EXPECT_EQ(*i1, values[2]);
706 i1 -= 2;
707 EXPECT_EQ(*i1, values[0]);
708 EXPECT_EQ((i1 + 2)[1], values[3]);
709
710 auto i2 = arr.begin() + 3;
711 EXPECT_EQ(*i2, values[3]);
712 EXPECT_EQ(*(i2 - 2), values[1]);
713 EXPECT_EQ(i2 - i1, 3);
714
715 {
716 auto j1 = arr.begin();
717 auto j1_cp = arr.begin();
718 j1 += 1;
719 j1_cp++;
720 EXPECT_EQ(j1, j1_cp);
721
722 j1 -= 1;
723 j1_cp--;
724 EXPECT_EQ(j1, j1_cp);
725 }
726
727 // Test >, <, >=, <=.
728 EXPECT_GT(i2, i1);
729 EXPECT_LT(i1, i2);
730 EXPECT_GE(i2, i1);
731 EXPECT_LE(i1, i2);
732 }
733
734 {
735 SCOPED_TRACE("Array iterator bidirectionality test.");
736 ExpectBidiIteratorConcept(arr.begin(), arr.end(), values);
737 ExpectBidiMutableIteratorConcept(arr.begin(), arr.end(), values);
738 }
739 }
740
741 // Test serializing and deserializing of an array with null elements.
742 TEST(ArrayTest, Serialization_ArrayOfStructPtr) {
743 ArrayValidateParams validate_nullable(2, true, nullptr);
744 ArrayValidateParams validate_non_nullable(2, false, nullptr);
745
746 Array<RectPtr> array = Array<RectPtr>::New(2);
747 array[1] = Rect::New();
748 array[1]->x = 1;
749 array[1]->y = 2;
750 array[1]->width = 3;
751 array[1]->height = 4;
752
753 size_t size_with_null = GetSerializedSize_(array);
754 EXPECT_EQ(8U + // array header
755 2 * 8U + // array payload (2 pointers)
756 8U + 4 * 4U, // struct header + contents (4 int32)
757 size_with_null);
758 Array_Data<Rect::Data_*>* output_with_null = nullptr;
759
760 // 1. Array with non-nullable structs should fail serialization due to
761 // the null first element.
762 {
763 FixedBufferForTesting buf_with_null(size_with_null);
764 EXPECT_EQ(mojo::internal::ValidationError::UNEXPECTED_NULL_POINTER,
765 SerializeArray_(&array, &buf_with_null, &output_with_null,
766 &validate_non_nullable));
767 }
768
769 // 2. Array with nullable structs should succeed.
770 {
771 FixedBufferForTesting buf_with_null(size_with_null);
772 EXPECT_EQ(mojo::internal::ValidationError::NONE,
773 SerializeArray_(&array, &buf_with_null, &output_with_null,
774 &validate_nullable));
775
776 Array<RectPtr> array2;
777 Deserialize_(output_with_null, &array2);
778 EXPECT_TRUE(array2[0].is_null());
779 EXPECT_FALSE(array2[1].is_null());
780 EXPECT_EQ(1, array2[1]->x);
781 EXPECT_EQ(2, array2[1]->y);
782 EXPECT_EQ(3, array2[1]->width);
783 EXPECT_EQ(4, array2[1]->height);
784 }
785
786 // 3. Array with non-nullable structs should succeed after we fill in
787 // the missing first element.
788 {
789 array[0] = Rect::New();
790 array[0]->x = -1;
791 array[0]->y = -2;
792 array[0]->width = -3;
793 array[0]->height = -4;
794
795 size_t size_without_null = GetSerializedSize_(array);
796 EXPECT_EQ(8U + // array header
797 2 * 8U + // array payload (2 pointers)
798 2 * (8U + 4 * 4U), // struct header + contents (4 int32)
799 size_without_null);
800
801 FixedBufferForTesting buf_without_null(size_without_null);
802 Array_Data<Rect::Data_*>* output_without_null = nullptr;
803 EXPECT_EQ(mojo::internal::ValidationError::NONE,
804 SerializeArray_(&array, &buf_without_null, &output_without_null,
805 &validate_non_nullable));
806
807 Array<RectPtr> array3;
808 Deserialize_(output_without_null, &array3);
809 EXPECT_FALSE(array3[0].is_null());
810 EXPECT_EQ(-1, array3[0]->x);
811 EXPECT_EQ(-2, array3[0]->y);
812 EXPECT_EQ(-3, array3[0]->width);
813 EXPECT_EQ(-4, array3[0]->height);
814 EXPECT_FALSE(array3[1].is_null());
815 EXPECT_EQ(1, array3[1]->x);
816 EXPECT_EQ(2, array3[1]->y);
817 EXPECT_EQ(3, array3[1]->width);
818 EXPECT_EQ(4, array3[1]->height);
819 }
820 }
821
822 } // namespace
823 } // namespace test
824 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/tests/BUILD.gn ('k') | mojo/public/cpp/bindings/tests/binding_callback_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698