OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 "chromeos/dbus/ibus/ibus_client.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/message_loop/message_loop.h" | |
9 #include "base/values.h" | |
10 #include "chromeos/dbus/ibus/ibus_constants.h" | |
11 #include "dbus/message.h" | |
12 #include "dbus/mock_bus.h" | |
13 #include "dbus/mock_object_proxy.h" | |
14 #include "dbus/object_path.h" | |
15 #include "dbus/values_util.h" | |
16 #include "testing/gmock/include/gmock/gmock.h" | |
17 #include "testing/gtest/include/gtest/gtest.h" | |
18 | |
19 using testing::Invoke; | |
20 using testing::Return; | |
21 using testing::_; | |
22 | |
23 namespace chromeos { | |
24 | |
25 namespace { | |
26 const char kClientName[] = "chrome"; | |
27 const char kEngineName[] = "engine"; | |
28 const bool kRestartFlag = true; | |
29 } // namespace | |
30 | |
31 class MockCreateInputContextCallback { | |
32 public: | |
33 MOCK_METHOD1(Run, void(const dbus::ObjectPath& object_path)); | |
34 }; | |
35 | |
36 class MockErrorCallback { | |
37 public: | |
38 MOCK_METHOD0(Run, void()); | |
39 }; | |
40 | |
41 class IBusClientTest : public testing::Test { | |
42 public: | |
43 IBusClientTest() : response_(NULL) {} | |
44 | |
45 // Handles CreateInputContext method call. | |
46 void OnCreateInputContext( | |
47 dbus::MethodCall* method_call, | |
48 int timeout_ms, | |
49 const dbus::ObjectProxy::ResponseCallback& callback, | |
50 const dbus::ObjectProxy::ErrorCallback& error_callback) { | |
51 dbus::MessageReader reader(method_call); | |
52 std::string client_name; | |
53 EXPECT_TRUE(reader.PopString(&client_name)); | |
54 EXPECT_EQ(kClientName, client_name); | |
55 EXPECT_FALSE(reader.HasMoreData()); | |
56 | |
57 message_loop_.PostTask(FROM_HERE, base::Bind(callback, response_)); | |
58 } | |
59 | |
60 // Handles fail case of CreateInputContext method call. | |
61 void OnCreateInputContextFail( | |
62 dbus::MethodCall* method_call, | |
63 int timeout_ms, | |
64 const dbus::ObjectProxy::ResponseCallback& callback, | |
65 const dbus::ObjectProxy::ErrorCallback& error_callback) { | |
66 dbus::MessageReader reader(method_call); | |
67 std::string client_name; | |
68 EXPECT_TRUE(reader.PopString(&client_name)); | |
69 EXPECT_EQ(kClientName, client_name); | |
70 EXPECT_FALSE(reader.HasMoreData()); | |
71 | |
72 message_loop_.PostTask(FROM_HERE, base::Bind(error_callback, | |
73 error_response_)); | |
74 } | |
75 | |
76 // Handles SetGlobalEngine method call. | |
77 void OnSetGlobalEngine( | |
78 dbus::MethodCall* method_call, | |
79 int timeout_ms, | |
80 const dbus::ObjectProxy::ResponseCallback& callback, | |
81 const dbus::ObjectProxy::ErrorCallback& error_callback) { | |
82 dbus::MessageReader reader(method_call); | |
83 std::string engine_name; | |
84 EXPECT_TRUE(reader.PopString(&engine_name)); | |
85 EXPECT_EQ(kEngineName, engine_name); | |
86 EXPECT_FALSE(reader.HasMoreData()); | |
87 message_loop_.PostTask(FROM_HERE, base::Bind(callback, response_)); | |
88 } | |
89 | |
90 // Handles fail case of SetGlobalEngine method call. | |
91 void OnSetGlobalEngineFail( | |
92 dbus::MethodCall* method_call, | |
93 int timeout_ms, | |
94 const dbus::ObjectProxy::ResponseCallback& callback, | |
95 const dbus::ObjectProxy::ErrorCallback& error_callback) { | |
96 dbus::MessageReader reader(method_call); | |
97 std::string engine_name; | |
98 EXPECT_TRUE(reader.PopString(&engine_name)); | |
99 EXPECT_EQ(kEngineName, engine_name); | |
100 EXPECT_FALSE(reader.HasMoreData()); | |
101 message_loop_.PostTask(FROM_HERE, base::Bind(error_callback, | |
102 error_response_)); | |
103 } | |
104 | |
105 // Handles Exit method call. | |
106 void OnExit(dbus::MethodCall* method_call, | |
107 int timeout_ms, | |
108 const dbus::ObjectProxy::ResponseCallback& callback, | |
109 const dbus::ObjectProxy::ErrorCallback& error_callback) { | |
110 dbus::MessageReader reader(method_call); | |
111 bool restart = false; | |
112 EXPECT_TRUE(reader.PopBool(&restart)); | |
113 EXPECT_EQ(kRestartFlag, restart); | |
114 EXPECT_FALSE(reader.HasMoreData()); | |
115 message_loop_.PostTask(FROM_HERE, base::Bind(callback, response_)); | |
116 } | |
117 | |
118 // Handles fail case of Exit method call. | |
119 void OnExitFail(dbus::MethodCall* method_call, | |
120 int timeout_ms, | |
121 const dbus::ObjectProxy::ResponseCallback& callback, | |
122 const dbus::ObjectProxy::ErrorCallback& error_callback) { | |
123 dbus::MessageReader reader(method_call); | |
124 bool restart = false; | |
125 EXPECT_TRUE(reader.PopBool(&restart)); | |
126 EXPECT_EQ(kRestartFlag, restart); | |
127 EXPECT_FALSE(reader.HasMoreData()); | |
128 message_loop_.PostTask(FROM_HERE, base::Bind(error_callback, | |
129 error_response_)); | |
130 } | |
131 | |
132 protected: | |
133 virtual void SetUp() OVERRIDE { | |
134 dbus::Bus::Options options; | |
135 mock_bus_ = new dbus::MockBus(options); | |
136 mock_proxy_ = new dbus::MockObjectProxy(mock_bus_.get(), | |
137 ibus::kServiceName, | |
138 dbus::ObjectPath( | |
139 ibus::bus::kServicePath)); | |
140 EXPECT_CALL(*mock_bus_.get(), | |
141 GetObjectProxy(ibus::kServiceName, | |
142 dbus::ObjectPath(ibus::bus::kServicePath))) | |
143 .WillOnce(Return(mock_proxy_.get())); | |
144 | |
145 EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()); | |
146 client_.reset( | |
147 IBusClient::Create(REAL_DBUS_CLIENT_IMPLEMENTATION, mock_bus_.get())); | |
148 } | |
149 | |
150 virtual void TearDown() OVERRIDE { | |
151 mock_bus_->ShutdownAndBlock(); | |
152 } | |
153 | |
154 // The IBus client to be tested. | |
155 scoped_ptr<IBusClient> client_; | |
156 | |
157 // A message loop to emulate asynchronous behavior. | |
158 base::MessageLoop message_loop_; | |
159 scoped_refptr<dbus::MockBus> mock_bus_; | |
160 scoped_refptr<dbus::MockObjectProxy> mock_proxy_; | |
161 | |
162 // Response returned by mock methods. | |
163 dbus::Response* response_; | |
164 dbus::ErrorResponse* error_response_; | |
165 }; | |
166 | |
167 TEST_F(IBusClientTest, CreateInputContextTest) { | |
168 // Set expectations. | |
169 const dbus::ObjectPath kInputContextObjectPath = | |
170 dbus::ObjectPath("/some/object/path"); | |
171 EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _)) | |
172 .WillOnce(Invoke(this, &IBusClientTest::OnCreateInputContext)); | |
173 MockCreateInputContextCallback callback; | |
174 EXPECT_CALL(callback, Run(kInputContextObjectPath)); | |
175 MockErrorCallback error_callback; | |
176 EXPECT_CALL(error_callback, Run()).Times(0); | |
177 | |
178 // Create response. | |
179 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); | |
180 dbus::MessageWriter writer(response.get()); | |
181 writer.AppendObjectPath(kInputContextObjectPath); | |
182 response_ = response.get(); | |
183 | |
184 // Call CreateInputContext. | |
185 client_->CreateInputContext( | |
186 kClientName, | |
187 base::Bind(&MockCreateInputContextCallback::Run, | |
188 base::Unretained(&callback)), | |
189 base::Bind(&MockErrorCallback::Run, | |
190 base::Unretained(&error_callback))); | |
191 | |
192 // Run the message loop. | |
193 message_loop_.RunUntilIdle(); | |
194 } | |
195 | |
196 TEST_F(IBusClientTest, CreateInputContext_NullResponseFail) { | |
197 // Set expectations. | |
198 EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _)) | |
199 .WillOnce(Invoke(this, &IBusClientTest::OnCreateInputContext)); | |
200 MockCreateInputContextCallback callback; | |
201 EXPECT_CALL(callback, Run(_)).Times(0); | |
202 MockErrorCallback error_callback; | |
203 EXPECT_CALL(error_callback, Run()); | |
204 | |
205 // Set NULL response. | |
206 response_ = NULL; | |
207 | |
208 // Call CreateInputContext. | |
209 client_->CreateInputContext( | |
210 kClientName, | |
211 base::Bind(&MockCreateInputContextCallback::Run, | |
212 base::Unretained(&callback)), | |
213 base::Bind(&MockErrorCallback::Run, | |
214 base::Unretained(&error_callback))); | |
215 | |
216 // Run the message loop. | |
217 message_loop_.RunUntilIdle(); | |
218 } | |
219 | |
220 TEST_F(IBusClientTest, CreateInputContext_InvalidResponseFail) { | |
221 // Set expectations. | |
222 EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _)) | |
223 .WillOnce(Invoke(this, &IBusClientTest::OnCreateInputContext)); | |
224 MockCreateInputContextCallback callback; | |
225 EXPECT_CALL(callback, Run(_)).Times(0); | |
226 MockErrorCallback error_callback; | |
227 EXPECT_CALL(error_callback, Run()); | |
228 | |
229 // Create invalid(empty) response. | |
230 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); | |
231 response_ = response.get(); | |
232 | |
233 // Call CreateInputContext. | |
234 client_->CreateInputContext( | |
235 kClientName, | |
236 base::Bind(&MockCreateInputContextCallback::Run, | |
237 base::Unretained(&callback)), | |
238 base::Bind(&MockErrorCallback::Run, | |
239 base::Unretained(&error_callback))); | |
240 | |
241 // Run the message loop. | |
242 message_loop_.RunUntilIdle(); | |
243 } | |
244 | |
245 TEST_F(IBusClientTest, CreateInputContext_MethodCallFail) { | |
246 // Set expectations | |
247 EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _)) | |
248 .WillOnce(Invoke(this, &IBusClientTest::OnCreateInputContextFail)); | |
249 MockCreateInputContextCallback callback; | |
250 EXPECT_CALL(callback, Run(_)).Times(0); | |
251 MockErrorCallback error_callback; | |
252 EXPECT_CALL(error_callback, Run()); | |
253 | |
254 // The error response is not used in CreateInputContext. | |
255 error_response_ = NULL; | |
256 | |
257 // Call CreateInputContext. | |
258 client_->CreateInputContext( | |
259 kClientName, | |
260 base::Bind(&MockCreateInputContextCallback::Run, | |
261 base::Unretained(&callback)), | |
262 base::Bind(&MockErrorCallback::Run, | |
263 base::Unretained(&error_callback))); | |
264 | |
265 // Run the message loop. | |
266 message_loop_.RunUntilIdle(); | |
267 } | |
268 | |
269 TEST_F(IBusClientTest, SetGlobalEngineTest) { | |
270 // Set expectations | |
271 EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _)) | |
272 .WillOnce(Invoke(this, &IBusClientTest::OnSetGlobalEngine)); | |
273 MockErrorCallback error_callback; | |
274 EXPECT_CALL(error_callback, Run()).Times(0); | |
275 | |
276 // Create empty response. | |
277 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); | |
278 response_ = response.get(); | |
279 | |
280 // The error response is not used in SetGLobalEngine. | |
281 error_response_ = NULL; | |
282 | |
283 // Call CreateInputContext. | |
284 client_->SetGlobalEngine( | |
285 kEngineName, | |
286 base::Bind(&MockErrorCallback::Run, | |
287 base::Unretained(&error_callback))); | |
288 | |
289 // Run the message loop. | |
290 message_loop_.RunUntilIdle(); | |
291 } | |
292 | |
293 TEST_F(IBusClientTest, SetGlobalEngineTest_InvalidResponse) { | |
294 // Set expectations | |
295 EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _)) | |
296 .WillOnce(Invoke(this, &IBusClientTest::OnSetGlobalEngineFail)); | |
297 MockErrorCallback error_callback; | |
298 EXPECT_CALL(error_callback, Run()); | |
299 | |
300 // Set invalid response. | |
301 response_ = NULL; | |
302 | |
303 // The error response is not used in SetGLobalEngine. | |
304 error_response_ = NULL; | |
305 | |
306 // Call CreateInputContext. | |
307 client_->SetGlobalEngine( | |
308 kEngineName, | |
309 base::Bind(&MockErrorCallback::Run, | |
310 base::Unretained(&error_callback))); | |
311 | |
312 // Run the message loop. | |
313 message_loop_.RunUntilIdle(); | |
314 } | |
315 | |
316 TEST_F(IBusClientTest, SetGlobalEngineTest_MethodCallFail) { | |
317 // Set expectations | |
318 EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _)) | |
319 .WillOnce(Invoke(this, &IBusClientTest::OnSetGlobalEngineFail)); | |
320 MockErrorCallback error_callback; | |
321 EXPECT_CALL(error_callback, Run()); | |
322 | |
323 // Create empty response. | |
324 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); | |
325 response_ = response.get(); | |
326 | |
327 // The error response is not used in SetGLobalEngine. | |
328 error_response_ = NULL; | |
329 | |
330 // Call CreateInputContext. | |
331 client_->SetGlobalEngine( | |
332 kEngineName, | |
333 base::Bind(&MockErrorCallback::Run, | |
334 base::Unretained(&error_callback))); | |
335 | |
336 // Run the message loop. | |
337 message_loop_.RunUntilIdle(); | |
338 } | |
339 | |
340 TEST_F(IBusClientTest, ExitTest) { | |
341 // Set expectations | |
342 EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _)) | |
343 .WillOnce(Invoke(this, &IBusClientTest::OnExit)); | |
344 MockErrorCallback error_callback; | |
345 EXPECT_CALL(error_callback, Run()).Times(0); | |
346 | |
347 // Create empty response. | |
348 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); | |
349 response_ = response.get(); | |
350 | |
351 // The error response is not used in SetGLobalEngine. | |
352 error_response_ = NULL; | |
353 | |
354 // Call CreateInputContext. | |
355 client_->Exit( | |
356 IBusClient::RESTART_IBUS_DAEMON, | |
357 base::Bind(&MockErrorCallback::Run, | |
358 base::Unretained(&error_callback))); | |
359 | |
360 // Run the message loop. | |
361 message_loop_.RunUntilIdle(); | |
362 } | |
363 | |
364 TEST_F(IBusClientTest, ExitTest_InvalidResponse) { | |
365 // Set expectations | |
366 EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _)) | |
367 .WillOnce(Invoke(this, &IBusClientTest::OnExit)); | |
368 MockErrorCallback error_callback; | |
369 EXPECT_CALL(error_callback, Run()); | |
370 | |
371 // Set invalid response. | |
372 response_ = NULL; | |
373 | |
374 // The error response is not used in SetGLobalEngine. | |
375 error_response_ = NULL; | |
376 | |
377 // Call CreateInputContext. | |
378 client_->Exit( | |
379 IBusClient::RESTART_IBUS_DAEMON, | |
380 base::Bind(&MockErrorCallback::Run, | |
381 base::Unretained(&error_callback))); | |
382 | |
383 // Run the message loop. | |
384 message_loop_.RunUntilIdle(); | |
385 } | |
386 | |
387 TEST_F(IBusClientTest, ExitTest_MethodCallFail) { | |
388 // Set expectations | |
389 EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _)) | |
390 .WillOnce(Invoke(this, &IBusClientTest::OnExitFail)); | |
391 MockErrorCallback error_callback; | |
392 EXPECT_CALL(error_callback, Run()); | |
393 | |
394 // Create empty response. | |
395 scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty()); | |
396 response_ = response.get(); | |
397 | |
398 // The error response is not used in SetGLobalEngine. | |
399 error_response_ = NULL; | |
400 | |
401 // Call CreateInputContext. | |
402 client_->Exit( | |
403 IBusClient::RESTART_IBUS_DAEMON, | |
404 base::Bind(&MockErrorCallback::Run, | |
405 base::Unretained(&error_callback))); | |
406 | |
407 // Run the message loop. | |
408 message_loop_.RunUntilIdle(); | |
409 } | |
410 | |
411 } // namespace chromeos | |
OLD | NEW |