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.
5 #include "chrome/browser/spellchecker/spellcheck_custom_dictionary.h"
9 #include "base/files/file_util.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/metrics/histogram_samples.h"
12 #include "base/metrics/statistics_recorder.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "chrome/browser/spellchecker/spellcheck_factory.h"
15 #include "chrome/browser/spellchecker/spellcheck_host_metrics.h"
16 #include "chrome/browser/spellchecker/spellcheck_service.h"
17 #include "chrome/common/chrome_constants.h"
18 #include "chrome/common/spellcheck_common.h"
19 #include "chrome/test/base/testing_profile.h"
20 #include "content/public/test/test_browser_thread_bundle.h"
21 #include "net/url_request/test_url_fetcher_factory.h"
22 #include "sync/api/sync_change.h"
23 #include "sync/api/sync_change_processor_wrapper_for_test.h"
24 #include "sync/api/sync_data.h"
25 #include "sync/api/sync_error_factory.h"
26 #include "sync/api/sync_error_factory_mock.h"
27 #include "sync/protocol/sync.pb.h"
28 #include "testing/gmock/include/gmock/gmock.h"
29 #include "testing/gtest/include/gtest/gtest.h"
32 // For version specific disabled tests below (http://crbug.com/230534).
33 #include "base/win/windows_version.h"
36 using base::HistogramBase
;
37 using base::HistogramSamples
;
38 using base::StatisticsRecorder
;
42 // Get all sync data for the custom dictionary without limiting to maximum
43 // number of syncable words.
44 syncer::SyncDataList
GetAllSyncDataNoLimit(
45 const SpellcheckCustomDictionary
* dictionary
) {
46 syncer::SyncDataList data
;
47 for (const std::string
& word
: dictionary
->GetWords()) {
48 sync_pb::EntitySpecifics specifics
;
49 specifics
.mutable_dictionary()->set_word(word
);
50 data
.push_back(syncer::SyncData::CreateLocalData(word
, word
, specifics
));
57 static scoped_ptr
<KeyedService
> BuildSpellcheckService(
58 content::BrowserContext
* profile
) {
59 return make_scoped_ptr(new SpellcheckService(static_cast<Profile
*>(profile
)));
62 class SpellcheckCustomDictionaryTest
: public testing::Test
{
64 void SetUp() override
{
65 // Use SetTestingFactoryAndUse to force creation and initialization.
66 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
67 &profile_
, &BuildSpellcheckService
);
69 StatisticsRecorder::Initialize();
72 // A wrapper around SpellcheckCustomDictionary::LoadDictionaryFile private
73 // function to avoid a large number of FRIEND_TEST declarations in
74 // SpellcheckCustomDictionary.
75 scoped_ptr
<std::set
<std::string
>> LoadDictionaryFile(
76 const base::FilePath
& path
) {
77 return SpellcheckCustomDictionary::LoadDictionaryFile(path
);
80 // A wrapper around SpellcheckCustomDictionary::UpdateDictionaryFile private
81 // function to avoid a large number of FRIEND_TEST declarations in
82 // SpellcheckCustomDictionary.
83 void UpdateDictionaryFile(
84 scoped_ptr
<SpellcheckCustomDictionary::Change
> dictionary_change
,
85 const base::FilePath
& path
) {
86 SpellcheckCustomDictionary::UpdateDictionaryFile(dictionary_change
.Pass(),
90 // A wrapper around SpellcheckCustomDictionary::OnLoaded private method to
91 // avoid a large number of FRIEND_TEST declarations in
92 // SpellcheckCustomDictionary.
93 void OnLoaded(SpellcheckCustomDictionary
& dictionary
,
94 scoped_ptr
<std::set
<std::string
>> custom_words
) {
95 dictionary
.OnLoaded(custom_words
.Pass());
98 // A wrapper around SpellcheckCustomDictionary::Apply private method to avoid
99 // a large number of FRIEND_TEST declarations in SpellcheckCustomDictionary.
101 SpellcheckCustomDictionary
& dictionary
,
102 const SpellcheckCustomDictionary::Change
& change
) {
103 return dictionary
.Apply(change
);
106 content::TestBrowserThreadBundle thread_bundle_
;
108 TestingProfile profile_
;
109 net::TestURLFetcherFactory fetcher_factory_
;
112 // An implementation of SyncErrorFactory that does not upload the error message
113 // and updates an outside error counter. This lets us know the number of error
114 // messages in an instance of this class after that instance is deleted.
115 class SyncErrorFactoryStub
: public syncer::SyncErrorFactory
{
117 explicit SyncErrorFactoryStub(int* error_counter
)
118 : error_counter_(error_counter
) {}
119 ~SyncErrorFactoryStub() override
{}
121 // Overridden from syncer::SyncErrorFactory:
122 syncer::SyncError
CreateAndUploadError(
123 const tracked_objects::Location
& location
,
124 const std::string
& message
) override
{
126 return syncer::SyncError(location
,
127 syncer::SyncError::DATATYPE_ERROR
,
134 DISALLOW_COPY_AND_ASSIGN(SyncErrorFactoryStub
);
137 // Counts the number of notifications for dictionary load and change.
138 class DictionaryObserverCounter
: public SpellcheckCustomDictionary::Observer
{
140 DictionaryObserverCounter() : loads_(0), changes_(0) {}
141 virtual ~DictionaryObserverCounter() {}
143 int loads() const { return loads_
; }
144 int changes() const { return changes_
; }
146 // Overridden from SpellcheckCustomDictionary::Observer:
147 void OnCustomDictionaryLoaded() override
{ loads_
++; }
148 void OnCustomDictionaryChanged(
149 const SpellcheckCustomDictionary::Change
& change
) override
{
156 DISALLOW_COPY_AND_ASSIGN(DictionaryObserverCounter
);
159 TEST_F(SpellcheckCustomDictionaryTest
, SaveAndLoad
) {
160 base::FilePath path
=
161 profile_
.GetPath().Append(chrome::kCustomDictionaryFileName
);
163 // The custom word list should be empty now.
164 EXPECT_TRUE(LoadDictionaryFile(path
)->empty());
166 scoped_ptr
<SpellcheckCustomDictionary::Change
> change(
167 new SpellcheckCustomDictionary::Change
);
168 change
->AddWord("bar");
169 change
->AddWord("foo");
171 UpdateDictionaryFile(change
.Pass(), path
);
172 std::set
<std::string
> expected
;
173 expected
.insert("bar");
174 expected
.insert("foo");
176 // The custom word list should include written words.
177 EXPECT_EQ(expected
, *LoadDictionaryFile(path
));
179 scoped_ptr
<SpellcheckCustomDictionary::Change
> change2(
180 new SpellcheckCustomDictionary::Change
);
181 change2
->RemoveWord("bar");
182 change2
->RemoveWord("foo");
183 UpdateDictionaryFile(change2
.Pass(), path
);
184 EXPECT_TRUE(LoadDictionaryFile(path
)->empty());
187 TEST_F(SpellcheckCustomDictionaryTest
, MultiProfile
) {
188 SpellcheckService
* spellcheck_service
=
189 SpellcheckServiceFactory::GetForContext(&profile_
);
190 SpellcheckCustomDictionary
* custom_dictionary
=
191 spellcheck_service
->GetCustomDictionary();
192 TestingProfile profile2
;
193 SpellcheckService
* spellcheck_service2
=
194 static_cast<SpellcheckService
*>(
195 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
196 &profile2
, &BuildSpellcheckService
));
197 SpellcheckCustomDictionary
* custom_dictionary2
=
198 spellcheck_service2
->GetCustomDictionary();
200 std::set
<std::string
> expected1
;
201 std::set
<std::string
> expected2
;
203 custom_dictionary
->AddWord("foo");
204 custom_dictionary
->AddWord("bar");
205 expected1
.insert("foo");
206 expected1
.insert("bar");
208 custom_dictionary2
->AddWord("hoge");
209 custom_dictionary2
->AddWord("fuga");
210 expected2
.insert("hoge");
211 expected2
.insert("fuga");
213 std::set
<std::string
> actual1
= custom_dictionary
->GetWords();
214 EXPECT_EQ(actual1
, expected1
);
216 std::set
<std::string
> actual2
= custom_dictionary2
->GetWords();
217 EXPECT_EQ(actual2
, expected2
);
220 // Legacy empty dictionary should be converted to new format empty dictionary.
221 TEST_F(SpellcheckCustomDictionaryTest
, LegacyEmptyDictionaryShouldBeConverted
) {
222 base::FilePath path
=
223 profile_
.GetPath().Append(chrome::kCustomDictionaryFileName
);
226 base::WriteFile(path
, content
.c_str(), content
.length());
227 EXPECT_TRUE(LoadDictionaryFile(path
)->empty());
230 // Legacy dictionary with two words should be converted to new format dictionary
232 TEST_F(SpellcheckCustomDictionaryTest
,
233 LegacyDictionaryWithTwoWordsShouldBeConverted
) {
234 base::FilePath path
=
235 profile_
.GetPath().Append(chrome::kCustomDictionaryFileName
);
237 std::string content
= "foo\nbar\nfoo\n";
238 base::WriteFile(path
, content
.c_str(), content
.length());
239 std::set
<std::string
> expected
;
240 expected
.insert("bar");
241 expected
.insert("foo");
242 EXPECT_EQ(expected
, *LoadDictionaryFile(path
));
245 // Illegal words should be removed. Leading and trailing whitespace should be
247 TEST_F(SpellcheckCustomDictionaryTest
,
248 IllegalWordsShouldBeRemovedFromDictionary
) {
249 base::FilePath path
=
250 profile_
.GetPath().Append(chrome::kCustomDictionaryFileName
);
252 std::string content
= "foo\n foo bar \n\n \nbar\n"
253 "01234567890123456789012345678901234567890123456789"
254 "01234567890123456789012345678901234567890123456789";
255 base::WriteFile(path
, content
.c_str(), content
.length());
256 std::set
<std::string
> expected
;
257 expected
.insert("bar");
258 expected
.insert("foo");
259 expected
.insert("foo bar");
260 EXPECT_EQ(expected
, *LoadDictionaryFile(path
));
263 // Write to dictionary should backup previous version and write the word to the
264 // end of the dictionary. If the dictionary file is corrupted on disk, the
265 // previous version should be reloaded.
266 TEST_F(SpellcheckCustomDictionaryTest
, CorruptedWriteShouldBeRecovered
) {
267 base::FilePath path
=
268 profile_
.GetPath().Append(chrome::kCustomDictionaryFileName
);
270 std::string content
= "foo\nbar";
271 base::WriteFile(path
, content
.c_str(), content
.length());
272 std::set
<std::string
> expected
;
273 expected
.insert("bar");
274 expected
.insert("foo");
275 EXPECT_EQ(expected
, *LoadDictionaryFile(path
));
277 scoped_ptr
<SpellcheckCustomDictionary::Change
> change(
278 new SpellcheckCustomDictionary::Change
);
279 change
->AddWord("baz");
280 UpdateDictionaryFile(change
.Pass(), path
);
282 base::ReadFileToString(path
, &content
);
283 content
.append("corruption");
284 base::WriteFile(path
, content
.c_str(), content
.length());
285 EXPECT_EQ(expected
, *LoadDictionaryFile(path
));
288 TEST_F(SpellcheckCustomDictionaryTest
,
289 GetAllSyncDataAccuratelyReflectsDictionaryState
) {
290 SpellcheckCustomDictionary
* dictionary
=
291 SpellcheckServiceFactory::GetForContext(
292 &profile_
)->GetCustomDictionary();
294 syncer::SyncDataList data
= dictionary
->GetAllSyncData(syncer::DICTIONARY
);
295 EXPECT_TRUE(data
.empty());
297 EXPECT_TRUE(dictionary
->AddWord("bar"));
298 EXPECT_TRUE(dictionary
->AddWord("foo"));
300 data
= dictionary
->GetAllSyncData(syncer::DICTIONARY
);
301 EXPECT_EQ(2UL, data
.size());
302 std::vector
<std::string
> words
;
303 words
.push_back("bar");
304 words
.push_back("foo");
305 for (size_t i
= 0; i
< data
.size(); i
++) {
306 EXPECT_TRUE(data
[i
].GetSpecifics().has_dictionary());
307 EXPECT_EQ(syncer::DICTIONARY
, data
[i
].GetDataType());
308 EXPECT_EQ(words
[i
], syncer::SyncDataLocal(data
[i
]).GetTag());
309 EXPECT_EQ(words
[i
], data
[i
].GetSpecifics().dictionary().word());
312 EXPECT_TRUE(dictionary
->RemoveWord("bar"));
313 EXPECT_TRUE(dictionary
->RemoveWord("foo"));
315 data
= dictionary
->GetAllSyncData(syncer::DICTIONARY
);
316 EXPECT_TRUE(data
.empty());
319 TEST_F(SpellcheckCustomDictionaryTest
, GetAllSyncDataHasLimit
) {
320 SpellcheckCustomDictionary
* dictionary
=
321 SpellcheckServiceFactory::GetForContext(
322 &profile_
)->GetCustomDictionary();
324 SpellcheckCustomDictionary::Change change
;
326 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
- 1;
328 change
.AddWord("foo" + base::Uint64ToString(i
));
330 Apply(*dictionary
, change
);
331 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
- 1,
332 dictionary
->GetWords().size());
333 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
- 1,
334 dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
336 dictionary
->AddWord("baz");
337 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
338 dictionary
->GetWords().size());
339 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
340 dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
342 dictionary
->AddWord("bar");
343 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
344 dictionary
->GetWords().size());
345 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
346 dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
348 dictionary
->AddWord("snafoo");
349 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 2,
350 dictionary
->GetWords().size());
351 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
352 dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
355 TEST_F(SpellcheckCustomDictionaryTest
, ProcessSyncChanges
) {
356 SpellcheckService
* spellcheck_service
=
357 SpellcheckServiceFactory::GetForContext(&profile_
);
358 SpellcheckCustomDictionary
* dictionary
=
359 spellcheck_service
->GetCustomDictionary();
361 dictionary
->AddWord("foo");
362 dictionary
->AddWord("bar");
364 syncer::SyncChangeList changes
;
366 // Add existing word.
367 std::string word
= "foo";
368 sync_pb::EntitySpecifics specifics
;
369 specifics
.mutable_dictionary()->set_word(word
);
370 changes
.push_back(syncer::SyncChange(
372 syncer::SyncChange::ACTION_ADD
,
373 syncer::SyncData::CreateLocalData(word
, word
, specifics
)));
376 // Add invalid word. This word is too long.
377 std::string word
= "01234567890123456789012345678901234567890123456789"
378 "01234567890123456789012345678901234567890123456789";
379 sync_pb::EntitySpecifics specifics
;
380 specifics
.mutable_dictionary()->set_word(word
);
381 changes
.push_back(syncer::SyncChange(
383 syncer::SyncChange::ACTION_ADD
,
384 syncer::SyncData::CreateLocalData(word
, word
, specifics
)));
388 std::string word
= "baz";
389 sync_pb::EntitySpecifics specifics
;
390 specifics
.mutable_dictionary()->set_word(word
);
391 changes
.push_back(syncer::SyncChange(
393 syncer::SyncChange::ACTION_ADD
,
394 syncer::SyncData::CreateLocalData(word
, word
, specifics
)));
397 // Remove missing word.
398 std::string word
= "snafoo";
399 sync_pb::EntitySpecifics specifics
;
400 specifics
.mutable_dictionary()->set_word(word
);
401 changes
.push_back(syncer::SyncChange(
403 syncer::SyncChange::ACTION_DELETE
,
404 syncer::SyncData::CreateLocalData(word
, word
, specifics
)));
407 // Remove existing word.
408 std::string word
= "bar";
409 sync_pb::EntitySpecifics specifics
;
410 specifics
.mutable_dictionary()->set_word(word
);
411 changes
.push_back(syncer::SyncChange(
413 syncer::SyncChange::ACTION_DELETE
,
414 syncer::SyncData::CreateLocalData(word
, word
, specifics
)));
417 EXPECT_FALSE(dictionary
->ProcessSyncChanges(FROM_HERE
, changes
).IsSet());
419 const std::set
<std::string
>& words
= dictionary
->GetWords();
420 EXPECT_EQ(2UL, words
.size());
421 EXPECT_EQ(0UL, words
.count("bar"));
422 EXPECT_EQ(1UL, words
.count("foo"));
423 EXPECT_EQ(1UL, words
.count("baz"));
426 TEST_F(SpellcheckCustomDictionaryTest
, MergeDataAndStartSyncing
) {
427 SpellcheckService
* spellcheck_service
=
428 SpellcheckServiceFactory::GetForContext(&profile_
);
429 SpellcheckCustomDictionary
* custom_dictionary
=
430 spellcheck_service
->GetCustomDictionary();
431 TestingProfile profile2
;
432 SpellcheckService
* spellcheck_service2
=
433 static_cast<SpellcheckService
*>(
434 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
435 &profile2
, &BuildSpellcheckService
));
436 SpellcheckCustomDictionary
* custom_dictionary2
=
437 spellcheck_service2
->GetCustomDictionary();
439 SpellcheckCustomDictionary::Change change
;
441 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
/ 2;
443 change
.AddWord("foo" + base::Uint64ToString(i
));
445 Apply(*custom_dictionary
, change
);
447 SpellcheckCustomDictionary::Change change2
;
449 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
/ 2;
451 change2
.AddWord("bar" + base::Uint64ToString(i
));
453 Apply(*custom_dictionary2
, change2
);
455 int error_counter
= 0;
457 custom_dictionary
->MergeDataAndStartSyncing(
459 custom_dictionary2
->GetAllSyncData(
461 scoped_ptr
<syncer::SyncChangeProcessor
>(
462 new syncer::SyncChangeProcessorWrapperForTest(
463 custom_dictionary2
)),
464 scoped_ptr
<syncer::SyncErrorFactory
>(
465 new SyncErrorFactoryStub(&error_counter
)))
468 EXPECT_EQ(0, error_counter
);
469 EXPECT_TRUE(custom_dictionary
->IsSyncing());
471 std::set
<std::string
> words
= custom_dictionary
->GetWords();
472 std::set
<std::string
> words2
= custom_dictionary2
->GetWords();
473 EXPECT_EQ(words
.size(), words2
.size());
474 EXPECT_EQ(words
, words2
);
477 TEST_F(SpellcheckCustomDictionaryTest
, SyncBeforeLoadDoesNotDuplicateWords
) {
478 SpellcheckCustomDictionary
* custom_dictionary
=
479 SpellcheckServiceFactory::GetForContext(&profile_
)->GetCustomDictionary();
481 TestingProfile profile2
;
482 SpellcheckCustomDictionary
* custom_dictionary2
=
483 static_cast<SpellcheckService
*>(
484 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
485 &profile2
, &BuildSpellcheckService
))
486 ->GetCustomDictionary();
488 scoped_ptr
<SpellcheckCustomDictionary::Change
> change(
489 new SpellcheckCustomDictionary::Change
);
490 change
->AddWord("foo");
491 Apply(*custom_dictionary2
, *change
);
493 base::FilePath path
=
494 profile_
.GetPath().Append(chrome::kCustomDictionaryFileName
);
495 UpdateDictionaryFile(change
.Pass(), path
);
496 EXPECT_TRUE(custom_dictionary
->GetWords().empty());
498 int error_counter
= 0;
500 custom_dictionary
->MergeDataAndStartSyncing(
502 custom_dictionary2
->GetAllSyncData(
504 scoped_ptr
<syncer::SyncChangeProcessor
>(
505 new syncer::SyncChangeProcessorWrapperForTest(
506 custom_dictionary2
)),
507 scoped_ptr
<syncer::SyncErrorFactory
>(
508 new SyncErrorFactoryStub(&error_counter
)))
511 EXPECT_EQ(0, error_counter
);
512 EXPECT_TRUE(custom_dictionary
->IsSyncing());
514 std::set
<std::string
> expected_words_in_memory
;
515 expected_words_in_memory
.insert("foo");
516 EXPECT_EQ(expected_words_in_memory
, custom_dictionary
->GetWords());
518 // Finish all writes to disk.
519 base::MessageLoop::current()->RunUntilIdle();
521 std::string actual_contents_on_disk
;
522 base::ReadFileToString(path
, &actual_contents_on_disk
);
523 static const char kExpectedContentsPrefix
[] = "foo\nchecksum_v1 = ";
525 kExpectedContentsPrefix
,
526 actual_contents_on_disk
.substr(0, sizeof kExpectedContentsPrefix
- 1));
529 TEST_F(SpellcheckCustomDictionaryTest
, DictionaryTooBigBeforeSyncing
) {
530 SpellcheckService
* spellcheck_service
=
531 SpellcheckServiceFactory::GetForContext(&profile_
);
532 SpellcheckCustomDictionary
* custom_dictionary
=
533 spellcheck_service
->GetCustomDictionary();
534 TestingProfile profile2
;
535 SpellcheckService
* spellcheck_service2
=
536 static_cast<SpellcheckService
*>(
537 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
538 &profile2
, &BuildSpellcheckService
));
539 SpellcheckCustomDictionary
* custom_dictionary2
=
540 spellcheck_service2
->GetCustomDictionary();
542 SpellcheckCustomDictionary::Change change
;
544 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1;
546 change
.AddWord("foo" + base::Uint64ToString(i
));
548 Apply(*custom_dictionary
, change
);
550 int error_counter
= 0;
552 custom_dictionary
->MergeDataAndStartSyncing(
554 custom_dictionary2
->GetAllSyncData(
556 scoped_ptr
<syncer::SyncChangeProcessor
>(
557 new syncer::SyncChangeProcessorWrapperForTest(
558 custom_dictionary2
)),
559 scoped_ptr
<syncer::SyncErrorFactory
>(
560 new SyncErrorFactoryStub(&error_counter
)))
563 EXPECT_EQ(0, error_counter
);
564 EXPECT_FALSE(custom_dictionary
->IsSyncing());
566 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
567 custom_dictionary
->GetWords().size());
568 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
569 custom_dictionary2
->GetWords().size());
571 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
572 custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
573 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
574 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
577 TEST_F(SpellcheckCustomDictionaryTest
, DictionaryTooBigAndServerFull
) {
578 SpellcheckService
* spellcheck_service
=
579 SpellcheckServiceFactory::GetForContext(&profile_
);
580 SpellcheckCustomDictionary
* custom_dictionary
=
581 spellcheck_service
->GetCustomDictionary();
582 TestingProfile profile2
;
583 SpellcheckService
* spellcheck_service2
=
584 static_cast<SpellcheckService
*>(
585 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
586 &profile2
, &BuildSpellcheckService
));
587 SpellcheckCustomDictionary
* custom_dictionary2
=
588 spellcheck_service2
->GetCustomDictionary();
590 SpellcheckCustomDictionary::Change change
;
591 SpellcheckCustomDictionary::Change change2
;
593 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
;
595 change
.AddWord("foo" + base::Uint64ToString(i
));
596 change2
.AddWord("bar" + base::Uint64ToString(i
));
598 change
.AddWord("foo");
599 Apply(*custom_dictionary
, change
);
600 Apply(*custom_dictionary2
, change2
);
602 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
603 custom_dictionary
->GetWords().size());
604 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
605 custom_dictionary2
->GetWords().size());
607 int error_counter
= 0;
609 custom_dictionary
->MergeDataAndStartSyncing(
611 custom_dictionary2
->GetAllSyncData(
613 scoped_ptr
<syncer::SyncChangeProcessor
>(
614 new syncer::SyncChangeProcessorWrapperForTest(
615 custom_dictionary2
)),
616 scoped_ptr
<syncer::SyncErrorFactory
>(
617 new SyncErrorFactoryStub(&error_counter
)))
620 EXPECT_EQ(0, error_counter
);
621 EXPECT_FALSE(custom_dictionary
->IsSyncing());
623 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
* 2 + 1,
624 custom_dictionary
->GetWords().size());
625 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
626 custom_dictionary2
->GetWords().size());
628 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
629 custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
630 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
631 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
634 TEST_F(SpellcheckCustomDictionaryTest
, ServerTooBig
) {
635 SpellcheckService
* spellcheck_service
=
636 SpellcheckServiceFactory::GetForContext(&profile_
);
637 SpellcheckCustomDictionary
* custom_dictionary
=
638 spellcheck_service
->GetCustomDictionary();
639 TestingProfile profile2
;
640 SpellcheckService
* spellcheck_service2
=
641 static_cast<SpellcheckService
*>(
642 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
643 &profile2
, &BuildSpellcheckService
));
644 SpellcheckCustomDictionary
* custom_dictionary2
=
645 spellcheck_service2
->GetCustomDictionary();
647 SpellcheckCustomDictionary::Change change
;
648 SpellcheckCustomDictionary::Change change2
;
650 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1;
652 change
.AddWord("foo" + base::Uint64ToString(i
));
653 change2
.AddWord("bar" + base::Uint64ToString(i
));
655 Apply(*custom_dictionary
, change
);
656 Apply(*custom_dictionary2
, change2
);
658 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
659 custom_dictionary
->GetWords().size());
660 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
661 custom_dictionary2
->GetWords().size());
663 int error_counter
= 0;
665 custom_dictionary
->MergeDataAndStartSyncing(
667 GetAllSyncDataNoLimit(custom_dictionary2
),
668 scoped_ptr
<syncer::SyncChangeProcessor
>(
669 new syncer::SyncChangeProcessorWrapperForTest(
670 custom_dictionary2
)),
671 scoped_ptr
<syncer::SyncErrorFactory
>(
672 new SyncErrorFactoryStub(&error_counter
)))
675 EXPECT_EQ(0, error_counter
);
676 EXPECT_FALSE(custom_dictionary
->IsSyncing());
678 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
* 2 + 2,
679 custom_dictionary
->GetWords().size());
680 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
681 custom_dictionary2
->GetWords().size());
683 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
684 custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
685 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
686 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
689 TEST_F(SpellcheckCustomDictionaryTest
, DictionaryTooBigToStartSyncing
) {
690 SpellcheckService
* spellcheck_service
=
691 SpellcheckServiceFactory::GetForContext(&profile_
);
692 SpellcheckCustomDictionary
* custom_dictionary
=
693 spellcheck_service
->GetCustomDictionary();
694 TestingProfile profile2
;
695 SpellcheckService
* spellcheck_service2
=
696 static_cast<SpellcheckService
*>(
697 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
698 &profile2
, &BuildSpellcheckService
));
699 SpellcheckCustomDictionary
* custom_dictionary2
=
700 spellcheck_service2
->GetCustomDictionary();
702 SpellcheckCustomDictionary::Change change
;
704 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
- 1;
706 change
.AddWord("foo" + base::Uint64ToString(i
));
708 Apply(*custom_dictionary
, change
);
710 custom_dictionary2
->AddWord("bar");
711 custom_dictionary2
->AddWord("baz");
713 int error_counter
= 0;
715 custom_dictionary
->MergeDataAndStartSyncing(
717 custom_dictionary2
->GetAllSyncData(
719 scoped_ptr
<syncer::SyncChangeProcessor
>(
720 new syncer::SyncChangeProcessorWrapperForTest(
721 custom_dictionary2
)),
722 scoped_ptr
<syncer::SyncErrorFactory
>(
723 new SyncErrorFactoryStub(&error_counter
)))
726 EXPECT_EQ(0, error_counter
);
727 EXPECT_FALSE(custom_dictionary
->IsSyncing());
729 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
730 custom_dictionary
->GetWords().size());
731 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
732 custom_dictionary2
->GetWords().size());
734 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
735 custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
736 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
737 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
740 TEST_F(SpellcheckCustomDictionaryTest
, DictionaryTooBigToContiueSyncing
) {
741 SpellcheckService
* spellcheck_service
=
742 SpellcheckServiceFactory::GetForContext(&profile_
);
743 SpellcheckCustomDictionary
* custom_dictionary
=
744 spellcheck_service
->GetCustomDictionary();
745 TestingProfile profile2
;
746 SpellcheckService
* spellcheck_service2
=
747 static_cast<SpellcheckService
*>(
748 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
749 &profile2
, &BuildSpellcheckService
));
750 SpellcheckCustomDictionary
* custom_dictionary2
=
751 spellcheck_service2
->GetCustomDictionary();
753 SpellcheckCustomDictionary::Change change
;
755 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
- 1;
757 change
.AddWord("foo" + base::Uint64ToString(i
));
759 Apply(*custom_dictionary
, change
);
761 int error_counter
= 0;
763 custom_dictionary
->MergeDataAndStartSyncing(
765 custom_dictionary2
->GetAllSyncData(
767 scoped_ptr
<syncer::SyncChangeProcessor
>(
768 new syncer::SyncChangeProcessorWrapperForTest(
769 custom_dictionary2
)),
770 scoped_ptr
<syncer::SyncErrorFactory
>(
771 new SyncErrorFactoryStub(&error_counter
)))
774 EXPECT_EQ(0, error_counter
);
775 EXPECT_TRUE(custom_dictionary
->IsSyncing());
777 custom_dictionary
->AddWord("bar");
778 EXPECT_EQ(0, error_counter
);
779 EXPECT_TRUE(custom_dictionary
->IsSyncing());
781 custom_dictionary
->AddWord("baz");
782 EXPECT_EQ(0, error_counter
);
783 EXPECT_FALSE(custom_dictionary
->IsSyncing());
785 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
786 custom_dictionary
->GetWords().size());
787 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
788 custom_dictionary2
->GetWords().size());
790 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
791 custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
792 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
793 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
796 TEST_F(SpellcheckCustomDictionaryTest
, LoadAfterSyncStart
) {
797 SpellcheckService
* spellcheck_service
=
798 SpellcheckServiceFactory::GetForContext(&profile_
);
799 SpellcheckCustomDictionary
* custom_dictionary
=
800 spellcheck_service
->GetCustomDictionary();
801 TestingProfile profile2
;
802 SpellcheckService
* spellcheck_service2
=
803 static_cast<SpellcheckService
*>(
804 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
805 &profile2
, &BuildSpellcheckService
));
806 SpellcheckCustomDictionary
* custom_dictionary2
=
807 spellcheck_service2
->GetCustomDictionary();
809 custom_dictionary
->AddWord("foo");
811 int error_counter
= 0;
813 custom_dictionary
->MergeDataAndStartSyncing(
815 custom_dictionary2
->GetAllSyncData(
817 scoped_ptr
<syncer::SyncChangeProcessor
>(
818 new syncer::SyncChangeProcessorWrapperForTest(
819 custom_dictionary2
)),
820 scoped_ptr
<syncer::SyncErrorFactory
>(
821 new SyncErrorFactoryStub(&error_counter
)))
824 EXPECT_EQ(0, error_counter
);
825 EXPECT_TRUE(custom_dictionary
->IsSyncing());
827 scoped_ptr
<std::set
<std::string
>> custom_words(new std::set
<std::string
>);
828 custom_words
->insert("bar");
829 OnLoaded(*custom_dictionary
, custom_words
.Pass());
830 EXPECT_TRUE(custom_dictionary
->IsSyncing());
832 EXPECT_EQ(2UL, custom_dictionary
->GetWords().size());
833 EXPECT_EQ(2UL, custom_dictionary2
->GetWords().size());
835 EXPECT_EQ(2UL, custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
836 EXPECT_EQ(2UL, custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
839 TEST_F(SpellcheckCustomDictionaryTest
, LoadAfterSyncStartTooBigToSync
) {
840 SpellcheckService
* spellcheck_service
=
841 SpellcheckServiceFactory::GetForContext(&profile_
);
842 SpellcheckCustomDictionary
* custom_dictionary
=
843 spellcheck_service
->GetCustomDictionary();
844 TestingProfile profile2
;
845 SpellcheckService
* spellcheck_service2
=
846 static_cast<SpellcheckService
*>(
847 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
848 &profile2
, &BuildSpellcheckService
));
849 SpellcheckCustomDictionary
* custom_dictionary2
=
850 spellcheck_service2
->GetCustomDictionary();
852 custom_dictionary
->AddWord("foo");
854 int error_counter
= 0;
856 custom_dictionary
->MergeDataAndStartSyncing(
858 custom_dictionary2
->GetAllSyncData(
860 scoped_ptr
<syncer::SyncChangeProcessor
>(
861 new syncer::SyncChangeProcessorWrapperForTest(
862 custom_dictionary2
)),
863 scoped_ptr
<syncer::SyncErrorFactory
>(
864 new SyncErrorFactoryStub(&error_counter
)))
867 EXPECT_EQ(0, error_counter
);
868 EXPECT_TRUE(custom_dictionary
->IsSyncing());
870 scoped_ptr
<std::set
<std::string
>> custom_words(new std::set
<std::string
>);
872 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
;
874 custom_words
->insert(custom_words
->end(), "foo" + base::Uint64ToString(i
));
876 OnLoaded(*custom_dictionary
, custom_words
.Pass());
877 EXPECT_EQ(0, error_counter
);
878 EXPECT_FALSE(custom_dictionary
->IsSyncing());
880 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
881 custom_dictionary
->GetWords().size());
882 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
883 custom_dictionary2
->GetWords().size());
885 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
886 custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
887 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
888 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
891 TEST_F(SpellcheckCustomDictionaryTest
, LoadDuplicatesAfterSync
) {
892 SpellcheckService
* spellcheck_service
=
893 SpellcheckServiceFactory::GetForContext(&profile_
);
894 SpellcheckCustomDictionary
* custom_dictionary
=
895 spellcheck_service
->GetCustomDictionary();
896 TestingProfile profile2
;
897 SpellcheckService
* spellcheck_service2
=
898 static_cast<SpellcheckService
*>(
899 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
900 &profile2
, &BuildSpellcheckService
));
901 SpellcheckCustomDictionary
* custom_dictionary2
=
902 spellcheck_service2
->GetCustomDictionary();
904 SpellcheckCustomDictionary::Change change
;
906 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
/ 2;
908 change
.AddWord("foo" + base::Uint64ToString(i
));
910 Apply(*custom_dictionary
, change
);
912 int error_counter
= 0;
914 custom_dictionary
->MergeDataAndStartSyncing(
916 custom_dictionary2
->GetAllSyncData(
918 scoped_ptr
<syncer::SyncChangeProcessor
>(
919 new syncer::SyncChangeProcessorWrapperForTest(
920 custom_dictionary2
)),
921 scoped_ptr
<syncer::SyncErrorFactory
>(
922 new SyncErrorFactoryStub(&error_counter
)))
925 EXPECT_EQ(0, error_counter
);
926 EXPECT_TRUE(custom_dictionary
->IsSyncing());
928 OnLoaded(*custom_dictionary
,
929 make_scoped_ptr(new std::set
<std::string
>(change
.to_add())));
930 EXPECT_EQ(0, error_counter
);
931 EXPECT_TRUE(custom_dictionary
->IsSyncing());
933 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
/ 2,
934 custom_dictionary
->GetWords().size());
935 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
/ 2,
936 custom_dictionary2
->GetWords().size());
938 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
/ 2,
939 custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
940 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
/ 2,
941 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
944 TEST_F(SpellcheckCustomDictionaryTest
, DictionaryLoadNotification
) {
945 SpellcheckService
* spellcheck_service
=
946 SpellcheckServiceFactory::GetForContext(&profile_
);
947 SpellcheckCustomDictionary
* custom_dictionary
=
948 spellcheck_service
->GetCustomDictionary();
950 DictionaryObserverCounter observer
;
951 custom_dictionary
->AddObserver(&observer
);
953 scoped_ptr
<std::set
<std::string
>> custom_words(new std::set
<std::string
>);
954 custom_words
->insert("foo");
955 custom_words
->insert("bar");
956 OnLoaded(*custom_dictionary
, custom_words
.Pass());
958 EXPECT_GE(observer
.loads(), 1);
959 EXPECT_LE(observer
.loads(), 2);
960 EXPECT_EQ(0, observer
.changes());
962 custom_dictionary
->RemoveObserver(&observer
);
965 TEST_F(SpellcheckCustomDictionaryTest
, DictionaryAddWordNotification
) {
966 SpellcheckService
* spellcheck_service
=
967 SpellcheckServiceFactory::GetForContext(&profile_
);
968 SpellcheckCustomDictionary
* custom_dictionary
=
969 spellcheck_service
->GetCustomDictionary();
971 OnLoaded(*custom_dictionary
, make_scoped_ptr(new std::set
<std::string
>));
973 DictionaryObserverCounter observer
;
974 custom_dictionary
->AddObserver(&observer
);
976 EXPECT_TRUE(custom_dictionary
->AddWord("foo"));
977 EXPECT_TRUE(custom_dictionary
->AddWord("bar"));
978 EXPECT_FALSE(custom_dictionary
->AddWord("bar"));
980 EXPECT_EQ(2, observer
.changes());
982 custom_dictionary
->RemoveObserver(&observer
);
985 TEST_F(SpellcheckCustomDictionaryTest
, DictionaryRemoveWordNotification
) {
986 SpellcheckService
* spellcheck_service
=
987 SpellcheckServiceFactory::GetForContext(&profile_
);
988 SpellcheckCustomDictionary
* custom_dictionary
=
989 spellcheck_service
->GetCustomDictionary();
991 OnLoaded(*custom_dictionary
, make_scoped_ptr(new std::set
<std::string
>));
993 EXPECT_TRUE(custom_dictionary
->AddWord("foo"));
994 EXPECT_TRUE(custom_dictionary
->AddWord("bar"));
996 DictionaryObserverCounter observer
;
997 custom_dictionary
->AddObserver(&observer
);
999 EXPECT_TRUE(custom_dictionary
->RemoveWord("foo"));
1000 EXPECT_TRUE(custom_dictionary
->RemoveWord("bar"));
1001 EXPECT_FALSE(custom_dictionary
->RemoveWord("baz"));
1003 EXPECT_EQ(2, observer
.changes());
1005 custom_dictionary
->RemoveObserver(&observer
);
1008 TEST_F(SpellcheckCustomDictionaryTest
, DictionarySyncNotification
) {
1009 SpellcheckService
* spellcheck_service
=
1010 SpellcheckServiceFactory::GetForContext(&profile_
);
1011 SpellcheckCustomDictionary
* custom_dictionary
=
1012 spellcheck_service
->GetCustomDictionary();
1013 TestingProfile profile2
;
1014 SpellcheckService
* spellcheck_service2
=
1015 static_cast<SpellcheckService
*>(
1016 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
1017 &profile2
, &BuildSpellcheckService
));
1018 SpellcheckCustomDictionary
* custom_dictionary2
=
1019 spellcheck_service2
->GetCustomDictionary();
1021 OnLoaded(*custom_dictionary
, make_scoped_ptr(new std::set
<std::string
>));
1022 OnLoaded(*custom_dictionary2
, make_scoped_ptr(new std::set
<std::string
>));
1024 custom_dictionary
->AddWord("foo");
1025 custom_dictionary
->AddWord("bar");
1026 custom_dictionary2
->AddWord("foo");
1027 custom_dictionary2
->AddWord("baz");
1029 DictionaryObserverCounter observer
;
1030 custom_dictionary
->AddObserver(&observer
);
1032 DictionaryObserverCounter observer2
;
1033 custom_dictionary2
->AddObserver(&observer2
);
1035 int error_counter
= 0;
1037 custom_dictionary
->MergeDataAndStartSyncing(
1039 custom_dictionary2
->GetAllSyncData(
1040 syncer::DICTIONARY
),
1041 scoped_ptr
<syncer::SyncChangeProcessor
>(
1042 new syncer::SyncChangeProcessorWrapperForTest(
1043 custom_dictionary2
)),
1044 scoped_ptr
<syncer::SyncErrorFactory
>(
1045 new SyncErrorFactoryStub(&error_counter
)))
1048 EXPECT_EQ(0, error_counter
);
1049 EXPECT_TRUE(custom_dictionary
->IsSyncing());
1051 EXPECT_EQ(1, observer
.changes());
1052 EXPECT_EQ(1, observer2
.changes());
1054 custom_dictionary
->RemoveObserver(&observer
);
1055 custom_dictionary2
->RemoveObserver(&observer2
);
1058 // The server has maximum number of words and the client has maximum number of
1059 // different words before association time. No new words should be pushed to the
1060 // sync server upon association. The client should accept words from the sync
1062 TEST_F(SpellcheckCustomDictionaryTest
, DictionarySyncLimit
) {
1063 TestingProfile server_profile
;
1064 SpellcheckService
* server_spellcheck_service
=
1065 static_cast<SpellcheckService
*>(
1066 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
1067 &server_profile
, &BuildSpellcheckService
));
1069 // Here, |server_custom_dictionary| plays the role of the sync server.
1070 SpellcheckCustomDictionary
* server_custom_dictionary
=
1071 server_spellcheck_service
->GetCustomDictionary();
1073 // Upload the maximum number of words to the sync server.
1075 SpellcheckService
* spellcheck_service
=
1076 SpellcheckServiceFactory::GetForContext(&profile_
);
1077 SpellcheckCustomDictionary
* custom_dictionary
=
1078 spellcheck_service
->GetCustomDictionary();
1080 SpellcheckCustomDictionary::Change change
;
1082 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
;
1084 change
.AddWord("foo" + base::Uint64ToString(i
));
1086 Apply(*custom_dictionary
, change
);
1088 int error_counter
= 0;
1091 ->MergeDataAndStartSyncing(
1093 server_custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
),
1094 scoped_ptr
<syncer::SyncChangeProcessor
>(
1095 new syncer::SyncChangeProcessorWrapperForTest(
1096 server_custom_dictionary
)),
1097 scoped_ptr
<syncer::SyncErrorFactory
>(
1098 new SyncErrorFactoryStub(&error_counter
)))
1101 EXPECT_EQ(0, error_counter
);
1102 EXPECT_TRUE(custom_dictionary
->IsSyncing());
1103 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
1104 custom_dictionary
->GetWords().size());
1107 // The sync server now has the maximum number of words.
1108 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
1109 server_custom_dictionary
->GetWords().size());
1111 // Associate the sync server with a client that also has the maximum number of
1112 // words, but all of these words are different from the ones on the sync
1115 TestingProfile client_profile
;
1116 SpellcheckService
* client_spellcheck_service
=
1117 static_cast<SpellcheckService
*>(
1118 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
1119 &client_profile
, &BuildSpellcheckService
));
1121 // Here, |client_custom_dictionary| plays the role of the client.
1122 SpellcheckCustomDictionary
* client_custom_dictionary
=
1123 client_spellcheck_service
->GetCustomDictionary();
1125 // Add the maximum number of words to the client. These words are all
1126 // different from those on the server.
1127 SpellcheckCustomDictionary::Change change
;
1129 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
;
1131 change
.AddWord("bar" + base::Uint64ToString(i
));
1133 Apply(*client_custom_dictionary
, change
);
1135 // Associate the server and the client.
1136 int error_counter
= 0;
1138 client_custom_dictionary
1139 ->MergeDataAndStartSyncing(
1141 server_custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
),
1142 scoped_ptr
<syncer::SyncChangeProcessor
>(
1143 new syncer::SyncChangeProcessorWrapperForTest(
1144 server_custom_dictionary
)),
1145 scoped_ptr
<syncer::SyncErrorFactory
>(
1146 new SyncErrorFactoryStub(&error_counter
)))
1149 EXPECT_EQ(0, error_counter
);
1150 EXPECT_FALSE(client_custom_dictionary
->IsSyncing());
1151 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
* 2,
1152 client_custom_dictionary
->GetWords().size());
1155 // The sync server should not receive more words, because it has the maximum
1156 // number of words already.
1157 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
1158 server_custom_dictionary
->GetWords().size());
1161 TEST_F(SpellcheckCustomDictionaryTest
, RecordSizeStatsCorrectly
) {
1163 // Failing consistently on Win7. See crbug.com/230534.
1164 if (base::win::GetVersion() >= base::win::VERSION_VISTA
)
1167 // Record a baseline.
1168 SpellCheckHostMetrics::RecordCustomWordCountStats(123);
1170 // Determine if test failures are due the statistics recorder not being
1171 // available or because the histogram just isn't there: crbug.com/230534.
1172 EXPECT_TRUE(StatisticsRecorder::IsActive());
1174 HistogramBase
* histogram
=
1175 StatisticsRecorder::FindHistogram("SpellCheck.CustomWords");
1176 ASSERT_TRUE(histogram
!= NULL
);
1177 scoped_ptr
<HistogramSamples
> baseline
= histogram
->SnapshotSamples();
1179 // Load the dictionary which should be empty.
1180 base::FilePath path
=
1181 profile_
.GetPath().Append(chrome::kCustomDictionaryFileName
);
1182 EXPECT_TRUE(LoadDictionaryFile(path
)->empty());
1184 // We expect there to be an entry with 0.
1186 StatisticsRecorder::FindHistogram("SpellCheck.CustomWords");
1187 ASSERT_TRUE(histogram
!= NULL
);
1188 scoped_ptr
<HistogramSamples
> samples
= histogram
->SnapshotSamples();
1190 samples
->Subtract(*baseline
);
1191 EXPECT_EQ(0,samples
->sum());
1193 scoped_ptr
<SpellcheckCustomDictionary::Change
> change(
1194 new SpellcheckCustomDictionary::Change
);
1195 change
->AddWord("bar");
1196 change
->AddWord("foo");
1197 UpdateDictionaryFile(change
.Pass(), path
);
1199 // Load the dictionary again and it should have 2 entries.
1200 EXPECT_EQ(2u, LoadDictionaryFile(path
)->size());
1203 StatisticsRecorder::FindHistogram("SpellCheck.CustomWords");
1204 ASSERT_TRUE(histogram
!= NULL
);
1205 scoped_ptr
<HistogramSamples
> samples2
= histogram
->SnapshotSamples();
1207 samples2
->Subtract(*baseline
);
1208 EXPECT_EQ(2,samples2
->sum());
1211 TEST_F(SpellcheckCustomDictionaryTest
, HasWord
) {
1212 SpellcheckService
* spellcheck_service
=
1213 SpellcheckServiceFactory::GetForContext(&profile_
);
1214 SpellcheckCustomDictionary
* custom_dictionary
=
1215 spellcheck_service
->GetCustomDictionary();
1216 OnLoaded(*custom_dictionary
, make_scoped_ptr(new std::set
<std::string
>));
1217 EXPECT_FALSE(custom_dictionary
->HasWord("foo"));
1218 EXPECT_FALSE(custom_dictionary
->HasWord("bar"));
1219 custom_dictionary
->AddWord("foo");
1220 EXPECT_TRUE(custom_dictionary
->HasWord("foo"));
1221 EXPECT_FALSE(custom_dictionary
->HasWord("bar"));