// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ui/base/ime/input_method_auralinux.h" #include #include "base/macros.h" #include "base/memory/singleton.h" #include "base/strings/string_split.h" #include "base/strings/utf_string_conversions.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/ime/dummy_text_input_client.h" #include "ui/base/ime/input_method_delegate.h" #include "ui/base/ime/input_method_initializer.h" #include "ui/base/ime/linux/fake_input_method_context.h" #include "ui/base/ime/linux/linux_input_method_context_factory.h" #include "ui/events/event.h" namespace ui { namespace { const base::char16 kActionCommit = L'C'; const base::char16 kActionCompositionStart = L'S'; const base::char16 kActionCompositionUpdate = L'U'; const base::char16 kActionCompositionEnd = L'E'; class TestResult { public: static TestResult* GetInstance() { return base::Singleton::get(); } void RecordAction(const base::string16& action) { recorded_actions_.push_back(action); } void ExpectAction(const std::string& action) { expected_actions_.push_back(base::ASCIIToUTF16(action)); } void Verify() { size_t len = recorded_actions_.size(); size_t len_exp = expected_actions_.size(); EXPECT_EQ(len_exp, len); for (size_t i = 0; i < len; i++) EXPECT_EQ(expected_actions_[i], recorded_actions_[i]); recorded_actions_.clear(); expected_actions_.clear(); } private: std::vector recorded_actions_; std::vector expected_actions_; }; class LinuxInputMethodContextForTesting : public LinuxInputMethodContext { public: LinuxInputMethodContextForTesting(LinuxInputMethodContextDelegate* delegate, bool is_simple) : delegate_(delegate), is_simple_(is_simple), is_sync_mode_(false), eat_key_(false), focused_(false) {} void SetSyncMode(bool is_sync_mode) { is_sync_mode_ = is_sync_mode; } void SetEatKey(bool eat_key) { eat_key_ = eat_key; } void AddCommitAction(const std::string& text) { actions_.push_back(base::ASCIIToUTF16("C:" + text)); } void AddCompositionUpdateAction(const std::string& text) { actions_.push_back(base::ASCIIToUTF16("U:" + text)); } void AddCompositionStartAction() { actions_.push_back(base::ASCIIToUTF16("S")); } void AddCompositionEndAction() { actions_.push_back(base::ASCIIToUTF16("E")); } protected: bool DispatchKeyEvent(const ui::KeyEvent& key_event) override { if (!is_sync_mode_) { actions_.clear(); return eat_key_; } for (const auto& action : actions_) { std::vector parts = base::SplitString( action, base::string16(1, ':'), base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); base::char16 id = parts[0][0]; base::string16 param; if (parts.size() > 1) param = parts[1]; if (id == kActionCommit) { delegate_->OnCommit(param); } else if (id == kActionCompositionStart) { delegate_->OnPreeditStart(); } else if (id == kActionCompositionUpdate) { CompositionText comp; comp.text = param; delegate_->OnPreeditChanged(comp); } else if (id == kActionCompositionEnd) { delegate_->OnPreeditEnd(); } } actions_.clear(); return eat_key_; } void Reset() override {} void Focus() override { focused_ = true; } void Blur() override { focused_ = false; } void SetCursorLocation(const gfx::Rect& rect) override { cursor_position_ = rect; } private: LinuxInputMethodContextDelegate* delegate_; std::vector actions_; bool is_simple_; bool is_sync_mode_; bool eat_key_; bool focused_; gfx::Rect cursor_position_; DISALLOW_COPY_AND_ASSIGN(LinuxInputMethodContextForTesting); }; class LinuxInputMethodContextFactoryForTesting : public LinuxInputMethodContextFactory { public: LinuxInputMethodContextFactoryForTesting(){}; scoped_ptr CreateInputMethodContext( LinuxInputMethodContextDelegate* delegate, bool is_simple) const override { return scoped_ptr( new LinuxInputMethodContextForTesting(delegate, is_simple)); }; private: DISALLOW_COPY_AND_ASSIGN(LinuxInputMethodContextFactoryForTesting); }; class InputMethodDelegateForTesting : public internal::InputMethodDelegate { public: InputMethodDelegateForTesting(){}; ~InputMethodDelegateForTesting() override{}; ui::EventDispatchDetails DispatchKeyEventPostIME( ui::KeyEvent* key_event) override { std::string action; switch (key_event->type()) { case ET_KEY_PRESSED: action = "keydown:"; break; case ET_KEY_RELEASED: action = "keyup:"; break; default: break; } std::stringstream ss; ss << key_event->key_code(); action += std::string(ss.str()); TestResult::GetInstance()->RecordAction(base::ASCIIToUTF16(action)); return ui::EventDispatchDetails(); } private: DISALLOW_COPY_AND_ASSIGN(InputMethodDelegateForTesting); }; class TextInputClientForTesting : public DummyTextInputClient { public: explicit TextInputClientForTesting(TextInputType text_input_type) : DummyTextInputClient(text_input_type){}; base::string16 composition_text; protected: void SetCompositionText(const CompositionText& composition) override { composition_text = composition.text; TestResult::GetInstance()->RecordAction( base::ASCIIToUTF16("compositionstart")); TestResult::GetInstance()->RecordAction( base::ASCIIToUTF16("compositionupdate:") + composition.text); } bool HasCompositionText() const override { return !composition_text.empty(); } void ConfirmCompositionText() override { TestResult::GetInstance()->RecordAction( base::ASCIIToUTF16("compositionend")); TestResult::GetInstance()->RecordAction(base::ASCIIToUTF16("textinput:") + composition_text); composition_text.clear(); } void ClearCompositionText() override { TestResult::GetInstance()->RecordAction( base::ASCIIToUTF16("compositionend")); composition_text.clear(); } void InsertText(const base::string16& text) override { if (HasCompositionText()) { TestResult::GetInstance()->RecordAction( base::ASCIIToUTF16("compositionend")); } TestResult::GetInstance()->RecordAction(base::ASCIIToUTF16("textinput:") + text); composition_text.clear(); } void InsertChar(const ui::KeyEvent& event) override { std::stringstream ss; ss << event.GetCharacter(); TestResult::GetInstance()->RecordAction(base::ASCIIToUTF16("keypress:") + base::ASCIIToUTF16(ss.str())); } }; class InputMethodAuraLinuxTest : public testing::Test { protected: InputMethodAuraLinuxTest() : factory_(NULL), input_method_auralinux_(NULL), delegate_(NULL), context_(NULL), context_simple_(NULL) { factory_ = new LinuxInputMethodContextFactoryForTesting(); LinuxInputMethodContextFactory::SetInstance(factory_); test_result_ = TestResult::GetInstance(); } ~InputMethodAuraLinuxTest() override { delete factory_; factory_ = NULL; test_result_ = NULL; } void SetUp() override { delegate_ = new InputMethodDelegateForTesting(); input_method_auralinux_ = new InputMethodAuraLinux(delegate_); input_method_auralinux_->OnFocus(); context_ = static_cast( input_method_auralinux_->GetContextForTesting(false)); context_simple_ = static_cast( input_method_auralinux_->GetContextForTesting(true)); } void TearDown() override { context_->SetSyncMode(false); context_->SetEatKey(false); context_simple_->SetSyncMode(false); context_simple_->SetEatKey(false); context_ = NULL; context_simple_ = NULL; delete input_method_auralinux_; input_method_auralinux_ = NULL; delete delegate_; delegate_ = NULL; } LinuxInputMethodContextFactoryForTesting* factory_; InputMethodAuraLinux* input_method_auralinux_; InputMethodDelegateForTesting* delegate_; LinuxInputMethodContextForTesting* context_; LinuxInputMethodContextForTesting* context_simple_; TestResult* test_result_; DISALLOW_COPY_AND_ASSIGN(InputMethodAuraLinuxTest); }; TEST_F(InputMethodAuraLinuxTest, BasicSyncModeTest) { context_->SetSyncMode(true); context_->SetEatKey(true); context_->AddCommitAction("a"); scoped_ptr client( new TextInputClientForTesting(TEXT_INPUT_TYPE_TEXT)); input_method_auralinux_->SetFocusedTextInputClient(client.get()); input_method_auralinux_->OnTextInputTypeChanged(client.get()); KeyEvent key_new(ET_KEY_PRESSED, VKEY_A, 0); key_new.set_character(L'a'); KeyEvent key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); test_result_->ExpectAction("keydown:65"); test_result_->ExpectAction("keypress:97"); test_result_->Verify(); input_method_auralinux_->DetachTextInputClient(client.get()); client.reset(new TextInputClientForTesting(TEXT_INPUT_TYPE_PASSWORD)); context_simple_->SetSyncMode(true); context_simple_->SetEatKey(false); input_method_auralinux_->SetFocusedTextInputClient(client.get()); input_method_auralinux_->OnTextInputTypeChanged(client.get()); key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); test_result_->ExpectAction("keydown:65"); test_result_->ExpectAction("keypress:97"); test_result_->Verify(); } TEST_F(InputMethodAuraLinuxTest, BasicAsyncModeTest) { context_->SetSyncMode(false); context_->SetEatKey(true); scoped_ptr client( new TextInputClientForTesting(TEXT_INPUT_TYPE_TEXT)); input_method_auralinux_->SetFocusedTextInputClient(client.get()); input_method_auralinux_->OnTextInputTypeChanged(client.get()); KeyEvent key_new(ET_KEY_PRESSED, VKEY_A, 0); key_new.set_character(L'a'); KeyEvent key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); input_method_auralinux_->OnCommit(base::ASCIIToUTF16("a")); test_result_->ExpectAction("keydown:229"); test_result_->ExpectAction("textinput:a"); test_result_->Verify(); input_method_auralinux_->DetachTextInputClient(client.get()); client.reset(new TextInputClientForTesting(TEXT_INPUT_TYPE_PASSWORD)); context_simple_->SetSyncMode(false); context_simple_->SetEatKey(false); input_method_auralinux_->SetFocusedTextInputClient(client.get()); input_method_auralinux_->OnTextInputTypeChanged(client.get()); key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); test_result_->ExpectAction("keydown:65"); test_result_->ExpectAction("keypress:97"); test_result_->Verify(); } TEST_F(InputMethodAuraLinuxTest, IBusUSTest) { context_->SetSyncMode(false); context_->SetEatKey(true); scoped_ptr client( new TextInputClientForTesting(TEXT_INPUT_TYPE_TEXT)); input_method_auralinux_->SetFocusedTextInputClient(client.get()); input_method_auralinux_->OnTextInputTypeChanged(client.get()); KeyEvent key_new(ET_KEY_PRESSED, VKEY_A, 0); key_new.set_character(L'a'); KeyEvent key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); // IBus mutes the key down. test_result_->Verify(); // IBus simulates a faked key down and handle it in sync mode. context_->SetSyncMode(true); context_->AddCommitAction("a"); key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); test_result_->ExpectAction("keydown:65"); test_result_->ExpectAction("keypress:97"); test_result_->Verify(); // IBus does NOT handle the key up. context_->SetEatKey(false); KeyEvent key_up(ET_KEY_RELEASED, VKEY_A, 0); input_method_auralinux_->DispatchKeyEvent(&key_up); test_result_->ExpectAction("keyup:65"); test_result_->Verify(); } TEST_F(InputMethodAuraLinuxTest, IBusPinyinTest) { context_->SetSyncMode(false); context_->SetEatKey(true); scoped_ptr client( new TextInputClientForTesting(TEXT_INPUT_TYPE_TEXT)); input_method_auralinux_->SetFocusedTextInputClient(client.get()); input_method_auralinux_->OnTextInputTypeChanged(client.get()); KeyEvent key(ET_KEY_PRESSED, VKEY_A, 0); key.set_character(L'a'); input_method_auralinux_->DispatchKeyEvent(&key); // IBus issues a standalone set_composition action. input_method_auralinux_->OnPreeditStart(); CompositionText comp; comp.text = base::ASCIIToUTF16("a"); input_method_auralinux_->OnPreeditChanged(comp); test_result_->ExpectAction("keydown:229"); test_result_->ExpectAction("compositionstart"); test_result_->ExpectAction("compositionupdate:a"); test_result_->Verify(); // IBus issues a commit text with composition after muting the space key down. KeyEvent key_up(ET_KEY_RELEASED, VKEY_SPACE, 0); input_method_auralinux_->DispatchKeyEvent(&key_up); input_method_auralinux_->OnPreeditEnd(); input_method_auralinux_->OnCommit(base::ASCIIToUTF16("A")); test_result_->ExpectAction("keydown:229"); test_result_->ExpectAction("compositionend"); test_result_->ExpectAction("keydown:229"); test_result_->ExpectAction("textinput:A"); test_result_->Verify(); } // crbug.com/463491 TEST_F(InputMethodAuraLinuxTest, DeadKeyTest) { context_simple_->SetSyncMode(true); context_simple_->SetEatKey(true); scoped_ptr client( new TextInputClientForTesting(TEXT_INPUT_TYPE_NONE)); input_method_auralinux_->SetFocusedTextInputClient(client.get()); input_method_auralinux_->OnTextInputTypeChanged(client.get()); KeyEvent dead_key(ET_KEY_PRESSED, VKEY_OEM_7, 0); dead_key.set_character(L'\''); input_method_auralinux_->DispatchKeyEvent(&dead_key); // The single quote key is muted. test_result_->ExpectAction("keydown:222"); test_result_->Verify(); context_simple_->AddCommitAction("X"); KeyEvent key(ET_KEY_PRESSED, VKEY_A, 0); key.set_character(L'a'); input_method_auralinux_->DispatchKeyEvent(&key); // The following A key generates the accent key: รก. test_result_->ExpectAction("keydown:65"); test_result_->ExpectAction("keypress:88"); test_result_->Verify(); } TEST_F(InputMethodAuraLinuxTest, MultiCommitsTest) { context_->SetSyncMode(true); context_->SetEatKey(true); context_->AddCommitAction("a"); context_->AddCommitAction("b"); context_->AddCommitAction("c"); scoped_ptr client( new TextInputClientForTesting(TEXT_INPUT_TYPE_TEXT)); input_method_auralinux_->SetFocusedTextInputClient(client.get()); input_method_auralinux_->OnTextInputTypeChanged(client.get()); KeyEvent key(ET_KEY_PRESSED, VKEY_A, 0); key.set_character(L'a'); input_method_auralinux_->DispatchKeyEvent(&key); test_result_->ExpectAction("keydown:229"); test_result_->ExpectAction("textinput:abc"); test_result_->Verify(); } TEST_F(InputMethodAuraLinuxTest, MixedCompositionAndCommitTest) { context_->SetSyncMode(true); context_->SetEatKey(true); context_->AddCommitAction("a"); context_->AddCompositionStartAction(); context_->AddCompositionUpdateAction("b"); context_->AddCommitAction("c"); context_->AddCompositionUpdateAction("d"); scoped_ptr client( new TextInputClientForTesting(TEXT_INPUT_TYPE_TEXT)); input_method_auralinux_->SetFocusedTextInputClient(client.get()); input_method_auralinux_->OnTextInputTypeChanged(client.get()); KeyEvent key_new(ET_KEY_PRESSED, VKEY_A, 0); key_new.set_character(L'a'); KeyEvent key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); test_result_->ExpectAction("keydown:229"); test_result_->ExpectAction("textinput:ac"); test_result_->ExpectAction("compositionstart"); test_result_->ExpectAction("compositionupdate:d"); test_result_->Verify(); context_->AddCommitAction("e"); key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); test_result_->ExpectAction("keydown:229"); test_result_->ExpectAction("compositionend"); test_result_->ExpectAction("textinput:e"); test_result_->Verify(); } TEST_F(InputMethodAuraLinuxTest, CompositionEndWithoutCommitTest) { context_->SetSyncMode(true); context_->SetEatKey(true); context_->AddCompositionStartAction(); context_->AddCompositionUpdateAction("a"); scoped_ptr client( new TextInputClientForTesting(TEXT_INPUT_TYPE_TEXT)); input_method_auralinux_->SetFocusedTextInputClient(client.get()); input_method_auralinux_->OnTextInputTypeChanged(client.get()); KeyEvent key_new(ET_KEY_PRESSED, VKEY_A, 0); key_new.set_character(L'a'); KeyEvent key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); test_result_->ExpectAction("keydown:229"); test_result_->ExpectAction("compositionstart"); test_result_->ExpectAction("compositionupdate:a"); test_result_->Verify(); context_->AddCompositionEndAction(); key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); test_result_->ExpectAction("keydown:229"); test_result_->ExpectAction("compositionend"); test_result_->Verify(); } TEST_F(InputMethodAuraLinuxTest, CompositionEndWithEmptyCommitTest) { context_->SetSyncMode(true); context_->SetEatKey(true); context_->AddCompositionStartAction(); context_->AddCompositionUpdateAction("a"); scoped_ptr client( new TextInputClientForTesting(TEXT_INPUT_TYPE_TEXT)); input_method_auralinux_->SetFocusedTextInputClient(client.get()); input_method_auralinux_->OnTextInputTypeChanged(client.get()); KeyEvent key_new(ET_KEY_PRESSED, VKEY_A, 0); key_new.set_character(L'a'); KeyEvent key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); test_result_->ExpectAction("keydown:229"); test_result_->ExpectAction("compositionstart"); test_result_->ExpectAction("compositionupdate:a"); test_result_->Verify(); context_->AddCompositionEndAction(); context_->AddCommitAction(""); key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); test_result_->ExpectAction("keydown:229"); test_result_->ExpectAction("compositionend"); test_result_->Verify(); } TEST_F(InputMethodAuraLinuxTest, CompositionEndWithCommitTest) { context_->SetSyncMode(true); context_->SetEatKey(true); context_->AddCompositionStartAction(); context_->AddCompositionUpdateAction("a"); scoped_ptr client( new TextInputClientForTesting(TEXT_INPUT_TYPE_TEXT)); input_method_auralinux_->SetFocusedTextInputClient(client.get()); input_method_auralinux_->OnTextInputTypeChanged(client.get()); KeyEvent key_new(ET_KEY_PRESSED, VKEY_A, 0); key_new.set_character(L'a'); KeyEvent key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); test_result_->ExpectAction("keydown:229"); test_result_->ExpectAction("compositionstart"); test_result_->ExpectAction("compositionupdate:a"); test_result_->Verify(); context_->AddCompositionEndAction(); context_->AddCommitAction("b"); key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); // Verifies single char commit under composition mode will call InsertText // intead of InsertChar. test_result_->ExpectAction("keydown:229"); test_result_->ExpectAction("compositionend"); test_result_->ExpectAction("textinput:b"); test_result_->Verify(); } TEST_F(InputMethodAuraLinuxTest, CompositionUpdateWithCommitTest) { context_->SetSyncMode(true); context_->SetEatKey(true); context_->AddCompositionStartAction(); context_->AddCompositionUpdateAction("a"); context_->AddCommitAction("b"); scoped_ptr client( new TextInputClientForTesting(TEXT_INPUT_TYPE_TEXT)); input_method_auralinux_->SetFocusedTextInputClient(client.get()); input_method_auralinux_->OnTextInputTypeChanged(client.get()); KeyEvent key_new(ET_KEY_PRESSED, VKEY_A, 0); key_new.set_character(L'a'); KeyEvent key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); test_result_->ExpectAction("keydown:229"); test_result_->ExpectAction("textinput:b"); test_result_->ExpectAction("compositionstart"); test_result_->ExpectAction("compositionupdate:a"); test_result_->Verify(); // crbug.com/513124. context_->SetSyncMode(true); context_->SetEatKey(true); context_->AddCommitAction("c"); context_->AddCompositionUpdateAction(""); key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); test_result_->ExpectAction("keydown:229"); test_result_->ExpectAction("compositionend"); test_result_->ExpectAction("textinput:c"); test_result_->Verify(); } TEST_F(InputMethodAuraLinuxTest, MixedAsyncAndSyncTest) { context_->SetSyncMode(false); context_->SetEatKey(true); scoped_ptr client( new TextInputClientForTesting(TEXT_INPUT_TYPE_TEXT)); input_method_auralinux_->SetFocusedTextInputClient(client.get()); input_method_auralinux_->OnTextInputTypeChanged(client.get()); KeyEvent key_new(ET_KEY_PRESSED, VKEY_A, 0); key_new.set_character(L'a'); KeyEvent key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); CompositionText comp; comp.text = base::ASCIIToUTF16("a"); input_method_auralinux_->OnPreeditChanged(comp); test_result_->ExpectAction("keydown:229"); test_result_->ExpectAction("compositionstart"); test_result_->ExpectAction("compositionupdate:a"); test_result_->Verify(); context_->SetSyncMode(true); context_->AddCompositionEndAction(); context_->AddCommitAction("b"); key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); test_result_->ExpectAction("keydown:229"); test_result_->ExpectAction("compositionend"); test_result_->ExpectAction("textinput:b"); test_result_->Verify(); } TEST_F(InputMethodAuraLinuxTest, MixedSyncAndAsyncTest) { context_->SetSyncMode(true); context_->SetEatKey(true); context_->AddCompositionStartAction(); context_->AddCompositionUpdateAction("a"); scoped_ptr client( new TextInputClientForTesting(TEXT_INPUT_TYPE_TEXT)); input_method_auralinux_->SetFocusedTextInputClient(client.get()); input_method_auralinux_->OnTextInputTypeChanged(client.get()); KeyEvent key_new(ET_KEY_PRESSED, VKEY_A, 0); key_new.set_character(L'a'); KeyEvent key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); test_result_->ExpectAction("keydown:229"); test_result_->ExpectAction("compositionstart"); test_result_->ExpectAction("compositionupdate:a"); test_result_->Verify(); context_->SetSyncMode(false); key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); input_method_auralinux_->OnCommit(base::ASCIIToUTF16("b")); test_result_->ExpectAction("keydown:229"); test_result_->ExpectAction("compositionend"); test_result_->ExpectAction("textinput:b"); test_result_->Verify(); context_->SetSyncMode(true); context_->AddCommitAction("c"); key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); test_result_->ExpectAction("keydown:65"); test_result_->ExpectAction("keypress:99"); test_result_->Verify(); } TEST_F(InputMethodAuraLinuxTest, ReleaseKeyTest) { context_->SetSyncMode(true); context_->SetEatKey(true); context_->AddCompositionUpdateAction("a"); scoped_ptr client( new TextInputClientForTesting(TEXT_INPUT_TYPE_TEXT)); input_method_auralinux_->SetFocusedTextInputClient(client.get()); input_method_auralinux_->OnTextInputTypeChanged(client.get()); KeyEvent key_new(ET_KEY_PRESSED, VKEY_A, 0); key_new.set_character(L'A'); KeyEvent key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); test_result_->ExpectAction("keydown:229"); test_result_->ExpectAction("compositionstart"); test_result_->ExpectAction("compositionupdate:a"); test_result_->Verify(); context_->SetEatKey(false); context_->AddCommitAction("b"); key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); test_result_->ExpectAction("compositionend"); test_result_->ExpectAction("textinput:b"); test_result_->ExpectAction("keydown:65"); test_result_->ExpectAction("keypress:65"); test_result_->Verify(); context_->AddCommitAction("c"); key = key_new; input_method_auralinux_->DispatchKeyEvent(&key); test_result_->ExpectAction("textinput:c"); test_result_->ExpectAction("keydown:65"); test_result_->ExpectAction("keypress:65"); test_result_->Verify(); } } // namespace } // namespace ui