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
3 // found in the LICENSE file.
7 #include "base/file_util.h"
8 #include "base/metrics/histogram_samples.h"
9 #include "base/metrics/statistics_recorder.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "chrome/browser/spellchecker/spellcheck_custom_dictionary.h"
12 #include "chrome/browser/spellchecker/spellcheck_factory.h"
13 #include "chrome/browser/spellchecker/spellcheck_host_metrics.h"
14 #include "chrome/browser/spellchecker/spellcheck_service.h"
15 #include "chrome/common/chrome_constants.h"
16 #include "chrome/common/spellcheck_common.h"
17 #include "chrome/test/base/testing_profile.h"
18 #include "content/public/test/test_browser_thread_bundle.h"
19 #include "net/url_request/test_url_fetcher_factory.h"
20 #include "sync/api/sync_change.h"
21 #include "sync/api/sync_data.h"
22 #include "sync/api/sync_error_factory.h"
23 #include "sync/api/sync_error_factory_mock.h"
24 #include "sync/protocol/sync.pb.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h"
29 // For version specific disabled tests below (http://crbug.com/230534).
30 #include "base/win/windows_version.h"
33 using base::HistogramBase
;
34 using base::HistogramSamples
;
35 using base::StatisticsRecorder
;
36 using chrome::spellcheck_common::WordList
;
37 using chrome::spellcheck_common::WordSet
;
41 // Get all sync data for the custom dictionary without limiting to maximum
42 // number of syncable words.
43 syncer::SyncDataList
GetAllSyncDataNoLimit(
44 const SpellcheckCustomDictionary
* dictionary
) {
45 syncer::SyncDataList data
;
47 const WordSet
& words
= dictionary
->GetWords();
48 for (WordSet::const_iterator it
= words
.begin(); it
!= words
.end(); ++it
) {
50 sync_pb::EntitySpecifics specifics
;
51 specifics
.mutable_dictionary()->set_word(word
);
52 data
.push_back(syncer::SyncData::CreateLocalData(word
, word
, specifics
));
59 static BrowserContextKeyedService
* BuildSpellcheckService(
60 content::BrowserContext
* profile
) {
61 return new SpellcheckService(static_cast<Profile
*>(profile
));
64 class SpellcheckCustomDictionaryTest
: public testing::Test
{
66 virtual void SetUp() OVERRIDE
{
67 // Use SetTestingFactoryAndUse to force creation and initialization.
68 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
69 &profile_
, &BuildSpellcheckService
);
71 StatisticsRecorder::Initialize();
74 // A wrapper around SpellcheckCustomDictionary::LoadDictionaryFile private
75 // function to avoid a large number of FRIEND_TEST declarations in
76 // SpellcheckCustomDictionary.
77 chrome::spellcheck_common::WordList
LoadDictionaryFile(
78 const base::FilePath
& path
) {
79 return SpellcheckCustomDictionary::LoadDictionaryFile(path
);
82 // A wrapper around SpellcheckCustomDictionary::UpdateDictionaryFile private
83 // function to avoid a large number of FRIEND_TEST declarations in
84 // SpellcheckCustomDictionary.
85 void UpdateDictionaryFile(
86 const SpellcheckCustomDictionary::Change
& dictionary_change
,
87 const base::FilePath
& path
) {
88 SpellcheckCustomDictionary::UpdateDictionaryFile(dictionary_change
, path
);
91 // A wrapper around SpellcheckCustomDictionary::OnLoaded private method to
92 // avoid a large number of FRIEND_TEST declarations in
93 // SpellcheckCustomDictionary.
95 SpellcheckCustomDictionary
& dictionary
,
96 const chrome::spellcheck_common::WordList
& custom_words
) {
97 dictionary
.OnLoaded(custom_words
);
100 // A wrapper around SpellcheckCustomDictionary::Apply private method to avoid
101 // a large number of FRIEND_TEST declarations in SpellcheckCustomDictionary.
103 SpellcheckCustomDictionary
& dictionary
,
104 const SpellcheckCustomDictionary::Change
& change
) {
105 return dictionary
.Apply(change
);
108 content::TestBrowserThreadBundle thread_bundle_
;
110 TestingProfile profile_
;
111 net::TestURLFetcherFactory fetcher_factory_
;
114 // A wrapper around SpellcheckCustomDictionary that does not own the wrapped
115 // object. An instance of this class can be inside of a scoped pointer safely
116 // while the dictionary is managed by another scoped pointer.
117 class SyncChangeProcessorDelegate
: public syncer::SyncChangeProcessor
{
119 explicit SyncChangeProcessorDelegate(SpellcheckCustomDictionary
* dictionary
)
120 : dictionary_(dictionary
) {}
121 virtual ~SyncChangeProcessorDelegate() {}
123 // Overridden from syncer::SyncChangeProcessor:
124 virtual syncer::SyncError
ProcessSyncChanges(
125 const tracked_objects::Location
& from_here
,
126 const syncer::SyncChangeList
& change_list
) OVERRIDE
{
127 return dictionary_
->ProcessSyncChanges(from_here
, change_list
);
131 SpellcheckCustomDictionary
* dictionary_
;
132 DISALLOW_COPY_AND_ASSIGN(SyncChangeProcessorDelegate
);
135 // An implementation of SyncErrorFactory that does not upload the error message
136 // and updates an outside error counter. This lets us know the number of error
137 // messages in an instance of this class after that instance is deleted.
138 class SyncErrorFactoryStub
: public syncer::SyncErrorFactory
{
140 explicit SyncErrorFactoryStub(int* error_counter
)
141 : error_counter_(error_counter
) {}
142 virtual ~SyncErrorFactoryStub() {}
144 // Overridden from syncer::SyncErrorFactory:
145 virtual syncer::SyncError
CreateAndUploadError(
146 const tracked_objects::Location
& location
,
147 const std::string
& message
) OVERRIDE
{
149 return syncer::SyncError(location
,
150 syncer::SyncError::DATATYPE_ERROR
,
157 DISALLOW_COPY_AND_ASSIGN(SyncErrorFactoryStub
);
160 // Counts the number of notifications for dictionary load and change.
161 class DictionaryObserverCounter
: public SpellcheckCustomDictionary::Observer
{
163 DictionaryObserverCounter() : loads_(0), changes_(0) {}
164 virtual ~DictionaryObserverCounter() {}
166 int loads() const { return loads_
; }
167 int changes() const { return changes_
; }
169 // Overridden from SpellcheckCustomDictionary::Observer:
170 virtual void OnCustomDictionaryLoaded() OVERRIDE
{ loads_
++; }
171 virtual void OnCustomDictionaryChanged(
172 const SpellcheckCustomDictionary::Change
& change
) OVERRIDE
{ changes_
++; }
177 DISALLOW_COPY_AND_ASSIGN(DictionaryObserverCounter
);
180 TEST_F(SpellcheckCustomDictionaryTest
, SaveAndLoad
) {
181 base::FilePath path
=
182 profile_
.GetPath().Append(chrome::kCustomDictionaryFileName
);
183 WordList loaded_custom_words
= LoadDictionaryFile(path
);
185 // The custom word list should be empty now.
187 EXPECT_EQ(expected
, loaded_custom_words
);
189 SpellcheckCustomDictionary::Change change
;
190 change
.AddWord("bar");
191 change
.AddWord("foo");
193 UpdateDictionaryFile(change
, path
);
194 expected
.push_back("bar");
195 expected
.push_back("foo");
197 // The custom word list should include written words.
198 loaded_custom_words
= LoadDictionaryFile(path
);
199 EXPECT_EQ(expected
, loaded_custom_words
);
201 change
= SpellcheckCustomDictionary::Change();
202 change
.RemoveWord("bar");
203 change
.RemoveWord("foo");
204 UpdateDictionaryFile(change
, path
);
205 loaded_custom_words
= LoadDictionaryFile(path
);
207 EXPECT_EQ(expected
, loaded_custom_words
);
210 TEST_F(SpellcheckCustomDictionaryTest
, MultiProfile
) {
211 SpellcheckService
* spellcheck_service
=
212 SpellcheckServiceFactory::GetForProfile(&profile_
);
213 SpellcheckCustomDictionary
* custom_dictionary
=
214 spellcheck_service
->GetCustomDictionary();
215 TestingProfile profile2
;
216 SpellcheckService
* spellcheck_service2
=
217 static_cast<SpellcheckService
*>(
218 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
219 &profile2
, &BuildSpellcheckService
));
220 SpellcheckCustomDictionary
* custom_dictionary2
=
221 spellcheck_service2
->GetCustomDictionary();
226 custom_dictionary
->AddWord("foo");
227 custom_dictionary
->AddWord("bar");
228 expected1
.insert("foo");
229 expected1
.insert("bar");
231 custom_dictionary2
->AddWord("hoge");
232 custom_dictionary2
->AddWord("fuga");
233 expected2
.insert("hoge");
234 expected2
.insert("fuga");
236 WordSet actual1
= custom_dictionary
->GetWords();
237 EXPECT_EQ(actual1
, expected1
);
239 WordSet actual2
= custom_dictionary2
->GetWords();
240 EXPECT_EQ(actual2
, expected2
);
243 // Legacy empty dictionary should be converted to new format empty dictionary.
244 TEST_F(SpellcheckCustomDictionaryTest
, LegacyEmptyDictionaryShouldBeConverted
) {
245 base::FilePath path
=
246 profile_
.GetPath().Append(chrome::kCustomDictionaryFileName
);
249 file_util::WriteFile(path
, content
.c_str(), content
.length());
250 WordList loaded_custom_words
= LoadDictionaryFile(path
);
251 EXPECT_TRUE(loaded_custom_words
.empty());
254 // Legacy dictionary with two words should be converted to new format dictionary
256 TEST_F(SpellcheckCustomDictionaryTest
,
257 LegacyDictionaryWithTwoWordsShouldBeConverted
) {
258 base::FilePath path
=
259 profile_
.GetPath().Append(chrome::kCustomDictionaryFileName
);
261 std::string content
= "foo\nbar\nfoo\n";
262 file_util::WriteFile(path
, content
.c_str(), content
.length());
263 WordList loaded_custom_words
= LoadDictionaryFile(path
);
265 expected
.push_back("bar");
266 expected
.push_back("foo");
267 EXPECT_EQ(expected
, loaded_custom_words
);
270 // Illegal words should be removed. Leading and trailing whitespace should be
272 TEST_F(SpellcheckCustomDictionaryTest
,
273 IllegalWordsShouldBeRemovedFromDictionary
) {
274 base::FilePath path
=
275 profile_
.GetPath().Append(chrome::kCustomDictionaryFileName
);
277 std::string content
= "foo\n foo bar \n\n \nbar\n"
278 "01234567890123456789012345678901234567890123456789"
279 "01234567890123456789012345678901234567890123456789";
280 file_util::WriteFile(path
, content
.c_str(), content
.length());
281 WordList loaded_custom_words
= LoadDictionaryFile(path
);
283 expected
.push_back("bar");
284 expected
.push_back("foo");
285 expected
.push_back("foo bar");
286 EXPECT_EQ(expected
, loaded_custom_words
);
289 // Write to dictionary should backup previous version and write the word to the
290 // end of the dictionary. If the dictionary file is corrupted on disk, the
291 // previous version should be reloaded.
292 TEST_F(SpellcheckCustomDictionaryTest
, CorruptedWriteShouldBeRecovered
) {
293 base::FilePath path
=
294 profile_
.GetPath().Append(chrome::kCustomDictionaryFileName
);
296 std::string content
= "foo\nbar";
297 file_util::WriteFile(path
, content
.c_str(), content
.length());
298 WordList loaded_custom_words
= LoadDictionaryFile(path
);
300 expected
.push_back("bar");
301 expected
.push_back("foo");
302 EXPECT_EQ(expected
, loaded_custom_words
);
304 SpellcheckCustomDictionary::Change change
;
305 change
.AddWord("baz");
306 UpdateDictionaryFile(change
, path
);
308 base::ReadFileToString(path
, &content
);
309 content
.append("corruption");
310 file_util::WriteFile(path
, content
.c_str(), content
.length());
311 loaded_custom_words
= LoadDictionaryFile(path
);
312 EXPECT_EQ(expected
, loaded_custom_words
);
315 TEST_F(SpellcheckCustomDictionaryTest
,
316 GetAllSyncDataAccuratelyReflectsDictionaryState
) {
317 SpellcheckCustomDictionary
* dictionary
=
318 SpellcheckServiceFactory::GetForProfile(
319 &profile_
)->GetCustomDictionary();
321 syncer::SyncDataList data
= dictionary
->GetAllSyncData(syncer::DICTIONARY
);
322 EXPECT_TRUE(data
.empty());
324 EXPECT_TRUE(dictionary
->AddWord("bar"));
325 EXPECT_TRUE(dictionary
->AddWord("foo"));
327 data
= dictionary
->GetAllSyncData(syncer::DICTIONARY
);
328 EXPECT_EQ(2UL, data
.size());
329 std::vector
<std::string
> words
;
330 words
.push_back("bar");
331 words
.push_back("foo");
332 for (size_t i
= 0; i
< data
.size(); i
++) {
333 EXPECT_TRUE(data
[i
].GetSpecifics().has_dictionary());
334 EXPECT_EQ(syncer::DICTIONARY
, data
[i
].GetDataType());
335 EXPECT_EQ(words
[i
], data
[i
].GetTag());
336 EXPECT_EQ(words
[i
], data
[i
].GetSpecifics().dictionary().word());
339 EXPECT_TRUE(dictionary
->RemoveWord("bar"));
340 EXPECT_TRUE(dictionary
->RemoveWord("foo"));
342 data
= dictionary
->GetAllSyncData(syncer::DICTIONARY
);
343 EXPECT_TRUE(data
.empty());
346 TEST_F(SpellcheckCustomDictionaryTest
, GetAllSyncDataHasLimit
) {
347 SpellcheckCustomDictionary
* dictionary
=
348 SpellcheckServiceFactory::GetForProfile(
349 &profile_
)->GetCustomDictionary();
351 SpellcheckCustomDictionary::Change change
;
353 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
- 1;
355 change
.AddWord("foo" + base::Uint64ToString(i
));
357 Apply(*dictionary
, change
);
358 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
- 1,
359 dictionary
->GetWords().size());
360 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
- 1,
361 dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
363 dictionary
->AddWord("baz");
364 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
365 dictionary
->GetWords().size());
366 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
367 dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
369 dictionary
->AddWord("bar");
370 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
371 dictionary
->GetWords().size());
372 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
373 dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
375 dictionary
->AddWord("snafoo");
376 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 2,
377 dictionary
->GetWords().size());
378 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
379 dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
382 TEST_F(SpellcheckCustomDictionaryTest
, ProcessSyncChanges
) {
383 SpellcheckService
* spellcheck_service
=
384 SpellcheckServiceFactory::GetForProfile(&profile_
);
385 SpellcheckCustomDictionary
* dictionary
=
386 spellcheck_service
->GetCustomDictionary();
388 dictionary
->AddWord("foo");
389 dictionary
->AddWord("bar");
391 syncer::SyncChangeList changes
;
393 // Add existing word.
394 std::string word
= "foo";
395 sync_pb::EntitySpecifics specifics
;
396 specifics
.mutable_dictionary()->set_word(word
);
397 changes
.push_back(syncer::SyncChange(
399 syncer::SyncChange::ACTION_ADD
,
400 syncer::SyncData::CreateLocalData(word
, word
, specifics
)));
403 // Add invalid word. This word is too long.
404 std::string word
= "01234567890123456789012345678901234567890123456789"
405 "01234567890123456789012345678901234567890123456789";
406 sync_pb::EntitySpecifics specifics
;
407 specifics
.mutable_dictionary()->set_word(word
);
408 changes
.push_back(syncer::SyncChange(
410 syncer::SyncChange::ACTION_ADD
,
411 syncer::SyncData::CreateLocalData(word
, word
, specifics
)));
415 std::string word
= "baz";
416 sync_pb::EntitySpecifics specifics
;
417 specifics
.mutable_dictionary()->set_word(word
);
418 changes
.push_back(syncer::SyncChange(
420 syncer::SyncChange::ACTION_ADD
,
421 syncer::SyncData::CreateLocalData(word
, word
, specifics
)));
424 // Remove missing word.
425 std::string word
= "snafoo";
426 sync_pb::EntitySpecifics specifics
;
427 specifics
.mutable_dictionary()->set_word(word
);
428 changes
.push_back(syncer::SyncChange(
430 syncer::SyncChange::ACTION_DELETE
,
431 syncer::SyncData::CreateLocalData(word
, word
, specifics
)));
434 // Remove existing word.
435 std::string word
= "bar";
436 sync_pb::EntitySpecifics specifics
;
437 specifics
.mutable_dictionary()->set_word(word
);
438 changes
.push_back(syncer::SyncChange(
440 syncer::SyncChange::ACTION_DELETE
,
441 syncer::SyncData::CreateLocalData(word
, word
, specifics
)));
444 EXPECT_FALSE(dictionary
->ProcessSyncChanges(FROM_HERE
, changes
).IsSet());
446 const WordSet
& words
= dictionary
->GetWords();
447 EXPECT_EQ(2UL, words
.size());
448 EXPECT_EQ(0UL, words
.count("bar"));
449 EXPECT_EQ(1UL, words
.count("foo"));
450 EXPECT_EQ(1UL, words
.count("baz"));
453 TEST_F(SpellcheckCustomDictionaryTest
, MergeDataAndStartSyncing
) {
454 SpellcheckService
* spellcheck_service
=
455 SpellcheckServiceFactory::GetForProfile(&profile_
);
456 SpellcheckCustomDictionary
* custom_dictionary
=
457 spellcheck_service
->GetCustomDictionary();
458 TestingProfile profile2
;
459 SpellcheckService
* spellcheck_service2
=
460 static_cast<SpellcheckService
*>(
461 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
462 &profile2
, &BuildSpellcheckService
));
463 SpellcheckCustomDictionary
* custom_dictionary2
=
464 spellcheck_service2
->GetCustomDictionary();
466 SpellcheckCustomDictionary::Change change
;
468 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
/ 2;
470 change
.AddWord("foo" + base::Uint64ToString(i
));
472 Apply(*custom_dictionary
, change
);
474 SpellcheckCustomDictionary::Change change2
;
476 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
/ 2;
478 change2
.AddWord("bar" + base::Uint64ToString(i
));
480 Apply(*custom_dictionary2
, change2
);
482 int error_counter
= 0;
483 EXPECT_FALSE(custom_dictionary
->MergeDataAndStartSyncing(
485 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
),
486 scoped_ptr
<syncer::SyncChangeProcessor
>(
487 new SyncChangeProcessorDelegate(custom_dictionary2
)),
488 scoped_ptr
<syncer::SyncErrorFactory
>(
489 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
490 EXPECT_EQ(0, error_counter
);
491 EXPECT_TRUE(custom_dictionary
->IsSyncing());
493 WordSet words
= custom_dictionary
->GetWords();
494 WordSet words2
= custom_dictionary2
->GetWords();
495 EXPECT_EQ(words
.size(), words2
.size());
496 EXPECT_EQ(words
, words2
);
499 TEST_F(SpellcheckCustomDictionaryTest
, DictionaryTooBigBeforeSyncing
) {
500 SpellcheckService
* spellcheck_service
=
501 SpellcheckServiceFactory::GetForProfile(&profile_
);
502 SpellcheckCustomDictionary
* custom_dictionary
=
503 spellcheck_service
->GetCustomDictionary();
504 TestingProfile profile2
;
505 SpellcheckService
* spellcheck_service2
=
506 static_cast<SpellcheckService
*>(
507 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
508 &profile2
, &BuildSpellcheckService
));
509 SpellcheckCustomDictionary
* custom_dictionary2
=
510 spellcheck_service2
->GetCustomDictionary();
512 SpellcheckCustomDictionary::Change change
;
514 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1;
516 change
.AddWord("foo" + base::Uint64ToString(i
));
518 Apply(*custom_dictionary
, change
);
520 int error_counter
= 0;
521 EXPECT_FALSE(custom_dictionary
->MergeDataAndStartSyncing(
523 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
),
524 scoped_ptr
<syncer::SyncChangeProcessor
>(
525 new SyncChangeProcessorDelegate(custom_dictionary2
)),
526 scoped_ptr
<syncer::SyncErrorFactory
>(
527 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
528 EXPECT_EQ(0, error_counter
);
529 EXPECT_FALSE(custom_dictionary
->IsSyncing());
531 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
532 custom_dictionary
->GetWords().size());
533 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
534 custom_dictionary2
->GetWords().size());
536 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
537 custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
538 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
539 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
542 TEST_F(SpellcheckCustomDictionaryTest
, DictionaryTooBigAndServerFull
) {
543 SpellcheckService
* spellcheck_service
=
544 SpellcheckServiceFactory::GetForProfile(&profile_
);
545 SpellcheckCustomDictionary
* custom_dictionary
=
546 spellcheck_service
->GetCustomDictionary();
547 TestingProfile profile2
;
548 SpellcheckService
* spellcheck_service2
=
549 static_cast<SpellcheckService
*>(
550 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
551 &profile2
, &BuildSpellcheckService
));
552 SpellcheckCustomDictionary
* custom_dictionary2
=
553 spellcheck_service2
->GetCustomDictionary();
555 SpellcheckCustomDictionary::Change change
;
556 SpellcheckCustomDictionary::Change change2
;
558 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
;
560 change
.AddWord("foo" + base::Uint64ToString(i
));
561 change2
.AddWord("bar" + base::Uint64ToString(i
));
563 change
.AddWord("foo");
564 Apply(*custom_dictionary
, change
);
565 Apply(*custom_dictionary2
, change2
);
567 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
568 custom_dictionary
->GetWords().size());
569 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
570 custom_dictionary2
->GetWords().size());
572 int error_counter
= 0;
573 EXPECT_FALSE(custom_dictionary
->MergeDataAndStartSyncing(
575 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
),
576 scoped_ptr
<syncer::SyncChangeProcessor
>(
577 new SyncChangeProcessorDelegate(custom_dictionary2
)),
578 scoped_ptr
<syncer::SyncErrorFactory
>(
579 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
580 EXPECT_EQ(0, error_counter
);
581 EXPECT_FALSE(custom_dictionary
->IsSyncing());
583 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
* 2 + 1,
584 custom_dictionary
->GetWords().size());
585 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
586 custom_dictionary2
->GetWords().size());
588 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
589 custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
590 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
591 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
594 TEST_F(SpellcheckCustomDictionaryTest
, ServerTooBig
) {
595 SpellcheckService
* spellcheck_service
=
596 SpellcheckServiceFactory::GetForProfile(&profile_
);
597 SpellcheckCustomDictionary
* custom_dictionary
=
598 spellcheck_service
->GetCustomDictionary();
599 TestingProfile profile2
;
600 SpellcheckService
* spellcheck_service2
=
601 static_cast<SpellcheckService
*>(
602 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
603 &profile2
, &BuildSpellcheckService
));
604 SpellcheckCustomDictionary
* custom_dictionary2
=
605 spellcheck_service2
->GetCustomDictionary();
607 SpellcheckCustomDictionary::Change change
;
608 SpellcheckCustomDictionary::Change change2
;
610 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1;
612 change
.AddWord("foo" + base::Uint64ToString(i
));
613 change2
.AddWord("bar" + base::Uint64ToString(i
));
615 Apply(*custom_dictionary
, change
);
616 Apply(*custom_dictionary2
, change2
);
618 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
619 custom_dictionary
->GetWords().size());
620 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
621 custom_dictionary2
->GetWords().size());
623 int error_counter
= 0;
624 EXPECT_FALSE(custom_dictionary
->MergeDataAndStartSyncing(
626 GetAllSyncDataNoLimit(custom_dictionary2
),
627 scoped_ptr
<syncer::SyncChangeProcessor
>(
628 new SyncChangeProcessorDelegate(custom_dictionary2
)),
629 scoped_ptr
<syncer::SyncErrorFactory
>(
630 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
631 EXPECT_EQ(0, error_counter
);
632 EXPECT_FALSE(custom_dictionary
->IsSyncing());
634 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
* 2 + 2,
635 custom_dictionary
->GetWords().size());
636 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
637 custom_dictionary2
->GetWords().size());
639 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
640 custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
641 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
642 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
645 TEST_F(SpellcheckCustomDictionaryTest
, DictionaryTooBigToStartSyncing
) {
646 SpellcheckService
* spellcheck_service
=
647 SpellcheckServiceFactory::GetForProfile(&profile_
);
648 SpellcheckCustomDictionary
* custom_dictionary
=
649 spellcheck_service
->GetCustomDictionary();
650 TestingProfile profile2
;
651 SpellcheckService
* spellcheck_service2
=
652 static_cast<SpellcheckService
*>(
653 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
654 &profile2
, &BuildSpellcheckService
));
655 SpellcheckCustomDictionary
* custom_dictionary2
=
656 spellcheck_service2
->GetCustomDictionary();
658 SpellcheckCustomDictionary::Change change
;
660 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
- 1;
662 change
.AddWord("foo" + base::Uint64ToString(i
));
664 Apply(*custom_dictionary
, change
);
666 custom_dictionary2
->AddWord("bar");
667 custom_dictionary2
->AddWord("baz");
669 int error_counter
= 0;
670 EXPECT_FALSE(custom_dictionary
->MergeDataAndStartSyncing(
672 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
),
673 scoped_ptr
<syncer::SyncChangeProcessor
>(
674 new SyncChangeProcessorDelegate(custom_dictionary2
)),
675 scoped_ptr
<syncer::SyncErrorFactory
>(
676 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
677 EXPECT_EQ(0, error_counter
);
678 EXPECT_FALSE(custom_dictionary
->IsSyncing());
680 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
681 custom_dictionary
->GetWords().size());
682 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
683 custom_dictionary2
->GetWords().size());
685 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
686 custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
687 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
688 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
691 TEST_F(SpellcheckCustomDictionaryTest
, DictionaryTooBigToContiueSyncing
) {
692 SpellcheckService
* spellcheck_service
=
693 SpellcheckServiceFactory::GetForProfile(&profile_
);
694 SpellcheckCustomDictionary
* custom_dictionary
=
695 spellcheck_service
->GetCustomDictionary();
696 TestingProfile profile2
;
697 SpellcheckService
* spellcheck_service2
=
698 static_cast<SpellcheckService
*>(
699 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
700 &profile2
, &BuildSpellcheckService
));
701 SpellcheckCustomDictionary
* custom_dictionary2
=
702 spellcheck_service2
->GetCustomDictionary();
704 SpellcheckCustomDictionary::Change change
;
706 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
- 1;
708 change
.AddWord("foo" + base::Uint64ToString(i
));
710 Apply(*custom_dictionary
, change
);
712 int error_counter
= 0;
713 EXPECT_FALSE(custom_dictionary
->MergeDataAndStartSyncing(
715 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
),
716 scoped_ptr
<syncer::SyncChangeProcessor
>(
717 new SyncChangeProcessorDelegate(custom_dictionary2
)),
718 scoped_ptr
<syncer::SyncErrorFactory
>(
719 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
720 EXPECT_EQ(0, error_counter
);
721 EXPECT_TRUE(custom_dictionary
->IsSyncing());
723 custom_dictionary
->AddWord("bar");
724 EXPECT_EQ(0, error_counter
);
725 EXPECT_TRUE(custom_dictionary
->IsSyncing());
727 custom_dictionary
->AddWord("baz");
728 EXPECT_EQ(0, error_counter
);
729 EXPECT_FALSE(custom_dictionary
->IsSyncing());
731 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
732 custom_dictionary
->GetWords().size());
733 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
734 custom_dictionary2
->GetWords().size());
736 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
737 custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
738 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
739 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
742 TEST_F(SpellcheckCustomDictionaryTest
, LoadAfterSyncStart
) {
743 SpellcheckService
* spellcheck_service
=
744 SpellcheckServiceFactory::GetForProfile(&profile_
);
745 SpellcheckCustomDictionary
* custom_dictionary
=
746 spellcheck_service
->GetCustomDictionary();
747 TestingProfile profile2
;
748 SpellcheckService
* spellcheck_service2
=
749 static_cast<SpellcheckService
*>(
750 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
751 &profile2
, &BuildSpellcheckService
));
752 SpellcheckCustomDictionary
* custom_dictionary2
=
753 spellcheck_service2
->GetCustomDictionary();
755 custom_dictionary
->AddWord("foo");
757 int error_counter
= 0;
758 EXPECT_FALSE(custom_dictionary
->MergeDataAndStartSyncing(
760 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
),
761 scoped_ptr
<syncer::SyncChangeProcessor
>(
762 new SyncChangeProcessorDelegate(custom_dictionary2
)),
763 scoped_ptr
<syncer::SyncErrorFactory
>(
764 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
765 EXPECT_EQ(0, error_counter
);
766 EXPECT_TRUE(custom_dictionary
->IsSyncing());
768 WordList custom_words
;
769 custom_words
.push_back("bar");
770 OnLoaded(*custom_dictionary
, custom_words
);
771 EXPECT_TRUE(custom_dictionary
->IsSyncing());
773 EXPECT_EQ(2UL, custom_dictionary
->GetWords().size());
774 EXPECT_EQ(2UL, custom_dictionary2
->GetWords().size());
776 EXPECT_EQ(2UL, custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
777 EXPECT_EQ(2UL, custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
780 TEST_F(SpellcheckCustomDictionaryTest
, LoadAfterSyncStartTooBigToSync
) {
781 SpellcheckService
* spellcheck_service
=
782 SpellcheckServiceFactory::GetForProfile(&profile_
);
783 SpellcheckCustomDictionary
* custom_dictionary
=
784 spellcheck_service
->GetCustomDictionary();
785 TestingProfile profile2
;
786 SpellcheckService
* spellcheck_service2
=
787 static_cast<SpellcheckService
*>(
788 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
789 &profile2
, &BuildSpellcheckService
));
790 SpellcheckCustomDictionary
* custom_dictionary2
=
791 spellcheck_service2
->GetCustomDictionary();
793 custom_dictionary
->AddWord("foo");
795 int error_counter
= 0;
796 EXPECT_FALSE(custom_dictionary
->MergeDataAndStartSyncing(
798 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
),
799 scoped_ptr
<syncer::SyncChangeProcessor
>(
800 new SyncChangeProcessorDelegate(custom_dictionary2
)),
801 scoped_ptr
<syncer::SyncErrorFactory
>(
802 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
803 EXPECT_EQ(0, error_counter
);
804 EXPECT_TRUE(custom_dictionary
->IsSyncing());
806 WordList custom_words
;
808 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
;
810 custom_words
.push_back("foo" + base::Uint64ToString(i
));
812 OnLoaded(*custom_dictionary
, custom_words
);
813 EXPECT_EQ(0, error_counter
);
814 EXPECT_FALSE(custom_dictionary
->IsSyncing());
816 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
817 custom_dictionary
->GetWords().size());
818 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
819 custom_dictionary2
->GetWords().size());
821 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
822 custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
823 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
824 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
827 TEST_F(SpellcheckCustomDictionaryTest
, LoadDuplicatesAfterSync
) {
828 SpellcheckService
* spellcheck_service
=
829 SpellcheckServiceFactory::GetForProfile(&profile_
);
830 SpellcheckCustomDictionary
* custom_dictionary
=
831 spellcheck_service
->GetCustomDictionary();
832 TestingProfile profile2
;
833 SpellcheckService
* spellcheck_service2
=
834 static_cast<SpellcheckService
*>(
835 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
836 &profile2
, &BuildSpellcheckService
));
837 SpellcheckCustomDictionary
* custom_dictionary2
=
838 spellcheck_service2
->GetCustomDictionary();
842 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
/ 2;
844 to_add
.push_back("foo" + base::Uint64ToString(i
));
846 Apply(*custom_dictionary
, SpellcheckCustomDictionary::Change(to_add
));
848 int error_counter
= 0;
849 EXPECT_FALSE(custom_dictionary
->MergeDataAndStartSyncing(
851 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
),
852 scoped_ptr
<syncer::SyncChangeProcessor
>(
853 new SyncChangeProcessorDelegate(custom_dictionary2
)),
854 scoped_ptr
<syncer::SyncErrorFactory
>(
855 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
856 EXPECT_EQ(0, error_counter
);
857 EXPECT_TRUE(custom_dictionary
->IsSyncing());
859 OnLoaded(*custom_dictionary
, to_add
);
860 EXPECT_EQ(0, error_counter
);
861 EXPECT_TRUE(custom_dictionary
->IsSyncing());
863 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
/ 2,
864 custom_dictionary
->GetWords().size());
865 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
/ 2,
866 custom_dictionary2
->GetWords().size());
868 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
/ 2,
869 custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
870 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
/ 2,
871 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
874 TEST_F(SpellcheckCustomDictionaryTest
, DictionaryLoadNotification
) {
875 SpellcheckService
* spellcheck_service
=
876 SpellcheckServiceFactory::GetForProfile(&profile_
);
877 SpellcheckCustomDictionary
* custom_dictionary
=
878 spellcheck_service
->GetCustomDictionary();
880 DictionaryObserverCounter observer
;
881 custom_dictionary
->AddObserver(&observer
);
883 WordList custom_words
;
884 custom_words
.push_back("foo");
885 custom_words
.push_back("bar");
886 OnLoaded(*custom_dictionary
, custom_words
);
888 EXPECT_GE(observer
.loads(), 1);
889 EXPECT_LE(observer
.loads(), 2);
890 EXPECT_EQ(0, observer
.changes());
892 custom_dictionary
->RemoveObserver(&observer
);
895 TEST_F(SpellcheckCustomDictionaryTest
, DictionaryAddWordNotification
) {
896 SpellcheckService
* spellcheck_service
=
897 SpellcheckServiceFactory::GetForProfile(&profile_
);
898 SpellcheckCustomDictionary
* custom_dictionary
=
899 spellcheck_service
->GetCustomDictionary();
901 OnLoaded(*custom_dictionary
, WordList());
903 DictionaryObserverCounter observer
;
904 custom_dictionary
->AddObserver(&observer
);
906 EXPECT_TRUE(custom_dictionary
->AddWord("foo"));
907 EXPECT_TRUE(custom_dictionary
->AddWord("bar"));
908 EXPECT_FALSE(custom_dictionary
->AddWord("bar"));
910 EXPECT_EQ(2, observer
.changes());
912 custom_dictionary
->RemoveObserver(&observer
);
915 TEST_F(SpellcheckCustomDictionaryTest
, DictionaryRemoveWordNotification
) {
916 SpellcheckService
* spellcheck_service
=
917 SpellcheckServiceFactory::GetForProfile(&profile_
);
918 SpellcheckCustomDictionary
* custom_dictionary
=
919 spellcheck_service
->GetCustomDictionary();
921 OnLoaded(*custom_dictionary
, WordList());
923 EXPECT_TRUE(custom_dictionary
->AddWord("foo"));
924 EXPECT_TRUE(custom_dictionary
->AddWord("bar"));
926 DictionaryObserverCounter observer
;
927 custom_dictionary
->AddObserver(&observer
);
929 EXPECT_TRUE(custom_dictionary
->RemoveWord("foo"));
930 EXPECT_TRUE(custom_dictionary
->RemoveWord("bar"));
931 EXPECT_FALSE(custom_dictionary
->RemoveWord("baz"));
933 EXPECT_EQ(2, observer
.changes());
935 custom_dictionary
->RemoveObserver(&observer
);
938 TEST_F(SpellcheckCustomDictionaryTest
, DictionarySyncNotification
) {
939 SpellcheckService
* spellcheck_service
=
940 SpellcheckServiceFactory::GetForProfile(&profile_
);
941 SpellcheckCustomDictionary
* custom_dictionary
=
942 spellcheck_service
->GetCustomDictionary();
943 TestingProfile profile2
;
944 SpellcheckService
* spellcheck_service2
=
945 static_cast<SpellcheckService
*>(
946 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
947 &profile2
, &BuildSpellcheckService
));
948 SpellcheckCustomDictionary
* custom_dictionary2
=
949 spellcheck_service2
->GetCustomDictionary();
951 OnLoaded(*custom_dictionary
, WordList());
952 OnLoaded(*custom_dictionary2
, WordList());
954 custom_dictionary
->AddWord("foo");
955 custom_dictionary
->AddWord("bar");
956 custom_dictionary2
->AddWord("foo");
957 custom_dictionary2
->AddWord("baz");
959 DictionaryObserverCounter observer
;
960 custom_dictionary
->AddObserver(&observer
);
962 DictionaryObserverCounter observer2
;
963 custom_dictionary2
->AddObserver(&observer2
);
965 int error_counter
= 0;
966 EXPECT_FALSE(custom_dictionary
->MergeDataAndStartSyncing(
968 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
),
969 scoped_ptr
<syncer::SyncChangeProcessor
>(
970 new SyncChangeProcessorDelegate(custom_dictionary2
)),
971 scoped_ptr
<syncer::SyncErrorFactory
>(
972 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
973 EXPECT_EQ(0, error_counter
);
974 EXPECT_TRUE(custom_dictionary
->IsSyncing());
976 EXPECT_EQ(1, observer
.changes());
977 EXPECT_EQ(1, observer2
.changes());
979 custom_dictionary
->RemoveObserver(&observer
);
980 custom_dictionary2
->RemoveObserver(&observer2
);
983 // The server has maximum number of words and the client has maximum number of
984 // different words before association time. No new words should be pushed to the
985 // sync server upon association. The client should accept words from the sync
987 TEST_F(SpellcheckCustomDictionaryTest
, DictionarySyncLimit
) {
988 TestingProfile server_profile
;
989 SpellcheckService
* server_spellcheck_service
=
990 static_cast<SpellcheckService
*>(
991 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
992 &server_profile
, &BuildSpellcheckService
));
994 // Here, |server_custom_dictionary| plays the role of the sync server.
995 SpellcheckCustomDictionary
* server_custom_dictionary
=
996 server_spellcheck_service
->GetCustomDictionary();
998 // Upload the maximum number of words to the sync server.
1000 SpellcheckService
* spellcheck_service
=
1001 SpellcheckServiceFactory::GetForProfile(&profile_
);
1002 SpellcheckCustomDictionary
* custom_dictionary
=
1003 spellcheck_service
->GetCustomDictionary();
1005 SpellcheckCustomDictionary::Change change
;
1007 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
;
1009 change
.AddWord("foo" + base::Uint64ToString(i
));
1011 Apply(*custom_dictionary
, change
);
1013 int error_counter
= 0;
1014 EXPECT_FALSE(custom_dictionary
->MergeDataAndStartSyncing(
1016 server_custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
),
1017 scoped_ptr
<syncer::SyncChangeProcessor
>(
1018 new SyncChangeProcessorDelegate(server_custom_dictionary
)),
1019 scoped_ptr
<syncer::SyncErrorFactory
>(
1020 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
1021 EXPECT_EQ(0, error_counter
);
1022 EXPECT_TRUE(custom_dictionary
->IsSyncing());
1023 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
1024 custom_dictionary
->GetWords().size());
1027 // The sync server now has the maximum number of words.
1028 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
1029 server_custom_dictionary
->GetWords().size());
1031 // Associate the sync server with a client that also has the maximum number of
1032 // words, but all of these words are different from the ones on the sync
1035 TestingProfile client_profile
;
1036 SpellcheckService
* client_spellcheck_service
=
1037 static_cast<SpellcheckService
*>(
1038 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
1039 &client_profile
, &BuildSpellcheckService
));
1041 // Here, |client_custom_dictionary| plays the role of the client.
1042 SpellcheckCustomDictionary
* client_custom_dictionary
=
1043 client_spellcheck_service
->GetCustomDictionary();
1045 // Add the maximum number of words to the client. These words are all
1046 // different from those on the server.
1047 SpellcheckCustomDictionary::Change change
;
1049 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
;
1051 change
.AddWord("bar" + base::Uint64ToString(i
));
1053 Apply(*client_custom_dictionary
, change
);
1055 // Associate the server and the client.
1056 int error_counter
= 0;
1057 EXPECT_FALSE(client_custom_dictionary
->MergeDataAndStartSyncing(
1059 server_custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
),
1060 scoped_ptr
<syncer::SyncChangeProcessor
>(
1061 new SyncChangeProcessorDelegate(server_custom_dictionary
)),
1062 scoped_ptr
<syncer::SyncErrorFactory
>(
1063 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
1064 EXPECT_EQ(0, error_counter
);
1065 EXPECT_FALSE(client_custom_dictionary
->IsSyncing());
1066 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
* 2,
1067 client_custom_dictionary
->GetWords().size());
1070 // The sync server should not receive more words, because it has the maximum
1071 // number of words already.
1072 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
1073 server_custom_dictionary
->GetWords().size());
1076 TEST_F(SpellcheckCustomDictionaryTest
, RecordSizeStatsCorrectly
) {
1078 // Failing consistently on Win7. See crbug.com/230534.
1079 if (base::win::GetVersion() >= base::win::VERSION_VISTA
)
1082 // Record a baseline.
1083 SpellCheckHostMetrics::RecordCustomWordCountStats(123);
1085 // Determine if test failures are due the statistics recorder not being
1086 // available or because the histogram just isn't there: crbug.com/230534.
1087 EXPECT_TRUE(StatisticsRecorder::IsActive());
1089 HistogramBase
* histogram
=
1090 StatisticsRecorder::FindHistogram("SpellCheck.CustomWords");
1091 ASSERT_TRUE(histogram
!= NULL
);
1092 scoped_ptr
<HistogramSamples
> baseline
= histogram
->SnapshotSamples();
1094 // Load the dictionary which should be empty.
1095 base::FilePath path
=
1096 profile_
.GetPath().Append(chrome::kCustomDictionaryFileName
);
1097 WordList loaded_custom_words
= LoadDictionaryFile(path
);
1098 EXPECT_EQ(0u, loaded_custom_words
.size());
1100 // We expect there to be an entry with 0.
1102 StatisticsRecorder::FindHistogram("SpellCheck.CustomWords");
1103 ASSERT_TRUE(histogram
!= NULL
);
1104 scoped_ptr
<HistogramSamples
> samples
= histogram
->SnapshotSamples();
1106 samples
->Subtract(*baseline
);
1107 EXPECT_EQ(0,samples
->sum());
1109 SpellcheckCustomDictionary::Change change
;
1110 change
.AddWord("bar");
1111 change
.AddWord("foo");
1112 UpdateDictionaryFile(change
, path
);
1114 // Load the dictionary again and it should have 2 entries.
1115 loaded_custom_words
= LoadDictionaryFile(path
);
1116 EXPECT_EQ(2u, loaded_custom_words
.size());
1119 StatisticsRecorder::FindHistogram("SpellCheck.CustomWords");
1120 ASSERT_TRUE(histogram
!= NULL
);
1121 scoped_ptr
<HistogramSamples
> samples2
= histogram
->SnapshotSamples();
1123 samples2
->Subtract(*baseline
);
1124 EXPECT_EQ(2,samples2
->sum());
1127 TEST_F(SpellcheckCustomDictionaryTest
, HasWord
) {
1128 SpellcheckService
* spellcheck_service
=
1129 SpellcheckServiceFactory::GetForProfile(&profile_
);
1130 SpellcheckCustomDictionary
* custom_dictionary
=
1131 spellcheck_service
->GetCustomDictionary();
1132 OnLoaded(*custom_dictionary
, WordList());
1133 EXPECT_FALSE(custom_dictionary
->HasWord("foo"));
1134 EXPECT_FALSE(custom_dictionary
->HasWord("bar"));
1135 custom_dictionary
->AddWord("foo");
1136 EXPECT_TRUE(custom_dictionary
->HasWord("foo"));
1137 EXPECT_FALSE(custom_dictionary
->HasWord("bar"));