45ab518fd3d8541ec0c0b168e95c0adbab49b288
[platform/framework/web/crosswalk.git] / src / ash / ime / candidate_window_view_unittest.cc
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.
4
5 #include "ash/ime/candidate_window_view.h"
6
7 #include <string>
8
9 #include "ash/ime/candidate_view.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "ui/views/test/views_test_base.h"
14 #include "ui/views/widget/widget.h"
15
16 namespace ash {
17 namespace ime {
18
19 namespace {
20 const char* kSampleCandidate[] = {
21   "Sample Candidate 1",
22   "Sample Candidate 2",
23   "Sample Candidate 3"
24 };
25 const char* kSampleAnnotation[] = {
26   "Sample Annotation 1",
27   "Sample Annotation 2",
28   "Sample Annotation 3"
29 };
30 const char* kSampleDescriptionTitle[] = {
31   "Sample Description Title 1",
32   "Sample Description Title 2",
33   "Sample Description Title 3",
34 };
35 const char* kSampleDescriptionBody[] = {
36   "Sample Description Body 1",
37   "Sample Description Body 2",
38   "Sample Description Body 3",
39 };
40
41 void InitCandidateWindow(size_t page_size,
42                          ui::CandidateWindow* candidate_window) {
43   candidate_window->set_cursor_position(0);
44   candidate_window->set_page_size(page_size);
45   candidate_window->mutable_candidates()->clear();
46   candidate_window->set_orientation(ui::CandidateWindow::VERTICAL);
47 }
48
49 void InitCandidateWindowWithCandidatesFilled(
50     size_t page_size,
51     ui::CandidateWindow* candidate_window) {
52   InitCandidateWindow(page_size, candidate_window);
53   for (size_t i = 0; i < page_size; ++i) {
54     ui::CandidateWindow::Entry entry;
55     entry.value = base::StringPrintf("value %lld",
56                                      static_cast<unsigned long long>(i));
57     entry.label = base::StringPrintf("%lld",
58                                      static_cast<unsigned long long>(i));
59     candidate_window->mutable_candidates()->push_back(entry);
60   }
61 }
62
63 }  // namespace
64
65 class CandidateWindowViewTest : public views::ViewsTestBase {
66  public:
67   CandidateWindowViewTest() {}
68   virtual ~CandidateWindowViewTest() {}
69
70  protected:
71   virtual void SetUp() {
72     views::ViewsTestBase::SetUp();
73     candidate_window_view_ = new CandidateWindowView(GetContext());
74     candidate_window_view_->InitWidget();
75   }
76
77   CandidateWindowView* candidate_window_view() {
78     return candidate_window_view_;
79   }
80
81   int selected_candidate_index_in_page() {
82     return candidate_window_view_->selected_candidate_index_in_page_;
83   }
84
85   size_t GetCandidatesSize() const {
86     return candidate_window_view_->candidate_views_.size();
87   }
88
89   CandidateView* GetCandidateAt(size_t i) {
90     return candidate_window_view_->candidate_views_[i];
91   }
92
93   void SelectCandidateAt(int index_in_page) {
94     candidate_window_view_->SelectCandidateAt(index_in_page);
95   }
96
97   void MaybeInitializeCandidateViews(
98       const ui::CandidateWindow& candidate_window) {
99     candidate_window_view_->MaybeInitializeCandidateViews(candidate_window);
100   }
101
102   void ExpectLabels(const std::string& shortcut,
103                     const std::string& candidate,
104                     const std::string& annotation,
105                     const CandidateView* row) {
106     EXPECT_EQ(shortcut, base::UTF16ToUTF8(row->shortcut_label_->text()));
107     EXPECT_EQ(candidate, base::UTF16ToUTF8(row->candidate_label_->text()));
108     EXPECT_EQ(annotation, base::UTF16ToUTF8(row->annotation_label_->text()));
109   }
110
111  private:
112   // owned by |parent_|.
113   CandidateWindowView* candidate_window_view_;
114
115   DISALLOW_COPY_AND_ASSIGN(CandidateWindowViewTest);
116 };
117
118 TEST_F(CandidateWindowViewTest, UpdateCandidatesTest_CursorVisibility) {
119   // Visible (by default) cursor.
120   ui::CandidateWindow candidate_window;
121   const int candidate_window_size = 9;
122   InitCandidateWindowWithCandidatesFilled(candidate_window_size,
123                                           &candidate_window);
124   candidate_window_view()->UpdateCandidates(candidate_window);
125   EXPECT_EQ(0, selected_candidate_index_in_page());
126
127   // Invisible cursor.
128   candidate_window.set_is_cursor_visible(false);
129   candidate_window_view()->UpdateCandidates(candidate_window);
130   EXPECT_EQ(-1, selected_candidate_index_in_page());
131
132   // Move the cursor to the end.
133   candidate_window.set_cursor_position(candidate_window_size - 1);
134   candidate_window_view()->UpdateCandidates(candidate_window);
135   EXPECT_EQ(-1, selected_candidate_index_in_page());
136
137   // Change the cursor to visible.  The cursor must be at the end.
138   candidate_window.set_is_cursor_visible(true);
139   candidate_window_view()->UpdateCandidates(candidate_window);
140   EXPECT_EQ(candidate_window_size - 1, selected_candidate_index_in_page());
141 }
142
143 TEST_F(CandidateWindowViewTest, SelectCandidateAtTest) {
144   // Set 9 candidates.
145   ui::CandidateWindow candidate_window_large;
146   const int candidate_window_large_size = 9;
147   InitCandidateWindowWithCandidatesFilled(candidate_window_large_size,
148                                           &candidate_window_large);
149   candidate_window_large.set_cursor_position(candidate_window_large_size - 1);
150   candidate_window_view()->UpdateCandidates(candidate_window_large);
151
152   // Select the last candidate.
153   SelectCandidateAt(candidate_window_large_size - 1);
154
155   // Reduce the number of candidates to 3.
156   ui::CandidateWindow candidate_window_small;
157   const int candidate_window_small_size = 3;
158   InitCandidateWindowWithCandidatesFilled(candidate_window_small_size,
159                                           &candidate_window_small);
160   candidate_window_small.set_cursor_position(candidate_window_small_size - 1);
161   // Make sure the test doesn't crash if the candidate window reduced
162   // its size. (crbug.com/174163)
163   candidate_window_view()->UpdateCandidates(candidate_window_small);
164   SelectCandidateAt(candidate_window_small_size - 1);
165 }
166
167 TEST_F(CandidateWindowViewTest, ShortcutSettingTest) {
168   const char* kEmptyLabel = "";
169   const char* kCustomizedLabel[] = { "a", "s", "d" };
170   const char* kExpectedHorizontalCustomizedLabel[] = { "a.", "s.", "d." };
171
172   {
173     SCOPED_TRACE("candidate_views allocation test");
174     const size_t kMaxPageSize = 16;
175     for (size_t i = 1; i < kMaxPageSize; ++i) {
176       ui::CandidateWindow candidate_window;
177       InitCandidateWindow(i, &candidate_window);
178       candidate_window_view()->UpdateCandidates(candidate_window);
179       EXPECT_EQ(i, GetCandidatesSize());
180     }
181   }
182   {
183     SCOPED_TRACE("Empty string for each labels expects empty labels(vertical)");
184     const size_t kPageSize = 3;
185     ui::CandidateWindow candidate_window;
186     InitCandidateWindow(kPageSize, &candidate_window);
187
188     candidate_window.set_orientation(ui::CandidateWindow::VERTICAL);
189     for (size_t i = 0; i < kPageSize; ++i) {
190       ui::CandidateWindow::Entry entry;
191       entry.value = kSampleCandidate[i];
192       entry.annotation = kSampleAnnotation[i];
193       entry.description_title = kSampleDescriptionTitle[i];
194       entry.description_body = kSampleDescriptionBody[i];
195       entry.label = kEmptyLabel;
196       candidate_window.mutable_candidates()->push_back(entry);
197     }
198
199     candidate_window_view()->UpdateCandidates(candidate_window);
200
201     ASSERT_EQ(kPageSize, GetCandidatesSize());
202     for (size_t i = 0; i < kPageSize; ++i) {
203       ExpectLabels(kEmptyLabel, kSampleCandidate[i], kSampleAnnotation[i],
204                    GetCandidateAt(i));
205     }
206   }
207   {
208     SCOPED_TRACE(
209         "Empty string for each labels expect empty labels(horizontal)");
210     const size_t kPageSize = 3;
211     ui::CandidateWindow candidate_window;
212     InitCandidateWindow(kPageSize, &candidate_window);
213
214     candidate_window.set_orientation(ui::CandidateWindow::HORIZONTAL);
215     for (size_t i = 0; i < kPageSize; ++i) {
216       ui::CandidateWindow::Entry entry;
217       entry.value = kSampleCandidate[i];
218       entry.annotation = kSampleAnnotation[i];
219       entry.description_title = kSampleDescriptionTitle[i];
220       entry.description_body = kSampleDescriptionBody[i];
221       entry.label = kEmptyLabel;
222       candidate_window.mutable_candidates()->push_back(entry);
223     }
224
225     candidate_window_view()->UpdateCandidates(candidate_window);
226
227     ASSERT_EQ(kPageSize, GetCandidatesSize());
228     // Confirm actual labels not containing ".".
229     for (size_t i = 0; i < kPageSize; ++i) {
230       ExpectLabels(kEmptyLabel, kSampleCandidate[i], kSampleAnnotation[i],
231                    GetCandidateAt(i));
232     }
233   }
234   {
235     SCOPED_TRACE("Vertical customized label case");
236     const size_t kPageSize = 3;
237     ui::CandidateWindow candidate_window;
238     InitCandidateWindow(kPageSize, &candidate_window);
239
240     candidate_window.set_orientation(ui::CandidateWindow::VERTICAL);
241     for (size_t i = 0; i < kPageSize; ++i) {
242       ui::CandidateWindow::Entry entry;
243       entry.value = kSampleCandidate[i];
244       entry.annotation = kSampleAnnotation[i];
245       entry.description_title = kSampleDescriptionTitle[i];
246       entry.description_body = kSampleDescriptionBody[i];
247       entry.label = kCustomizedLabel[i];
248       candidate_window.mutable_candidates()->push_back(entry);
249     }
250
251     candidate_window_view()->UpdateCandidates(candidate_window);
252
253     ASSERT_EQ(kPageSize, GetCandidatesSize());
254     // Confirm actual labels not containing ".".
255     for (size_t i = 0; i < kPageSize; ++i) {
256       ExpectLabels(kCustomizedLabel[i],
257                    kSampleCandidate[i],
258                    kSampleAnnotation[i],
259                    GetCandidateAt(i));
260     }
261   }
262   {
263     SCOPED_TRACE("Horizontal customized label case");
264     const size_t kPageSize = 3;
265     ui::CandidateWindow candidate_window;
266     InitCandidateWindow(kPageSize, &candidate_window);
267
268     candidate_window.set_orientation(ui::CandidateWindow::HORIZONTAL);
269     for (size_t i = 0; i < kPageSize; ++i) {
270       ui::CandidateWindow::Entry entry;
271       entry.value = kSampleCandidate[i];
272       entry.annotation = kSampleAnnotation[i];
273       entry.description_title = kSampleDescriptionTitle[i];
274       entry.description_body = kSampleDescriptionBody[i];
275       entry.label = kCustomizedLabel[i];
276       candidate_window.mutable_candidates()->push_back(entry);
277     }
278
279     candidate_window_view()->UpdateCandidates(candidate_window);
280
281     ASSERT_EQ(kPageSize, GetCandidatesSize());
282     // Confirm actual labels not containing ".".
283     for (size_t i = 0; i < kPageSize; ++i) {
284       ExpectLabels(kExpectedHorizontalCustomizedLabel[i],
285                    kSampleCandidate[i],
286                    kSampleAnnotation[i],
287                    GetCandidateAt(i));
288     }
289   }
290 }
291
292 TEST_F(CandidateWindowViewTest, DoNotChangeRowHeightWithLabelSwitchTest) {
293   const size_t kPageSize = 10;
294   ui::CandidateWindow candidate_window;
295   ui::CandidateWindow no_shortcut_candidate_window;
296
297   const char kSampleCandidate1[] = "Sample String 1";
298   const char kSampleCandidate2[] = "\xE3\x81\x82";  // multi byte string.
299   const char kSampleCandidate3[] = ".....";
300
301   const char kSampleShortcut1[] = "1";
302   const char kSampleShortcut2[] = "b";
303   const char kSampleShortcut3[] = "C";
304
305   const char kSampleAnnotation1[] = "Sample Annotation 1";
306   const char kSampleAnnotation2[] = "\xE3\x81\x82";  // multi byte string.
307   const char kSampleAnnotation3[] = "......";
308
309   // Create CandidateWindow object.
310   InitCandidateWindow(kPageSize, &candidate_window);
311
312   candidate_window.set_cursor_position(0);
313   candidate_window.set_page_size(3);
314   candidate_window.mutable_candidates()->clear();
315   candidate_window.set_orientation(ui::CandidateWindow::VERTICAL);
316   no_shortcut_candidate_window.CopyFrom(candidate_window);
317
318   ui::CandidateWindow::Entry entry;
319   entry.value = kSampleCandidate1;
320   entry.annotation = kSampleAnnotation1;
321   candidate_window.mutable_candidates()->push_back(entry);
322   entry.label = kSampleShortcut1;
323   no_shortcut_candidate_window.mutable_candidates()->push_back(entry);
324
325   entry.value = kSampleCandidate2;
326   entry.annotation = kSampleAnnotation2;
327   candidate_window.mutable_candidates()->push_back(entry);
328   entry.label = kSampleShortcut2;
329   no_shortcut_candidate_window.mutable_candidates()->push_back(entry);
330
331   entry.value = kSampleCandidate3;
332   entry.annotation = kSampleAnnotation3;
333   candidate_window.mutable_candidates()->push_back(entry);
334   entry.label = kSampleShortcut3;
335   no_shortcut_candidate_window.mutable_candidates()->push_back(entry);
336
337   int before_height = 0;
338
339   // Test for shortcut mode to no-shortcut mode.
340   // Initialize with a shortcut mode candidate window.
341   MaybeInitializeCandidateViews(candidate_window);
342   ASSERT_EQ(3UL, GetCandidatesSize());
343   // Check the selected index is invalidated.
344   EXPECT_EQ(-1, selected_candidate_index_in_page());
345   before_height =
346       GetCandidateAt(0)->GetContentsBounds().height();
347   // Checks all entry have same row height.
348   for (size_t i = 1; i < GetCandidatesSize(); ++i)
349     EXPECT_EQ(before_height, GetCandidateAt(i)->GetContentsBounds().height());
350
351   // Initialize with a no shortcut mode candidate window.
352   MaybeInitializeCandidateViews(no_shortcut_candidate_window);
353   ASSERT_EQ(3UL, GetCandidatesSize());
354   // Check the selected index is invalidated.
355   EXPECT_EQ(-1, selected_candidate_index_in_page());
356   EXPECT_EQ(before_height, GetCandidateAt(0)->GetContentsBounds().height());
357   // Checks all entry have same row height.
358   for (size_t i = 1; i < GetCandidatesSize(); ++i)
359     EXPECT_EQ(before_height, GetCandidateAt(i)->GetContentsBounds().height());
360
361   // Test for no-shortcut mode to shortcut mode.
362   // Initialize with a no shortcut mode candidate window.
363   MaybeInitializeCandidateViews(no_shortcut_candidate_window);
364   ASSERT_EQ(3UL, GetCandidatesSize());
365   // Check the selected index is invalidated.
366   EXPECT_EQ(-1, selected_candidate_index_in_page());
367   before_height = GetCandidateAt(0)->GetContentsBounds().height();
368   // Checks all entry have same row height.
369   for (size_t i = 1; i < GetCandidatesSize(); ++i)
370     EXPECT_EQ(before_height, GetCandidateAt(i)->GetContentsBounds().height());
371
372   // Initialize with a shortcut mode candidate window.
373   MaybeInitializeCandidateViews(candidate_window);
374   ASSERT_EQ(3UL, GetCandidatesSize());
375   // Check the selected index is invalidated.
376   EXPECT_EQ(-1, selected_candidate_index_in_page());
377   EXPECT_EQ(before_height, GetCandidateAt(0)->GetContentsBounds().height());
378   // Checks all entry have same row height.
379   for (size_t i = 1; i < GetCandidatesSize(); ++i)
380     EXPECT_EQ(before_height, GetCandidateAt(i)->GetContentsBounds().height());
381 }
382
383 }  // namespace ime
384 }  // namespace ash