1 // Copyright 2016 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 <memory>
6 #include <string>
7 #include <unordered_map>
8 #include <vector>
9
10 #include "base/message_loop/message_loop.h"
11 #include "mojo/public/cpp/bindings/binding.h"
12 #include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
13 #include "mojo/public/cpp/bindings/lib/serialization.h"
14 #include "mojo/public/interfaces/bindings/tests/test_data_view.mojom.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace mojo {
18 namespace test {
19 namespace data_view {
20 namespace {
21
22 class DataViewTest : public testing::Test {
23 private:
24 base::MessageLoop message_loop_;
25 };
26
27 struct DataViewHolder {
28 std::unique_ptr<TestStructDataView> data_view;
29 mojo::Message message;
30 mojo::internal::SerializationContext context;
31 };
32
SerializeTestStruct(TestStructPtr input)33 std::unique_ptr<DataViewHolder> SerializeTestStruct(TestStructPtr input) {
34 auto result = std::make_unique<DataViewHolder>();
35 result->message = Message(0, 0, 0, 0, nullptr);
36 internal::TestStruct_Data::BufferWriter writer;
37 mojo::internal::Serialize<TestStructDataView>(
38 input, result->message.payload_buffer(), &writer, &result->context);
39 result->data_view =
40 std::make_unique<TestStructDataView>(writer.data(), &result->context);
41 return result;
42 }
43
44 class TestInterfaceImpl : public TestInterface {
45 public:
TestInterfaceImpl(TestInterfaceRequest request)46 explicit TestInterfaceImpl(TestInterfaceRequest request)
47 : binding_(this, std::move(request)) {}
~TestInterfaceImpl()48 ~TestInterfaceImpl() override {}
49
50 // TestInterface implementation:
Echo(int32_t value,const EchoCallback & callback)51 void Echo(int32_t value, const EchoCallback& callback) override {
52 callback.Run(value);
53 }
54
55 private:
56 Binding<TestInterface> binding_;
57 };
58
59 } // namespace
60
TEST_F(DataViewTest,String)61 TEST_F(DataViewTest, String) {
62 TestStructPtr obj(TestStruct::New());
63 obj->f_string = "hello";
64
65 auto data_view_holder = SerializeTestStruct(std::move(obj));
66 auto& data_view = *data_view_holder->data_view;
67
68 StringDataView string_data_view;
69 data_view.GetFStringDataView(&string_data_view);
70
71 ASSERT_FALSE(string_data_view.is_null());
72 EXPECT_EQ(std::string("hello"),
73 std::string(string_data_view.storage(), string_data_view.size()));
74 }
75
TEST_F(DataViewTest,NestedStruct)76 TEST_F(DataViewTest, NestedStruct) {
77 TestStructPtr obj(TestStruct::New());
78 obj->f_struct = NestedStruct::New();
79 obj->f_struct->f_int32 = 42;
80
81 auto data_view_holder = SerializeTestStruct(std::move(obj));
82 auto& data_view = *data_view_holder->data_view;
83
84 NestedStructDataView struct_data_view;
85 data_view.GetFStructDataView(&struct_data_view);
86
87 ASSERT_FALSE(struct_data_view.is_null());
88 EXPECT_EQ(42, struct_data_view.f_int32());
89 }
90
TEST_F(DataViewTest,NativeStruct)91 TEST_F(DataViewTest, NativeStruct) {
92 TestStructPtr obj(TestStruct::New());
93 obj->f_native_struct = native::NativeStruct::New();
94 obj->f_native_struct->data = std::vector<uint8_t>({3, 2, 1});
95
96 auto data_view_holder = SerializeTestStruct(std::move(obj));
97 auto& data_view = *data_view_holder->data_view;
98
99 native::NativeStructDataView struct_data_view;
100 data_view.GetFNativeStructDataView(&struct_data_view);
101
102 ArrayDataView<uint8_t> data_data_view;
103 struct_data_view.GetDataDataView(&data_data_view);
104
105 ASSERT_FALSE(data_data_view.is_null());
106 ASSERT_EQ(3u, data_data_view.size());
107 EXPECT_EQ(3, data_data_view[0]);
108 EXPECT_EQ(2, data_data_view[1]);
109 EXPECT_EQ(1, data_data_view[2]);
110 EXPECT_EQ(3, *data_data_view.data());
111 }
112
TEST_F(DataViewTest,BoolArray)113 TEST_F(DataViewTest, BoolArray) {
114 TestStructPtr obj(TestStruct::New());
115 obj->f_bool_array = {true, false};
116
117 auto data_view_holder = SerializeTestStruct(std::move(obj));
118 auto& data_view = *data_view_holder->data_view;
119
120 ArrayDataView<bool> array_data_view;
121 data_view.GetFBoolArrayDataView(&array_data_view);
122
123 ASSERT_FALSE(array_data_view.is_null());
124 ASSERT_EQ(2u, array_data_view.size());
125 EXPECT_TRUE(array_data_view[0]);
126 EXPECT_FALSE(array_data_view[1]);
127 }
128
TEST_F(DataViewTest,IntegerArray)129 TEST_F(DataViewTest, IntegerArray) {
130 TestStructPtr obj(TestStruct::New());
131 obj->f_int32_array = {1024, 128};
132
133 auto data_view_holder = SerializeTestStruct(std::move(obj));
134 auto& data_view = *data_view_holder->data_view;
135
136 ArrayDataView<int32_t> array_data_view;
137 data_view.GetFInt32ArrayDataView(&array_data_view);
138
139 ASSERT_FALSE(array_data_view.is_null());
140 ASSERT_EQ(2u, array_data_view.size());
141 EXPECT_EQ(1024, array_data_view[0]);
142 EXPECT_EQ(128, array_data_view[1]);
143 EXPECT_EQ(1024, *array_data_view.data());
144 }
145
TEST_F(DataViewTest,EnumArray)146 TEST_F(DataViewTest, EnumArray) {
147 TestStructPtr obj(TestStruct::New());
148 obj->f_enum_array = {TestEnum::VALUE_1, TestEnum::VALUE_0};
149
150 auto data_view_holder = SerializeTestStruct(std::move(obj));
151 auto& data_view = *data_view_holder->data_view;
152
153 ArrayDataView<TestEnum> array_data_view;
154 data_view.GetFEnumArrayDataView(&array_data_view);
155
156 ASSERT_FALSE(array_data_view.is_null());
157 ASSERT_EQ(2u, array_data_view.size());
158 EXPECT_EQ(TestEnum::VALUE_1, array_data_view[0]);
159 EXPECT_EQ(TestEnum::VALUE_0, array_data_view[1]);
160 EXPECT_EQ(TestEnum::VALUE_0, *(array_data_view.data() + 1));
161
162 TestEnum output;
163 ASSERT_TRUE(array_data_view.Read(0, &output));
164 EXPECT_EQ(TestEnum::VALUE_1, output);
165 }
166
TEST_F(DataViewTest,InterfaceArray)167 TEST_F(DataViewTest, InterfaceArray) {
168 TestInterfacePtrInfo ptr_info;
169 TestInterfaceImpl impl(MakeRequest(&ptr_info));
170
171 TestStructPtr obj(TestStruct::New());
172 obj->f_interface_array.push_back(std::move(ptr_info));
173
174 auto data_view_holder = SerializeTestStruct(std::move(obj));
175 auto& data_view = *data_view_holder->data_view;
176
177 ArrayDataView<TestInterfacePtrDataView> array_data_view;
178 data_view.GetFInterfaceArrayDataView(&array_data_view);
179
180 ASSERT_FALSE(array_data_view.is_null());
181 ASSERT_EQ(1u, array_data_view.size());
182
183 TestInterfacePtr ptr2 = array_data_view.Take<TestInterfacePtr>(0);
184 ASSERT_TRUE(ptr2);
185 int32_t result = 0;
186 ASSERT_TRUE(ptr2->Echo(42, &result));
187 EXPECT_EQ(42, result);
188 }
189
TEST_F(DataViewTest,NestedArray)190 TEST_F(DataViewTest, NestedArray) {
191 TestStructPtr obj(TestStruct::New());
192 obj->f_nested_array = {{3, 4}, {2}};
193
194 auto data_view_holder = SerializeTestStruct(std::move(obj));
195 auto& data_view = *data_view_holder->data_view;
196
197 ArrayDataView<ArrayDataView<int32_t>> array_data_view;
198 data_view.GetFNestedArrayDataView(&array_data_view);
199
200 ASSERT_FALSE(array_data_view.is_null());
201 ASSERT_EQ(2u, array_data_view.size());
202
203 ArrayDataView<int32_t> nested_array_data_view;
204 array_data_view.GetDataView(0, &nested_array_data_view);
205 ASSERT_FALSE(nested_array_data_view.is_null());
206 ASSERT_EQ(2u, nested_array_data_view.size());
207 EXPECT_EQ(4, nested_array_data_view[1]);
208
209 std::vector<int32_t> vec;
210 ASSERT_TRUE(array_data_view.Read(1, &vec));
211 ASSERT_EQ(1u, vec.size());
212 EXPECT_EQ(2, vec[0]);
213 }
214
TEST_F(DataViewTest,StructArray)215 TEST_F(DataViewTest, StructArray) {
216 NestedStructPtr nested_struct(NestedStruct::New());
217 nested_struct->f_int32 = 42;
218
219 TestStructPtr obj(TestStruct::New());
220 obj->f_struct_array.push_back(std::move(nested_struct));
221
222 auto data_view_holder = SerializeTestStruct(std::move(obj));
223 auto& data_view = *data_view_holder->data_view;
224
225 ArrayDataView<NestedStructDataView> array_data_view;
226 data_view.GetFStructArrayDataView(&array_data_view);
227
228 ASSERT_FALSE(array_data_view.is_null());
229 ASSERT_EQ(1u, array_data_view.size());
230
231 NestedStructDataView struct_data_view;
232 array_data_view.GetDataView(0, &struct_data_view);
233 ASSERT_FALSE(struct_data_view.is_null());
234 EXPECT_EQ(42, struct_data_view.f_int32());
235
236 NestedStructPtr nested_struct2;
237 ASSERT_TRUE(array_data_view.Read(0, &nested_struct2));
238 ASSERT_TRUE(nested_struct2);
239 EXPECT_EQ(42, nested_struct2->f_int32);
240 }
241
TEST_F(DataViewTest,Map)242 TEST_F(DataViewTest, Map) {
243 TestStructPtr obj(TestStruct::New());
244 obj->f_map["1"] = 1;
245 obj->f_map["2"] = 2;
246
247 auto data_view_holder = SerializeTestStruct(std::move(obj));
248 auto& data_view = *data_view_holder->data_view;
249
250 MapDataView<StringDataView, int32_t> map_data_view;
251 data_view.GetFMapDataView(&map_data_view);
252
253 ASSERT_FALSE(map_data_view.is_null());
254 ASSERT_EQ(2u, map_data_view.size());
255
256 ASSERT_FALSE(map_data_view.keys().is_null());
257 ASSERT_EQ(2u, map_data_view.keys().size());
258
259 ASSERT_FALSE(map_data_view.values().is_null());
260 ASSERT_EQ(2u, map_data_view.values().size());
261
262 std::vector<std::string> keys;
263 ASSERT_TRUE(map_data_view.ReadKeys(&keys));
264 std::vector<int32_t> values;
265 ASSERT_TRUE(map_data_view.ReadValues(&values));
266
267 std::unordered_map<std::string, int32_t> map;
268 for (size_t i = 0; i < 2; ++i)
269 map[keys[i]] = values[i];
270
271 EXPECT_EQ(1, map["1"]);
272 EXPECT_EQ(2, map["2"]);
273 }
274
TEST_F(DataViewTest,UnionArray)275 TEST_F(DataViewTest, UnionArray) {
276 TestUnionPtr union_ptr(TestUnion::New());
277 union_ptr->set_f_int32(1024);
278
279 TestStructPtr obj(TestStruct::New());
280 obj->f_union_array.push_back(std::move(union_ptr));
281
282 auto data_view_holder = SerializeTestStruct(std::move(obj));
283 auto& data_view = *data_view_holder->data_view;
284
285 ArrayDataView<TestUnionDataView> array_data_view;
286 data_view.GetFUnionArrayDataView(&array_data_view);
287 ASSERT_FALSE(array_data_view.is_null());
288 ASSERT_EQ(1u, array_data_view.size());
289
290 TestUnionDataView union_data_view;
291 array_data_view.GetDataView(0, &union_data_view);
292 ASSERT_FALSE(union_data_view.is_null());
293
294 TestUnionPtr union_ptr2;
295 ASSERT_TRUE(array_data_view.Read(0, &union_ptr2));
296 ASSERT_TRUE(union_ptr2->is_f_int32());
297 EXPECT_EQ(1024, union_ptr2->get_f_int32());
298 }
299
300 } // namespace data_view
301 } // namespace test
302 } // namespace mojo
303