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

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

Issue 611633002: mojom: Add associative arrays to the mojom language. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Moved test classes to their own shared file. Created 6 years, 2 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 "mojo/public/cpp/bindings/array.h"
6 #include "mojo/public/cpp/bindings/lib/array_serialization.h"
7 #include "mojo/public/cpp/bindings/lib/bindings_internal.h"
8 #include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
9 #include "mojo/public/cpp/bindings/map.h"
10 #include "mojo/public/cpp/bindings/string.h"
11 #include "mojo/public/cpp/bindings/struct_ptr.h"
12 #include "mojo/public/cpp/bindings/tests/container_test_util.h"
13 #include "mojo/public/cpp/environment/environment.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace mojo {
17 namespace test {
18
19 namespace {
20
21 struct StringIntData {
22 const char* string_data;
23 int int_data;
24 } kStringIntData[] = {
25 {"one", 1},
26 {"two", 2},
27 {"three", 3},
28 {"four", 4},
29 };
30
31 const size_t kStringIntDataSize = 4;
32
33 class MapTest : public testing::Test {
34 public:
35 virtual ~MapTest() {}
36
37 private:
38 Environment env_;
39 };
40
41 // Tests that basic Map operations work.
42 TEST_F(MapTest, InsertWorks) {
43 Map<String, int> map;
44 for (size_t i = 0; i < kStringIntDataSize; ++i)
45 map.insert(kStringIntData[i].string_data, kStringIntData[i].int_data);
46
47 for (size_t i = 0; i < kStringIntDataSize; ++i) {
48 EXPECT_EQ(kStringIntData[i].int_data,
49 map.at(kStringIntData[i].string_data));
50 }
51 }
52
53 TEST_F(MapTest, ConstructedFromArray) {
54 Array<String> keys(kStringIntDataSize);
55 Array<int> values(kStringIntDataSize);
56 for (size_t i = 0; i < kStringIntDataSize; ++i) {
57 keys[i] = kStringIntData[i].string_data;
58 values[i] = kStringIntData[i].int_data;
59 }
60
61 Map<String, int> map(keys.Pass(), values.Pass());
62
63 for (size_t i = 0; i < kStringIntDataSize; ++i) {
64 EXPECT_EQ(kStringIntData[i].int_data,
65 map.at(mojo::String(kStringIntData[i].string_data)));
66 }
67 }
68
69 TEST_F(MapTest, DecomposeMapTo) {
70 Array<String> keys(kStringIntDataSize);
71 Array<int> values(kStringIntDataSize);
72 for (size_t i = 0; i < kStringIntDataSize; ++i) {
73 keys[i] = kStringIntData[i].string_data;
74 values[i] = kStringIntData[i].int_data;
75 }
76
77 Map<String, int> map(keys.Pass(), values.Pass());
78 EXPECT_EQ(kStringIntDataSize, map.size());
79
80 Array<String> keys2;
81 Array<int> values2;
82 map.DecomposeMapTo(&keys2, &values2);
83 EXPECT_EQ(0u, map.size());
84
85 EXPECT_EQ(kStringIntDataSize, keys2.size());
86 EXPECT_EQ(kStringIntDataSize, values2.size());
87
88 for (size_t i = 0; i < kStringIntDataSize; ++i) {
89 // We are not guaranteed that the copies have the same sorting as the
90 // originals.
91 String key = kStringIntData[i].string_data;
92 int value = kStringIntData[i].int_data;
93
94 bool found = false;
95 for (size_t j = 0; j < keys2.size(); ++j) {
96 if (keys2[j] == key) {
97 EXPECT_EQ(value, values2[j]);
98 found = true;
99 break;
100 }
101 }
102
103 EXPECT_TRUE(found);
104 }
105 }
106
107 TEST_F(MapTest, Insert_Copyable) {
108 ASSERT_EQ(0u, CopyableType::num_instances());
109 mojo::Map<mojo::String, CopyableType> map;
110 std::vector<CopyableType*> value_ptrs;
111
112 for (size_t i = 0; i < kStringIntDataSize; ++i) {
113 const char* key = kStringIntData[i].string_data;
114 CopyableType value;
115 value_ptrs.push_back(value.ptr());
116 map.insert(key, value);
117 ASSERT_EQ(i + 1, map.size());
118 ASSERT_EQ(i + 1, value_ptrs.size());
119 EXPECT_EQ(map.size() + 1, CopyableType::num_instances());
120 EXPECT_TRUE(map.at(key).copied());
121 EXPECT_EQ(value_ptrs[i], map.at(key).ptr());
122 map.at(key).ResetCopied();
123 EXPECT_TRUE(map);
124 }
125
126 // std::map doesn't have a capacity() method like std::vector so this test is
127 // a lot more boring.
128
129 map.reset();
130 EXPECT_EQ(0u, CopyableType::num_instances());
131 }
132
133 TEST_F(MapTest, Insert_MoveOnly) {
134 ASSERT_EQ(0u, MoveOnlyType::num_instances());
135 mojo::Map<mojo::String, MoveOnlyType> map;
136 std::vector<MoveOnlyType*> value_ptrs;
137
138 for (size_t i = 0; i < kStringIntDataSize; ++i) {
139 const char* key = kStringIntData[i].string_data;
140 MoveOnlyType value;
141 value_ptrs.push_back(value.ptr());
142 map.insert(key, value.Pass());
143 ASSERT_EQ(i + 1, map.size());
144 ASSERT_EQ(i + 1, value_ptrs.size());
145 EXPECT_EQ(map.size() + 1, MoveOnlyType::num_instances());
146 EXPECT_TRUE(map.at(key).moved());
147 EXPECT_EQ(value_ptrs[i], map.at(key).ptr());
148 map.at(key).ResetMoved();
149 EXPECT_TRUE(map);
150 }
151
152 // std::map doesn't have a capacity() method like std::vector so this test is
153 // a lot more boring.
154
155 map.reset();
156 EXPECT_EQ(0u, CopyableType::num_instances());
157 }
158
159 TEST_F(MapTest, STLToMojo) {
160 std::map<std::string, int> stl_data;
161 for (size_t i = 0; i < kStringIntDataSize; ++i)
162 stl_data[kStringIntData[i].string_data] = kStringIntData[i].int_data;
163
164 Map<String, int32_t> mojo_data = Map<String, int32_t>::From(stl_data);
165
166 for (size_t i = 0; i < kStringIntDataSize; ++i) {
167 EXPECT_EQ(kStringIntData[i].int_data,
168 mojo_data.at(kStringIntData[i].string_data));
169 }
170 }
171
172 TEST_F(MapTest, MojoToSTL) {
173 Map<String, int32_t> mojo_map;
174 for (size_t i = 0; i < kStringIntDataSize; ++i)
175 mojo_map.insert(kStringIntData[i].string_data, kStringIntData[i].int_data);
176
177 std::map<std::string, int> stl_map =
178 mojo_map.To<std::map<std::string, int>>();
179 for (size_t i = 0; i < kStringIntDataSize; ++i) {
180 auto it = stl_map.find(kStringIntData[i].string_data);
181 ASSERT_TRUE(it != stl_map.end());
182 EXPECT_EQ(kStringIntData[i].int_data, it->second);
183 }
184 }
185
186 TEST_F(MapTest, MapArrayClone) {
187 Map<String, Array<String>> m;
188 for (size_t i = 0; i < kStringIntDataSize; ++i) {
189 Array<String> s;
190 s.push_back(kStringIntData[i].string_data);
191 m.insert(kStringIntData[i].string_data, s.Pass());
192 }
193
194 Map<String, Array<String>> m2 = m.Clone();
195
196 for (auto it = m2.begin(); it != m2.end(); ++it) {
197 ASSERT_EQ(1u, it.GetValue().size());
198 EXPECT_EQ(it.GetKey(), it.GetValue().at(0));
199 }
200 }
201
202 // Data class for an end-to-end test of serialization. Because making a more
203 // limited test case tickles a clang compiler bug, we copy a minimal version of
204 // what our current cpp bindings do.
205 namespace internal {
206
207 class ArrayOfMap_Data {
208 public:
209 static ArrayOfMap_Data* New(mojo::internal::Buffer* buf) {
210 return new (buf->Allocate(sizeof(ArrayOfMap_Data))) ArrayOfMap_Data();
211 }
212
213 mojo::internal::StructHeader header_;
214
215 mojo::internal::ArrayPointer<mojo::internal::Map_Data<int32_t, int8_t>*>
216 first;
217 mojo::internal::ArrayPointer<
218 mojo::internal::Map_Data<mojo::internal::String_Data*,
219 mojo::internal::Array_Data<bool>*>*> second;
220
221 private:
222 ArrayOfMap_Data() {
223 header_.num_bytes = sizeof(*this);
224 header_.num_fields = 2;
225 }
226 ~ArrayOfMap_Data(); // NOT IMPLEMENTED
227 };
228 static_assert(sizeof(ArrayOfMap_Data) == 24, "Bad sizeof(ArrayOfMap_Data)");
229
230 } // namespace internal
231
232 class ArrayOfMapImpl;
233 typedef mojo::StructPtr<ArrayOfMapImpl> ArrayOfMapImplPtr;
234
235 class ArrayOfMapImpl {
236 public:
237 typedef internal::ArrayOfMap_Data Data_;
238 static ArrayOfMapImplPtr New() {
239 ArrayOfMapImplPtr rv;
240 mojo::internal::StructHelper<ArrayOfMapImpl>::Initialize(&rv);
241 return rv.Pass();
242 }
243
244 mojo::Array<mojo::Map<int32_t, int8_t>> first;
245 mojo::Array<mojo::Map<mojo::String, mojo::Array<bool>>> second;
246 };
247
248 size_t GetSerializedSize_(const ArrayOfMapImplPtr& input) {
249 if (!input)
250 return 0;
251 size_t size = sizeof(internal::ArrayOfMap_Data);
252 size += GetSerializedSize_(input->first);
253 size += GetSerializedSize_(input->second);
254 return size;
255 }
256
257 void Serialize_(ArrayOfMapImplPtr input,
258 mojo::internal::Buffer* buf,
259 internal::ArrayOfMap_Data** output) {
260 if (input) {
261 internal::ArrayOfMap_Data* result = internal::ArrayOfMap_Data::New(buf);
262 mojo::SerializeArray_<mojo::internal::ArrayValidateParams<
263 0,
264 false,
265 mojo::internal::
266 ArrayValidateParams<0, false, mojo::internal::NoValidateParams>>>(
267 mojo::internal::Forward(input->first), buf, &result->first.ptr);
268 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
269 !result->first.ptr,
270 mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
271 "null first field in ArrayOfMapImpl struct");
272 mojo::SerializeArray_<mojo::internal::ArrayValidateParams<
273 0,
274 false,
275 mojo::internal::ArrayValidateParams<
276 0,
277 false,
278 mojo::internal::ArrayValidateParams<
279 0,
280 false,
281 mojo::internal::NoValidateParams>>>>(
282 mojo::internal::Forward(input->second), buf, &result->second.ptr);
283 MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
284 !result->second.ptr,
285 mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
286 "null second field in ArrayOfMapImpl struct");
287 *output = result;
288 } else {
289 *output = nullptr;
290 }
291 }
292
293 void Deserialize_(internal::ArrayOfMap_Data* input, ArrayOfMapImplPtr* output) {
294 if (input) {
295 ArrayOfMapImplPtr result(ArrayOfMapImpl::New());
296 Deserialize_(input->first.ptr, &result->first);
297 Deserialize_(input->second.ptr, &result->second);
298 *output = result.Pass();
299 } else {
300 output->reset();
301 }
302 }
303
304 TEST_F(MapTest, ArrayOfMap) {
305 Array<Map<int32_t, int8_t>> first_array(1);
306 first_array[0].insert(1, 42);
307
308 Array<Map<String, Array<bool>>> second_array(1);
309 Array<bool> map_value(2);
310 map_value[0] = false;
311 map_value[1] = true;
312 second_array[0].insert("hello world", map_value.Pass());
313
314 ArrayOfMapImplPtr to_pass(ArrayOfMapImpl::New());
315 to_pass->first = first_array.Pass();
316 to_pass->second = second_array.Pass();
317
318 size_t size = GetSerializedSize_(to_pass);
319 mojo::internal::FixedBuffer buf(size);
320 internal::ArrayOfMap_Data* data;
321 Serialize_(mojo::internal::Forward(to_pass), &buf, &data);
322
323 ArrayOfMapImplPtr to_receive(ArrayOfMapImpl::New());
324 Deserialize_(data, &to_receive);
325
326 ASSERT_EQ(1u, to_receive->first.size());
327 ASSERT_EQ(1u, to_receive->first[0].size());
328 ASSERT_EQ(42, to_receive->first[0].at(1));
329
330 ASSERT_EQ(1u, to_receive->second.size());
331 ASSERT_EQ(1u, to_receive->second[0].size());
332 ASSERT_FALSE(to_receive->second[0].at("hello world")[0]);
333 ASSERT_TRUE(to_receive->second[0].at("hello world")[1]);
334 }
335
336 } // namespace
337 } // namespace test
338 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/tests/container_test_util.cc ('k') | mojo/public/cpp/bindings/tests/string_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698