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 "mojo/public/cpp/bindings/stl_converters.h"
6
7#include <map>
8#include <string>
9#include <vector>
10
11#include "mojo/public/cpp/bindings/array.h"
12#include "mojo/public/cpp/bindings/map.h"
13#include "mojo/public/cpp/bindings/string.h"
14#include "mojo/public/cpp/bindings/tests/container_test_util.h"
15#include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h"
16#include "testing/gtest/include/gtest/gtest.h"
17
18namespace mojo {
19namespace test {
20
21using STLConvertersTest = testing::Test;
22
23TEST_F(STLConvertersTest, AvoidUnnecessaryCopies) {
24  Array<CopyableType> mojo_array(1);
25  std::vector<CopyableType> stl_vector = UnwrapToSTLType(std::move(mojo_array));
26  ASSERT_EQ(1u, stl_vector.size());
27  ASSERT_FALSE(stl_vector[0].copied());
28  Array<CopyableType> mojo_array2 = WrapSTLType(std::move(stl_vector));
29  ASSERT_EQ(1u, mojo_array2.size());
30  ASSERT_FALSE(mojo_array2[0].copied());
31
32  Map<int32_t, CopyableType> mojo_map;
33  mojo_map.insert(42, CopyableType());
34  mojo_map[42].ResetCopied();
35  std::map<int32_t, CopyableType> stl_map =
36      UnwrapToSTLType(std::move(mojo_map));
37  ASSERT_EQ(1u, stl_map.size());
38  ASSERT_FALSE(stl_map[42].copied());
39  Map<int32_t, CopyableType> mojo_map2 = WrapSTLType(std::move(stl_map));
40  ASSERT_EQ(1u, mojo_map2.size());
41  ASSERT_FALSE(mojo_map2[42].copied());
42}
43
44TEST_F(STLConvertersTest, RecursiveConversion) {
45  Array<Map<String, Array<int32_t>>> mojo_obj(2);
46  mojo_obj[0] = nullptr;
47  mojo_obj[1]["hello"].push_back(123);
48  mojo_obj[1]["hello"].push_back(456);
49
50  std::vector<std::map<std::string, std::vector<int32_t>>> stl_obj =
51      UnwrapToSTLType(std::move(mojo_obj));
52
53  ASSERT_EQ(2u, stl_obj.size());
54  ASSERT_TRUE(stl_obj[0].empty());
55  ASSERT_EQ(1u, stl_obj[1].size());
56  ASSERT_EQ(2u, stl_obj[1]["hello"].size());
57  ASSERT_EQ(123, stl_obj[1]["hello"][0]);
58  ASSERT_EQ(456, stl_obj[1]["hello"][1]);
59
60  Array<Map<String, Array<int32_t>>> mojo_obj2 =
61      WrapSTLType(std::move(stl_obj));
62
63  ASSERT_EQ(2u, mojo_obj2.size());
64  ASSERT_EQ(0u, mojo_obj2[0].size());
65  // The null flag has been lost when converted to std::map.
66  ASSERT_FALSE(mojo_obj2[0].is_null());
67  ASSERT_EQ(1u, mojo_obj2[1].size());
68  ASSERT_EQ(2u, mojo_obj2[1]["hello"].size());
69  ASSERT_EQ(123, mojo_obj2[1]["hello"][0]);
70  ASSERT_EQ(456, mojo_obj2[1]["hello"][1]);
71}
72
73TEST_F(STLConvertersTest, StopsAtMojoStruct) {
74  Array<NamedRegionPtr> mojo_obj(1);
75  mojo_obj[0] = NamedRegion::New();
76  mojo_obj[0]->name.emplace("hello");
77  mojo_obj[0]->rects.emplace(3);
78
79  std::vector<NamedRegionPtr> stl_obj = UnwrapToSTLType(std::move(mojo_obj));
80
81  ASSERT_EQ(1u, stl_obj.size());
82  ASSERT_EQ("hello", stl_obj[0]->name.value());
83  ASSERT_EQ(3u, stl_obj[0]->rects->size());
84
85  Array<NamedRegionPtr> mojo_obj2 = WrapSTLType(std::move(stl_obj));
86
87  ASSERT_EQ(1u, mojo_obj2.size());
88  ASSERT_EQ("hello", mojo_obj2[0]->name.value());
89  ASSERT_EQ(3u, mojo_obj2[0]->rects->size());
90}
91
92}  // namespace test
93}  // namespace mojo
94