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/map.h" | |
6 | |
7 #include <stddef.h> | |
8 #include <stdint.h> | |
9 #include <unordered_map> | |
10 #include <utility> | |
11 | |
12 #include "mojo/public/cpp/bindings/array.h" | |
13 #include "mojo/public/cpp/bindings/string.h" | |
14 #include "mojo/public/cpp/bindings/tests/container_test_util.h" | |
15 #include "mojo/public/cpp/bindings/tests/map_common_test.h" | |
16 #include "mojo/public/cpp/bindings/tests/rect_chromium.h" | |
17 #include "mojo/public/interfaces/bindings/tests/rect.mojom.h" | |
18 #include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h" | |
19 #include "testing/gtest/include/gtest/gtest.h" | |
20 | |
21 namespace mojo { | |
22 namespace test { | |
23 | |
24 namespace { | |
25 | |
26 using MapTest = testing::Test; | |
27 | |
28 MAP_COMMON_TEST(Map, NullAndEmpty) | |
29 MAP_COMMON_TEST(Map, InsertWorks) | |
30 MAP_COMMON_TEST(Map, TestIndexOperator) | |
31 MAP_COMMON_TEST(Map, TestIndexOperatorAsRValue) | |
32 MAP_COMMON_TEST(Map, TestIndexOperatorMoveOnly) | |
33 MAP_COMMON_TEST(Map, MapArrayClone) | |
34 MAP_COMMON_TEST(Map, ArrayOfMap) | |
35 | |
36 TEST_F(MapTest, ConstructedFromArray) { | |
37 Array<String> keys(kStringIntDataSize); | |
38 Array<int> values(kStringIntDataSize); | |
39 for (size_t i = 0; i < kStringIntDataSize; ++i) { | |
40 keys[i] = kStringIntData[i].string_data; | |
41 values[i] = kStringIntData[i].int_data; | |
42 } | |
43 | |
44 Map<String, int> map(std::move(keys), std::move(values)); | |
45 | |
46 for (size_t i = 0; i < kStringIntDataSize; ++i) { | |
47 EXPECT_EQ(kStringIntData[i].int_data, | |
48 map.at(mojo::String(kStringIntData[i].string_data))); | |
49 } | |
50 } | |
51 | |
52 TEST_F(MapTest, DecomposeMapTo) { | |
53 Array<String> keys(kStringIntDataSize); | |
54 Array<int> values(kStringIntDataSize); | |
55 for (size_t i = 0; i < kStringIntDataSize; ++i) { | |
56 keys[i] = kStringIntData[i].string_data; | |
57 values[i] = kStringIntData[i].int_data; | |
58 } | |
59 | |
60 Map<String, int> map(std::move(keys), std::move(values)); | |
61 EXPECT_EQ(kStringIntDataSize, map.size()); | |
62 | |
63 Array<String> keys2; | |
64 Array<int> values2; | |
65 map.DecomposeMapTo(&keys2, &values2); | |
66 EXPECT_EQ(0u, map.size()); | |
67 | |
68 EXPECT_EQ(kStringIntDataSize, keys2.size()); | |
69 EXPECT_EQ(kStringIntDataSize, values2.size()); | |
70 | |
71 for (size_t i = 0; i < kStringIntDataSize; ++i) { | |
72 // We are not guaranteed that the copies have the same sorting as the | |
73 // originals. | |
74 String key = kStringIntData[i].string_data; | |
75 int value = kStringIntData[i].int_data; | |
76 | |
77 bool found = false; | |
78 for (size_t j = 0; j < keys2.size(); ++j) { | |
79 if (keys2[j] == key) { | |
80 EXPECT_EQ(value, values2[j]); | |
81 found = true; | |
82 break; | |
83 } | |
84 } | |
85 | |
86 EXPECT_TRUE(found); | |
87 } | |
88 } | |
89 | |
90 TEST_F(MapTest, Insert_Copyable) { | |
91 ASSERT_EQ(0u, CopyableType::num_instances()); | |
92 mojo::Map<mojo::String, CopyableType> map; | |
93 std::vector<CopyableType*> value_ptrs; | |
94 | |
95 for (size_t i = 0; i < kStringIntDataSize; ++i) { | |
96 const char* key = kStringIntData[i].string_data; | |
97 CopyableType value; | |
98 value_ptrs.push_back(value.ptr()); | |
99 map.insert(key, value); | |
100 ASSERT_EQ(i + 1, map.size()); | |
101 ASSERT_EQ(i + 1, value_ptrs.size()); | |
102 EXPECT_EQ(map.size() + 1, CopyableType::num_instances()); | |
103 EXPECT_TRUE(map.at(key).copied()); | |
104 EXPECT_EQ(value_ptrs[i], map.at(key).ptr()); | |
105 map.at(key).ResetCopied(); | |
106 EXPECT_TRUE(map); | |
107 } | |
108 | |
109 // std::map doesn't have a capacity() method like std::vector so this test is | |
110 // a lot more boring. | |
111 | |
112 map = nullptr; | |
113 EXPECT_EQ(0u, CopyableType::num_instances()); | |
114 } | |
115 | |
116 TEST_F(MapTest, Insert_MoveOnly) { | |
117 ASSERT_EQ(0u, MoveOnlyType::num_instances()); | |
118 mojo::Map<mojo::String, MoveOnlyType> map; | |
119 std::vector<MoveOnlyType*> value_ptrs; | |
120 | |
121 for (size_t i = 0; i < kStringIntDataSize; ++i) { | |
122 const char* key = kStringIntData[i].string_data; | |
123 MoveOnlyType value; | |
124 value_ptrs.push_back(value.ptr()); | |
125 map.insert(key, std::move(value)); | |
126 ASSERT_EQ(i + 1, map.size()); | |
127 ASSERT_EQ(i + 1, value_ptrs.size()); | |
128 EXPECT_EQ(map.size() + 1, MoveOnlyType::num_instances()); | |
129 EXPECT_TRUE(map.at(key).moved()); | |
130 EXPECT_EQ(value_ptrs[i], map.at(key).ptr()); | |
131 map.at(key).ResetMoved(); | |
132 EXPECT_TRUE(map); | |
133 } | |
134 | |
135 // std::map doesn't have a capacity() method like std::vector so this test is | |
136 // a lot more boring. | |
137 | |
138 map = nullptr; | |
139 EXPECT_EQ(0u, MoveOnlyType::num_instances()); | |
140 } | |
141 | |
142 TEST_F(MapTest, IndexOperator_MoveOnly) { | |
143 ASSERT_EQ(0u, MoveOnlyType::num_instances()); | |
144 mojo::Map<mojo::String, MoveOnlyType> map; | |
145 std::vector<MoveOnlyType*> value_ptrs; | |
146 | |
147 for (size_t i = 0; i < kStringIntDataSize; ++i) { | |
148 const char* key = kStringIntData[i].string_data; | |
149 MoveOnlyType value; | |
150 value_ptrs.push_back(value.ptr()); | |
151 map[key] = std::move(value); | |
152 ASSERT_EQ(i + 1, map.size()); | |
153 ASSERT_EQ(i + 1, value_ptrs.size()); | |
154 EXPECT_EQ(map.size() + 1, MoveOnlyType::num_instances()); | |
155 EXPECT_TRUE(map.at(key).moved()); | |
156 EXPECT_EQ(value_ptrs[i], map.at(key).ptr()); | |
157 map.at(key).ResetMoved(); | |
158 EXPECT_TRUE(map); | |
159 } | |
160 | |
161 // std::map doesn't have a capacity() method like std::vector so this test is | |
162 // a lot more boring. | |
163 | |
164 map = nullptr; | |
165 EXPECT_EQ(0u, MoveOnlyType::num_instances()); | |
166 } | |
167 | |
168 TEST_F(MapTest, STLToMojo) { | |
169 std::map<std::string, int> stl_data; | |
170 for (size_t i = 0; i < kStringIntDataSize; ++i) | |
171 stl_data[kStringIntData[i].string_data] = kStringIntData[i].int_data; | |
172 | |
173 Map<String, int32_t> mojo_data = Map<String, int32_t>::From(stl_data); | |
174 for (size_t i = 0; i < kStringIntDataSize; ++i) { | |
175 EXPECT_EQ(kStringIntData[i].int_data, | |
176 mojo_data.at(kStringIntData[i].string_data)); | |
177 } | |
178 } | |
179 | |
180 TEST_F(MapTest, MojoToSTL) { | |
181 Map<String, int32_t> mojo_map; | |
182 for (size_t i = 0; i < kStringIntDataSize; ++i) | |
183 mojo_map.insert(kStringIntData[i].string_data, kStringIntData[i].int_data); | |
184 | |
185 std::map<std::string, int> stl_map = | |
186 mojo_map.To<std::map<std::string, int>>(); | |
187 for (size_t i = 0; i < kStringIntDataSize; ++i) { | |
188 auto it = stl_map.find(kStringIntData[i].string_data); | |
189 ASSERT_TRUE(it != stl_map.end()); | |
190 EXPECT_EQ(kStringIntData[i].int_data, it->second); | |
191 } | |
192 } | |
193 | |
194 TEST_F(MapTest, MoveFromAndToSTLMap_Copyable) { | |
195 std::map<int32_t, CopyableType> map1; | |
196 map1.insert(std::make_pair(123, CopyableType())); | |
197 map1[123].ResetCopied(); | |
198 | |
199 Map<int32_t, CopyableType> mojo_map(std::move(map1)); | |
200 ASSERT_EQ(1u, mojo_map.size()); | |
201 ASSERT_NE(mojo_map.end(), mojo_map.find(123)); | |
202 ASSERT_FALSE(mojo_map[123].copied()); | |
203 | |
204 std::map<int32_t, CopyableType> map2(mojo_map.PassStorage()); | |
205 ASSERT_EQ(1u, map2.size()); | |
206 ASSERT_NE(map2.end(), map2.find(123)); | |
207 ASSERT_FALSE(map2[123].copied()); | |
208 | |
209 ASSERT_EQ(0u, mojo_map.size()); | |
210 ASSERT_TRUE(mojo_map.is_null()); | |
211 } | |
212 | |
213 TEST_F(MapTest, MoveFromAndToSTLMap_MoveOnly) { | |
214 std::map<int32_t, MoveOnlyType> map1; | |
215 map1.insert(std::make_pair(123, MoveOnlyType())); | |
216 | |
217 Map<int32_t, MoveOnlyType> mojo_map(std::move(map1)); | |
218 ASSERT_EQ(1u, mojo_map.size()); | |
219 ASSERT_NE(mojo_map.end(), mojo_map.find(123)); | |
220 | |
221 std::map<int32_t, MoveOnlyType> map2(mojo_map.PassStorage()); | |
222 ASSERT_EQ(1u, map2.size()); | |
223 ASSERT_NE(map2.end(), map2.find(123)); | |
224 | |
225 ASSERT_EQ(0u, mojo_map.size()); | |
226 ASSERT_TRUE(mojo_map.is_null()); | |
227 } | |
228 | |
229 static RectPtr MakeRect(int32_t x, int32_t y, int32_t width, int32_t height) { | |
230 RectPtr rect_ptr = Rect::New(); | |
231 rect_ptr->x = x; | |
232 rect_ptr->y = y; | |
233 rect_ptr->width = width; | |
234 rect_ptr->height = height; | |
235 return rect_ptr; | |
236 } | |
237 | |
238 TEST_F(MapTest, StructKey) { | |
239 std::unordered_map<RectPtr, int32_t> map; | |
240 map.insert(std::make_pair(MakeRect(1, 2, 3, 4), 123)); | |
241 | |
242 RectPtr key = MakeRect(1, 2, 3, 4); | |
243 ASSERT_NE(map.end(), map.find(key)); | |
244 ASSERT_EQ(123, map.find(key)->second); | |
245 | |
246 map.erase(key); | |
247 ASSERT_EQ(0u, map.size()); | |
248 } | |
249 | |
250 static ContainsHashablePtr MakeContainsHashablePtr(RectChromium rect) { | |
251 ContainsHashablePtr ptr = ContainsHashable::New(); | |
252 ptr->rect = rect; | |
253 return ptr; | |
254 } | |
255 | |
256 TEST_F(MapTest, TypemappedStructKey) { | |
257 std::unordered_map<ContainsHashablePtr, int32_t> map; | |
258 map.insert( | |
259 std::make_pair(MakeContainsHashablePtr(RectChromium(1, 2, 3, 4)), 123)); | |
260 | |
261 ContainsHashablePtr key = MakeContainsHashablePtr(RectChromium(1, 2, 3, 4)); | |
262 ASSERT_NE(map.end(), map.find(key)); | |
263 ASSERT_EQ(123, map.find(key)->second); | |
264 | |
265 map.erase(key); | |
266 ASSERT_EQ(0u, map.size()); | |
267 } | |
268 | |
269 } // namespace | |
270 } // namespace test | |
271 } // namespace mojo | |
OLD | NEW |