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. 4 5 #include "chrome/browser/chromeos/input_method/candidate_window_controller_impl.h" 6 7 #include "testing/gtest/include/gtest/gtest.h" 8 9 namespace chromeos { 10 namespace input_method { 11 12 namespace { 13 14 const size_t kSampleCandidateSize = 3; 15 const char* kSampleCandidate[] = { 16 "Sample Candidate 1", 17 "Sample Candidate 2", 18 "Sample Candidate 3", 19 }; 20 const char* kSampleDescriptionTitle[] = { 21 "Sample Description Title 1", 22 "Sample Description Title 2", 23 "Sample Description Title 3", 24 }; 25 const char* kSampleDescriptionBody[] = { 26 "Sample Description Body 1", 27 "Sample Description Body 2", 28 "Sample Description Body 3", 29 }; 30 31 class TestableCandidateWindowControllerImpl : 32 public CandidateWindowControllerImpl { 33 public: 34 TestableCandidateWindowControllerImpl() {} 35 virtual ~TestableCandidateWindowControllerImpl() {} 36 37 // Changes access right for testing. 38 using CandidateWindowControllerImpl::GetInfolistWindowPosition; 39 using CandidateWindowControllerImpl::ConvertLookupTableToInfolistEntry; 40 using CandidateWindowControllerImpl::ShouldUpdateInfolist; 41 42 private: 43 DISALLOW_COPY_AND_ASSIGN(TestableCandidateWindowControllerImpl); 44 }; 45 46 } // namespace 47 48 class CandidateWindowControllerImplTest : public testing::Test { 49 public: 50 CandidateWindowControllerImplTest() 51 : kScreenRect(gfx::Rect(0, 0, 1000, 1000)) { 52 } 53 54 virtual ~CandidateWindowControllerImplTest() { 55 } 56 57 protected: 58 const gfx::Rect kScreenRect; 59 }; 60 61 TEST_F(CandidateWindowControllerImplTest, 62 GetInfolistWindowPositionTest_NoOverflow) { 63 const gfx::Rect candidate_window_rect(100, 110, 120, 130); 64 const gfx::Size infolist_window_size(200, 200); 65 66 // If there is no overflow to show infolist window, the expected position is 67 // right-top of candidate window position. 68 const gfx::Point expected_point(candidate_window_rect.right(), 69 candidate_window_rect.y()); 70 EXPECT_EQ(expected_point, 71 TestableCandidateWindowControllerImpl::GetInfolistWindowPosition( 72 candidate_window_rect, 73 kScreenRect, 74 infolist_window_size)); 75 } 76 77 TEST_F(CandidateWindowControllerImplTest, 78 GetInfolistWindowPositionTest_RightOverflow) { 79 const gfx::Rect candidate_window_rect(900, 110, 120, 130); 80 const gfx::Size infolist_window_size(200, 200); 81 82 // If right of infolist window area is no in screen, show infolist left side 83 // of candidate window, that is 84 // x : candidate_window_rect.left - infolist_window.width, 85 // y : candidate_window_rect.top 86 const gfx::Point expected_point( 87 candidate_window_rect.x() - infolist_window_size.width(), 88 candidate_window_rect.y()); 89 EXPECT_EQ(expected_point, 90 TestableCandidateWindowControllerImpl::GetInfolistWindowPosition( 91 candidate_window_rect, 92 kScreenRect, 93 infolist_window_size)); 94 } 95 96 TEST_F(CandidateWindowControllerImplTest, 97 GetInfolistWindowPositionTest_BottomOverflow) { 98 const gfx::Rect candidate_window_rect(100, 910, 120, 130); 99 const gfx::Size infolist_window_size(200, 200); 100 101 // If bottom of infolist window area is no in screen, show infolist clipping 102 // with screen bounds. 103 // x : candidate_window_rect.right 104 // y : screen_rect.bottom - infolist_window_rect.height 105 const gfx::Point expected_point( 106 candidate_window_rect.right(), 107 kScreenRect.bottom() - infolist_window_size.height()); 108 EXPECT_EQ(expected_point, 109 TestableCandidateWindowControllerImpl::GetInfolistWindowPosition( 110 candidate_window_rect, 111 kScreenRect, 112 infolist_window_size)); 113 } 114 115 TEST_F(CandidateWindowControllerImplTest, 116 GetInfolistWindowPositionTest_RightBottomOverflow) { 117 const gfx::Rect candidate_window_rect(900, 910, 120, 130); 118 const gfx::Size infolist_window_size(200, 200); 119 120 const gfx::Point expected_point( 121 candidate_window_rect.x() - infolist_window_size.width(), 122 kScreenRect.bottom() - infolist_window_size.height()); 123 EXPECT_EQ(expected_point, 124 TestableCandidateWindowControllerImpl::GetInfolistWindowPosition( 125 candidate_window_rect, 126 kScreenRect, 127 infolist_window_size)); 128 } 129 130 TEST_F(CandidateWindowControllerImplTest, 131 ConvertLookupTableToInfolistEntryTest_DenseCase) { 132 IBusLookupTable table; 133 table.set_page_size(10); 134 for (size_t i = 0; i < kSampleCandidateSize; ++i) { 135 IBusLookupTable::Entry entry; 136 entry.value = kSampleCandidate[i]; 137 entry.description_title = kSampleDescriptionTitle[i]; 138 entry.description_body = kSampleDescriptionBody[i]; 139 table.mutable_candidates()->push_back(entry); 140 } 141 table.set_cursor_position(1); 142 143 std::vector<InfolistWindowView::Entry> infolist_entries; 144 size_t focused_index = 0; 145 146 TestableCandidateWindowControllerImpl::ConvertLookupTableToInfolistEntry( 147 table, 148 &infolist_entries, 149 &focused_index); 150 151 EXPECT_EQ(kSampleCandidateSize, infolist_entries.size()); 152 EXPECT_EQ(1UL, focused_index); 153 } 154 155 TEST_F(CandidateWindowControllerImplTest, 156 ConvertLookupTableToInfolistEntryTest_SparseCase) { 157 IBusLookupTable table; 158 table.set_page_size(10); 159 for (size_t i = 0; i < kSampleCandidateSize; ++i) { 160 IBusLookupTable::Entry entry; 161 entry.value = kSampleCandidate[i]; 162 table.mutable_candidates()->push_back(entry); 163 } 164 165 std::vector<IBusLookupTable::Entry>* candidates = 166 table.mutable_candidates(); 167 (*candidates)[2].description_title = kSampleDescriptionTitle[2]; 168 (*candidates)[2].description_body = kSampleDescriptionBody[2]; 169 170 table.set_cursor_position(2); 171 172 std::vector<InfolistWindowView::Entry> infolist_entries; 173 size_t focused_index = 0; 174 175 TestableCandidateWindowControllerImpl::ConvertLookupTableToInfolistEntry( 176 table, 177 &infolist_entries, 178 &focused_index); 179 180 // Infolist entries skips empty descriptions, so expected entry size is 1 and 181 // expected focus index is 0. 182 EXPECT_EQ(1UL, infolist_entries.size()); 183 EXPECT_EQ(0UL, focused_index); 184 } 185 186 TEST_F(CandidateWindowControllerImplTest, 187 ConvertLookupTableToInfolistEntryTest_SparseNoSelectionCase) { 188 IBusLookupTable table; 189 table.set_page_size(10); 190 191 for (size_t i = 0; i < kSampleCandidateSize; ++i) { 192 IBusLookupTable::Entry entry; 193 entry.value = kSampleCandidate[i]; 194 table.mutable_candidates()->push_back(entry); 195 } 196 197 std::vector<IBusLookupTable::Entry>* candidates = 198 table.mutable_candidates(); 199 (*candidates)[2].description_title = kSampleDescriptionTitle[2]; 200 (*candidates)[2].description_body = kSampleDescriptionBody[2]; 201 202 table.set_cursor_position(0); 203 204 std::vector<InfolistWindowView::Entry> infolist_entries; 205 size_t focused_index = 0; 206 207 TestableCandidateWindowControllerImpl::ConvertLookupTableToInfolistEntry( 208 table, 209 &infolist_entries, 210 &focused_index); 211 212 // Infolist entries skips empty descriptions, so expected entry size is 1 and 213 // there is no focused index because no infolist entry candidate is selected. 214 EXPECT_EQ(1UL, infolist_entries.size()); 215 EXPECT_EQ(static_cast<size_t>(-1), focused_index); 216 } 217 218 TEST_F(CandidateWindowControllerImplTest, 219 ConvertLookupTableToInfolistEntryTest_NoInfolistCase) { 220 IBusLookupTable table; 221 table.set_page_size(10); 222 223 for (size_t i = 0; i < kSampleCandidateSize; ++i) { 224 IBusLookupTable::Entry entry; 225 entry.value = kSampleCandidate[i]; 226 table.mutable_candidates()->push_back(entry); 227 } 228 table.set_cursor_position(1); 229 230 std::vector<InfolistWindowView::Entry> infolist_entries; 231 size_t focused_index = 0; 232 233 TestableCandidateWindowControllerImpl::ConvertLookupTableToInfolistEntry( 234 table, 235 &infolist_entries, 236 &focused_index); 237 238 EXPECT_TRUE(infolist_entries.empty()); 239 EXPECT_EQ(static_cast<size_t>(-1), focused_index); 240 } 241 242 TEST_F(CandidateWindowControllerImplTest, ShouldUpdateInfolist_EmptyUpdate) { 243 std::vector<InfolistWindowView::Entry> old_entry; 244 std::vector<InfolistWindowView::Entry> new_entry; 245 EXPECT_FALSE(TestableCandidateWindowControllerImpl::ShouldUpdateInfolist( 246 old_entry, 247 InfolistWindowView::InvalidFocusIndex(), 248 new_entry, 249 InfolistWindowView::InvalidFocusIndex())); 250 } 251 252 TEST_F(CandidateWindowControllerImplTest, 253 ShouldUpdateInfolist_SameEntryUpdate) { 254 std::vector<InfolistWindowView::Entry> old_entry; 255 std::vector<InfolistWindowView::Entry> new_entry; 256 InfolistWindowView::Entry entry; 257 entry.title = kSampleDescriptionTitle[0]; 258 entry.body = kSampleDescriptionBody[0]; 259 260 old_entry.push_back(entry); 261 new_entry.push_back(entry); 262 263 EXPECT_FALSE(TestableCandidateWindowControllerImpl::ShouldUpdateInfolist( 264 old_entry, 265 InfolistWindowView::InvalidFocusIndex(), 266 new_entry, 267 InfolistWindowView::InvalidFocusIndex())); 268 } 269 270 TEST_F(CandidateWindowControllerImplTest, 271 ShouldUpdateInfolist_FOcusIndexDifferentUpdate) { 272 std::vector<InfolistWindowView::Entry> old_entry; 273 std::vector<InfolistWindowView::Entry> new_entry; 274 InfolistWindowView::Entry entry; 275 entry.title = kSampleDescriptionTitle[0]; 276 entry.body = kSampleDescriptionBody[0]; 277 278 old_entry.push_back(entry); 279 new_entry.push_back(entry); 280 281 EXPECT_TRUE(TestableCandidateWindowControllerImpl::ShouldUpdateInfolist( 282 old_entry, 283 0UL, 284 new_entry, 285 InfolistWindowView::InvalidFocusIndex())); 286 } 287 288 TEST_F(CandidateWindowControllerImplTest, 289 ShouldUpdateInfolist_DifferentEntryUpdate) { 290 std::vector<InfolistWindowView::Entry> old_entry; 291 std::vector<InfolistWindowView::Entry> new_entry; 292 InfolistWindowView::Entry entry1; 293 InfolistWindowView::Entry entry2; 294 entry1.title = kSampleDescriptionTitle[0]; 295 entry1.body = kSampleDescriptionBody[0]; 296 old_entry.push_back(entry1); 297 298 // Both title and body are different. 299 entry2.title = kSampleDescriptionTitle[1]; 300 entry2.body = kSampleDescriptionBody[1]; 301 new_entry.push_back(entry2); 302 EXPECT_TRUE(TestableCandidateWindowControllerImpl::ShouldUpdateInfolist( 303 old_entry, 304 InfolistWindowView::InvalidFocusIndex(), 305 new_entry, 306 InfolistWindowView::InvalidFocusIndex())); 307 new_entry.clear(); 308 309 // Only title is different. 310 entry2.title = kSampleDescriptionTitle[1]; 311 entry2.body = kSampleDescriptionBody[0]; 312 new_entry.push_back(entry2); 313 EXPECT_TRUE(TestableCandidateWindowControllerImpl::ShouldUpdateInfolist( 314 old_entry, 315 InfolistWindowView::InvalidFocusIndex(), 316 new_entry, 317 InfolistWindowView::InvalidFocusIndex())); 318 new_entry.clear(); 319 320 // Only body is different. 321 entry2.title = kSampleDescriptionTitle[0]; 322 entry2.body = kSampleDescriptionBody[1]; 323 new_entry.push_back(entry2); 324 EXPECT_TRUE(TestableCandidateWindowControllerImpl::ShouldUpdateInfolist( 325 old_entry, 326 InfolistWindowView::InvalidFocusIndex(), 327 new_entry, 328 InfolistWindowView::InvalidFocusIndex())); 329 new_entry.clear(); 330 } 331 332 } // namespace input_method 333 } // namespace chromeos 334