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