| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 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/spellchecker/spellcheck_platform.h" | |
| 6 | |
| 7 #include <stddef.h> | |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 #include "base/macros.h" | |
| 11 #include "base/message_loop/message_loop.h" | |
| 12 #include "base/single_thread_task_runner.h" | |
| 13 #include "base/strings/string_util.h" | |
| 14 #include "base/strings/utf_string_conversions.h" | |
| 15 #include "components/spellcheck/common/spellcheck_result.h" | |
| 16 #include "content/public/test/test_utils.h" | |
| 17 #include "testing/gtest/include/gtest/gtest.h" | |
| 18 | |
| 19 namespace { | |
| 20 | |
| 21 class SpellcheckPlatformMacTest: public testing::Test { | |
| 22 public: | |
| 23 SpellcheckPlatformMacTest() | |
| 24 : callback_(base::Bind(&SpellcheckPlatformMacTest::CompletionCallback, | |
| 25 base::Unretained(this))), | |
| 26 callback_finished_(false) {} | |
| 27 | |
| 28 void WaitForCallback() { | |
| 29 content::RunMessageLoop(); | |
| 30 } | |
| 31 | |
| 32 std::vector<SpellCheckResult> results_; | |
| 33 spellcheck_platform::TextCheckCompleteCallback callback_; | |
| 34 bool callback_finished_; | |
| 35 | |
| 36 private: | |
| 37 void QuitMessageLoop() { | |
| 38 CHECK(base::MessageLoop::current() == &message_loop_); | |
| 39 base::MessageLoop::current()->QuitWhenIdle(); | |
| 40 } | |
| 41 | |
| 42 void CompletionCallback(const std::vector<SpellCheckResult>& results) { | |
| 43 results_ = results; | |
| 44 callback_finished_ = true; | |
| 45 message_loop_.task_runner()->PostTask( | |
| 46 FROM_HERE, base::Bind(&SpellcheckPlatformMacTest::QuitMessageLoop, | |
| 47 base::Unretained(this))); | |
| 48 } | |
| 49 | |
| 50 base::MessageLoopForUI message_loop_; | |
| 51 spellcheck_platform::ScopedEnglishLanguageForTest scoped_language_; | |
| 52 }; | |
| 53 | |
| 54 // Tests that words are properly ignored. Currently only enabled on OS X as it | |
| 55 // is the only platform to support ignoring words. Note that in this test, we | |
| 56 // supply a non-zero doc_tag, in order to test that ignored words are matched to | |
| 57 // the correct document. | |
| 58 TEST_F(SpellcheckPlatformMacTest, IgnoreWords_EN_US) { | |
| 59 const char* kTestCases[] = { | |
| 60 "teh", | |
| 61 "morblier", | |
| 62 "watre", | |
| 63 "noooen", | |
| 64 }; | |
| 65 | |
| 66 for (size_t i = 0; i < arraysize(kTestCases); ++i) { | |
| 67 const base::string16 word(base::ASCIIToUTF16(kTestCases[i])); | |
| 68 const int doc_tag = spellcheck_platform::GetDocumentTag(); | |
| 69 | |
| 70 // The word should show up as misspelled. | |
| 71 EXPECT_FALSE(spellcheck_platform::CheckSpelling(word, doc_tag)) << word; | |
| 72 | |
| 73 // Ignore the word. | |
| 74 spellcheck_platform::IgnoreWord(word); | |
| 75 | |
| 76 // The word should now show up as correctly spelled. | |
| 77 EXPECT_TRUE(spellcheck_platform::CheckSpelling(word, doc_tag)) << word; | |
| 78 | |
| 79 // Close the docuemnt. Any words that we had previously ignored should no | |
| 80 // longer be ignored and thus should show up as misspelled. | |
| 81 spellcheck_platform::CloseDocumentWithTag(doc_tag); | |
| 82 | |
| 83 // The word should now show be spelled wrong again | |
| 84 EXPECT_FALSE(spellcheck_platform::CheckSpelling(word, doc_tag)) << word; | |
| 85 } | |
| 86 } // Test IgnoreWords_EN_US | |
| 87 | |
| 88 TEST_F(SpellcheckPlatformMacTest, SpellCheckSuggestions_EN_US) { | |
| 89 static const struct { | |
| 90 const char* input; // A string to be tested. | |
| 91 const char* suggested_word; // A suggested word that should occur. | |
| 92 } kTestCases[] = { | |
| 93 // We need to have separate test cases here, since hunspell and the OS X | |
| 94 // spellchecking service occasionally differ on what they consider a valid | |
| 95 // suggestion for a given word, although these lists could likely be | |
| 96 // integrated somewhat. The test cases for non-Mac are in | |
| 97 // chrome/renderer/spellcheck_unittest.cc | |
| 98 // These words come from the wikipedia page of the most commonly | |
| 99 // misspelled words in english. | |
| 100 // (http://en.wikipedia.org/wiki/Commonly_misspelled_words). | |
| 101 // However, 10.6 loads multiple dictionaries and enables many non-English | |
| 102 // dictionaries by default. As a result, we have removed from the list any | |
| 103 // word that is marked as correct because it is correct in another | |
| 104 // language. | |
| 105 {"absense", "absence"}, | |
| 106 {"acceptible", "acceptable"}, | |
| 107 {"accidentaly", "accidentally"}, | |
| 108 {"acheive", "achieve"}, | |
| 109 {"acknowlege", "acknowledge"}, | |
| 110 {"acquaintence", "acquaintance"}, | |
| 111 {"aquire", "acquire"}, | |
| 112 {"aquit", "acquit"}, | |
| 113 {"acrage", "acreage"}, | |
| 114 {"adultary", "adultery"}, | |
| 115 {"advertize", "advertise"}, | |
| 116 {"adviseable", "advisable"}, | |
| 117 {"alchohol", "alcohol"}, | |
| 118 {"alege", "allege"}, | |
| 119 {"allegaince", "allegiance"}, | |
| 120 {"allmost", "almost"}, | |
| 121 // Ideally, this test should pass. It works in firefox, but not in hunspell | |
| 122 // or OS X. | |
| 123 // {"alot", "a lot"}, | |
| 124 {"amatuer", "amateur"}, | |
| 125 {"ammend", "amend"}, | |
| 126 {"amung", "among"}, | |
| 127 {"anually", "annually"}, | |
| 128 {"apparant", "apparent"}, | |
| 129 {"artic", "arctic"}, | |
| 130 {"arguement", "argument"}, | |
| 131 {"athiest", "atheist"}, | |
| 132 {"athelete", "athlete"}, | |
| 133 {"avrage", "average"}, | |
| 134 {"awfull", "awful"}, | |
| 135 {"ballance", "balance"}, | |
| 136 {"basicly", "basically"}, | |
| 137 {"becuase", "because"}, | |
| 138 {"becomeing", "becoming"}, | |
| 139 {"befor", "before"}, | |
| 140 {"begining", "beginning"}, | |
| 141 {"beleive", "believe"}, | |
| 142 {"bellweather", "bellwether"}, | |
| 143 {"benifit", "benefit"}, | |
| 144 // This particular spelling correction was removed in OSX 10.10. Replacing | |
| 145 // it with another spelling correction that also works on older OSes. | |
| 146 // {"bouy", "buoy"}, | |
| 147 {"bouy", "body"}, | |
| 148 {"briliant", "brilliant"}, | |
| 149 {"burgler", "burglar"}, | |
| 150 {"camoflage", "camouflage"}, | |
| 151 {"carefull", "careful"}, | |
| 152 {"Carribean", "Caribbean"}, | |
| 153 {"catagory", "category"}, | |
| 154 {"cauhgt", "caught"}, | |
| 155 {"cieling", "ceiling"}, | |
| 156 {"cemetary", "cemetery"}, | |
| 157 {"certin", "certain"}, | |
| 158 {"changable", "changeable"}, | |
| 159 {"cheif", "chief"}, | |
| 160 {"citezen", "citizen"}, | |
| 161 {"collaegue", "colleague"}, | |
| 162 {"colum", "column"}, | |
| 163 {"comming", "coming"}, | |
| 164 {"commited", "committed"}, | |
| 165 {"compitition", "competition"}, | |
| 166 {"conceed", "concede"}, | |
| 167 {"congradulate", "congratulate"}, | |
| 168 {"consciencious", "conscientious"}, | |
| 169 {"concious", "conscious"}, | |
| 170 {"concensus", "consensus"}, | |
| 171 {"contraversy", "controversy"}, | |
| 172 {"conveniance", "convenience"}, | |
| 173 {"critecize", "criticize"}, | |
| 174 {"dacquiri", "daiquiri"}, | |
| 175 {"decieve", "deceive"}, | |
| 176 {"dicide", "decide"}, | |
| 177 {"definate", "definite"}, | |
| 178 {"definitly", "definitely"}, | |
| 179 {"desparate", "desperate"}, | |
| 180 {"develope", "develop"}, | |
| 181 {"diffrence", "difference"}, | |
| 182 {"disapear", "disappear"}, | |
| 183 {"disapoint", "disappoint"}, | |
| 184 {"disasterous", "disastrous"}, | |
| 185 {"disipline", "discipline"}, | |
| 186 {"drunkeness", "drunkenness"}, | |
| 187 {"dumbell", "dumbbell"}, | |
| 188 {"easely", "easily"}, | |
| 189 {"eigth", "eight"}, | |
| 190 {"embarass", "embarrass"}, | |
| 191 {"enviroment", "environment"}, | |
| 192 {"equiped", "equipped"}, | |
| 193 {"equiptment", "equipment"}, | |
| 194 {"exagerate", "exaggerate"}, | |
| 195 {"exellent", "excellent"}, | |
| 196 {"exsept", "except"}, | |
| 197 {"exercize", "exercise"}, | |
| 198 {"exilerate", "exhilarate"}, | |
| 199 {"existance", "existence"}, | |
| 200 {"experiance", "experience"}, | |
| 201 {"experament", "experiment"}, | |
| 202 {"explaination", "explanation"}, | |
| 203 {"facinating", "fascinating"}, | |
| 204 {"firey", "fiery"}, | |
| 205 {"finaly", "finally"}, | |
| 206 {"flourescent", "fluorescent"}, | |
| 207 {"foriegn", "foreign"}, | |
| 208 {"fourty", "forty"}, | |
| 209 {"foreward", "forward"}, | |
| 210 {"freind", "friend"}, | |
| 211 {"fundemental", "fundamental"}, | |
| 212 {"guage", "gauge"}, | |
| 213 {"generaly", "generally"}, | |
| 214 {"goverment", "government"}, | |
| 215 {"gratefull", "grateful"}, | |
| 216 {"garantee", "guarantee"}, | |
| 217 {"guidence", "guidance"}, | |
| 218 {"happyness", "happiness"}, | |
| 219 {"harrass", "harass"}, | |
| 220 {"heighth", "height"}, | |
| 221 {"heirarchy", "hierarchy"}, | |
| 222 {"humerous", "humorous"}, | |
| 223 {"hygene", "hygiene"}, | |
| 224 {"hipocrit", "hypocrite"}, | |
| 225 {"idenity", "identity"}, | |
| 226 {"ignorence", "ignorance"}, | |
| 227 {"imaginery", "imaginary"}, | |
| 228 {"immitate", "imitate"}, | |
| 229 {"immitation", "imitation"}, | |
| 230 {"imediately", "immediately"}, | |
| 231 {"incidently", "incidentally"}, | |
| 232 {"independant", "independent"}, | |
| 233 {"indispensible", "indispensable"}, | |
| 234 {"innoculate", "inoculate"}, | |
| 235 {"inteligence", "intelligence"}, | |
| 236 {"intresting", "interesting"}, | |
| 237 {"interuption", "interruption"}, | |
| 238 {"irrelevent", "irrelevant"}, | |
| 239 {"irritible", "irritable"}, | |
| 240 {"jellous", "jealous"}, | |
| 241 {"knowlege", "knowledge"}, | |
| 242 {"labratory", "laboratory"}, | |
| 243 {"lenght", "length"}, | |
| 244 {"liason", "liaison"}, | |
| 245 {"libary", "library"}, | |
| 246 {"lisence", "license"}, | |
| 247 {"lonelyness", "loneliness"}, | |
| 248 {"lieing", "lying"}, | |
| 249 {"maintenence", "maintenance"}, | |
| 250 {"manuever", "maneuver"}, | |
| 251 {"marrige", "marriage"}, | |
| 252 {"mathmatics", "mathematics"}, | |
| 253 {"medcine", "medicine"}, | |
| 254 {"miniture", "miniature"}, | |
| 255 {"minite", "minute"}, | |
| 256 {"mischevous", "mischievous"}, | |
| 257 {"mispell", "misspell"}, | |
| 258 // Maybe this one should pass, as it works in hunspell, but not in firefox. | |
| 259 // {"misterius", "mysterious"}, | |
| 260 {"naturaly", "naturally"}, | |
| 261 {"neccessary", "necessary"}, | |
| 262 {"neice", "niece"}, | |
| 263 {"nieghbor", "neighbor"}, | |
| 264 {"nieghbour", "neighbor"}, | |
| 265 {"niether", "neither"}, | |
| 266 {"noticable", "noticeable"}, | |
| 267 {"occassion", "occasion"}, | |
| 268 {"occasionaly", "occasionally"}, | |
| 269 {"occurrance", "occurrence"}, | |
| 270 {"occured", "occurred"}, | |
| 271 {"ommision", "omission"}, | |
| 272 {"oppurtunity", "opportunity"}, | |
| 273 {"outragous", "outrageous"}, | |
| 274 {"parrallel", "parallel"}, | |
| 275 {"parliment", "parliament"}, | |
| 276 {"particurly", "particularly"}, | |
| 277 {"passtime", "pastime"}, | |
| 278 {"peculier", "peculiar"}, | |
| 279 {"percieve", "perceive"}, | |
| 280 {"pernament", "permanent"}, | |
| 281 {"perseverence", "perseverance"}, | |
| 282 {"personaly", "personally"}, | |
| 283 {"persaude", "persuade"}, | |
| 284 {"pichure", "picture"}, | |
| 285 {"peice", "piece"}, | |
| 286 {"plagerize", "plagiarize"}, | |
| 287 {"playright", "playwright"}, | |
| 288 {"plesant", "pleasant"}, | |
| 289 {"pollitical", "political"}, | |
| 290 {"posession", "possession"}, | |
| 291 {"potatos", "potatoes"}, | |
| 292 {"practicle", "practical"}, | |
| 293 {"preceed", "precede"}, | |
| 294 {"predjudice", "prejudice"}, | |
| 295 {"presance", "presence"}, | |
| 296 {"privelege", "privilege"}, | |
| 297 // This one should probably work. It does in FF and Hunspell. | |
| 298 // {"probly", "probably"}, | |
| 299 {"proffesional", "professional"}, | |
| 300 {"promiss", "promise"}, | |
| 301 {"pronounciation", "pronunciation"}, | |
| 302 {"prufe", "proof"}, | |
| 303 {"psycology", "psychology"}, | |
| 304 {"publically", "publicly"}, | |
| 305 {"quanity", "quantity"}, | |
| 306 {"quarentine", "quarantine"}, | |
| 307 {"questionaire", "questionnaire"}, | |
| 308 {"readible", "readable"}, | |
| 309 {"realy", "really"}, | |
| 310 {"recieve", "receive"}, | |
| 311 {"reciept", "receipt"}, | |
| 312 {"reconize", "recognize"}, | |
| 313 {"recomend", "recommend"}, | |
| 314 {"refered", "referred"}, | |
| 315 {"referance", "reference"}, | |
| 316 {"relevent", "relevant"}, | |
| 317 {"religous", "religious"}, | |
| 318 {"repitition", "repetition"}, | |
| 319 {"restarant", "restaurant"}, | |
| 320 {"rythm", "rhythm"}, | |
| 321 {"rediculous", "ridiculous"}, | |
| 322 {"sacrefice", "sacrifice"}, | |
| 323 {"saftey", "safety"}, | |
| 324 {"sissors", "scissors"}, | |
| 325 {"secratary", "secretary"}, | |
| 326 {"seperate", "separate"}, | |
| 327 {"sargent", "sergeant"}, | |
| 328 {"shineing", "shining"}, | |
| 329 {"similer", "similar"}, | |
| 330 {"sinceerly", "sincerely"}, | |
| 331 {"speach", "speech"}, | |
| 332 {"strenght", "strength"}, | |
| 333 {"succesful", "successful"}, | |
| 334 {"supercede", "supersede"}, | |
| 335 {"surelly", "surely"}, | |
| 336 {"suprise", "surprise"}, | |
| 337 {"temperture", "temperature"}, | |
| 338 {"temprary", "temporary"}, | |
| 339 {"tommorrow", "tomorrow"}, | |
| 340 {"tounge", "tongue"}, | |
| 341 {"truely", "truly"}, | |
| 342 {"twelth", "twelfth"}, | |
| 343 {"tyrany", "tyranny"}, | |
| 344 {"underate", "underrate"}, | |
| 345 {"untill", "until"}, | |
| 346 {"unuseual", "unusual"}, | |
| 347 {"upholstry", "upholstery"}, | |
| 348 {"usible", "usable"}, | |
| 349 {"useing", "using"}, | |
| 350 {"usualy", "usually"}, | |
| 351 {"vaccuum", "vacuum"}, | |
| 352 {"vegatarian", "vegetarian"}, | |
| 353 {"vehical", "vehicle"}, | |
| 354 {"visious", "vicious"}, | |
| 355 {"villege", "village"}, | |
| 356 {"wierd", "weird"}, | |
| 357 {"wellcome", "welcome"}, | |
| 358 {"wellfare", "welfare"}, | |
| 359 {"wilfull", "willful"}, | |
| 360 {"withold", "withhold"}, | |
| 361 {"writting", "writing"}, | |
| 362 }; | |
| 363 | |
| 364 for (size_t i = 0; i < arraysize(kTestCases); ++i) { | |
| 365 const base::string16 word(base::ASCIIToUTF16(kTestCases[i].input)); | |
| 366 EXPECT_FALSE(spellcheck_platform::CheckSpelling(word, 0)) << word; | |
| 367 | |
| 368 // Check if the suggested words occur. | |
| 369 std::vector<base::string16> suggestions; | |
| 370 spellcheck_platform::FillSuggestionList(word, &suggestions); | |
| 371 bool suggested_word_is_present = false; | |
| 372 const base::string16 suggested_word( | |
| 373 base::ASCIIToUTF16(kTestCases[i].suggested_word)); | |
| 374 for (size_t j = 0; j < suggestions.size(); j++) { | |
| 375 if (suggestions[j].compare(suggested_word) == 0) { | |
| 376 suggested_word_is_present = true; | |
| 377 break; | |
| 378 } | |
| 379 } | |
| 380 EXPECT_TRUE(suggested_word_is_present) << suggested_word; | |
| 381 } | |
| 382 } | |
| 383 | |
| 384 // The OSX spellchecker returns non-spellcheck results when invoked on a | |
| 385 // sentence, specifically an NSTextCheckingTypeOrthography result indicating | |
| 386 // the language used in that sentence. Test that it is filtered out from | |
| 387 // RequestTextCheck results. | |
| 388 TEST_F(SpellcheckPlatformMacTest, SpellCheckIgnoresOrthography) { | |
| 389 base::string16 test_string(base::ASCIIToUTF16("Icland is awesome.")); | |
| 390 spellcheck_platform::RequestTextCheck(0, test_string, callback_); | |
| 391 WaitForCallback(); | |
| 392 EXPECT_TRUE(callback_finished_); | |
| 393 EXPECT_EQ(1U, results_.size()); | |
| 394 } | |
| 395 | |
| 396 } // namespace | |
| OLD | NEW |