OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "mojo/public/cpp/bindings/array.h" | 5 #include "mojo/public/cpp/bindings/array.h" |
| 6 #include "mojo/public/cpp/bindings/lib/array_internal.h" |
6 #include "mojo/public/cpp/bindings/lib/array_serialization.h" | 7 #include "mojo/public/cpp/bindings/lib/array_serialization.h" |
7 #include "mojo/public/cpp/bindings/lib/fixed_buffer.h" | 8 #include "mojo/public/cpp/bindings/lib/fixed_buffer.h" |
8 #include "mojo/public/cpp/environment/environment.h" | 9 #include "mojo/public/cpp/environment/environment.h" |
9 #include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h" | |
10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
11 | 11 |
12 namespace mojo { | 12 namespace mojo { |
13 namespace test { | 13 namespace test { |
14 namespace { | 14 namespace { |
15 | 15 |
16 class CopyableType { | 16 class CopyableType { |
17 public: | 17 public: |
18 CopyableType() : copied_(false), ptr_(this) { num_instances_++; } | 18 CopyableType() : copied_(false), ptr_(this) { num_instances_++; } |
19 CopyableType(const CopyableType& other) : copied_(true), ptr_(other.ptr()) { | 19 CopyableType(const CopyableType& other) : copied_(true), ptr_(other.ptr()) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 void ResetMoved() { moved_ = false; } | 60 void ResetMoved() { moved_ = false; } |
61 | 61 |
62 private: | 62 private: |
63 bool moved_; | 63 bool moved_; |
64 static size_t num_instances_; | 64 static size_t num_instances_; |
65 MoveOnlyType* ptr_; | 65 MoveOnlyType* ptr_; |
66 }; | 66 }; |
67 | 67 |
68 size_t MoveOnlyType::num_instances_ = 0; | 68 size_t MoveOnlyType::num_instances_ = 0; |
69 | 69 |
| 70 class ArrayTest : public testing::Test { |
| 71 public: |
| 72 virtual ~ArrayTest() {} |
| 73 |
| 74 private: |
| 75 Environment env_; |
| 76 }; |
| 77 |
70 // Tests that basic Array operations work. | 78 // Tests that basic Array operations work. |
71 TEST(ArrayTest, Basic) { | 79 TEST_F(ArrayTest, Basic) { |
72 Array<char> array(8); | 80 Array<char> array(8); |
73 for (size_t i = 0; i < array.size(); ++i) { | 81 for (size_t i = 0; i < array.size(); ++i) { |
74 char val = static_cast<char>(i*2); | 82 char val = static_cast<char>(i*2); |
75 array[i] = val; | 83 array[i] = val; |
76 EXPECT_EQ(val, array.at(i)); | 84 EXPECT_EQ(val, array.at(i)); |
77 } | 85 } |
78 } | 86 } |
79 | 87 |
80 // Tests that basic Array<bool> operations work. | 88 // Tests that basic Array<bool> operations work. |
81 TEST(ArrayTest, Bool) { | 89 TEST_F(ArrayTest, Bool) { |
82 Array<bool> array(64); | 90 Array<bool> array(64); |
83 for (size_t i = 0; i < array.size(); ++i) { | 91 for (size_t i = 0; i < array.size(); ++i) { |
84 bool val = i % 3 == 0; | 92 bool val = i % 3 == 0; |
85 array[i] = val; | 93 array[i] = val; |
86 EXPECT_EQ(val, array.at(i)); | 94 EXPECT_EQ(val, array.at(i)); |
87 } | 95 } |
88 } | 96 } |
89 | 97 |
90 // Tests that Array<ScopedMessagePipeHandle> supports transferring handles. | 98 // Tests that Array<ScopedMessagePipeHandle> supports transferring handles. |
91 TEST(ArrayTest, Handle) { | 99 TEST_F(ArrayTest, Handle) { |
92 MessagePipe pipe; | 100 MessagePipe pipe; |
93 Array<ScopedMessagePipeHandle> handles(2); | 101 Array<ScopedMessagePipeHandle> handles(2); |
94 handles[0] = pipe.handle0.Pass(); | 102 handles[0] = pipe.handle0.Pass(); |
95 handles[1].reset(pipe.handle1.release()); | 103 handles[1].reset(pipe.handle1.release()); |
96 | 104 |
97 EXPECT_FALSE(pipe.handle0.is_valid()); | 105 EXPECT_FALSE(pipe.handle0.is_valid()); |
98 EXPECT_FALSE(pipe.handle1.is_valid()); | 106 EXPECT_FALSE(pipe.handle1.is_valid()); |
99 | 107 |
100 Array<ScopedMessagePipeHandle> handles2 = handles.Pass(); | 108 Array<ScopedMessagePipeHandle> handles2 = handles.Pass(); |
101 EXPECT_TRUE(handles2[0].is_valid()); | 109 EXPECT_TRUE(handles2[0].is_valid()); |
102 EXPECT_TRUE(handles2[1].is_valid()); | 110 EXPECT_TRUE(handles2[1].is_valid()); |
103 | 111 |
104 ScopedMessagePipeHandle pipe_handle = handles2[0].Pass(); | 112 ScopedMessagePipeHandle pipe_handle = handles2[0].Pass(); |
105 EXPECT_TRUE(pipe_handle.is_valid()); | 113 EXPECT_TRUE(pipe_handle.is_valid()); |
106 EXPECT_FALSE(handles2[0].is_valid()); | 114 EXPECT_FALSE(handles2[0].is_valid()); |
107 } | 115 } |
108 | 116 |
109 // Tests that Array<ScopedMessagePipeHandle> supports closing handles. | 117 // Tests that Array<ScopedMessagePipeHandle> supports closing handles. |
110 TEST(ArrayTest, HandlesAreClosed) { | 118 TEST_F(ArrayTest, HandlesAreClosed) { |
111 MessagePipe pipe; | 119 MessagePipe pipe; |
112 MojoHandle pipe0_value = pipe.handle0.get().value(); | 120 MojoHandle pipe0_value = pipe.handle0.get().value(); |
113 MojoHandle pipe1_value = pipe.handle0.get().value(); | 121 MojoHandle pipe1_value = pipe.handle0.get().value(); |
114 | 122 |
115 { | 123 { |
116 Array<ScopedMessagePipeHandle> handles(2); | 124 Array<ScopedMessagePipeHandle> handles(2); |
117 handles[0] = pipe.handle0.Pass(); | 125 handles[0] = pipe.handle0.Pass(); |
118 handles[1].reset(pipe.handle0.release()); | 126 handles[1].reset(pipe.handle0.release()); |
119 } | 127 } |
120 | 128 |
121 // We expect the pipes to have been closed. | 129 // We expect the pipes to have been closed. |
122 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe0_value)); | 130 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe0_value)); |
123 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe1_value)); | 131 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe1_value)); |
124 } | 132 } |
125 | 133 |
126 TEST(ArrayTest, Serialization_ArrayOfPOD) { | 134 TEST_F(ArrayTest, Serialization_ArrayOfPOD) { |
127 Array<int32_t> array(4); | 135 Array<int32_t> array(4); |
128 for (size_t i = 0; i < array.size(); ++i) | 136 for (size_t i = 0; i < array.size(); ++i) |
129 array[i] = static_cast<int32_t>(i); | 137 array[i] = static_cast<int32_t>(i); |
130 | 138 |
131 size_t size = GetSerializedSize_(array); | 139 size_t size = GetSerializedSize_(array); |
132 EXPECT_EQ(8U + 4*4U, size); | 140 EXPECT_EQ(8U + 4*4U, size); |
133 | 141 |
134 internal::FixedBuffer buf(size); | 142 internal::FixedBuffer buf(size); |
135 internal::Array_Data<int32_t>* data; | 143 internal::Array_Data<int32_t>* data; |
136 Serialize_(array.Pass(), &buf, &data); | 144 SerializeArray_<internal::ArrayValidateParams<0, false, |
| 145 internal::NoValidateParams> >( |
| 146 array.Pass(), &buf, &data); |
137 | 147 |
138 Array<int32_t> array2; | 148 Array<int32_t> array2; |
139 Deserialize_(data, &array2); | 149 Deserialize_(data, &array2); |
140 | 150 |
141 EXPECT_EQ(4U, array2.size()); | 151 EXPECT_EQ(4U, array2.size()); |
142 for (size_t i = 0; i < array2.size(); ++i) | 152 for (size_t i = 0; i < array2.size(); ++i) |
143 EXPECT_EQ(static_cast<int32_t>(i), array2[i]); | 153 EXPECT_EQ(static_cast<int32_t>(i), array2[i]); |
144 } | 154 } |
145 | 155 |
146 TEST(ArrayTest, Serialization_ArrayOfArrayOfPOD) { | 156 TEST_F(ArrayTest, Serialization_ArrayOfArrayOfPOD) { |
147 Array<Array<int32_t> > array(2); | 157 Array<Array<int32_t> > array(2); |
148 for (size_t j = 0; j < array.size(); ++j) { | 158 for (size_t j = 0; j < array.size(); ++j) { |
149 Array<int32_t> inner(4); | 159 Array<int32_t> inner(4); |
150 for (size_t i = 0; i < inner.size(); ++i) | 160 for (size_t i = 0; i < inner.size(); ++i) |
151 inner[i] = static_cast<int32_t>(i + (j * 10)); | 161 inner[i] = static_cast<int32_t>(i + (j * 10)); |
152 array[j] = inner.Pass(); | 162 array[j] = inner.Pass(); |
153 } | 163 } |
154 | 164 |
155 size_t size = GetSerializedSize_(array); | 165 size_t size = GetSerializedSize_(array); |
156 EXPECT_EQ(8U + 2*8U + 2*(8U + 4*4U), size); | 166 EXPECT_EQ(8U + 2*8U + 2*(8U + 4*4U), size); |
157 | 167 |
158 internal::FixedBuffer buf(size); | 168 internal::FixedBuffer buf(size); |
159 internal::Array_Data<internal::Array_Data<int32_t>*>* data; | 169 internal::Array_Data<internal::Array_Data<int32_t>*>* data; |
160 Serialize_(array.Pass(), &buf, &data); | 170 SerializeArray_<internal::ArrayValidateParams<0, false, |
| 171 internal::ArrayValidateParams<0, false, |
| 172 internal::NoValidateParams> > >( |
| 173 array.Pass(), &buf, &data); |
161 | 174 |
162 Array<Array<int32_t> > array2; | 175 Array<Array<int32_t> > array2; |
163 Deserialize_(data, &array2); | 176 Deserialize_(data, &array2); |
164 | 177 |
165 EXPECT_EQ(2U, array2.size()); | 178 EXPECT_EQ(2U, array2.size()); |
166 for (size_t j = 0; j < array2.size(); ++j) { | 179 for (size_t j = 0; j < array2.size(); ++j) { |
167 const Array<int32_t>& inner = array2[j]; | 180 const Array<int32_t>& inner = array2[j]; |
168 EXPECT_EQ(4U, inner.size()); | 181 EXPECT_EQ(4U, inner.size()); |
169 for (size_t i = 0; i < inner.size(); ++i) | 182 for (size_t i = 0; i < inner.size(); ++i) |
170 EXPECT_EQ(static_cast<int32_t>(i + (j * 10)), inner[i]); | 183 EXPECT_EQ(static_cast<int32_t>(i + (j * 10)), inner[i]); |
171 } | 184 } |
172 } | 185 } |
173 | 186 |
174 TEST(ArrayTest, Serialization_ArrayOfBool) { | 187 TEST_F(ArrayTest, Serialization_ArrayOfBool) { |
175 Array<bool> array(10); | 188 Array<bool> array(10); |
176 for (size_t i = 0; i < array.size(); ++i) | 189 for (size_t i = 0; i < array.size(); ++i) |
177 array[i] = i % 2 ? true : false; | 190 array[i] = i % 2 ? true : false; |
178 | 191 |
179 size_t size = GetSerializedSize_(array); | 192 size_t size = GetSerializedSize_(array); |
180 EXPECT_EQ(8U + 8U, size); | 193 EXPECT_EQ(8U + 8U, size); |
181 | 194 |
182 internal::FixedBuffer buf(size); | 195 internal::FixedBuffer buf(size); |
183 internal::Array_Data<bool>* data; | 196 internal::Array_Data<bool>* data; |
184 Serialize_(array.Pass(), &buf, &data); | 197 SerializeArray_<internal::ArrayValidateParams<0, false, |
| 198 internal::NoValidateParams> >( |
| 199 array.Pass(), &buf, &data); |
185 | 200 |
186 Array<bool> array2; | 201 Array<bool> array2; |
187 Deserialize_(data, &array2); | 202 Deserialize_(data, &array2); |
188 | 203 |
189 EXPECT_EQ(10U, array2.size()); | 204 EXPECT_EQ(10U, array2.size()); |
190 for (size_t i = 0; i < array2.size(); ++i) | 205 for (size_t i = 0; i < array2.size(); ++i) |
191 EXPECT_EQ(i % 2 ? true : false, array2[i]); | 206 EXPECT_EQ(i % 2 ? true : false, array2[i]); |
192 } | 207 } |
193 | 208 |
194 TEST(ArrayTest, Serialization_ArrayOfString) { | 209 TEST_F(ArrayTest, Serialization_ArrayOfString) { |
195 Array<String> array(10); | 210 Array<String> array(10); |
196 for (size_t i = 0; i < array.size(); ++i) { | 211 for (size_t i = 0; i < array.size(); ++i) { |
197 char c = 'A' + 1; | 212 char c = 'A' + static_cast<char>(i); |
198 array[i] = String(&c, 1); | 213 array[i] = String(&c, 1); |
199 } | 214 } |
200 | 215 |
201 size_t size = GetSerializedSize_(array); | 216 size_t size = GetSerializedSize_(array); |
202 EXPECT_EQ(8U + // array header | 217 EXPECT_EQ(8U + // array header |
203 10*8U + // array payload (10 pointers) | 218 10*8U + // array payload (10 pointers) |
204 10*(8U + // string header | 219 10*(8U + // string header |
205 8U), // string length of 1 padded to 8 | 220 8U), // string length of 1 padded to 8 |
206 size); | 221 size); |
207 | 222 |
208 internal::FixedBuffer buf(size); | 223 internal::FixedBuffer buf(size); |
209 internal::Array_Data<internal::String_Data*>* data; | 224 internal::Array_Data<internal::String_Data*>* data; |
210 Serialize_(array.Pass(), &buf, &data); | 225 SerializeArray_<internal::ArrayValidateParams<0, false, |
| 226 internal::ArrayValidateParams<0, false, |
| 227 internal::NoValidateParams> > >( |
| 228 array.Pass(), &buf, &data); |
211 | 229 |
212 Array<String> array2; | 230 Array<String> array2; |
213 Deserialize_(data, &array2); | 231 Deserialize_(data, &array2); |
214 | 232 |
215 EXPECT_EQ(10U, array2.size()); | 233 EXPECT_EQ(10U, array2.size()); |
216 for (size_t i = 0; i < array2.size(); ++i) { | 234 for (size_t i = 0; i < array2.size(); ++i) { |
217 char c = 'A' + 1; | 235 char c = 'A' + static_cast<char>(i); |
218 EXPECT_EQ(String(&c, 1), array2[i]); | 236 EXPECT_EQ(String(&c, 1), array2[i]); |
219 } | 237 } |
220 } | 238 } |
221 | 239 |
222 TEST(ArrayTest, Resize_Copyable) { | 240 TEST_F(ArrayTest, Resize_Copyable) { |
223 ASSERT_EQ(0u, CopyableType::num_instances()); | 241 ASSERT_EQ(0u, CopyableType::num_instances()); |
224 mojo::Array<CopyableType> array(3); | 242 mojo::Array<CopyableType> array(3); |
225 std::vector<CopyableType*> value_ptrs; | 243 std::vector<CopyableType*> value_ptrs; |
226 value_ptrs.push_back(array[0].ptr()); | 244 value_ptrs.push_back(array[0].ptr()); |
227 value_ptrs.push_back(array[1].ptr()); | 245 value_ptrs.push_back(array[1].ptr()); |
228 | 246 |
229 for (size_t i = 0; i < array.size(); i++) | 247 for (size_t i = 0; i < array.size(); i++) |
230 array[i].ResetCopied(); | 248 array[i].ResetCopied(); |
231 | 249 |
232 array.resize(2); | 250 array.resize(2); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 EXPECT_EQ(value_ptrs[i], array[i].ptr()); | 282 EXPECT_EQ(value_ptrs[i], array[i].ptr()); |
265 } | 283 } |
266 array.reset(); | 284 array.reset(); |
267 EXPECT_EQ(0u, CopyableType::num_instances()); | 285 EXPECT_EQ(0u, CopyableType::num_instances()); |
268 EXPECT_FALSE(array); | 286 EXPECT_FALSE(array); |
269 array.resize(0); | 287 array.resize(0); |
270 EXPECT_EQ(0u, CopyableType::num_instances()); | 288 EXPECT_EQ(0u, CopyableType::num_instances()); |
271 EXPECT_TRUE(array); | 289 EXPECT_TRUE(array); |
272 } | 290 } |
273 | 291 |
274 TEST(ArrayTest, Resize_MoveOnly) { | 292 TEST_F(ArrayTest, Resize_MoveOnly) { |
275 ASSERT_EQ(0u, MoveOnlyType::num_instances()); | 293 ASSERT_EQ(0u, MoveOnlyType::num_instances()); |
276 mojo::Array<MoveOnlyType> array(3); | 294 mojo::Array<MoveOnlyType> array(3); |
277 std::vector<MoveOnlyType*> value_ptrs; | 295 std::vector<MoveOnlyType*> value_ptrs; |
278 value_ptrs.push_back(array[0].ptr()); | 296 value_ptrs.push_back(array[0].ptr()); |
279 value_ptrs.push_back(array[1].ptr()); | 297 value_ptrs.push_back(array[1].ptr()); |
280 | 298 |
281 for (size_t i = 0; i < array.size(); i++) | 299 for (size_t i = 0; i < array.size(); i++) |
282 EXPECT_FALSE(array[i].moved()); | 300 EXPECT_FALSE(array[i].moved()); |
283 | 301 |
284 array.resize(2); | 302 array.resize(2); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 EXPECT_FALSE(array[i].moved()); | 334 EXPECT_FALSE(array[i].moved()); |
317 | 335 |
318 array.reset(); | 336 array.reset(); |
319 EXPECT_EQ(0u, MoveOnlyType::num_instances()); | 337 EXPECT_EQ(0u, MoveOnlyType::num_instances()); |
320 EXPECT_FALSE(array); | 338 EXPECT_FALSE(array); |
321 array.resize(0); | 339 array.resize(0); |
322 EXPECT_EQ(0u, MoveOnlyType::num_instances()); | 340 EXPECT_EQ(0u, MoveOnlyType::num_instances()); |
323 EXPECT_TRUE(array); | 341 EXPECT_TRUE(array); |
324 } | 342 } |
325 | 343 |
326 TEST(ArrayTest, PushBack_Copyable) { | 344 TEST_F(ArrayTest, PushBack_Copyable) { |
327 ASSERT_EQ(0u, CopyableType::num_instances()); | 345 ASSERT_EQ(0u, CopyableType::num_instances()); |
328 mojo::Array<CopyableType> array(2); | 346 mojo::Array<CopyableType> array(2); |
329 array.reset(); | 347 array.reset(); |
330 std::vector<CopyableType*> value_ptrs; | 348 std::vector<CopyableType*> value_ptrs; |
331 size_t capacity = array.storage().capacity(); | 349 size_t capacity = array.storage().capacity(); |
332 for (size_t i = 0; i < capacity; i++) { | 350 for (size_t i = 0; i < capacity; i++) { |
333 CopyableType value; | 351 CopyableType value; |
334 value_ptrs.push_back(value.ptr()); | 352 value_ptrs.push_back(value.ptr()); |
335 array.push_back(value); | 353 array.push_back(value); |
336 ASSERT_EQ(i + 1, array.size()); | 354 ASSERT_EQ(i + 1, array.size()); |
(...skipping 14 matching lines...) Expand all Loading... |
351 EXPECT_EQ(array.size(), CopyableType::num_instances()); | 369 EXPECT_EQ(array.size(), CopyableType::num_instances()); |
352 | 370 |
353 for (size_t i = 0; i < array.size(); i++) { | 371 for (size_t i = 0; i < array.size(); i++) { |
354 EXPECT_TRUE(array[i].copied()); | 372 EXPECT_TRUE(array[i].copied()); |
355 EXPECT_EQ(value_ptrs[i], array[i].ptr()); | 373 EXPECT_EQ(value_ptrs[i], array[i].ptr()); |
356 } | 374 } |
357 array.reset(); | 375 array.reset(); |
358 EXPECT_EQ(0u, CopyableType::num_instances()); | 376 EXPECT_EQ(0u, CopyableType::num_instances()); |
359 } | 377 } |
360 | 378 |
361 TEST(ArrayTest, PushBack_MoveOnly) { | 379 TEST_F(ArrayTest, PushBack_MoveOnly) { |
362 ASSERT_EQ(0u, MoveOnlyType::num_instances()); | 380 ASSERT_EQ(0u, MoveOnlyType::num_instances()); |
363 mojo::Array<MoveOnlyType> array(2); | 381 mojo::Array<MoveOnlyType> array(2); |
364 array.reset(); | 382 array.reset(); |
365 std::vector<MoveOnlyType*> value_ptrs; | 383 std::vector<MoveOnlyType*> value_ptrs; |
366 size_t capacity = array.storage().capacity(); | 384 size_t capacity = array.storage().capacity(); |
367 for (size_t i = 0; i < capacity; i++) { | 385 for (size_t i = 0; i < capacity; i++) { |
368 MoveOnlyType value; | 386 MoveOnlyType value; |
369 value_ptrs.push_back(value.ptr()); | 387 value_ptrs.push_back(value.ptr()); |
370 array.push_back(value.Pass()); | 388 array.push_back(value.Pass()); |
371 ASSERT_EQ(i + 1, array.size()); | 389 ASSERT_EQ(i + 1, array.size()); |
(...skipping 17 matching lines...) Expand all Loading... |
389 EXPECT_TRUE(array[i].moved()); | 407 EXPECT_TRUE(array[i].moved()); |
390 EXPECT_EQ(value_ptrs[i], array[i].ptr()); | 408 EXPECT_EQ(value_ptrs[i], array[i].ptr()); |
391 } | 409 } |
392 array.reset(); | 410 array.reset(); |
393 EXPECT_EQ(0u, MoveOnlyType::num_instances()); | 411 EXPECT_EQ(0u, MoveOnlyType::num_instances()); |
394 } | 412 } |
395 | 413 |
396 } // namespace | 414 } // namespace |
397 } // namespace test | 415 } // namespace test |
398 } // namespace mojo | 416 } // namespace mojo |
OLD | NEW |