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