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