Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / chromeos / input_method / input_method_engine_unittest.cc
blob5c84b729b25d31065f1f8074327a4dcad6aab3eb
1 // Copyright 2014 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 "base/logging.h"
6 #include "base/metrics/histogram.h"
7 #include "base/metrics/histogram_samples.h"
8 #include "base/metrics/statistics_recorder.h"
9 #include "base/test/histogram_tester.h"
10 #include "chrome/browser/chromeos/input_method/input_method_configuration.h"
11 #include "chrome/browser/chromeos/input_method/input_method_engine.h"
12 #include "chrome/browser/chromeos/input_method/input_method_engine_interface.h"
13 #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h"
14 #include "chrome/browser/profiles/profile_manager.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "ui/base/ime/chromeos/extension_ime_util.h"
17 #include "ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.h"
18 #include "ui/base/ime/chromeos/mock_ime_input_context_handler.h"
19 #include "ui/base/ime/text_input_flags.h"
20 #include "ui/gfx/geometry/rect.h"
22 namespace chromeos {
24 namespace input_method {
25 namespace {
27 const char kTestExtensionId[] = "mppnpdlheglhdfmldimlhpnegondlapf";
28 const char kTestExtensionId2[] = "dmpipdbjkoajgdeppkffbjhngfckdloi";
29 const char kTestImeComponentId[] = "test_engine_id";
31 enum CallsBitmap {
32 NONE = 0U,
33 ACTIVATE = 1U,
34 DEACTIVATED = 2U,
35 ONFOCUS = 4U,
36 ONBLUR = 8U,
37 ONCOMPOSITIONBOUNDSCHANGED = 16U
40 void InitInputMethod() {
41 ComponentExtensionIMEManager* comp_ime_manager =
42 new ComponentExtensionIMEManager;
43 MockComponentExtIMEManagerDelegate* delegate =
44 new MockComponentExtIMEManagerDelegate;
46 ComponentExtensionIME ext1;
47 ext1.id = kTestExtensionId;
49 ComponentExtensionEngine ext1_engine1;
50 ext1_engine1.engine_id = kTestImeComponentId;
51 ext1_engine1.language_codes.push_back("en-US");
52 ext1_engine1.layouts.push_back("us");
53 ext1.engines.push_back(ext1_engine1);
55 std::vector<ComponentExtensionIME> ime_list;
56 ime_list.push_back(ext1);
57 delegate->set_ime_list(ime_list);
58 comp_ime_manager->Initialize(
59 scoped_ptr<ComponentExtensionIMEManagerDelegate>(delegate).Pass());
61 MockInputMethodManager* manager = new MockInputMethodManager;
62 manager->SetComponentExtensionIMEManager(
63 scoped_ptr<ComponentExtensionIMEManager>(comp_ime_manager).Pass());
64 InitializeForTesting(manager);
67 class TestObserver : public InputMethodEngineInterface::Observer {
68 public:
69 TestObserver() : calls_bitmap_(NONE) {}
70 ~TestObserver() override {}
72 void OnActivate(const std::string& engine_id) override {
73 calls_bitmap_ |= ACTIVATE;
75 void OnDeactivated(const std::string& engine_id) override {
76 calls_bitmap_ |= DEACTIVATED;
78 void OnFocus(
79 const InputMethodEngineInterface::InputContext& context) override {
80 calls_bitmap_ |= ONFOCUS;
82 void OnBlur(int context_id) override { calls_bitmap_ |= ONBLUR; }
83 bool IsInterestedInKeyEvent() const override { return true; }
84 void OnKeyEvent(const std::string& engine_id,
85 const InputMethodEngineInterface::KeyboardEvent& event,
86 input_method::KeyEventHandle* key_data) override {}
87 void OnInputContextUpdate(
88 const InputMethodEngineInterface::InputContext& context) override {}
89 void OnCandidateClicked(
90 const std::string& engine_id,
91 int candidate_id,
92 InputMethodEngineInterface::MouseButtonEvent button) override {}
93 void OnMenuItemActivated(const std::string& engine_id,
94 const std::string& menu_id) override {}
95 void OnSurroundingTextChanged(const std::string& engine_id,
96 const std::string& text,
97 int cursor_pos,
98 int anchor_pos,
99 int offset) override {}
100 void OnCompositionBoundsChanged(
101 const std::vector<gfx::Rect>& bounds) override {
102 calls_bitmap_ |= ONCOMPOSITIONBOUNDSCHANGED;
104 void OnReset(const std::string& engine_id) override {}
106 unsigned char GetCallsBitmapAndReset() {
107 unsigned char ret = calls_bitmap_;
108 calls_bitmap_ = NONE;
109 return ret;
112 private:
113 unsigned char calls_bitmap_;
115 DISALLOW_COPY_AND_ASSIGN(TestObserver);
118 class InputMethodEngineTest : public testing::Test {
119 public:
120 InputMethodEngineTest() : observer_(NULL), input_view_("inputview.html") {
121 languages_.push_back("en-US");
122 layouts_.push_back("us");
123 InitInputMethod();
124 IMEBridge::Initialize();
125 mock_ime_input_context_handler_.reset(new MockIMEInputContextHandler());
126 IMEBridge::Get()->SetInputContextHandler(
127 mock_ime_input_context_handler_.get());
129 ~InputMethodEngineTest() override {
130 IMEBridge::Get()->SetInputContextHandler(NULL);
131 engine_.reset();
132 Shutdown();
135 protected:
136 void CreateEngine(bool whitelisted) {
137 engine_.reset(new InputMethodEngine());
138 observer_ = new TestObserver();
139 scoped_ptr<InputMethodEngineInterface::Observer> observer_ptr(observer_);
140 engine_->Initialize(observer_ptr.Pass(),
141 whitelisted ? kTestExtensionId : kTestExtensionId2,
142 ProfileManager::GetActiveUserProfile());
145 void FocusIn(ui::TextInputType input_type) {
146 IMEEngineHandlerInterface::InputContext input_context(
147 input_type, ui::TEXT_INPUT_MODE_DEFAULT, ui::TEXT_INPUT_FLAG_NONE);
148 engine_->FocusIn(input_context);
149 IMEBridge::Get()->SetCurrentInputContext(input_context);
152 scoped_ptr<InputMethodEngine> engine_;
154 TestObserver* observer_;
155 std::vector<std::string> languages_;
156 std::vector<std::string> layouts_;
157 GURL options_page_;
158 GURL input_view_;
160 scoped_ptr<MockIMEInputContextHandler> mock_ime_input_context_handler_;
162 private:
163 DISALLOW_COPY_AND_ASSIGN(InputMethodEngineTest);
166 } // namespace
168 TEST_F(InputMethodEngineTest, TestSwitching) {
169 CreateEngine(false);
170 // Enable/disable with focus.
171 FocusIn(ui::TEXT_INPUT_TYPE_URL);
172 EXPECT_EQ(NONE, observer_->GetCallsBitmapAndReset());
173 engine_->Enable(kTestImeComponentId);
174 EXPECT_EQ(ACTIVATE | ONFOCUS, observer_->GetCallsBitmapAndReset());
175 engine_->Disable();
176 EXPECT_EQ(DEACTIVATED, observer_->GetCallsBitmapAndReset());
177 // Enable/disable without focus.
178 engine_->FocusOut();
179 EXPECT_EQ(NONE, observer_->GetCallsBitmapAndReset());
180 engine_->Enable(kTestImeComponentId);
181 EXPECT_EQ(ACTIVATE | ONFOCUS, observer_->GetCallsBitmapAndReset());
182 engine_->Disable();
183 EXPECT_EQ(DEACTIVATED, observer_->GetCallsBitmapAndReset());
184 // Focus change when enabled.
185 engine_->Enable(kTestImeComponentId);
186 EXPECT_EQ(ACTIVATE | ONFOCUS, observer_->GetCallsBitmapAndReset());
187 engine_->FocusOut();
188 EXPECT_EQ(ONBLUR, observer_->GetCallsBitmapAndReset());
189 // Focus change when disabled.
190 engine_->Disable();
191 EXPECT_EQ(DEACTIVATED, observer_->GetCallsBitmapAndReset());
192 FocusIn(ui::TEXT_INPUT_TYPE_TEXT);
193 EXPECT_EQ(NONE, observer_->GetCallsBitmapAndReset());
194 engine_->FocusOut();
195 EXPECT_EQ(NONE, observer_->GetCallsBitmapAndReset());
198 TEST_F(InputMethodEngineTest, TestSwitching_Password_3rd_Party) {
199 CreateEngine(false);
200 // Enable/disable with focus.
201 FocusIn(ui::TEXT_INPUT_TYPE_PASSWORD);
202 EXPECT_EQ(NONE, observer_->GetCallsBitmapAndReset());
203 engine_->Enable(kTestImeComponentId);
204 EXPECT_EQ(ACTIVATE | ONFOCUS, observer_->GetCallsBitmapAndReset());
205 engine_->Disable();
206 EXPECT_EQ(DEACTIVATED, observer_->GetCallsBitmapAndReset());
207 // Focus change when enabled.
208 engine_->Enable(kTestImeComponentId);
209 EXPECT_EQ(ACTIVATE | ONFOCUS, observer_->GetCallsBitmapAndReset());
210 engine_->FocusOut();
211 EXPECT_EQ(ONBLUR, observer_->GetCallsBitmapAndReset());
212 FocusIn(ui::TEXT_INPUT_TYPE_PASSWORD);
213 EXPECT_EQ(ONFOCUS, observer_->GetCallsBitmapAndReset());
214 engine_->Disable();
215 EXPECT_EQ(DEACTIVATED, observer_->GetCallsBitmapAndReset());
218 TEST_F(InputMethodEngineTest, TestSwitching_Password_Whitelisted) {
219 CreateEngine(true);
220 // Enable/disable with focus.
221 FocusIn(ui::TEXT_INPUT_TYPE_PASSWORD);
222 EXPECT_EQ(NONE, observer_->GetCallsBitmapAndReset());
223 engine_->Enable(kTestImeComponentId);
224 EXPECT_EQ(ACTIVATE | ONFOCUS, observer_->GetCallsBitmapAndReset());
225 engine_->Disable();
226 EXPECT_EQ(DEACTIVATED, observer_->GetCallsBitmapAndReset());
227 // Focus change when enabled.
228 engine_->Enable(kTestImeComponentId);
229 EXPECT_EQ(ACTIVATE | ONFOCUS, observer_->GetCallsBitmapAndReset());
230 engine_->FocusOut();
231 EXPECT_EQ(ONBLUR, observer_->GetCallsBitmapAndReset());
232 FocusIn(ui::TEXT_INPUT_TYPE_PASSWORD);
233 EXPECT_EQ(ONFOCUS, observer_->GetCallsBitmapAndReset());
234 engine_->Disable();
235 EXPECT_EQ(DEACTIVATED, observer_->GetCallsBitmapAndReset());
238 TEST_F(InputMethodEngineTest, TestHistograms) {
239 CreateEngine(true);
240 FocusIn(ui::TEXT_INPUT_TYPE_TEXT);
241 engine_->Enable(kTestImeComponentId);
242 std::vector<InputMethodEngineInterface::SegmentInfo> segments;
243 int context = engine_->GetCotextIdForTesting();
244 std::string error;
245 base::HistogramTester histograms;
246 engine_->SetComposition(context, "test", 0, 0, 0, segments, NULL);
247 engine_->CommitText(context, "input", &error);
248 engine_->SetComposition(context, "test", 0, 0, 0, segments, NULL);
249 engine_->CommitText(context,
250 "\xE5\x85\xA5\xE5\x8A\x9B", // 2 UTF-8 characters
251 &error);
252 engine_->SetComposition(context, "test", 0, 0, 0, segments, NULL);
253 engine_->CommitText(context, "input\xE5\x85\xA5\xE5\x8A\x9B", &error);
254 histograms.ExpectTotalCount("InputMethod.CommitLength", 3);
255 histograms.ExpectBucketCount("InputMethod.CommitLength", 5, 1);
256 histograms.ExpectBucketCount("InputMethod.CommitLength", 2, 1);
257 histograms.ExpectBucketCount("InputMethod.CommitLength", 7, 1);
260 TEST_F(InputMethodEngineTest, TestCompositionBoundsChanged) {
261 CreateEngine(true);
262 // Enable/disable with focus.
263 std::vector<gfx::Rect> rects;
264 rects.push_back(gfx::Rect());
265 engine_->SetCompositionBounds(rects);
266 EXPECT_EQ(ONCOMPOSITIONBOUNDSCHANGED,
267 observer_->GetCallsBitmapAndReset());
270 } // namespace input_method
271 } // namespace chromeos