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 "base/files/file_path.h"
6 #include "base/message_loop/message_loop.h"
7 #include "base/run_loop.h"
8 #include "base/values.h"
9 #include "mojo/common/common_custom_types.mojom.h"
10 #include "mojo/common/test_common_custom_types.mojom.h"
11 #include "mojo/public/cpp/bindings/binding.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace mojo {
15 namespace common {
16 namespace test {
17 namespace {
18
19 template <typename T>
20 struct BounceTestTraits {
ExpectEqualitymojo::common::test::__anon2d369a120111::BounceTestTraits21 static void ExpectEquality(const T& a, const T& b) {
22 EXPECT_EQ(a, b);
23 }
24 };
25
26 template <>
27 struct BounceTestTraits<base::DictionaryValue> {
ExpectEqualitymojo::common::test::__anon2d369a120111::BounceTestTraits28 static void ExpectEquality(const base::DictionaryValue& a,
29 const base::DictionaryValue& b) {
30 EXPECT_TRUE(a.Equals(&b));
31 }
32 };
33
34 template <>
35 struct BounceTestTraits<base::ListValue> {
ExpectEqualitymojo::common::test::__anon2d369a120111::BounceTestTraits36 static void ExpectEquality(const base::ListValue& a,
37 const base::ListValue& b) {
38 EXPECT_TRUE(a.Equals(&b));
39 }
40 };
41
42 template <typename T>
DoExpectResponse(T * expected_value,const base::Closure & closure,const T & value)43 void DoExpectResponse(T* expected_value,
44 const base::Closure& closure,
45 const T& value) {
46 BounceTestTraits<T>::ExpectEquality(*expected_value, value);
47 closure.Run();
48 }
49
50 template <typename T>
ExpectResponse(T * expected_value,const base::Closure & closure)51 base::Callback<void(const T&)> ExpectResponse(T* expected_value,
52 const base::Closure& closure) {
53 return base::Bind(&DoExpectResponse<T>, expected_value, closure);
54 }
55
56 class TestFilePathImpl : public TestFilePath {
57 public:
TestFilePathImpl(TestFilePathRequest request)58 explicit TestFilePathImpl(TestFilePathRequest request)
59 : binding_(this, std::move(request)) {}
60
61 // TestFilePath implementation:
BounceFilePath(const base::FilePath & in,const BounceFilePathCallback & callback)62 void BounceFilePath(const base::FilePath& in,
63 const BounceFilePathCallback& callback) override {
64 callback.Run(in);
65 }
66
67 private:
68 mojo::Binding<TestFilePath> binding_;
69 };
70
71 class TestTimeImpl : public TestTime {
72 public:
TestTimeImpl(TestTimeRequest request)73 explicit TestTimeImpl(TestTimeRequest request)
74 : binding_(this, std::move(request)) {}
75
76 // TestTime implementation:
BounceTime(const base::Time & in,const BounceTimeCallback & callback)77 void BounceTime(const base::Time& in,
78 const BounceTimeCallback& callback) override {
79 callback.Run(in);
80 }
81
BounceTimeDelta(const base::TimeDelta & in,const BounceTimeDeltaCallback & callback)82 void BounceTimeDelta(const base::TimeDelta& in,
83 const BounceTimeDeltaCallback& callback) override {
84 callback.Run(in);
85 }
86
BounceTimeTicks(const base::TimeTicks & in,const BounceTimeTicksCallback & callback)87 void BounceTimeTicks(const base::TimeTicks& in,
88 const BounceTimeTicksCallback& callback) override {
89 callback.Run(in);
90 }
91
92 private:
93 mojo::Binding<TestTime> binding_;
94 };
95
96 class TestValueImpl : public TestValue {
97 public:
TestValueImpl(TestValueRequest request)98 explicit TestValueImpl(TestValueRequest request)
99 : binding_(this, std::move(request)) {}
100
101 // TestValue implementation:
BounceDictionaryValue(const base::DictionaryValue & in,const BounceDictionaryValueCallback & callback)102 void BounceDictionaryValue(
103 const base::DictionaryValue& in,
104 const BounceDictionaryValueCallback& callback) override {
105 callback.Run(in);
106 }
BounceListValue(const base::ListValue & in,const BounceListValueCallback & callback)107 void BounceListValue(const base::ListValue& in,
108 const BounceListValueCallback& callback) override {
109 callback.Run(in);
110 }
111
112 private:
113 mojo::Binding<TestValue> binding_;
114 };
115
116 class CommonCustomTypesTest : public testing::Test {
117 protected:
CommonCustomTypesTest()118 CommonCustomTypesTest() {}
~CommonCustomTypesTest()119 ~CommonCustomTypesTest() override {}
120
121 private:
122 base::MessageLoop message_loop_;
123
124 DISALLOW_COPY_AND_ASSIGN(CommonCustomTypesTest);
125 };
126
127 } // namespace
128
TEST_F(CommonCustomTypesTest,FilePath)129 TEST_F(CommonCustomTypesTest, FilePath) {
130 base::RunLoop run_loop;
131
132 TestFilePathPtr ptr;
133 TestFilePathImpl impl(GetProxy(&ptr));
134
135 base::FilePath dir(FILE_PATH_LITERAL("hello"));
136 base::FilePath file = dir.Append(FILE_PATH_LITERAL("world"));
137
138 ptr->BounceFilePath(file, ExpectResponse(&file, run_loop.QuitClosure()));
139
140 run_loop.Run();
141 }
142
TEST_F(CommonCustomTypesTest,Time)143 TEST_F(CommonCustomTypesTest, Time) {
144 base::RunLoop run_loop;
145
146 TestTimePtr ptr;
147 TestTimeImpl impl(GetProxy(&ptr));
148
149 base::Time t = base::Time::Now();
150
151 ptr->BounceTime(t, ExpectResponse(&t, run_loop.QuitClosure()));
152
153 run_loop.Run();
154 }
155
TEST_F(CommonCustomTypesTest,TimeDelta)156 TEST_F(CommonCustomTypesTest, TimeDelta) {
157 base::RunLoop run_loop;
158
159 TestTimePtr ptr;
160 TestTimeImpl impl(GetProxy(&ptr));
161
162 base::TimeDelta t = base::TimeDelta::FromDays(123);
163
164 ptr->BounceTimeDelta(t, ExpectResponse(&t, run_loop.QuitClosure()));
165
166 run_loop.Run();
167 }
168
TEST_F(CommonCustomTypesTest,TimeTicks)169 TEST_F(CommonCustomTypesTest, TimeTicks) {
170 base::RunLoop run_loop;
171
172 TestTimePtr ptr;
173 TestTimeImpl impl(GetProxy(&ptr));
174
175 base::TimeTicks t = base::TimeTicks::Now();
176
177 ptr->BounceTimeTicks(t, ExpectResponse(&t, run_loop.QuitClosure()));
178
179 run_loop.Run();
180 }
181
TEST_F(CommonCustomTypesTest,Value)182 TEST_F(CommonCustomTypesTest, Value) {
183 TestValuePtr ptr;
184 TestValueImpl impl(GetProxy(&ptr));
185
186 base::DictionaryValue dict;
187 dict.SetBoolean("bool", false);
188 dict.SetInteger("int", 2);
189 dict.SetString("string", "some string");
190 dict.SetBoolean("nested.bool", true);
191 dict.SetInteger("nested.int", 9);
192 dict.Set("some_binary", base::BinaryValue::CreateWithCopiedBuffer("mojo", 4));
193 {
194 std::unique_ptr<base::ListValue> dict_list(new base::ListValue());
195 dict_list->AppendString("string");
196 dict_list->AppendBoolean(true);
197 dict.Set("list", std::move(dict_list));
198 }
199 {
200 base::RunLoop run_loop;
201 ptr->BounceDictionaryValue(
202 dict, ExpectResponse(&dict, run_loop.QuitClosure()));
203 run_loop.Run();
204 }
205
206 base::ListValue list;
207 list.AppendString("string");
208 list.AppendDouble(42.1);
209 list.AppendBoolean(true);
210 list.Append(base::BinaryValue::CreateWithCopiedBuffer("mojo", 4));
211 {
212 std::unique_ptr<base::DictionaryValue> list_dict(
213 new base::DictionaryValue());
214 list_dict->SetString("string", "str");
215 list.Append(std::move(list_dict));
216 }
217 {
218 base::RunLoop run_loop;
219 ptr->BounceListValue(list, ExpectResponse(&list, run_loop.QuitClosure()));
220 run_loop.Run();
221 }
222 }
223
224 } // namespace test
225 } // namespace common
226 } // namespace mojo
227