diff options
author | nona@chromium.org <nona@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-18 19:35:47 +0000 |
---|---|---|
committer | nona@chromium.org <nona@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-18 19:35:47 +0000 |
commit | 9bd9e9f1eb9def55a0b57e8eb2c67748a7e43f40 (patch) | |
tree | 7df1a53779bef2a0a288ed047f720c7ead5b0a7f /ui | |
parent | d816127ab369f884b81bab3a187380c91bf6a894 (diff) | |
download | chromium_src-9bd9e9f1eb9def55a0b57e8eb2c67748a7e43f40.zip chromium_src-9bd9e9f1eb9def55a0b57e8eb2c67748a7e43f40.tar.gz chromium_src-9bd9e9f1eb9def55a0b57e8eb2c67748a7e43f40.tar.bz2 |
Introduce unit tests for ui::InputMethodIBus
This patch set only introduces unit tests for DispatchKeyEvent with DBus communication.
The unit tests for ProcessKeyEventPostIME will be done by another patch set.
BUG=134616
TEST=ran ui_unittests
Review URL: https://chromiumcodereview.appspot.com/11175004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@162760 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/base/ime/input_method_ibus.cc | 37 | ||||
-rw-r--r-- | ui/base/ime/input_method_ibus.h | 23 | ||||
-rw-r--r-- | ui/base/ime/input_method_ibus_unittest.cc | 673 |
3 files changed, 704 insertions, 29 deletions
diff --git a/ui/base/ime/input_method_ibus.cc b/ui/base/ime/input_method_ibus.cc index 5a643c7..1113f51 100644 --- a/ui/base/ime/input_method_ibus.cc +++ b/ui/base/ime/input_method_ibus.cc @@ -68,24 +68,6 @@ uint32 IBusStateFromXFlags(unsigned int flags) { Button1Mask | Button2Mask | Button3Mask)); } -void IBusKeyEventFromNativeKeyEvent(const base::NativeEvent& native_event, - uint32* ibus_keyval, - uint32* ibus_keycode, - uint32* ibus_state) { - DCHECK(native_event); // A fabricated event is not supported here. - XKeyEvent* x_key = GetKeyEvent(native_event); - - // Yes, ibus uses X11 keysym. We cannot use XLookupKeysym(), which doesn't - // translate Shift and CapsLock states. - KeySym keysym = NoSymbol; - ::XLookupString(x_key, NULL, 0, &keysym, NULL); - *ibus_keyval = keysym; - *ibus_keycode = x_key->keycode; - *ibus_state = IBusStateFromXFlags(x_key->state); - if (native_event->type == KeyRelease) - *ibus_state |= kIBusReleaseMask; -} - chromeos::IBusInputContextClient* GetInputContextClient() { return chromeos::DBusThreadManager::Get()->GetIBusInputContextClient(); } @@ -551,6 +533,25 @@ void InputMethodIBus::ProcessKeyEventPostIME( DispatchKeyEventPostIME(native_event); } +void InputMethodIBus::IBusKeyEventFromNativeKeyEvent( + const base::NativeEvent& native_event, + uint32* ibus_keyval, + uint32* ibus_keycode, + uint32* ibus_state) { + DCHECK(native_event); // A fabricated event is not supported here. + XKeyEvent* x_key = GetKeyEvent(native_event); + + // Yes, ibus uses X11 keysym. We cannot use XLookupKeysym(), which doesn't + // translate Shift and CapsLock states. + KeySym keysym = NoSymbol; + ::XLookupString(x_key, NULL, 0, &keysym, NULL); + *ibus_keyval = keysym; + *ibus_keycode = x_key->keycode; + *ibus_state = IBusStateFromXFlags(x_key->state); + if (native_event->type == KeyRelease) + *ibus_state |= kIBusReleaseMask; +} + void InputMethodIBus::ProcessFilteredKeyPressEvent( const base::NativeEvent& native_event) { if (NeedInsertChar()) diff --git a/ui/base/ime/input_method_ibus.h b/ui/base/ime/input_method_ibus.h index 396d82d..e02659a 100644 --- a/ui/base/ime/input_method_ibus.h +++ b/ui/base/ime/input_method_ibus.h @@ -66,6 +66,21 @@ class UI_EXPORT InputMethodIBus : public InputMethodBase { uint32 cursor_position, CompositionText* out_composition) const; + // Process a key returned from the input method. + virtual void ProcessKeyEventPostIME(const base::NativeEvent& native_key_event, + uint32 ibus_keycode, + bool handled); + + // Converts |native_event| to ibus representation. + virtual void IBusKeyEventFromNativeKeyEvent( + const base::NativeEvent& native_event, + uint32* ibus_keyval, + uint32* ibus_keycode, + uint32* ibus_state); + + // Resets context and abandon all pending results and key events. + void ResetContext(); + private: enum InputContextState { // The input context is not working. @@ -96,18 +111,10 @@ class UI_EXPORT InputMethodIBus : public InputMethodBase { // Asks the client to confirm current composition text. void ConfirmCompositionText(); - // Resets context and abandon all pending results and key events. - void ResetContext(); - // Checks the availability of focused text input client and update focus // state. void UpdateContextFocusState(); - // Process a key returned from the input method. - void ProcessKeyEventPostIME(const base::NativeEvent& native_key_event, - uint32 ibus_keycode, - bool handled); - // Processes a key event that was already filtered by the input method. // A VKEY_PROCESSKEY may be dispatched to the focused View. void ProcessFilteredKeyPressEvent(const base::NativeEvent& native_key_event); diff --git a/ui/base/ime/input_method_ibus_unittest.cc b/ui/base/ime/input_method_ibus_unittest.cc index d926048..c356b30 100644 --- a/ui/base/ime/input_method_ibus_unittest.cc +++ b/ui/base/ime/input_method_ibus_unittest.cc @@ -2,6 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <X11/Xlib.h> +#undef Bool +#undef FocusIn +#undef FocusOut +#undef None + #include <cstring> #include "base/i18n/char_iterator.h" @@ -21,6 +27,15 @@ namespace ui { namespace { const int kCreateInputContextMaxTrialCount = 10; +const uint32 kTestIBusKeyVal1 = 97; +const uint32 kTestIBusKeyVal2 = 30; +const uint32 kTestIBusKeyVal3 = 0; +const uint32 kTestIBusKeyCode1 = 98; +const uint32 kTestIBusKeyCode2 = 48; +const uint32 kTestIBusKeyCode3 = 1; +const uint32 kTestIBusState1 = 99; +const uint32 kTestIBusState2 = 46; +const uint32 kTestIBusState3 = 8; uint32 GetOffsetInUTF16(const std::string& utf8_string, uint32 utf8_offset) { string16 utf16_string = UTF8ToUTF16(utf8_string); @@ -31,17 +46,101 @@ uint32 GetOffsetInUTF16(const std::string& utf8_string, uint32 utf8_offset) { return char_iterator.array_pos(); } +bool IsEqualXKeyEvent(const XEvent& e1, const XEvent& e2) { + if ((e1.type == KeyPress && e2.type == KeyPress) || + (e1.type == KeyRelease && e2.type == KeyRelease)) { + return !std::memcmp(&e1.xkey, &e2.xkey, sizeof(XKeyEvent)); + } + return false; +} + +enum KeyEventHandlerBehavior { + KEYEVENT_CONSUME, + KEYEVENT_NOT_CONSUME, + KEYEVENT_ERROR, +}; + } // namespace +using chromeos::IBusInputContextClient; + class TestableInputMethodIBus : public InputMethodIBus { public: explicit TestableInputMethodIBus(internal::InputMethodDelegate* delegate) - : InputMethodIBus(delegate) { + : InputMethodIBus(delegate), + process_key_event_post_ime_call_count_(0) { } - // Change access rights. + struct ProcessKeyEventPostIMEArgs { + ProcessKeyEventPostIMEArgs() : ibus_keyval(0), handled(false) { + std::memset(&event, 0, sizeof(XEvent)); + } + XEvent event; + uint32 ibus_keyval; + bool handled; + }; + + struct IBusKeyEventFromNativeKeyEventResult { + IBusKeyEventFromNativeKeyEventResult() : keyval(0), keycode(0), state(0) {} + uint32 keyval; + uint32 keycode; + uint32 state; + }; + + // InputMethodIBus override. + virtual void ProcessKeyEventPostIME(const base::NativeEvent& native_key_event, + uint32 ibus_keyval, + bool handled) OVERRIDE { + process_key_event_post_ime_args_.event = *native_key_event; + process_key_event_post_ime_args_.ibus_keyval = ibus_keyval; + process_key_event_post_ime_args_.handled = handled; + ++process_key_event_post_ime_call_count_; + } + + // We can't call X11 related function without display in unit test, so + // override with mock function. + virtual void IBusKeyEventFromNativeKeyEvent( + const base::NativeEvent& native_event, + uint32* ibus_keyval, + uint32* ibus_keycode, + uint32* ibus_state) OVERRIDE { + EXPECT_TRUE(native_event); + EXPECT_TRUE(ibus_keyval); + EXPECT_TRUE(ibus_keycode); + EXPECT_TRUE(ibus_state); + *ibus_keyval = ibus_key_event_from_native_key_event_result_.keyval; + *ibus_keycode = ibus_key_event_from_native_key_event_result_.keycode; + *ibus_state = ibus_key_event_from_native_key_event_result_.state; + } + + void ResetCallCount() { + process_key_event_post_ime_call_count_ = 0; + } + + const ProcessKeyEventPostIMEArgs& process_key_event_post_ime_args() const { + return process_key_event_post_ime_args_; + } + + int process_key_event_post_ime_call_count() const { + return process_key_event_post_ime_call_count_; + } + + IBusKeyEventFromNativeKeyEventResult* + mutable_ibus_key_event_from_native_key_event_result() { + return &ibus_key_event_from_native_key_event_result_; + } + + // Change access rights for testing. using InputMethodIBus::ExtractCompositionText; + using InputMethodIBus::ResetContext; + + private: + ProcessKeyEventPostIMEArgs process_key_event_post_ime_args_; + int process_key_event_post_ime_call_count_; + + IBusKeyEventFromNativeKeyEventResult + ibus_key_event_from_native_key_event_result_; }; class CreateInputContextSuccessHandler { @@ -116,6 +215,82 @@ class CreateInputContextDelayHandler { DISALLOW_COPY_AND_ASSIGN(CreateInputContextDelayHandler); }; +class SynchronousKeyEventHandler { + public: + SynchronousKeyEventHandler(uint32 expected_keyval, + uint32 expected_keycode, + uint32 expected_state, + KeyEventHandlerBehavior behavior) + : expected_keyval_(expected_keyval), + expected_keycode_(expected_keycode), + expected_state_(expected_state), + behavior_(behavior) {} + + virtual ~SynchronousKeyEventHandler() {} + + void Run(uint32 keyval, + uint32 keycode, + uint32 state, + const IBusInputContextClient::ProcessKeyEventCallback& callback, + const IBusInputContextClient::ErrorCallback& error_callback) { + EXPECT_EQ(expected_keyval_, keyval); + EXPECT_EQ(expected_keycode_, keycode); + EXPECT_EQ(expected_state_, state); + if (behavior_ == KEYEVENT_ERROR) + error_callback.Run(); + else + callback.Run(behavior_ == KEYEVENT_CONSUME); + } + + private: + const uint32 expected_keyval_; + const uint32 expected_keycode_; + const uint32 expected_state_; + const KeyEventHandlerBehavior behavior_; + + DISALLOW_COPY_AND_ASSIGN(SynchronousKeyEventHandler); +}; + +class AsynchronousKeyEventHandler { + public: + AsynchronousKeyEventHandler(uint32 expected_keyval, + uint32 expected_keycode, + uint32 expected_state) + : expected_keyval_(expected_keyval), + expected_keycode_(expected_keycode), + expected_state_(expected_state) {} + + virtual ~AsynchronousKeyEventHandler() {} + + void Run(uint32 keyval, + uint32 keycode, + uint32 state, + const IBusInputContextClient::ProcessKeyEventCallback& callback, + const IBusInputContextClient::ErrorCallback& error_callback) { + EXPECT_EQ(expected_keyval_, keyval); + EXPECT_EQ(expected_keycode_, keycode); + EXPECT_EQ(expected_state_, state); + callback_ = callback; + error_callback_ = error_callback; + } + + void RunCallback(KeyEventHandlerBehavior behavior) { + if (behavior == KEYEVENT_ERROR) + error_callback_.Run(); + else + callback_.Run(behavior == KEYEVENT_CONSUME); + } + + private: + const uint32 expected_keyval_; + const uint32 expected_keycode_; + const uint32 expected_state_; + IBusInputContextClient::ProcessKeyEventCallback callback_; + IBusInputContextClient::ErrorCallback error_callback_; + + DISALLOW_COPY_AND_ASSIGN(AsynchronousKeyEventHandler); +}; + class InputMethodIBusTest : public internal::InputMethodDelegate, public testing::Test, public TextInputClient { @@ -893,6 +1068,498 @@ TEST_F(InputMethodIBusTest, ExtractCompositionTextTest_SelectionEndWithCursor) { EXPECT_TRUE(composition_text.underlines[0].thick); } -// TODO(nona): Write more tests, especially for key event functions. +class InputMethodIBusKeyEventTest : public InputMethodIBusTest { + public: + InputMethodIBusKeyEventTest() {} + virtual ~InputMethodIBusKeyEventTest() {} + + virtual void SetUp() OVERRIDE { + InputMethodIBusTest::SetUp(); + SetCreateContextSuccessHandler(); + chromeos::DBusThreadManager::Get()->InitIBusBus("dummy address"); + ime_->Init(true); + ime_->OnConnected(); + } + + DISALLOW_COPY_AND_ASSIGN(InputMethodIBusKeyEventTest); +}; + +TEST_F(InputMethodIBusKeyEventTest, KeyEventConsumeTest) { + XEvent event = {}; + event.xkey.type = KeyPress; + + // Set up IBusKeyEventFromNativeKeyEvent result. + ime_->mutable_ibus_key_event_from_native_key_event_result()->keyval + = kTestIBusKeyVal1; + ime_->mutable_ibus_key_event_from_native_key_event_result()->keycode + = kTestIBusKeyCode1; + ime_->mutable_ibus_key_event_from_native_key_event_result()->state + = kTestIBusState1; + + // Set up ProcessKeyEvent handler. + SynchronousKeyEventHandler success_consume_handler(kTestIBusKeyVal1, + kTestIBusKeyCode1, + kTestIBusState1, + KEYEVENT_CONSUME); + mock_ibus_input_context_client_->set_process_key_event_handler( + base::Bind(&SynchronousKeyEventHandler::Run, + base::Unretained(&success_consume_handler))); + + // Do key event. + input_type_ = TEXT_INPUT_TYPE_TEXT; + ime_->OnTextInputTypeChanged(this); + ime_->DispatchKeyEvent(&event); + + // Check result + EXPECT_EQ(1, + mock_ibus_input_context_client_->process_key_event_call_count()); + EXPECT_EQ(1, ime_->process_key_event_post_ime_call_count()); + EXPECT_TRUE(IsEqualXKeyEvent(event, + ime_->process_key_event_post_ime_args().event)); + EXPECT_EQ(kTestIBusKeyVal1, + ime_->process_key_event_post_ime_args().ibus_keyval); + EXPECT_TRUE(ime_->process_key_event_post_ime_args().handled); +} + +TEST_F(InputMethodIBusKeyEventTest, KeyEventNotConsumeTest) { + XEvent event = {}; + event.xkey.type = KeyPress; + + // Set up IBusKeyEventFromNativeKeyEvent result. + ime_->mutable_ibus_key_event_from_native_key_event_result()->keyval + = kTestIBusKeyVal1; + ime_->mutable_ibus_key_event_from_native_key_event_result()->keycode + = kTestIBusKeyCode1; + ime_->mutable_ibus_key_event_from_native_key_event_result()->state + = kTestIBusState1; + + // Set up ProcessKeyEvent handler. + SynchronousKeyEventHandler success_nonconsume_handler(kTestIBusKeyVal1, + kTestIBusKeyCode1, + kTestIBusState1, + KEYEVENT_NOT_CONSUME); + mock_ibus_input_context_client_->set_process_key_event_handler( + base::Bind(&SynchronousKeyEventHandler::Run, + base::Unretained(&success_nonconsume_handler))); + + // Do key event. + input_type_ = TEXT_INPUT_TYPE_TEXT; + ime_->OnTextInputTypeChanged(this); + ime_->DispatchKeyEvent(&event); + + EXPECT_EQ(1, + mock_ibus_input_context_client_->process_key_event_call_count()); + EXPECT_EQ(1, ime_->process_key_event_post_ime_call_count()); + EXPECT_TRUE(IsEqualXKeyEvent(event, + ime_->process_key_event_post_ime_args().event)); + EXPECT_EQ(kTestIBusKeyVal1, + ime_->process_key_event_post_ime_args().ibus_keyval); + EXPECT_FALSE(ime_->process_key_event_post_ime_args().handled); +} + +TEST_F(InputMethodIBusKeyEventTest, KeyEventFailTest) { + XEvent event = {}; + event.xkey.type = KeyPress; + + // Set up IBusKeyEventFromNativeKeyEvent result. + ime_->mutable_ibus_key_event_from_native_key_event_result()->keyval + = kTestIBusKeyVal1; + ime_->mutable_ibus_key_event_from_native_key_event_result()->keycode + = kTestIBusKeyCode1; + ime_->mutable_ibus_key_event_from_native_key_event_result()->state + = kTestIBusState1; + + // Set up ProcessKeyEvent handler. + SynchronousKeyEventHandler fail_handler(kTestIBusKeyVal1, + kTestIBusKeyCode1, + kTestIBusState1, + KEYEVENT_ERROR); + mock_ibus_input_context_client_->set_process_key_event_handler( + base::Bind(&SynchronousKeyEventHandler::Run, + base::Unretained(&fail_handler))); + + // Do key event. + input_type_ = TEXT_INPUT_TYPE_TEXT; + ime_->OnTextInputTypeChanged(this); + ime_->DispatchKeyEvent(&event); + + // Check result + EXPECT_EQ(1, + mock_ibus_input_context_client_->process_key_event_call_count()); + EXPECT_EQ(1, ime_->process_key_event_post_ime_call_count()); + EXPECT_EQ(kTestIBusKeyVal1, + ime_->process_key_event_post_ime_args().ibus_keyval); + // If some error is happend, key should not be consumed. + EXPECT_FALSE(ime_->process_key_event_post_ime_args().handled); +} + +TEST_F(InputMethodIBusKeyEventTest, KeyEventDelayResponseSuccessTest) { + XEvent event = {}; + event.xkey.type = KeyPress; + + // Set up IBusKeyEventFromNativeKeyEvent result. + ime_->mutable_ibus_key_event_from_native_key_event_result()->keyval + = kTestIBusKeyVal1; + ime_->mutable_ibus_key_event_from_native_key_event_result()->keycode + = kTestIBusKeyCode1; + ime_->mutable_ibus_key_event_from_native_key_event_result()->state + = kTestIBusState1; + + // Set up ProcessKeyEvent handler. + AsynchronousKeyEventHandler success_consume_handler(kTestIBusKeyVal1, + kTestIBusKeyCode1, + kTestIBusState1); + mock_ibus_input_context_client_->set_process_key_event_handler( + base::Bind(&AsynchronousKeyEventHandler::Run, + base::Unretained(&success_consume_handler))); + + // Do key event. + input_type_ = TEXT_INPUT_TYPE_TEXT; + ime_->OnTextInputTypeChanged(this); + ime_->DispatchKeyEvent(&event); + + // Check before state. + EXPECT_EQ(1, + mock_ibus_input_context_client_->process_key_event_call_count()); + EXPECT_EQ(0, ime_->process_key_event_post_ime_call_count()); + + // Do callback. + success_consume_handler.RunCallback(KEYEVENT_CONSUME); + + // Check the results + EXPECT_EQ(1, ime_->process_key_event_post_ime_call_count()); + EXPECT_TRUE(IsEqualXKeyEvent(event, + ime_->process_key_event_post_ime_args().event)); + EXPECT_EQ(kTestIBusKeyVal1, + ime_->process_key_event_post_ime_args().ibus_keyval); + EXPECT_TRUE(ime_->process_key_event_post_ime_args().handled); +} + +TEST_F(InputMethodIBusKeyEventTest, KeyEventDelayResponseFailTest) { + XEvent event = {}; + event.xkey.type = KeyPress; + + // Set up IBusKeyEventFromNativeKeyEvent result. + ime_->mutable_ibus_key_event_from_native_key_event_result()->keyval + = kTestIBusKeyVal1; + ime_->mutable_ibus_key_event_from_native_key_event_result()->keycode + = kTestIBusKeyCode1; + ime_->mutable_ibus_key_event_from_native_key_event_result()->state + = kTestIBusState1; + + // Set up ProcessKeyEvent handler. + AsynchronousKeyEventHandler fail_handler(kTestIBusKeyVal1, kTestIBusKeyCode1, + kTestIBusState1); + mock_ibus_input_context_client_->set_process_key_event_handler( + base::Bind(&AsynchronousKeyEventHandler::Run, + base::Unretained(&fail_handler))); + + // Do key event. + input_type_ = TEXT_INPUT_TYPE_TEXT; + ime_->OnTextInputTypeChanged(this); + ime_->DispatchKeyEvent(&event); + + // Check before state. + EXPECT_EQ(1, + mock_ibus_input_context_client_->process_key_event_call_count()); + EXPECT_EQ(0, ime_->process_key_event_post_ime_call_count()); + + // Do callback. + fail_handler.RunCallback(KEYEVENT_ERROR); + + // Check the results + EXPECT_EQ(1, ime_->process_key_event_post_ime_call_count()); + EXPECT_TRUE(IsEqualXKeyEvent(event, + ime_->process_key_event_post_ime_args().event)); + EXPECT_EQ(kTestIBusKeyVal1, + ime_->process_key_event_post_ime_args().ibus_keyval); + EXPECT_FALSE(ime_->process_key_event_post_ime_args().handled); +} + +TEST_F(InputMethodIBusKeyEventTest, MultiKeyEventDelayResponseSuccessTest) { + // Preparation + input_type_ = TEXT_INPUT_TYPE_TEXT; + ime_->OnTextInputTypeChanged(this); + + XEvent event = {}; + event.xkey.type = KeyPress; + + // Set up IBusKeyEventFromNativeKeyEvent result for first key event. + ime_->mutable_ibus_key_event_from_native_key_event_result()->keyval + = kTestIBusKeyVal1; + ime_->mutable_ibus_key_event_from_native_key_event_result()->keycode + = kTestIBusKeyCode1; + ime_->mutable_ibus_key_event_from_native_key_event_result()->state + = kTestIBusState1; + + // Set up ProcessKeyEvent handler. + AsynchronousKeyEventHandler handler1(kTestIBusKeyVal1, kTestIBusKeyCode1, + kTestIBusState1); + mock_ibus_input_context_client_->set_process_key_event_handler( + base::Bind(&AsynchronousKeyEventHandler::Run, + base::Unretained(&handler1))); + + // Do key event. + ime_->DispatchKeyEvent(&event); + + // Set up IBusKeyEventFromNativeKeyEvent result for second key event. + ime_->mutable_ibus_key_event_from_native_key_event_result()->keyval + = kTestIBusKeyVal2; + ime_->mutable_ibus_key_event_from_native_key_event_result()->keycode + = kTestIBusKeyCode2; + ime_->mutable_ibus_key_event_from_native_key_event_result()->state + = kTestIBusState2; + + // Set up yet another ProcessKeyEvent handler. + AsynchronousKeyEventHandler handler2(kTestIBusKeyVal2, kTestIBusKeyCode2, + kTestIBusState2); + mock_ibus_input_context_client_->set_process_key_event_handler( + base::Bind(&AsynchronousKeyEventHandler::Run, + base::Unretained(&handler2))); + + // Do key event again. + ime_->DispatchKeyEvent(&event); + + // Check before state. + EXPECT_EQ(2, + mock_ibus_input_context_client_->process_key_event_call_count()); + EXPECT_EQ(0, ime_->process_key_event_post_ime_call_count()); + + // Do callback for first key event. + handler1.RunCallback(KEYEVENT_CONSUME); + + // Check the results for first key event. + EXPECT_EQ(1, ime_->process_key_event_post_ime_call_count()); + EXPECT_TRUE(IsEqualXKeyEvent(event, + ime_->process_key_event_post_ime_args().event)); + EXPECT_EQ(kTestIBusKeyVal1, + ime_->process_key_event_post_ime_args().ibus_keyval); + EXPECT_TRUE(ime_->process_key_event_post_ime_args().handled); + + // Do callback for second key event. + handler2.RunCallback(KEYEVENT_NOT_CONSUME); + + // Check the results for second key event. + EXPECT_EQ(2, ime_->process_key_event_post_ime_call_count()); + EXPECT_TRUE(IsEqualXKeyEvent(event, + ime_->process_key_event_post_ime_args().event)); + EXPECT_EQ(kTestIBusKeyVal2, + ime_->process_key_event_post_ime_args().ibus_keyval); + EXPECT_FALSE(ime_->process_key_event_post_ime_args().handled); +} + +TEST_F(InputMethodIBusKeyEventTest, MultiKeyEventDelayResponseFailTest) { + // Preparation + input_type_ = TEXT_INPUT_TYPE_TEXT; + ime_->OnTextInputTypeChanged(this); + + XEvent event = {}; + event.xkey.type = KeyPress; + + // Set up IBusKeyEventFromNativeKeyEvent result for first key event. + ime_->mutable_ibus_key_event_from_native_key_event_result()->keyval + = kTestIBusKeyVal1; + ime_->mutable_ibus_key_event_from_native_key_event_result()->keycode + = kTestIBusKeyCode1; + ime_->mutable_ibus_key_event_from_native_key_event_result()->state + = kTestIBusState1; + + // Set up ProcessKeyEvent handler. + AsynchronousKeyEventHandler handler1(kTestIBusKeyVal1, kTestIBusKeyCode1, + kTestIBusState1); + mock_ibus_input_context_client_->set_process_key_event_handler( + base::Bind(&AsynchronousKeyEventHandler::Run, + base::Unretained(&handler1))); + + // Do key event. + ime_->DispatchKeyEvent(&event); + + // Set up IBusKeyEventFromNativeKeyEvent result for second key event. + ime_->mutable_ibus_key_event_from_native_key_event_result()->keyval + = kTestIBusKeyVal2; + ime_->mutable_ibus_key_event_from_native_key_event_result()->keycode + = kTestIBusKeyCode2; + ime_->mutable_ibus_key_event_from_native_key_event_result()->state + = kTestIBusState2; + + // Set up yet another ProcessKeyEvent handler. + AsynchronousKeyEventHandler handler2(kTestIBusKeyVal2, kTestIBusKeyCode2, + kTestIBusState2); + mock_ibus_input_context_client_->set_process_key_event_handler( + base::Bind(&AsynchronousKeyEventHandler::Run, + base::Unretained(&handler2))); + + // Do key event again. + ime_->DispatchKeyEvent(&event); + + // Check before state. + EXPECT_EQ(2, + mock_ibus_input_context_client_->process_key_event_call_count()); + EXPECT_EQ(0, ime_->process_key_event_post_ime_call_count()); + + // Do callback for first key event. + handler1.RunCallback(KEYEVENT_ERROR); + + // Check the results for first key event. + EXPECT_EQ(1, ime_->process_key_event_post_ime_call_count()); + EXPECT_TRUE(IsEqualXKeyEvent(event, + ime_->process_key_event_post_ime_args().event)); + EXPECT_EQ(kTestIBusKeyVal1, + ime_->process_key_event_post_ime_args().ibus_keyval); + EXPECT_FALSE(ime_->process_key_event_post_ime_args().handled); + + // Do callback for second key event. + handler2.RunCallback(KEYEVENT_ERROR); + + // Check the results for second key event. + EXPECT_EQ(2, ime_->process_key_event_post_ime_call_count()); + EXPECT_TRUE(IsEqualXKeyEvent(event, + ime_->process_key_event_post_ime_args().event)); + EXPECT_EQ(kTestIBusKeyVal2, + ime_->process_key_event_post_ime_args().ibus_keyval); + EXPECT_FALSE(ime_->process_key_event_post_ime_args().handled); +} + +TEST_F(InputMethodIBusKeyEventTest, + MultiKeyEventDelayResponseSuccessFailMixTest) { + // Preparation + input_type_ = TEXT_INPUT_TYPE_TEXT; + ime_->OnTextInputTypeChanged(this); + + XEvent event = {}; + event.xkey.type = KeyPress; + + // Set up IBusKeyEventFromNativeKeyEvent result for first key event. + ime_->mutable_ibus_key_event_from_native_key_event_result()->keyval + = kTestIBusKeyVal1; + ime_->mutable_ibus_key_event_from_native_key_event_result()->keycode + = kTestIBusKeyCode1; + ime_->mutable_ibus_key_event_from_native_key_event_result()->state + = kTestIBusState1; + + // Set up ProcessKeyEvent handler. + AsynchronousKeyEventHandler handler1(kTestIBusKeyVal1, kTestIBusKeyCode1, + kTestIBusState1); + mock_ibus_input_context_client_->set_process_key_event_handler( + base::Bind(&AsynchronousKeyEventHandler::Run, + base::Unretained(&handler1))); + + // Do key event. + ime_->DispatchKeyEvent(&event); + + // Set up IBusKeyEventFromNativeKeyEvent result for second key event. + ime_->mutable_ibus_key_event_from_native_key_event_result()->keyval + = kTestIBusKeyVal2; + ime_->mutable_ibus_key_event_from_native_key_event_result()->keycode + = kTestIBusKeyCode2; + ime_->mutable_ibus_key_event_from_native_key_event_result()->state + = kTestIBusState2; + + // Set up yet another ProcessKeyEvent handler. + AsynchronousKeyEventHandler handler2(kTestIBusKeyVal2, kTestIBusKeyCode2, + kTestIBusState2); + mock_ibus_input_context_client_->set_process_key_event_handler( + base::Bind(&AsynchronousKeyEventHandler::Run, + base::Unretained(&handler2))); + + // Do key event again. + ime_->DispatchKeyEvent(&event); + + // Set up IBusKeyEventFromNativeKeyEvent result for second key event. + ime_->mutable_ibus_key_event_from_native_key_event_result()->keyval + = kTestIBusKeyVal3; + ime_->mutable_ibus_key_event_from_native_key_event_result()->keycode + = kTestIBusKeyCode3; + ime_->mutable_ibus_key_event_from_native_key_event_result()->state + = kTestIBusState3; + + // Set up yet another ProcessKeyEvent handler. + AsynchronousKeyEventHandler handler3(kTestIBusKeyVal3, kTestIBusKeyCode3, + kTestIBusState3); + mock_ibus_input_context_client_->set_process_key_event_handler( + base::Bind(&AsynchronousKeyEventHandler::Run, + base::Unretained(&handler3))); + + // Do key event again. + ime_->DispatchKeyEvent(&event); + + // Check before state. + EXPECT_EQ(3, + mock_ibus_input_context_client_->process_key_event_call_count()); + EXPECT_EQ(0, ime_->process_key_event_post_ime_call_count()); + + // Do callback for first key event. + handler1.RunCallback(KEYEVENT_CONSUME); + + // Check the results for first key event. + EXPECT_EQ(1, ime_->process_key_event_post_ime_call_count()); + EXPECT_TRUE(IsEqualXKeyEvent(event, + ime_->process_key_event_post_ime_args().event)); + EXPECT_EQ(kTestIBusKeyVal1, + ime_->process_key_event_post_ime_args().ibus_keyval); + EXPECT_TRUE(ime_->process_key_event_post_ime_args().handled); + + // Do callback for second key event. + handler2.RunCallback(KEYEVENT_ERROR); + + // Check the results for second key event. + EXPECT_EQ(2, ime_->process_key_event_post_ime_call_count()); + EXPECT_TRUE(IsEqualXKeyEvent(event, + ime_->process_key_event_post_ime_args().event)); + EXPECT_EQ(kTestIBusKeyVal2, + ime_->process_key_event_post_ime_args().ibus_keyval); + EXPECT_FALSE(ime_->process_key_event_post_ime_args().handled); + + // Do callback for first key event. + handler3.RunCallback(KEYEVENT_CONSUME); + + // Check the results for first key event. + EXPECT_EQ(3, ime_->process_key_event_post_ime_call_count()); + EXPECT_TRUE(IsEqualXKeyEvent(event, + ime_->process_key_event_post_ime_args().event)); + EXPECT_EQ(kTestIBusKeyVal3, + ime_->process_key_event_post_ime_args().ibus_keyval); + EXPECT_TRUE(ime_->process_key_event_post_ime_args().handled); +} + +TEST_F(InputMethodIBusKeyEventTest, KeyEventDelayResponseResetTest) { + XEvent event = {}; + event.xkey.type = KeyPress; + + // Set up IBusKeyEventFromNativeKeyEvent result. + ime_->mutable_ibus_key_event_from_native_key_event_result()->keyval + = kTestIBusKeyVal1; + ime_->mutable_ibus_key_event_from_native_key_event_result()->keycode + = kTestIBusKeyCode1; + ime_->mutable_ibus_key_event_from_native_key_event_result()->state + = kTestIBusState1; + + // Set up ProcessKeyEvent handler. + AsynchronousKeyEventHandler success_consume_handler(kTestIBusKeyVal1, + kTestIBusKeyCode1, + kTestIBusState1); + mock_ibus_input_context_client_->set_process_key_event_handler( + base::Bind(&AsynchronousKeyEventHandler::Run, + base::Unretained(&success_consume_handler))); + + // Do key event. + input_type_ = TEXT_INPUT_TYPE_TEXT; + ime_->OnTextInputTypeChanged(this); + ime_->DispatchKeyEvent(&event); + + // Check before state. + EXPECT_EQ(1, + mock_ibus_input_context_client_->process_key_event_call_count()); + EXPECT_EQ(0, ime_->process_key_event_post_ime_call_count()); + + ime_->ResetContext(); + + // Do callback. + success_consume_handler.RunCallback(KEYEVENT_CONSUME); + + EXPECT_EQ(0, ime_->process_key_event_post_ime_call_count()); +} + +// TODO(nona): Introduce ProcessKeyEventPostIME tests(crbug.com/156593). } // namespace ui |