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.
5 #include "chromeos/dbus/ibus/ibus_panel_service.h"
9 #include "base/message_loop.h"
10 #include "base/values.h"
11 #include "chromeos/dbus/ibus/ibus_constants.h"
12 #include "chromeos/dbus/ibus/ibus_input_context_client.h"
13 #include "chromeos/dbus/ibus/ibus_lookup_table.h"
14 #include "chromeos/dbus/ibus/ibus_property.h"
15 #include "chromeos/dbus/ibus/ibus_text.h"
16 #include "dbus/message.h"
17 #include "dbus/mock_bus.h"
18 #include "dbus/mock_exported_object.h"
19 #include "dbus/object_path.h"
20 #include "dbus/values_util.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 using testing::Invoke
;
25 using testing::Return
;
32 class MockIBusPanelCandidateWindowHandler
33 : public IBusPanelCandidateWindowHandlerInterface
{
35 MockIBusPanelCandidateWindowHandler() {}
36 MOCK_METHOD2(UpdateLookupTable
, void(const IBusLookupTable
& table
,
38 MOCK_METHOD0(HideLookupTable
, void());
39 MOCK_METHOD2(UpdateAuxiliaryText
, void(const std::string
& text
,
41 MOCK_METHOD0(HideAuxiliaryText
, void());
42 MOCK_METHOD3(UpdatePreeditText
, void(const std::string
& text
,
45 MOCK_METHOD0(HidePreeditText
, void());
46 MOCK_METHOD2(SetCursorLocation
, void(const ibus::Rect
& cursor_location
,
47 const ibus::Rect
& composition_head
));
50 DISALLOW_COPY_AND_ASSIGN(MockIBusPanelCandidateWindowHandler
);
53 class MockIBusPanelPropertyHandler
: public IBusPanelPropertyHandlerInterface
{
55 MockIBusPanelPropertyHandler() {}
56 MOCK_METHOD1(RegisterProperties
,
57 void(const IBusPropertyList
& properties
));
58 MOCK_METHOD1(UpdateProperty
, void(const IBusProperty
& property
));
61 DISALLOW_COPY_AND_ASSIGN(MockIBusPanelPropertyHandler
);
64 class MockResponseSender
{
66 // GMock doesn't support mocking methods which take scoped_ptr<>.
67 MOCK_METHOD1(MockRun
, void(dbus::Response
* reponse
));
68 void Run(scoped_ptr
<dbus::Response
> response
) {
69 MockRun(response
.get());
73 // This class is used to verify that a method call response is empty. This class
74 // verifies the response has correct message serial number and has no entry in
76 class EmptyResponseVerifier
{
78 explicit EmptyResponseVerifier(uint32 expected_serial_number
)
79 : expected_serial_number_(expected_serial_number
) {}
81 // Verifies the given |response| has no argument.
82 void Verify(dbus::Response
* response
) {
83 EXPECT_EQ(expected_serial_number_
, response
->GetReplySerial());
84 dbus::MessageReader
reader(response
);
85 EXPECT_FALSE(reader
.HasMoreData());
89 const uint32 expected_serial_number_
;
91 DISALLOW_COPY_AND_ASSIGN(EmptyResponseVerifier
);
94 // This class is used to verify the CandidateClicked method call arguments.
95 class CandidateClickedVerifier
{
97 CandidateClickedVerifier(uint32 expected_index
,
98 ibus::IBusMouseButton expected_button
,
99 uint32 expected_state
)
100 : expected_index_(expected_index
),
101 expected_button_(expected_button
),
102 expected_state_(expected_state
) {}
104 // Verifies the given |signal| is a valid message.
105 void Verify(dbus::Signal
* signal
) {
110 // Read signal arguments.
111 dbus::MessageReader
reader(signal
);
112 EXPECT_TRUE(reader
.PopUint32(&index
));
113 EXPECT_TRUE(reader
.PopUint32(&button
));
114 EXPECT_TRUE(reader
.PopUint32(&state
));
115 EXPECT_FALSE(reader
.HasMoreData());
118 EXPECT_EQ(expected_index_
, index
);
119 EXPECT_EQ(expected_button_
, static_cast<ibus::IBusMouseButton
>(button
));
120 EXPECT_EQ(expected_state_
, state
);
124 uint32 expected_index_
;
125 ibus::IBusMouseButton expected_button_
;
126 uint32 expected_state_
;
128 DISALLOW_COPY_AND_ASSIGN(CandidateClickedVerifier
);
131 // This class is used to verify that a method call has empty argument.
132 class NullArgumentVerifier
{
134 explicit NullArgumentVerifier(const std::string
& expected_signal_name
)
135 : expected_signal_name_(expected_signal_name
) {}
137 // Verifies the given |signal| is a valid message.
138 void Verify(dbus::Signal
* signal
) {
139 EXPECT_EQ(expected_signal_name_
, signal
->GetMember());
140 dbus::MessageReader
reader(signal
);
141 EXPECT_FALSE(reader
.HasMoreData());
145 std::string expected_signal_name_
;
146 DISALLOW_COPY_AND_ASSIGN(NullArgumentVerifier
);
149 class UpdateLookupTableVerifier
{
151 UpdateLookupTableVerifier(const IBusLookupTable
& table
, bool visible
)
155 void Verify(const IBusLookupTable
& table
, bool visible
) {
156 EXPECT_EQ(table_
.page_size(), table
.page_size());
157 EXPECT_EQ(table_
.cursor_position(), table
.cursor_position());
158 EXPECT_EQ(visible_
, visible
);
162 const IBusLookupTable
& table_
;
165 DISALLOW_COPY_AND_ASSIGN(UpdateLookupTableVerifier
);
168 // This class is used to verify that a method call which has a PropertyList
169 // object. This class verifies a method call has correct arguments based on
170 // checking given |keys|.
171 class PropertyListVerifier
{
173 explicit PropertyListVerifier(const std::vector
<std::string
>& expected_keys
)
174 : expected_keys_(expected_keys
) {
177 // Verifies the given |resposne| has IBusPropertyList.
178 void Verify(const IBusPropertyList
& properties
) {
179 ASSERT_EQ(expected_keys_
.size(), properties
.size());
180 for (size_t i
= 0; i
< properties
.size(); ++i
) {
181 EXPECT_EQ(expected_keys_
[i
], properties
[i
]->key());
186 const std::vector
<std::string
> expected_keys_
;
189 // This class is used to verify that a method call which has a Property object.
190 // This class verifies a method call has correct argument based on |key|.
191 class PropertyVerifier
{
193 explicit PropertyVerifier(const std::string
& key
) : key_(key
) {}
195 // Verifies the given |resposne| has IBusPropertyList.
196 void Verify(const IBusProperty
& property
) {
197 EXPECT_EQ(key_
, property
.key());
201 const std::string key_
;
206 class IBusPanelServiceTest
: public testing::Test
{
208 IBusPanelServiceTest() {}
210 virtual void SetUp() OVERRIDE
{
211 // Create a mock bus.
212 dbus::Bus::Options options
;
213 options
.bus_type
= dbus::Bus::SYSTEM
;
214 mock_bus_
= new dbus::MockBus(options
);
216 // Create a mock exported object.
217 mock_exported_object_
= new dbus::MockExportedObject(
219 dbus::ObjectPath(ibus::panel::kServicePath
));
221 EXPECT_CALL(*mock_bus_
.get(),
222 GetExportedObject(dbus::ObjectPath(
223 ibus::panel::kServicePath
)))
224 .WillOnce(Return(mock_exported_object_
.get()));
226 EXPECT_CALL(*mock_exported_object_
, ExportMethod(
227 ibus::panel::kServiceInterface
,
228 ibus::panel::kUpdateLookupTableMethod
, _
, _
))
230 Invoke(this, &IBusPanelServiceTest::OnMethodExported
));
232 EXPECT_CALL(*mock_exported_object_
, ExportMethod(
233 ibus::panel::kServiceInterface
,
234 ibus::panel::kHideLookupTableMethod
, _
, _
))
236 Invoke(this, &IBusPanelServiceTest::OnMethodExported
));
238 EXPECT_CALL(*mock_exported_object_
, ExportMethod(
239 ibus::panel::kServiceInterface
,
240 ibus::panel::kUpdateAuxiliaryTextMethod
, _
, _
))
242 Invoke(this, &IBusPanelServiceTest::OnMethodExported
));
244 EXPECT_CALL(*mock_exported_object_
, ExportMethod(
245 ibus::panel::kServiceInterface
,
246 ibus::panel::kHideAuxiliaryTextMethod
, _
, _
))
248 Invoke(this, &IBusPanelServiceTest::OnMethodExported
));
250 EXPECT_CALL(*mock_exported_object_
, ExportMethod(
251 ibus::panel::kServiceInterface
,
252 ibus::panel::kUpdatePreeditTextMethod
, _
, _
))
254 Invoke(this, &IBusPanelServiceTest::OnMethodExported
));
256 EXPECT_CALL(*mock_exported_object_
, ExportMethod(
257 ibus::panel::kServiceInterface
,
258 ibus::panel::kHidePreeditTextMethod
, _
, _
))
260 Invoke(this, &IBusPanelServiceTest::OnMethodExported
));
262 EXPECT_CALL(*mock_exported_object_
, ExportMethod(
263 ibus::panel::kServiceInterface
,
264 ibus::panel::kRegisterPropertiesMethod
, _
, _
))
266 Invoke(this, &IBusPanelServiceTest::OnMethodExported
));
268 EXPECT_CALL(*mock_exported_object_
, ExportMethod(
269 ibus::panel::kServiceInterface
,
270 ibus::panel::kUpdatePropertyMethod
, _
, _
))
272 Invoke(this, &IBusPanelServiceTest::OnMethodExported
));
274 EXPECT_CALL(*mock_exported_object_
, ExportMethod(
275 ibus::panel::kServiceInterface
,
276 ibus::panel::kFocusInMethod
, _
, _
))
278 Invoke(this, &IBusPanelServiceTest::OnMethodExported
));
280 EXPECT_CALL(*mock_exported_object_
, ExportMethod(
281 ibus::panel::kServiceInterface
,
282 ibus::panel::kFocusOutMethod
, _
, _
))
284 Invoke(this, &IBusPanelServiceTest::OnMethodExported
));
286 EXPECT_CALL(*mock_exported_object_
, ExportMethod(
287 ibus::panel::kServiceInterface
,
288 ibus::panel::kStateChangedMethod
, _
, _
))
290 Invoke(this, &IBusPanelServiceTest::OnMethodExported
));
292 // Suppress uninteresting mock function call warning.
293 EXPECT_CALL(*mock_bus_
.get(),
294 AssertOnOriginThread())
295 .WillRepeatedly(Return());
297 stub_input_context_client_
.reset(IBusInputContextClient::Create(
298 STUB_DBUS_CLIENT_IMPLEMENTATION
));
301 service_
.reset(IBusPanelService::Create(
302 REAL_DBUS_CLIENT_IMPLEMENTATION
,
304 stub_input_context_client_
.get()));
306 // Set panel handler.
307 candidate_window_handler_
.reset(new MockIBusPanelCandidateWindowHandler());
308 service_
->SetUpCandidateWindowHandler(candidate_window_handler_
.get());
309 property_handler_
.reset(new MockIBusPanelPropertyHandler());
310 service_
->SetUpPropertyHandler(property_handler_
.get());
314 // The service to be tested.
315 scoped_ptr
<IBusPanelService
> service_
;
316 // The mock candidate window panel handler. Do not free, this is owned by
318 scoped_ptr
<MockIBusPanelCandidateWindowHandler
> candidate_window_handler_
;
319 // The mock property handler. Do not free, this is owned by IBusPanelService.
320 scoped_ptr
<MockIBusPanelPropertyHandler
> property_handler_
;
321 // The stub input context client.
322 scoped_ptr
<IBusInputContextClient
> stub_input_context_client_
;
324 scoped_refptr
<dbus::MockBus
> mock_bus_
;
325 // The mock exported object.
326 scoped_refptr
<dbus::MockExportedObject
> mock_exported_object_
;
327 // A message loop to emulate asynchronous behavior.
328 MessageLoop message_loop_
;
329 // The map from method call to method call handler.
330 std::map
<std::string
, dbus::ExportedObject::MethodCallCallback
>
331 method_callback_map_
;
334 // Used to implement the mock method call.
335 void OnMethodExported(
336 const std::string
& interface_name
,
337 const std::string
& method_name
,
338 const dbus::ExportedObject::MethodCallCallback
& method_callback
,
339 const dbus::ExportedObject::OnExportedCallback
& on_exported_callback
) {
340 method_callback_map_
[method_name
] = method_callback
;
341 const bool success
= true;
342 message_loop_
.PostTask(FROM_HERE
, base::Bind(on_exported_callback
,
349 TEST_F(IBusPanelServiceTest
, HideLookupTableTest
) {
351 const uint32 kSerialNo
= 1;
352 EXPECT_CALL(*candidate_window_handler_
, HideLookupTable());
353 MockResponseSender response_sender
;
354 EmptyResponseVerifier
response_expectation(kSerialNo
);
355 EXPECT_CALL(response_sender
, MockRun(_
))
356 .WillOnce(Invoke(&response_expectation
,
357 &EmptyResponseVerifier::Verify
));
359 // Create method call;
360 dbus::MethodCall
method_call(ibus::panel::kServiceInterface
,
361 ibus::panel::kHideLookupTableMethod
);
362 method_call
.SetSerial(kSerialNo
);
364 // Call exported function.
365 EXPECT_NE(method_callback_map_
.find(ibus::panel::kHideLookupTableMethod
),
366 method_callback_map_
.end());
367 method_callback_map_
[ibus::panel::kHideLookupTableMethod
].Run(
369 base::Bind(&MockResponseSender::Run
,
370 base::Unretained(&response_sender
)));
373 TEST_F(IBusPanelServiceTest
, HideAuxiliaryTextTest
) {
375 const uint32 kSerialNo
= 1;
376 EXPECT_CALL(*candidate_window_handler_
, HideAuxiliaryText());
377 MockResponseSender response_sender
;
378 EmptyResponseVerifier
response_expectation(kSerialNo
);
379 EXPECT_CALL(response_sender
, MockRun(_
))
380 .WillOnce(Invoke(&response_expectation
,
381 &EmptyResponseVerifier::Verify
));
383 // Create method call;
384 dbus::MethodCall
method_call(ibus::panel::kServiceInterface
,
385 ibus::panel::kHideAuxiliaryTextMethod
);
386 method_call
.SetSerial(kSerialNo
);
388 // Call exported function.
389 EXPECT_NE(method_callback_map_
.find(ibus::panel::kHideAuxiliaryTextMethod
),
390 method_callback_map_
.end());
391 method_callback_map_
[ibus::panel::kHideAuxiliaryTextMethod
].Run(
393 base::Bind(&MockResponseSender::Run
,
394 base::Unretained(&response_sender
)));
397 TEST_F(IBusPanelServiceTest
, HidePreeditTextTest
) {
399 const uint32 kSerialNo
= 1;
400 EXPECT_CALL(*candidate_window_handler_
, HidePreeditText());
401 MockResponseSender response_sender
;
402 EmptyResponseVerifier
response_expectation(kSerialNo
);
403 EXPECT_CALL(response_sender
, MockRun(_
))
404 .WillOnce(Invoke(&response_expectation
,
405 &EmptyResponseVerifier::Verify
));
407 // Create method call;
408 dbus::MethodCall
method_call(ibus::panel::kServiceInterface
,
409 ibus::panel::kHidePreeditTextMethod
);
410 method_call
.SetSerial(kSerialNo
);
412 // Call exported function.
413 EXPECT_NE(method_callback_map_
.find(ibus::panel::kHidePreeditTextMethod
),
414 method_callback_map_
.end());
415 method_callback_map_
[ibus::panel::kHidePreeditTextMethod
].Run(
417 base::Bind(&MockResponseSender::Run
,
418 base::Unretained(&response_sender
)));
421 TEST_F(IBusPanelServiceTest
, UpdateLookupTableTest
) {
423 const uint32 kSerialNo
= 1;
424 IBusLookupTable table
;
425 table
.set_page_size(3);
426 table
.set_cursor_position(4);
427 const bool kVisible
= false;
430 UpdateLookupTableVerifier
evaluator(table
, kVisible
);
431 EXPECT_CALL(*candidate_window_handler_
, UpdateLookupTable(_
, _
))
432 .WillOnce(Invoke(&evaluator
,
433 &UpdateLookupTableVerifier::Verify
));
434 MockResponseSender response_sender
;
435 EmptyResponseVerifier
response_expectation(kSerialNo
);
436 EXPECT_CALL(response_sender
, MockRun(_
))
437 .WillOnce(Invoke(&response_expectation
,
438 &EmptyResponseVerifier::Verify
));
440 // Create method call;
441 dbus::MethodCall
method_call(ibus::panel::kServiceInterface
,
442 ibus::panel::kUpdateLookupTableMethod
);
443 method_call
.SetSerial(kSerialNo
);
444 dbus::MessageWriter
writer(&method_call
);
445 AppendIBusLookupTable(table
, &writer
);
446 writer
.AppendBool(kVisible
);
448 // Call exported function.
449 EXPECT_NE(method_callback_map_
.find(ibus::panel::kUpdateLookupTableMethod
),
450 method_callback_map_
.end());
451 method_callback_map_
[ibus::panel::kUpdateLookupTableMethod
].Run(
453 base::Bind(&MockResponseSender::Run
,
454 base::Unretained(&response_sender
)));
457 TEST_F(IBusPanelServiceTest
, UpdateAuxiliaryTextTest
) {
459 const uint32 kSerialNo
= 1;
460 const std::string text
= "Sample text";
461 const bool kVisible
= false;
463 EXPECT_CALL(*candidate_window_handler_
, UpdateAuxiliaryText(text
, kVisible
));
464 MockResponseSender response_sender
;
465 EmptyResponseVerifier
response_expectation(kSerialNo
);
466 EXPECT_CALL(response_sender
, MockRun(_
))
467 .WillOnce(Invoke(&response_expectation
,
468 &EmptyResponseVerifier::Verify
));
470 // Create method call;
471 dbus::MethodCall
method_call(ibus::panel::kServiceInterface
,
472 ibus::panel::kUpdateAuxiliaryTextMethod
);
473 method_call
.SetSerial(kSerialNo
);
474 dbus::MessageWriter
writer(&method_call
);
475 AppendStringAsIBusText(text
, &writer
);
476 writer
.AppendBool(kVisible
);
478 // Call exported function.
479 EXPECT_NE(method_callback_map_
.find(ibus::panel::kUpdateAuxiliaryTextMethod
),
480 method_callback_map_
.end());
481 method_callback_map_
[ibus::panel::kUpdateAuxiliaryTextMethod
].Run(
483 base::Bind(&MockResponseSender::Run
,
484 base::Unretained(&response_sender
)));
487 TEST_F(IBusPanelServiceTest
, UpdatePreeditTextTest
) {
489 const uint32 kSerialNo
= 1;
490 const std::string text
= "Sample text";
491 const uint32 kCursorPos
= 4;
492 const bool kVisible
= false;
494 EXPECT_CALL(*candidate_window_handler_
,
495 UpdatePreeditText(text
, kCursorPos
, kVisible
));
496 MockResponseSender response_sender
;
497 EmptyResponseVerifier
response_expectation(kSerialNo
);
498 EXPECT_CALL(response_sender
, MockRun(_
))
499 .WillOnce(Invoke(&response_expectation
,
500 &EmptyResponseVerifier::Verify
));
502 // Create method call;
503 dbus::MethodCall
method_call(ibus::panel::kServiceInterface
,
504 ibus::panel::kUpdatePreeditTextMethod
);
505 method_call
.SetSerial(kSerialNo
);
506 dbus::MessageWriter
writer(&method_call
);
507 AppendStringAsIBusText(text
, &writer
);
508 writer
.AppendUint32(kCursorPos
);
509 writer
.AppendBool(kVisible
);
511 // Call exported function.
512 EXPECT_NE(method_callback_map_
.find(ibus::panel::kUpdatePreeditTextMethod
),
513 method_callback_map_
.end());
514 method_callback_map_
[ibus::panel::kUpdatePreeditTextMethod
].Run(
516 base::Bind(&MockResponseSender::Run
,
517 base::Unretained(&response_sender
)));
520 TEST_F(IBusPanelServiceTest
, CursorUpTest
) {
522 NullArgumentVerifier
evaluator(ibus::panel::kCursorUpSignal
);
523 EXPECT_CALL(*mock_exported_object_
, SendSignal(_
))
524 .WillOnce(Invoke(&evaluator
, &NullArgumentVerifier::Verify
));
527 service_
->CursorUp();
530 TEST_F(IBusPanelServiceTest
, CursorDownTest
) {
532 NullArgumentVerifier
evaluator(ibus::panel::kCursorDownSignal
);
533 EXPECT_CALL(*mock_exported_object_
, SendSignal(_
))
534 .WillOnce(Invoke(&evaluator
, &NullArgumentVerifier::Verify
));
537 service_
->CursorDown();
540 TEST_F(IBusPanelServiceTest
, PageUpTest
) {
542 NullArgumentVerifier
evaluator(ibus::panel::kPageUpSignal
);
543 EXPECT_CALL(*mock_exported_object_
, SendSignal(_
))
544 .WillOnce(Invoke(&evaluator
, &NullArgumentVerifier::Verify
));
550 TEST_F(IBusPanelServiceTest
, PageDownTest
) {
552 NullArgumentVerifier
evaluator(ibus::panel::kPageDownSignal
);
553 EXPECT_CALL(*mock_exported_object_
, SendSignal(_
))
554 .WillOnce(Invoke(&evaluator
, &NullArgumentVerifier::Verify
));
557 service_
->PageDown();
560 TEST_F(IBusPanelServiceTest
, RegisterPropertiesTest
) {
562 std::vector
<std::string
> keys
;
563 keys
.push_back("key1");
564 keys
.push_back("key2");
565 keys
.push_back("key3");
566 IBusPropertyList properties
;
567 for (size_t i
= 0; i
< keys
.size(); ++i
) {
568 IBusProperty
* property
= new IBusProperty
;
569 property
->set_key(keys
[i
]);
570 properties
.push_back(property
);
573 PropertyListVerifier
response_expectation(keys
);
574 EXPECT_CALL(*property_handler_
, RegisterProperties(_
))
575 .WillOnce(Invoke(&response_expectation
,
576 &PropertyListVerifier::Verify
));
578 MockResponseSender response_sender
;
579 EXPECT_CALL(response_sender
, MockRun(_
));
581 // Create method call;
582 dbus::MethodCall
method_call(ibus::panel::kServiceInterface
,
583 ibus::panel::kRegisterPropertiesMethod
);
584 method_call
.SetSerial(1UL);
585 dbus::MessageWriter
writer(&method_call
);
586 AppendIBusPropertyList(properties
, &writer
);
588 // Call exported function.
589 EXPECT_NE(method_callback_map_
.find(ibus::panel::kRegisterPropertiesMethod
),
590 method_callback_map_
.end());
591 method_callback_map_
[ibus::panel::kRegisterPropertiesMethod
].Run(
593 base::Bind(&MockResponseSender::Run
, base::Unretained(&response_sender
)));
596 TEST_F(IBusPanelServiceTest
, UpdatePropertyTest
) {
598 const char kKey
[] = "key";
599 IBusProperty property
;
600 property
.set_key(kKey
);
602 PropertyVerifier
response_expectation(kKey
);
603 EXPECT_CALL(*property_handler_
, UpdateProperty(_
))
604 .WillOnce(Invoke(&response_expectation
, &PropertyVerifier::Verify
));
606 MockResponseSender response_sender
;
607 EXPECT_CALL(response_sender
, MockRun(_
));
609 // Create method call;
610 dbus::MethodCall
method_call(ibus::panel::kServiceInterface
,
611 ibus::panel::kUpdatePropertyMethod
);
612 method_call
.SetSerial(1UL);
613 dbus::MessageWriter
writer(&method_call
);
614 AppendIBusProperty(property
, &writer
);
616 // Call exported function.
617 EXPECT_NE(method_callback_map_
.find(ibus::panel::kUpdatePropertyMethod
),
618 method_callback_map_
.end());
619 method_callback_map_
[ibus::panel::kUpdatePropertyMethod
].Run(
621 base::Bind(&MockResponseSender::Run
,
622 base::Unretained(&response_sender
)));
625 } // namespace chromeos