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