Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(485)

Side by Side Diff: chrome/renderer/spellchecker/spellcheck_unittest.cc

Issue 1092243002: Handle typographical apostrophe with spelling service client (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix ozone and mac Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/files/file_util.h" 5 #include "base/files/file_util.h"
6 #include "base/message_loop/message_loop.h" 6 #include "base/message_loop/message_loop.h"
7 #include "base/path_service.h" 7 #include "base/path_service.h"
8 #include "base/strings/sys_string_conversions.h" 8 #include "base/strings/sys_string_conversions.h"
9 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/common/chrome_paths.h" 10 #include "chrome/common/chrome_paths.h"
11 #include "chrome/common/spellcheck_common.h" 11 #include "chrome/common/spellcheck_common.h"
12 #include "chrome/common/spellcheck_result.h" 12 #include "chrome/common/spellcheck_result.h"
13 #include "chrome/renderer/spellchecker/hunspell_engine.h" 13 #include "chrome/renderer/spellchecker/hunspell_engine.h"
14 #include "chrome/renderer/spellchecker/spellcheck.h" 14 #include "chrome/renderer/spellchecker/spellcheck.h"
15 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/WebKit/public/web/WebTextCheckingCompletion.h" 16 #include "third_party/WebKit/public/web/WebTextCheckingCompletion.h"
17 #include "third_party/WebKit/public/web/WebTextCheckingResult.h" 17 #include "third_party/WebKit/public/web/WebTextCheckingResult.h"
18 18
19 #define TYPOGRAPHICAL_APOSTROPHE L"\x2019"
groby-ooo-7-16 2015/04/25 00:19:02 Eeeeeeeek. I suppose we need the define, but... ee
please use gerrit instead 2015/06/17 03:52:07 Ack
20
19 namespace { 21 namespace {
20 22
21 base::FilePath GetHunspellDirectory() { 23 base::FilePath GetHunspellDirectory() {
22 base::FilePath hunspell_directory; 24 base::FilePath hunspell_directory;
23 if (!PathService::Get(base::DIR_SOURCE_ROOT, &hunspell_directory)) 25 if (!PathService::Get(base::DIR_SOURCE_ROOT, &hunspell_directory))
24 return base::FilePath(); 26 return base::FilePath();
25 27
26 hunspell_directory = hunspell_directory.AppendASCII("third_party"); 28 hunspell_directory = hunspell_directory.AppendASCII("third_party");
27 hunspell_directory = hunspell_directory.AppendASCII("hunspell_dictionaries"); 29 hunspell_directory = hunspell_directory.AppendASCII("hunspell_dictionaries");
28 return hunspell_directory; 30 return hunspell_directory;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 74
73 ~SpellCheckTest() override {} 75 ~SpellCheckTest() override {}
74 76
75 SpellCheck* spell_check() { return spell_check_.get(); } 77 SpellCheck* spell_check() { return spell_check_.get(); }
76 78
77 bool CheckSpelling(const std::string& word, int tag) { 79 bool CheckSpelling(const std::string& word, int tag) {
78 return spell_check_->spellcheck_.platform_spelling_engine_->CheckSpelling( 80 return spell_check_->spellcheck_.platform_spelling_engine_->CheckSpelling(
79 base::ASCIIToUTF16(word), tag); 81 base::ASCIIToUTF16(word), tag);
80 } 82 }
81 83
84 bool IsValidContraction(const base::string16& word, int tag) {
85 return spell_check_->spellcheck_.IsValidContraction(word, tag);
86 }
87
82 #if !defined(OS_MACOSX) 88 #if !defined(OS_MACOSX)
83 protected: 89 protected:
84 void TestSpellCheckParagraph( 90 void TestSpellCheckParagraph(
85 const base::string16& input, 91 const base::string16& input,
86 const std::vector<SpellCheckResult>& expected) { 92 const std::vector<SpellCheckResult>& expected) {
87 blink::WebVector<blink::WebTextCheckingResult> results; 93 blink::WebVector<blink::WebTextCheckingResult> results;
88 spell_check()->SpellCheckParagraph(input, 94 spell_check()->SpellCheckParagraph(input,
89 &results); 95 &results);
90 96
91 EXPECT_EQ(results.size(), expected.size()); 97 EXPECT_EQ(results.size(), expected.size());
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 // Two valid Greek words (meaning "hello") consisting of seven Greek 200 // Two valid Greek words (meaning "hello") consisting of seven Greek
195 // letters 201 // letters
196 {L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5", true}, 202 {L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5", true},
197 // A valid Russian word (meaning "hello") consisting of twelve Cyrillic 203 // A valid Russian word (meaning "hello") consisting of twelve Cyrillic
198 // letters 204 // letters
199 {L"\x0437\x0434\x0440\x0430\x0432\x0441" 205 {L"\x0437\x0434\x0440\x0430\x0432\x0441"
200 L"\x0442\x0432\x0443\x0439\x0442\x0435", true}, 206 L"\x0442\x0432\x0443\x0439\x0442\x0435", true},
201 // A valid English contraction 207 // A valid English contraction
202 {L"isn't", true}, 208 {L"isn't", true},
203 // A valid English contraction with a typographical apostrophe. 209 // A valid English contraction with a typographical apostrophe.
204 {L"isn\x2019t", true}, 210 {L"isn" TYPOGRAPHICAL_APOSTROPHE L"t", true},
205 // A valid English word enclosed with underscores. 211 // A valid English word enclosed with underscores.
206 {L"_hello_", true}, 212 {L"_hello_", true},
207 213
208 // A valid English word with a preceding whitespace 214 // A valid English word with a preceding whitespace
209 {L" " L"hello", true}, 215 {L" " L"hello", true},
210 // A valid English word with a preceding no-break space 216 // A valid English word with a preceding no-break space
211 {L"\xA0" L"hello", true}, 217 {L"\xA0" L"hello", true},
212 // A valid English word with a preceding ideographic space 218 // A valid English word with a preceding ideographic space
213 {L"\x3000" L"hello", true}, 219 {L"\x3000" L"hello", true},
214 // A valid English word with a preceding Chinese word 220 // A valid English word with a preceding Chinese word
(...skipping 918 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 base::string16 text = base::ASCIIToUTF16("zz"); 1139 base::string16 text = base::ASCIIToUTF16("zz");
1134 std::vector<SpellCheckResult> spellcheck_results; 1140 std::vector<SpellCheckResult> spellcheck_results;
1135 spellcheck_results.push_back(SpellCheckResult( 1141 spellcheck_results.push_back(SpellCheckResult(
1136 SpellCheckResult::SPELLING, 0, 2, base::string16())); 1142 SpellCheckResult::SPELLING, 0, 2, base::string16()));
1137 blink::WebVector<blink::WebTextCheckingResult> textcheck_results; 1143 blink::WebVector<blink::WebTextCheckingResult> textcheck_results;
1138 spell_check()->CreateTextCheckingResults(SpellCheck::USE_NATIVE_CHECKER, 1144 spell_check()->CreateTextCheckingResults(SpellCheck::USE_NATIVE_CHECKER,
1139 0, 1145 0,
1140 text, 1146 text,
1141 spellcheck_results, 1147 spellcheck_results,
1142 &textcheck_results); 1148 &textcheck_results);
1143 EXPECT_EQ(spellcheck_results.size(), textcheck_results.size()); 1149 ASSERT_EQ(spellcheck_results.size(), textcheck_results.size());
1144 EXPECT_EQ(blink::WebTextDecorationTypeSpelling, 1150 EXPECT_EQ(blink::WebTextDecorationTypeSpelling,
1145 textcheck_results[0].decoration); 1151 textcheck_results[0].decoration);
1146 EXPECT_EQ(spellcheck_results[0].location, textcheck_results[0].location); 1152 EXPECT_EQ(spellcheck_results[0].location, textcheck_results[0].location);
1147 EXPECT_EQ(spellcheck_results[0].length, textcheck_results[0].length); 1153 EXPECT_EQ(spellcheck_results[0].length, textcheck_results[0].length);
1148 } 1154 }
1149 1155
1150 // Verify that the SpellCheck class replaces the spelling marker added to a 1156 // Verify that the SpellCheck class replaces the spelling marker added to a
1151 // contextually-misspelled word "bean" with a grammar marker. 1157 // contextually-misspelled word "bean" with a grammar marker.
1152 { 1158 {
1153 base::string16 text = base::ASCIIToUTF16("I have bean to USA."); 1159 base::string16 text = base::ASCIIToUTF16("I have bean to USA.");
1154 std::vector<SpellCheckResult> spellcheck_results; 1160 std::vector<SpellCheckResult> spellcheck_results;
1155 spellcheck_results.push_back(SpellCheckResult( 1161 spellcheck_results.push_back(SpellCheckResult(
1156 SpellCheckResult::SPELLING, 7, 4, base::string16())); 1162 SpellCheckResult::SPELLING, 7, 4, base::string16()));
1157 blink::WebVector<blink::WebTextCheckingResult> textcheck_results; 1163 blink::WebVector<blink::WebTextCheckingResult> textcheck_results;
1158 spell_check()->CreateTextCheckingResults(SpellCheck::USE_NATIVE_CHECKER, 1164 spell_check()->CreateTextCheckingResults(SpellCheck::USE_NATIVE_CHECKER,
1159 0, 1165 0,
1160 text, 1166 text,
1161 spellcheck_results, 1167 spellcheck_results,
1162 &textcheck_results); 1168 &textcheck_results);
1163 EXPECT_EQ(spellcheck_results.size(), textcheck_results.size()); 1169 ASSERT_EQ(spellcheck_results.size(), textcheck_results.size());
1164 EXPECT_EQ(blink::WebTextDecorationTypeGrammar, 1170 EXPECT_EQ(blink::WebTextDecorationTypeGrammar,
1165 textcheck_results[0].decoration); 1171 textcheck_results[0].decoration);
1166 EXPECT_EQ(spellcheck_results[0].location, textcheck_results[0].location); 1172 EXPECT_EQ(spellcheck_results[0].location, textcheck_results[0].location);
1167 EXPECT_EQ(spellcheck_results[0].length, textcheck_results[0].length); 1173 EXPECT_EQ(spellcheck_results[0].length, textcheck_results[0].length);
1168 } 1174 }
1175
1176 // Verify that the SpellCheck preserves the original apostrophe type in the
1177 // checked text, regardless of the type of apostrophe the browser returns.
1178 {
1179 base::string16 text = base::WideToUTF16(
1180 L"Ik've havn" TYPOGRAPHICAL_APOSTROPHE L"t ni'n"
1181 TYPOGRAPHICAL_APOSTROPHE L"out-s I've I" TYPOGRAPHICAL_APOSTROPHE
1182 L"ve");
1183 std::vector<SpellCheckResult> spellcheck_results;
1184
1185 // All typewriter apostrophe results.
1186 spellcheck_results.push_back(SpellCheckResult(
1187 SpellCheckResult::SPELLING, 0, 5, base::WideToUTF16(L"I've")));
groby-ooo-7-16 2015/04/25 00:19:02 UTF8ToUTF16 is enough here. No need to go wide cha
please use gerrit instead 2015/06/17 03:52:07 Done.
1188 spellcheck_results.push_back(SpellCheckResult(
1189 SpellCheckResult::SPELLING, 6, 6, base::WideToUTF16(L"haven't")));
1190 spellcheck_results.push_back(SpellCheckResult(
1191 SpellCheckResult::SPELLING, 13, 10, base::WideToUTF16(L"in'n'out's")));
1192
1193 // Replacements that differ only by apostrophe type should be ignored.
1194 spellcheck_results.push_back(SpellCheckResult(
1195 SpellCheckResult::SPELLING, 24, 4, base::WideToUTF16(L"I've")));
1196 spellcheck_results.push_back(SpellCheckResult(
1197 SpellCheckResult::SPELLING, 29, 4, base::WideToUTF16(L"I've")));
1198
1199 // All typographical apostrophe results.
1200 spellcheck_results.push_back(SpellCheckResult(
1201 SpellCheckResult::SPELLING, 0, 5,
1202 base::WideToUTF16(L"I" TYPOGRAPHICAL_APOSTROPHE L"ve")));
1203 spellcheck_results.push_back(SpellCheckResult(
1204 SpellCheckResult::SPELLING, 6, 6,
1205 base::WideToUTF16(L"haven" TYPOGRAPHICAL_APOSTROPHE L"t")));
1206 spellcheck_results.push_back(SpellCheckResult(
1207 SpellCheckResult::SPELLING, 13, 10, base::WideToUTF16(
1208 L"in" TYPOGRAPHICAL_APOSTROPHE L"n" TYPOGRAPHICAL_APOSTROPHE L"out"
1209 TYPOGRAPHICAL_APOSTROPHE L"s")));
1210
1211 // Replacements that differ only by apostrophe type should be ignored.
1212 spellcheck_results.push_back(SpellCheckResult(
1213 SpellCheckResult::SPELLING, 24, 4,
1214 base::WideToUTF16(L"I" TYPOGRAPHICAL_APOSTROPHE L"ve")));
1215 spellcheck_results.push_back(SpellCheckResult(
1216 SpellCheckResult::SPELLING, 29, 4,
1217 base::WideToUTF16(L"I" TYPOGRAPHICAL_APOSTROPHE L"ve")));
1218
1219 blink::WebVector<blink::WebTextCheckingResult> textcheck_results;
1220 spell_check()->CreateTextCheckingResults(SpellCheck::USE_NATIVE_CHECKER,
1221 0,
1222 text,
1223 spellcheck_results,
1224 &textcheck_results);
1225
1226 static const wchar_t* kExpectedReplacements[] = {
1227 L"I've",
1228 L"haven" TYPOGRAPHICAL_APOSTROPHE L"t",
1229 L"in'n" TYPOGRAPHICAL_APOSTROPHE L"out's",
1230 L"I've",
1231 L"haven" TYPOGRAPHICAL_APOSTROPHE L"t",
1232 L"in'n" TYPOGRAPHICAL_APOSTROPHE L"out" TYPOGRAPHICAL_APOSTROPHE L"s",
1233 };
1234
1235 ASSERT_EQ(arraysize(kExpectedReplacements), textcheck_results.size());
1236 for (size_t i = 0; i < arraysize(kExpectedReplacements); ++i) {
1237 EXPECT_EQ(base::WideToUTF16(kExpectedReplacements[i]),
1238 textcheck_results[i].replacement);
1239 }
1240 }
1169 } 1241 }
1170 1242
1171 #endif 1243 #endif
1172 1244
1173 // Checks some words that should be present in all English dictionaries. 1245 // Checks some words that should be present in all English dictionaries.
1174 TEST_F(SpellCheckTest, EnglishWords) { 1246 TEST_F(SpellCheckTest, EnglishWords) {
1175 static const struct { 1247 static const struct {
1176 const char* input; 1248 const char* input;
1177 bool should_pass; 1249 bool should_pass;
1178 } kTestCases[] = { 1250 } kTestCases[] = {
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
1366 strlen(kTestCases[i].misspelled), 1438 strlen(kTestCases[i].misspelled),
1367 0, 1439 0,
1368 &misspelling_start, 1440 &misspelling_start,
1369 &misspelling_length, 1441 &misspelling_length,
1370 &suggestions)); 1442 &suggestions));
1371 EXPECT_GE(suggestions.size(), static_cast<size_t>(1)); 1443 EXPECT_GE(suggestions.size(), static_cast<size_t>(1));
1372 if (suggestions.size() > 0) 1444 if (suggestions.size() > 0)
1373 EXPECT_EQ(suggestions[0], base::ASCIIToUTF16(kTestCases[i].suggestion)); 1445 EXPECT_EQ(suggestions[0], base::ASCIIToUTF16(kTestCases[i].suggestion));
1374 } 1446 }
1375 } 1447 }
1448
1449 // Words with apostrophes should be valid contractions.
1450 TEST_F(SpellCheckTest, IsValidContraction) {
1451 static const char* kLanguages[] = {
1452 "en-AU",
1453 "en-CA",
1454 "en-GB",
1455 "en-US",
1456 };
1457
1458 static const wchar_t* kWords[] = {
1459 L"in'n'out",
1460 L"in" TYPOGRAPHICAL_APOSTROPHE L"n" TYPOGRAPHICAL_APOSTROPHE L"out",
1461 };
1462
1463 for (size_t i = 0; i < arraysize(kLanguages); ++i) {
1464 ReinitializeSpellCheck(kLanguages[i]);
1465 for (size_t j = 0; j < arraysize(kWords); ++j)
1466 EXPECT_TRUE(IsValidContraction(base::WideToUTF16(kWords[j]), 0));
1467 }
1468 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698