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