| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2006-2008 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 "webkit/glue/webkit_glue.h" | |
| 6 | |
| 7 #include "base/file_util.h" | |
| 8 #include "base/message_loop.h" | |
| 9 #include "base/path_service.h" | |
| 10 #include "chrome/browser/spellchecker.h" | |
| 11 #include "chrome/common/chrome_paths.h" | |
| 12 #include "testing/gtest/include/gtest/gtest.h" | |
| 13 | |
| 14 namespace { | |
| 15 class SpellCheckTest : public testing::Test { | |
| 16 private: | |
| 17 MessageLoop message_loop_; | |
| 18 }; | |
| 19 | |
| 20 const std::wstring kTempCustomDictionaryFile(L"temp_custom_dictionary.txt"); | |
| 21 | |
| 22 } // namespace | |
| 23 | |
| 24 // Represents a special initialization function used only for the unit tests | |
| 25 // in this file. | |
| 26 extern void InitHunspellWithFiles(FILE* file_aff_hunspell, | |
| 27 FILE* file_dic_hunspell); | |
| 28 | |
| 29 // Operates unit tests for the webkit_glue::SpellCheckWord() function | |
| 30 // with the US English dictionary. | |
| 31 // The unit tests in this function consist of: | |
| 32 // * Tests for the function with empty strings; | |
| 33 // * Tests for the function with a valid English word; | |
| 34 // * Tests for the function with a valid non-English word; | |
| 35 // * Tests for the function with a valid English word with a preceding | |
| 36 // space character; | |
| 37 // * Tests for the function with a valid English word with a preceding | |
| 38 // non-English word; | |
| 39 // * Tests for the function with a valid English word with a following | |
| 40 // space character; | |
| 41 // * Tests for the function with a valid English word with a following | |
| 42 // non-English word; | |
| 43 // * Tests for the function with two valid English words concatenated | |
| 44 // with space characters or non-English words; | |
| 45 // * Tests for the function with an invalid English word; | |
| 46 // * Tests for the function with an invalid English word with a preceding | |
| 47 // space character; | |
| 48 // * Tests for the function with an invalid English word with a preceding | |
| 49 // non-English word; | |
| 50 // * Tests for the function with2 an invalid English word with a following | |
| 51 // space character; | |
| 52 // * Tests for the function with an invalid English word with a following | |
| 53 // non-English word, and; | |
| 54 // * Tests for the function with two invalid English words concatenated | |
| 55 // with space characters or non-English words. | |
| 56 // A test with a "[ROBUSTNESS]" mark shows it is a robustness test and it uses | |
| 57 // grammartically incorrect string. | |
| 58 // TODO(hbono): Please feel free to add more tests. | |
| 59 TEST_F(SpellCheckTest, SpellCheckStrings_EN_US) { | |
| 60 static const struct { | |
| 61 // A string to be tested. | |
| 62 const wchar_t* input; | |
| 63 // An expected result for this test case. | |
| 64 // * true: the input string does not have any invalid words. | |
| 65 // * false: the input string has one or more invalid words. | |
| 66 bool expected_result; | |
| 67 // The position and the length of the first invalid word. | |
| 68 int misspelling_start; | |
| 69 int misspelling_length; | |
| 70 } kTestCases[] = { | |
| 71 // Empty strings. | |
| 72 {NULL, true, 0, 0}, | |
| 73 {L"", true, 0, 0}, | |
| 74 {L" ", true, 0, 0}, | |
| 75 {L"\xA0", true, 0, 0}, | |
| 76 {L"\x3000", true, 0, 0}, | |
| 77 | |
| 78 // A valid English word "hello". | |
| 79 {L"hello", true, 0, 0}, | |
| 80 // A valid Chinese word (meaning "hello") consisiting of two CJKV | |
| 81 // ideographs | |
| 82 {L"\x4F60\x597D", true, 0, 0}, | |
| 83 // A valid Korean word (meaning "hello") consisting of five hangul | |
| 84 // syllables | |
| 85 {L"\xC548\xB155\xD558\xC138\xC694", true, 0, 0}, | |
| 86 // A valid Japanese word (meaning "hello") consisting of five Hiragana | |
| 87 // letters | |
| 88 {L"\x3053\x3093\x306B\x3061\x306F", true, 0, 0}, | |
| 89 // A valid Hindi word (meaning ?) consisting of six Devanagari letters | |
| 90 // (This word is copied from "http://b/issue?id=857583".) | |
| 91 {L"\x0930\x093E\x091C\x0927\x093E\x0928", true, 0, 0}, | |
| 92 // A valid English word "affix" using a Latin ligature 'ffi' | |
| 93 {L"a\xFB03x", true, 0, 0}, | |
| 94 // A valid English word "hello" (fullwidth version) | |
| 95 {L"\xFF28\xFF45\xFF4C\xFF4C\xFF4F", true, 0, 0}, | |
| 96 // Two valid Greek words (meaning "hello") consisting of seven Greek | |
| 97 // letters | |
| 98 {L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5", true, 0, 0}, | |
| 99 // A valid Russian word (meainng "hello") consisting of twelve Cyrillic | |
| 100 // letters | |
| 101 {L"\x0437\x0434\x0440\x0430\x0432\x0441" | |
| 102 L"\x0442\x0432\x0443\x0439\x0442\x0435", true, 0, 0}, | |
| 103 // A valid English contraction | |
| 104 {L"isn't", true, 0, 0}, | |
| 105 // A valid English word enclosed with underscores. | |
| 106 {L"_hello_", true, 0, 0}, | |
| 107 | |
| 108 // A valid English word with a preceding whitespace | |
| 109 {L" " L"hello", true, 0, 0}, | |
| 110 // A valid English word with a preceding no-break space | |
| 111 {L"\xA0" L"hello", true, 0, 0}, | |
| 112 // A valid English word with a preceding ideographic space | |
| 113 {L"\x3000" L"hello", true, 0, 0}, | |
| 114 // A valid English word with a preceding Chinese word | |
| 115 {L"\x4F60\x597D" L"hello", true, 0, 0}, | |
| 116 // [ROBUSTNESS] A valid English word with a preceding Korean word | |
| 117 {L"\xC548\xB155\xD558\xC138\xC694" L"hello", true, 0, 0}, | |
| 118 // A valid English word with a preceding Japanese word | |
| 119 {L"\x3053\x3093\x306B\x3061\x306F" L"hello", true, 0, 0}, | |
| 120 // [ROBUSTNESS] A valid English word with a preceding Hindi word | |
| 121 {L"\x0930\x093E\x091C\x0927\x093E\x0928" L"hello", true, 0, 0}, | |
| 122 // [ROBUSTNESS] A valid English word with two preceding Greek words | |
| 123 {L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5" | |
| 124 L"hello", true, 0, 0}, | |
| 125 // [ROBUSTNESS] A valid English word with a preceding Russian word | |
| 126 {L"\x0437\x0434\x0440\x0430\x0432\x0441" | |
| 127 L"\x0442\x0432\x0443\x0439\x0442\x0435" L"hello", true, 0, 0}, | |
| 128 | |
| 129 // A valid English word with a following whitespace | |
| 130 {L"hello" L" ", true, 0, 0}, | |
| 131 // A valid English word with a following no-break space | |
| 132 {L"hello" L"\xA0", true, 0, 0}, | |
| 133 // A valid English word with a following ideographic space | |
| 134 {L"hello" L"\x3000", true, 0, 0}, | |
| 135 // A valid English word with a following Chinese word | |
| 136 {L"hello" L"\x4F60\x597D", true, 0, 0}, | |
| 137 // [ROBUSTNESS] A valid English word with a following Korean word | |
| 138 {L"hello" L"\xC548\xB155\xD558\xC138\xC694", true, 0, 0}, | |
| 139 // A valid English word with a following Japanese word | |
| 140 {L"hello" L"\x3053\x3093\x306B\x3061\x306F", true, 0, 0}, | |
| 141 // [ROBUSTNESS] A valid English word with a following Hindi word | |
| 142 {L"hello" L"\x0930\x093E\x091C\x0927\x093E\x0928", true, 0, 0}, | |
| 143 // [ROBUSTNESS] A valid English word with two following Greek words | |
| 144 {L"hello" | |
| 145 L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5", true, 0, 0}, | |
| 146 // [ROBUSTNESS] A valid English word with a following Russian word | |
| 147 {L"hello" L"\x0437\x0434\x0440\x0430\x0432\x0441" | |
| 148 L"\x0442\x0432\x0443\x0439\x0442\x0435", true, 0, 0}, | |
| 149 | |
| 150 // Two valid English words concatenated with a whitespace | |
| 151 {L"hello" L" " L"hello", true, 0, 0}, | |
| 152 // Two valid English words concatenated with a no-break space | |
| 153 {L"hello" L"\xA0" L"hello", true, 0, 0}, | |
| 154 // Two valid English words concatenated with an ideographic space | |
| 155 {L"hello" L"\x3000" L"hello", true, 0, 0}, | |
| 156 // Two valid English words concatenated with a Chinese word | |
| 157 {L"hello" L"\x4F60\x597D" L"hello", true, 0, 0}, | |
| 158 // [ROBUSTNESS] Two valid English words concatenated with a Korean word | |
| 159 {L"hello" L"\xC548\xB155\xD558\xC138\xC694" L"hello", true, 0, 0}, | |
| 160 // Two valid English words concatenated with a Japanese word | |
| 161 {L"hello" L"\x3053\x3093\x306B\x3061\x306F" L"hello", true, 0, 0}, | |
| 162 // [ROBUSTNESS] Two valid English words concatenated with a Hindi word | |
| 163 {L"hello" L"\x0930\x093E\x091C\x0927\x093E\x0928" L"hello" , true, 0, 0}, | |
| 164 // [ROBUSTNESS] Two valid English words concatenated with two Greek words | |
| 165 {L"hello" L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5" | |
| 166 L"hello", true, 0, 0}, | |
| 167 // [ROBUSTNESS] Two valid English words concatenated with a Russian word | |
| 168 {L"hello" L"\x0437\x0434\x0440\x0430\x0432\x0441" | |
| 169 L"\x0442\x0432\x0443\x0439\x0442\x0435" L"hello", true, 0, 0}, | |
| 170 // [ROBUSTNESS] Two valid English words concatenated with a contraction | |
| 171 // character. | |
| 172 {L"hello:hello", true, 0, 0}, | |
| 173 | |
| 174 // An invalid English word | |
| 175 {L"ifmmp", false, 0, 5}, | |
| 176 // An invalid English word "bffly" containing a Latin ligature 'ffl' | |
| 177 {L"b\xFB04y", false, 0, 3}, | |
| 178 // An invalid English word "ifmmp" (fullwidth version) | |
| 179 {L"\xFF29\xFF46\xFF4D\xFF4D\xFF50", false, 0, 5}, | |
| 180 // An invalid English contraction | |
| 181 {L"jtm'u", false, 0, 5}, | |
| 182 // An invalid English word enclosed with underscores. | |
| 183 {L"_ifmmp_", false, 1, 5}, | |
| 184 | |
| 185 // An invalid English word with a preceding whitespace | |
| 186 {L" " L"ifmmp", false, 1, 5}, | |
| 187 // An invalid English word with a preceding no-break space | |
| 188 {L"\xA0" L"ifmmp", false, 1, 5}, | |
| 189 // An invalid English word with a preceding ideographic space | |
| 190 {L"\x3000" L"ifmmp", false, 1, 5}, | |
| 191 // An invalid English word with a preceding Chinese word | |
| 192 {L"\x4F60\x597D" L"ifmmp", false, 2, 5}, | |
| 193 // [ROBUSTNESS] An invalid English word with a preceding Korean word | |
| 194 {L"\xC548\xB155\xD558\xC138\xC694" L"ifmmp", false, 5, 5}, | |
| 195 // An invalid English word with a preceding Japanese word | |
| 196 {L"\x3053\x3093\x306B\x3061\x306F" L"ifmmp", false, 5, 5}, | |
| 197 // [ROBUSTNESS] An invalid English word with a preceding Hindi word | |
| 198 {L"\x0930\x093E\x091C\x0927\x093E\x0928" L"ifmmp", false, 6, 5}, | |
| 199 // [ROBUSTNESS] An invalid English word with two preceding Greek words | |
| 200 {L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5" | |
| 201 L"ifmmp", false, 8, 5}, | |
| 202 // [ROBUSTNESS] An invalid English word with a preceding Russian word | |
| 203 {L"\x0437\x0434\x0440\x0430\x0432\x0441" | |
| 204 L"\x0442\x0432\x0443\x0439\x0442\x0435" L"ifmmp", false, 12, 5}, | |
| 205 | |
| 206 // An invalid English word with a following whitespace | |
| 207 {L"ifmmp" L" ", false, 0, 5}, | |
| 208 // An invalid English word with a following no-break space | |
| 209 {L"ifmmp" L"\xA0", false, 0, 5}, | |
| 210 // An invalid English word with a following ideographic space | |
| 211 {L"ifmmp" L"\x3000", false, 0, 5}, | |
| 212 // An invalid English word with a following Chinese word | |
| 213 {L"ifmmp" L"\x4F60\x597D", false, 0, 5}, | |
| 214 // [ROBUSTNESS] An invalid English word with a following Korean word | |
| 215 {L"ifmmp" L"\xC548\xB155\xD558\xC138\xC694", false, 0, 5}, | |
| 216 // An invalid English word with a following Japanese word | |
| 217 {L"ifmmp" L"\x3053\x3093\x306B\x3061\x306F", false, 0, 5}, | |
| 218 // [ROBUSTNESS] An invalid English word with a following Hindi word | |
| 219 {L"ifmmp" L"\x0930\x093E\x091C\x0927\x093E\x0928", false, 0, 5}, | |
| 220 // [ROBUSTNESS] An invalid English word with two following Greek words | |
| 221 {L"ifmmp" | |
| 222 L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5", false, 0, 5}, | |
| 223 // [ROBUSTNESS] An invalid English word with a following Russian word | |
| 224 {L"ifmmp" L"\x0437\x0434\x0440\x0430\x0432\x0441" | |
| 225 L"\x0442\x0432\x0443\x0439\x0442\x0435", false, 0, 5}, | |
| 226 | |
| 227 // Two invalid English words concatenated with a whitespace | |
| 228 {L"ifmmp" L" " L"ifmmp", false, 0, 5}, | |
| 229 // Two invalid English words concatenated with a no-break space | |
| 230 {L"ifmmp" L"\xA0" L"ifmmp", false, 0, 5}, | |
| 231 // Two invalid English words concatenated with an ideographic space | |
| 232 {L"ifmmp" L"\x3000" L"ifmmp", false, 0, 5}, | |
| 233 // Two invalid English words concatenated with a Chinese word | |
| 234 {L"ifmmp" L"\x4F60\x597D" L"ifmmp", false, 0, 5}, | |
| 235 // [ROBUSTNESS] Two invalid English words concatenated with a Korean word | |
| 236 {L"ifmmp" L"\xC548\xB155\xD558\xC138\xC694" L"ifmmp", false, 0, 5}, | |
| 237 // Two invalid English words concatenated with a Japanese word | |
| 238 {L"ifmmp" L"\x3053\x3093\x306B\x3061\x306F" L"ifmmp", false, 0, 5}, | |
| 239 // [ROBUSTNESS] Two invalid English words concatenated with a Hindi word | |
| 240 {L"ifmmp" L"\x0930\x093E\x091C\x0927\x093E\x0928" L"ifmmp" , false, 0, 5}, | |
| 241 // [ROBUSTNESS] Two invalid English words concatenated with two Greek words | |
| 242 {L"ifmmp" L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5" | |
| 243 L"ifmmp", false, 0, 5}, | |
| 244 // [ROBUSTNESS] Two invalid English words concatenated with a Russian word | |
| 245 {L"ifmmp" L"\x0437\x0434\x0440\x0430\x0432\x0441" | |
| 246 L"\x0442\x0432\x0443\x0439\x0442\x0435" L"ifmmp", false, 0, 5}, | |
| 247 // [ROBUSTNESS] Two invalid English words concatenated with a contraction | |
| 248 // character. | |
| 249 {L"ifmmp:ifmmp", false, 0, 11}, | |
| 250 }; | |
| 251 | |
| 252 std::wstring hunspell_directory; | |
| 253 ASSERT_TRUE(PathService::Get(chrome::DIR_APP_DICTIONARIES, | |
| 254 &hunspell_directory)); | |
| 255 | |
| 256 scoped_refptr<SpellChecker> spell_checker(new SpellChecker( | |
| 257 hunspell_directory, L"en-US", NULL, L"")); | |
| 258 | |
| 259 for (int i = 0; i < arraysize(kTestCases); i++) { | |
| 260 size_t input_length = 0; | |
| 261 if (kTestCases[i].input != NULL) { | |
| 262 input_length = wcslen(kTestCases[i].input); | |
| 263 } | |
| 264 int misspelling_start; | |
| 265 int misspelling_length; | |
| 266 bool result = spell_checker->SpellCheckWord(kTestCases[i].input, | |
| 267 static_cast<int>(input_length), | |
| 268 &misspelling_start, | |
| 269 &misspelling_length, NULL); | |
| 270 | |
| 271 EXPECT_EQ(result, kTestCases[i].expected_result); | |
| 272 EXPECT_EQ(misspelling_start, kTestCases[i].misspelling_start); | |
| 273 EXPECT_EQ(misspelling_length, kTestCases[i].misspelling_length); | |
| 274 } | |
| 275 } | |
| 276 | |
| 277 | |
| 278 TEST_F(SpellCheckTest, SpellCheckSuggestions_EN_US) { | |
| 279 static const struct { | |
| 280 // A string to be tested. | |
| 281 const wchar_t* input; | |
| 282 // An expected result for this test case. | |
| 283 // * true: the input string does not have any invalid words. | |
| 284 // * false: the input string has one or more invalid words. | |
| 285 bool expected_result; | |
| 286 // The position and the length of the first invalid word. | |
| 287 int misspelling_start; | |
| 288 int misspelling_length; | |
| 289 | |
| 290 // A suggested word that should occur. | |
| 291 const wchar_t* suggested_word; | |
| 292 } kTestCases[] = { // A valid English word with a preceding whitespace | |
| 293 {L"ello", false, 0, 0, L"hello"}, | |
| 294 {L"ello", false, 0, 0, L"cello"}, | |
| 295 {L"wate", false, 0, 0, L"water"}, | |
| 296 {L"wate", false, 0, 0, L"waste"}, | |
| 297 {L"wate", false, 0, 0, L"sate"}, | |
| 298 {L"wate", false, 0, 0, L"rate"}, | |
| 299 {L"jum", false, 0, 0, L"jump"}, | |
| 300 {L"jum", false, 0, 0, L"rum"}, | |
| 301 {L"jum", false, 0, 0, L"sum"}, | |
| 302 {L"jum", false, 0, 0, L"tum"}, | |
| 303 // TODO (Sidchat): add many more examples. | |
| 304 }; | |
| 305 | |
| 306 std::wstring hunspell_directory; | |
| 307 ASSERT_TRUE(PathService::Get(chrome::DIR_APP_DICTIONARIES, | |
| 308 &hunspell_directory)); | |
| 309 | |
| 310 scoped_refptr<SpellChecker> spell_checker(new SpellChecker( | |
| 311 hunspell_directory, L"en-US", NULL, L"")); | |
| 312 | |
| 313 for (int i = 0; i < arraysize(kTestCases); i++) { | |
| 314 std::vector<std::wstring> suggestions; | |
| 315 size_t input_length = 0; | |
| 316 if (kTestCases[i].input != NULL) { | |
| 317 input_length = wcslen(kTestCases[i].input); | |
| 318 } | |
| 319 int misspelling_start; | |
| 320 int misspelling_length; | |
| 321 bool result = spell_checker->SpellCheckWord(kTestCases[i].input, | |
| 322 static_cast<int>(input_length), | |
| 323 &misspelling_start, | |
| 324 &misspelling_length, | |
| 325 &suggestions); | |
| 326 | |
| 327 // Check for spelling. | |
| 328 EXPECT_EQ(result, kTestCases[i].expected_result); | |
| 329 | |
| 330 // Check if the suggested words occur. | |
| 331 bool suggested_word_is_present = false; | |
| 332 for (int j=0; j < static_cast<int>(suggestions.size()); j++) { | |
| 333 if (suggestions.at(j).compare(kTestCases[i].suggested_word) == 0) { | |
| 334 suggested_word_is_present = true; | |
| 335 break; | |
| 336 } | |
| 337 } | |
| 338 | |
| 339 EXPECT_TRUE(suggested_word_is_present); | |
| 340 } | |
| 341 } | |
| 342 | |
| 343 // This test Adds words to the SpellChecker and veifies that it remembers them. | |
| 344 TEST_F(SpellCheckTest, DISABLED_SpellCheckAddToDictionary_EN_US) { | |
| 345 static const struct { | |
| 346 // A string to be added to SpellChecker. | |
| 347 const wchar_t* word_to_add; | |
| 348 } kTestCases[] = { // word to be added to SpellChecker | |
| 349 {L"Googley"}, | |
| 350 {L"Googleplex"}, | |
| 351 {L"Googler"}, | |
| 352 }; | |
| 353 | |
| 354 std::wstring hunspell_directory; | |
| 355 ASSERT_TRUE(PathService::Get(chrome::DIR_APP_DICTIONARIES, | |
| 356 &hunspell_directory)); | |
| 357 | |
| 358 scoped_refptr<SpellChecker> spell_checker(new SpellChecker( | |
| 359 hunspell_directory, L"en-US", NULL, kTempCustomDictionaryFile)); | |
| 360 | |
| 361 for (int i = 0; i < arraysize(kTestCases); i++) { | |
| 362 // Add the word to spellchecker. | |
| 363 spell_checker->AddWord(std::wstring(kTestCases[i].word_to_add)); | |
| 364 | |
| 365 // Now check whether it is added to Spellchecker. | |
| 366 std::vector<std::wstring> suggestions; | |
| 367 size_t input_length = 0; | |
| 368 if (kTestCases[i].word_to_add != NULL) { | |
| 369 input_length = wcslen(kTestCases[i].word_to_add); | |
| 370 } | |
| 371 int misspelling_start; | |
| 372 int misspelling_length; | |
| 373 bool result = spell_checker->SpellCheckWord(kTestCases[i].word_to_add, | |
| 374 static_cast<int>(input_length), | |
| 375 &misspelling_start, | |
| 376 &misspelling_length, | |
| 377 &suggestions); | |
| 378 | |
| 379 // Check for spelling. | |
| 380 EXPECT_TRUE(result); | |
| 381 } | |
| 382 | |
| 383 // Now initialize another spellchecker to see that AddToWord is permanent. | |
| 384 scoped_refptr<SpellChecker> spell_checker_new(new SpellChecker( | |
| 385 hunspell_directory, L"en-US", NULL, kTempCustomDictionaryFile)); | |
| 386 | |
| 387 for (int i = 0; i < arraysize(kTestCases); i++) { | |
| 388 // Now check whether it is added to Spellchecker. | |
| 389 std::vector<std::wstring> suggestions; | |
| 390 size_t input_length = 0; | |
| 391 if (kTestCases[i].word_to_add != NULL) { | |
| 392 input_length = wcslen(kTestCases[i].word_to_add); | |
| 393 } | |
| 394 int misspelling_start; | |
| 395 int misspelling_length; | |
| 396 bool result = spell_checker_new->SpellCheckWord( | |
| 397 kTestCases[i].word_to_add, | |
| 398 static_cast<int>(input_length), | |
| 399 &misspelling_start, | |
| 400 &misspelling_length, | |
| 401 &suggestions); | |
| 402 | |
| 403 // Check for spelling. | |
| 404 EXPECT_TRUE(result); | |
| 405 } | |
| 406 | |
| 407 // Remove the temp custom dictionary file. | |
| 408 file_util::Delete(kTempCustomDictionaryFile, false); | |
| 409 } | |
| 410 | |
| 411 // SpellChecker should suggest custome words for misspelled words. | |
| 412 TEST_F(SpellCheckTest, DISABLED_SpellCheckSuggestionsAddToDictionary_EN_US) { | |
| 413 static const struct { | |
| 414 // A string to be added to SpellChecker. | |
| 415 const wchar_t* word_to_add; | |
| 416 } kTestCases[] = { // word to be added to SpellChecker | |
| 417 {L"Googley"}, | |
| 418 {L"Googleplex"}, | |
| 419 {L"Googler"}, | |
| 420 }; | |
| 421 | |
| 422 std::wstring hunspell_directory; | |
| 423 ASSERT_TRUE(PathService::Get(chrome::DIR_APP_DICTIONARIES, | |
| 424 &hunspell_directory)); | |
| 425 | |
| 426 scoped_refptr<SpellChecker> spell_checker(new SpellChecker( | |
| 427 hunspell_directory, L"en-US", NULL, kTempCustomDictionaryFile)); | |
| 428 | |
| 429 for (int i = 0; i < arraysize(kTestCases); i++) { | |
| 430 // Add the word to spellchecker. | |
| 431 spell_checker->AddWord(std::wstring(kTestCases[i].word_to_add)); | |
| 432 } | |
| 433 | |
| 434 // Now check to see whether the custom words are suggested for | |
| 435 // misspelled but similar words. | |
| 436 static const struct { | |
| 437 // A string to be tested. | |
| 438 const wchar_t* input; | |
| 439 // An expected result for this test case. | |
| 440 // * true: the input string does not have any invalid words. | |
| 441 // * false: the input string has one or more invalid words. | |
| 442 bool expected_result; | |
| 443 // The position and the length of the first invalid word. | |
| 444 int misspelling_start; | |
| 445 int misspelling_length; | |
| 446 | |
| 447 // A suggested word that should occur. | |
| 448 const wchar_t* suggested_word; | |
| 449 } kTestCasesToBeTested[] = { | |
| 450 {L"oogley", false, 0, 0, L"Googley"}, | |
| 451 {L"oogler", false, 0, 0, L"Googler"}, | |
| 452 {L"oogleplex", false, 0, 0, L"Googleplex"}, | |
| 453 }; | |
| 454 | |
| 455 for (int i = 0; i < arraysize(kTestCasesToBeTested); i++) { | |
| 456 std::vector<std::wstring> suggestions; | |
| 457 size_t input_length = 0; | |
| 458 if (kTestCasesToBeTested[i].input != NULL) { | |
| 459 input_length = wcslen(kTestCasesToBeTested[i].input); | |
| 460 } | |
| 461 int misspelling_start; | |
| 462 int misspelling_length; | |
| 463 bool result = spell_checker->SpellCheckWord(kTestCasesToBeTested[i].input, | |
| 464 static_cast<int>(input_length), | |
| 465 &misspelling_start, | |
| 466 &misspelling_length, | |
| 467 &suggestions); | |
| 468 | |
| 469 // Check for spelling. | |
| 470 EXPECT_EQ(result, kTestCasesToBeTested[i].expected_result); | |
| 471 | |
| 472 // Check if the suggested words occur. | |
| 473 bool suggested_word_is_present = false; | |
| 474 for (int j=0; j < static_cast<int>(suggestions.size()); j++) { | |
| 475 if (suggestions.at(j).compare(kTestCasesToBeTested[i].suggested_word) == | |
| 476 0) { | |
| 477 suggested_word_is_present = true; | |
| 478 break; | |
| 479 } | |
| 480 } | |
| 481 | |
| 482 EXPECT_TRUE(suggested_word_is_present); | |
| 483 } | |
| 484 | |
| 485 // Remove the temp custom dictionary file. | |
| 486 file_util::Delete(kTempCustomDictionaryFile, false); | |
| 487 } | |
| OLD | NEW |