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
);
130 virtual syncer::SyncDataList
GetAllSyncData(syncer::ModelType type
) const
132 return syncer::SyncDataList();
136 SpellcheckCustomDictionary
* dictionary_
;
137 DISALLOW_COPY_AND_ASSIGN(SyncChangeProcessorDelegate
);
140 // An implementation of SyncErrorFactory that does not upload the error message
141 // and updates an outside error counter. This lets us know the number of error
142 // messages in an instance of this class after that instance is deleted.
143 class SyncErrorFactoryStub
: public syncer::SyncErrorFactory
{
145 explicit SyncErrorFactoryStub(int* error_counter
)
146 : error_counter_(error_counter
) {}
147 virtual ~SyncErrorFactoryStub() {}
149 // Overridden from syncer::SyncErrorFactory:
150 virtual syncer::SyncError
CreateAndUploadError(
151 const tracked_objects::Location
& location
,
152 const std::string
& message
) OVERRIDE
{
154 return syncer::SyncError(location
,
155 syncer::SyncError::DATATYPE_ERROR
,
162 DISALLOW_COPY_AND_ASSIGN(SyncErrorFactoryStub
);
165 // Counts the number of notifications for dictionary load and change.
166 class DictionaryObserverCounter
: public SpellcheckCustomDictionary::Observer
{
168 DictionaryObserverCounter() : loads_(0), changes_(0) {}
169 virtual ~DictionaryObserverCounter() {}
171 int loads() const { return loads_
; }
172 int changes() const { return changes_
; }
174 // Overridden from SpellcheckCustomDictionary::Observer:
175 virtual void OnCustomDictionaryLoaded() OVERRIDE
{ loads_
++; }
176 virtual void OnCustomDictionaryChanged(
177 const SpellcheckCustomDictionary::Change
& change
) OVERRIDE
{ changes_
++; }
182 DISALLOW_COPY_AND_ASSIGN(DictionaryObserverCounter
);
185 TEST_F(SpellcheckCustomDictionaryTest
, SaveAndLoad
) {
186 base::FilePath path
=
187 profile_
.GetPath().Append(chrome::kCustomDictionaryFileName
);
188 WordList loaded_custom_words
= LoadDictionaryFile(path
);
190 // The custom word list should be empty now.
192 EXPECT_EQ(expected
, loaded_custom_words
);
194 SpellcheckCustomDictionary::Change change
;
195 change
.AddWord("bar");
196 change
.AddWord("foo");
198 UpdateDictionaryFile(change
, path
);
199 expected
.push_back("bar");
200 expected
.push_back("foo");
202 // The custom word list should include written words.
203 loaded_custom_words
= LoadDictionaryFile(path
);
204 EXPECT_EQ(expected
, loaded_custom_words
);
206 change
= SpellcheckCustomDictionary::Change();
207 change
.RemoveWord("bar");
208 change
.RemoveWord("foo");
209 UpdateDictionaryFile(change
, path
);
210 loaded_custom_words
= LoadDictionaryFile(path
);
212 EXPECT_EQ(expected
, loaded_custom_words
);
215 TEST_F(SpellcheckCustomDictionaryTest
, MultiProfile
) {
216 SpellcheckService
* spellcheck_service
=
217 SpellcheckServiceFactory::GetForContext(&profile_
);
218 SpellcheckCustomDictionary
* custom_dictionary
=
219 spellcheck_service
->GetCustomDictionary();
220 TestingProfile profile2
;
221 SpellcheckService
* spellcheck_service2
=
222 static_cast<SpellcheckService
*>(
223 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
224 &profile2
, &BuildSpellcheckService
));
225 SpellcheckCustomDictionary
* custom_dictionary2
=
226 spellcheck_service2
->GetCustomDictionary();
231 custom_dictionary
->AddWord("foo");
232 custom_dictionary
->AddWord("bar");
233 expected1
.insert("foo");
234 expected1
.insert("bar");
236 custom_dictionary2
->AddWord("hoge");
237 custom_dictionary2
->AddWord("fuga");
238 expected2
.insert("hoge");
239 expected2
.insert("fuga");
241 WordSet actual1
= custom_dictionary
->GetWords();
242 EXPECT_EQ(actual1
, expected1
);
244 WordSet actual2
= custom_dictionary2
->GetWords();
245 EXPECT_EQ(actual2
, expected2
);
248 // Legacy empty dictionary should be converted to new format empty dictionary.
249 TEST_F(SpellcheckCustomDictionaryTest
, LegacyEmptyDictionaryShouldBeConverted
) {
250 base::FilePath path
=
251 profile_
.GetPath().Append(chrome::kCustomDictionaryFileName
);
254 file_util::WriteFile(path
, content
.c_str(), content
.length());
255 WordList loaded_custom_words
= LoadDictionaryFile(path
);
256 EXPECT_TRUE(loaded_custom_words
.empty());
259 // Legacy dictionary with two words should be converted to new format dictionary
261 TEST_F(SpellcheckCustomDictionaryTest
,
262 LegacyDictionaryWithTwoWordsShouldBeConverted
) {
263 base::FilePath path
=
264 profile_
.GetPath().Append(chrome::kCustomDictionaryFileName
);
266 std::string content
= "foo\nbar\nfoo\n";
267 file_util::WriteFile(path
, content
.c_str(), content
.length());
268 WordList loaded_custom_words
= LoadDictionaryFile(path
);
270 expected
.push_back("bar");
271 expected
.push_back("foo");
272 EXPECT_EQ(expected
, loaded_custom_words
);
275 // Illegal words should be removed. Leading and trailing whitespace should be
277 TEST_F(SpellcheckCustomDictionaryTest
,
278 IllegalWordsShouldBeRemovedFromDictionary
) {
279 base::FilePath path
=
280 profile_
.GetPath().Append(chrome::kCustomDictionaryFileName
);
282 std::string content
= "foo\n foo bar \n\n \nbar\n"
283 "01234567890123456789012345678901234567890123456789"
284 "01234567890123456789012345678901234567890123456789";
285 file_util::WriteFile(path
, content
.c_str(), content
.length());
286 WordList loaded_custom_words
= LoadDictionaryFile(path
);
288 expected
.push_back("bar");
289 expected
.push_back("foo");
290 expected
.push_back("foo bar");
291 EXPECT_EQ(expected
, loaded_custom_words
);
294 // Write to dictionary should backup previous version and write the word to the
295 // end of the dictionary. If the dictionary file is corrupted on disk, the
296 // previous version should be reloaded.
297 TEST_F(SpellcheckCustomDictionaryTest
, CorruptedWriteShouldBeRecovered
) {
298 base::FilePath path
=
299 profile_
.GetPath().Append(chrome::kCustomDictionaryFileName
);
301 std::string content
= "foo\nbar";
302 file_util::WriteFile(path
, content
.c_str(), content
.length());
303 WordList loaded_custom_words
= LoadDictionaryFile(path
);
305 expected
.push_back("bar");
306 expected
.push_back("foo");
307 EXPECT_EQ(expected
, loaded_custom_words
);
309 SpellcheckCustomDictionary::Change change
;
310 change
.AddWord("baz");
311 UpdateDictionaryFile(change
, path
);
313 base::ReadFileToString(path
, &content
);
314 content
.append("corruption");
315 file_util::WriteFile(path
, content
.c_str(), content
.length());
316 loaded_custom_words
= LoadDictionaryFile(path
);
317 EXPECT_EQ(expected
, loaded_custom_words
);
320 TEST_F(SpellcheckCustomDictionaryTest
,
321 GetAllSyncDataAccuratelyReflectsDictionaryState
) {
322 SpellcheckCustomDictionary
* dictionary
=
323 SpellcheckServiceFactory::GetForContext(
324 &profile_
)->GetCustomDictionary();
326 syncer::SyncDataList data
= dictionary
->GetAllSyncData(syncer::DICTIONARY
);
327 EXPECT_TRUE(data
.empty());
329 EXPECT_TRUE(dictionary
->AddWord("bar"));
330 EXPECT_TRUE(dictionary
->AddWord("foo"));
332 data
= dictionary
->GetAllSyncData(syncer::DICTIONARY
);
333 EXPECT_EQ(2UL, data
.size());
334 std::vector
<std::string
> words
;
335 words
.push_back("bar");
336 words
.push_back("foo");
337 for (size_t i
= 0; i
< data
.size(); i
++) {
338 EXPECT_TRUE(data
[i
].GetSpecifics().has_dictionary());
339 EXPECT_EQ(syncer::DICTIONARY
, data
[i
].GetDataType());
340 EXPECT_EQ(words
[i
], data
[i
].GetTag());
341 EXPECT_EQ(words
[i
], data
[i
].GetSpecifics().dictionary().word());
344 EXPECT_TRUE(dictionary
->RemoveWord("bar"));
345 EXPECT_TRUE(dictionary
->RemoveWord("foo"));
347 data
= dictionary
->GetAllSyncData(syncer::DICTIONARY
);
348 EXPECT_TRUE(data
.empty());
351 TEST_F(SpellcheckCustomDictionaryTest
, GetAllSyncDataHasLimit
) {
352 SpellcheckCustomDictionary
* dictionary
=
353 SpellcheckServiceFactory::GetForContext(
354 &profile_
)->GetCustomDictionary();
356 SpellcheckCustomDictionary::Change change
;
358 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
- 1;
360 change
.AddWord("foo" + base::Uint64ToString(i
));
362 Apply(*dictionary
, change
);
363 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
- 1,
364 dictionary
->GetWords().size());
365 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
- 1,
366 dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
368 dictionary
->AddWord("baz");
369 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
370 dictionary
->GetWords().size());
371 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
372 dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
374 dictionary
->AddWord("bar");
375 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
376 dictionary
->GetWords().size());
377 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
378 dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
380 dictionary
->AddWord("snafoo");
381 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 2,
382 dictionary
->GetWords().size());
383 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
384 dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
387 TEST_F(SpellcheckCustomDictionaryTest
, ProcessSyncChanges
) {
388 SpellcheckService
* spellcheck_service
=
389 SpellcheckServiceFactory::GetForContext(&profile_
);
390 SpellcheckCustomDictionary
* dictionary
=
391 spellcheck_service
->GetCustomDictionary();
393 dictionary
->AddWord("foo");
394 dictionary
->AddWord("bar");
396 syncer::SyncChangeList changes
;
398 // Add existing word.
399 std::string word
= "foo";
400 sync_pb::EntitySpecifics specifics
;
401 specifics
.mutable_dictionary()->set_word(word
);
402 changes
.push_back(syncer::SyncChange(
404 syncer::SyncChange::ACTION_ADD
,
405 syncer::SyncData::CreateLocalData(word
, word
, specifics
)));
408 // Add invalid word. This word is too long.
409 std::string word
= "01234567890123456789012345678901234567890123456789"
410 "01234567890123456789012345678901234567890123456789";
411 sync_pb::EntitySpecifics specifics
;
412 specifics
.mutable_dictionary()->set_word(word
);
413 changes
.push_back(syncer::SyncChange(
415 syncer::SyncChange::ACTION_ADD
,
416 syncer::SyncData::CreateLocalData(word
, word
, specifics
)));
420 std::string word
= "baz";
421 sync_pb::EntitySpecifics specifics
;
422 specifics
.mutable_dictionary()->set_word(word
);
423 changes
.push_back(syncer::SyncChange(
425 syncer::SyncChange::ACTION_ADD
,
426 syncer::SyncData::CreateLocalData(word
, word
, specifics
)));
429 // Remove missing word.
430 std::string word
= "snafoo";
431 sync_pb::EntitySpecifics specifics
;
432 specifics
.mutable_dictionary()->set_word(word
);
433 changes
.push_back(syncer::SyncChange(
435 syncer::SyncChange::ACTION_DELETE
,
436 syncer::SyncData::CreateLocalData(word
, word
, specifics
)));
439 // Remove existing word.
440 std::string word
= "bar";
441 sync_pb::EntitySpecifics specifics
;
442 specifics
.mutable_dictionary()->set_word(word
);
443 changes
.push_back(syncer::SyncChange(
445 syncer::SyncChange::ACTION_DELETE
,
446 syncer::SyncData::CreateLocalData(word
, word
, specifics
)));
449 EXPECT_FALSE(dictionary
->ProcessSyncChanges(FROM_HERE
, changes
).IsSet());
451 const WordSet
& words
= dictionary
->GetWords();
452 EXPECT_EQ(2UL, words
.size());
453 EXPECT_EQ(0UL, words
.count("bar"));
454 EXPECT_EQ(1UL, words
.count("foo"));
455 EXPECT_EQ(1UL, words
.count("baz"));
458 TEST_F(SpellcheckCustomDictionaryTest
, MergeDataAndStartSyncing
) {
459 SpellcheckService
* spellcheck_service
=
460 SpellcheckServiceFactory::GetForContext(&profile_
);
461 SpellcheckCustomDictionary
* custom_dictionary
=
462 spellcheck_service
->GetCustomDictionary();
463 TestingProfile profile2
;
464 SpellcheckService
* spellcheck_service2
=
465 static_cast<SpellcheckService
*>(
466 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
467 &profile2
, &BuildSpellcheckService
));
468 SpellcheckCustomDictionary
* custom_dictionary2
=
469 spellcheck_service2
->GetCustomDictionary();
471 SpellcheckCustomDictionary::Change change
;
473 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
/ 2;
475 change
.AddWord("foo" + base::Uint64ToString(i
));
477 Apply(*custom_dictionary
, change
);
479 SpellcheckCustomDictionary::Change change2
;
481 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
/ 2;
483 change2
.AddWord("bar" + base::Uint64ToString(i
));
485 Apply(*custom_dictionary2
, change2
);
487 int error_counter
= 0;
488 EXPECT_FALSE(custom_dictionary
->MergeDataAndStartSyncing(
490 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
),
491 scoped_ptr
<syncer::SyncChangeProcessor
>(
492 new SyncChangeProcessorDelegate(custom_dictionary2
)),
493 scoped_ptr
<syncer::SyncErrorFactory
>(
494 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
495 EXPECT_EQ(0, error_counter
);
496 EXPECT_TRUE(custom_dictionary
->IsSyncing());
498 WordSet words
= custom_dictionary
->GetWords();
499 WordSet words2
= custom_dictionary2
->GetWords();
500 EXPECT_EQ(words
.size(), words2
.size());
501 EXPECT_EQ(words
, words2
);
504 TEST_F(SpellcheckCustomDictionaryTest
, DictionaryTooBigBeforeSyncing
) {
505 SpellcheckService
* spellcheck_service
=
506 SpellcheckServiceFactory::GetForContext(&profile_
);
507 SpellcheckCustomDictionary
* custom_dictionary
=
508 spellcheck_service
->GetCustomDictionary();
509 TestingProfile profile2
;
510 SpellcheckService
* spellcheck_service2
=
511 static_cast<SpellcheckService
*>(
512 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
513 &profile2
, &BuildSpellcheckService
));
514 SpellcheckCustomDictionary
* custom_dictionary2
=
515 spellcheck_service2
->GetCustomDictionary();
517 SpellcheckCustomDictionary::Change change
;
519 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1;
521 change
.AddWord("foo" + base::Uint64ToString(i
));
523 Apply(*custom_dictionary
, change
);
525 int error_counter
= 0;
526 EXPECT_FALSE(custom_dictionary
->MergeDataAndStartSyncing(
528 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
),
529 scoped_ptr
<syncer::SyncChangeProcessor
>(
530 new SyncChangeProcessorDelegate(custom_dictionary2
)),
531 scoped_ptr
<syncer::SyncErrorFactory
>(
532 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
533 EXPECT_EQ(0, error_counter
);
534 EXPECT_FALSE(custom_dictionary
->IsSyncing());
536 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
537 custom_dictionary
->GetWords().size());
538 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
539 custom_dictionary2
->GetWords().size());
541 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
542 custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
543 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
544 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
547 TEST_F(SpellcheckCustomDictionaryTest
, DictionaryTooBigAndServerFull
) {
548 SpellcheckService
* spellcheck_service
=
549 SpellcheckServiceFactory::GetForContext(&profile_
);
550 SpellcheckCustomDictionary
* custom_dictionary
=
551 spellcheck_service
->GetCustomDictionary();
552 TestingProfile profile2
;
553 SpellcheckService
* spellcheck_service2
=
554 static_cast<SpellcheckService
*>(
555 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
556 &profile2
, &BuildSpellcheckService
));
557 SpellcheckCustomDictionary
* custom_dictionary2
=
558 spellcheck_service2
->GetCustomDictionary();
560 SpellcheckCustomDictionary::Change change
;
561 SpellcheckCustomDictionary::Change change2
;
563 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
;
565 change
.AddWord("foo" + base::Uint64ToString(i
));
566 change2
.AddWord("bar" + base::Uint64ToString(i
));
568 change
.AddWord("foo");
569 Apply(*custom_dictionary
, change
);
570 Apply(*custom_dictionary2
, change2
);
572 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
573 custom_dictionary
->GetWords().size());
574 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
575 custom_dictionary2
->GetWords().size());
577 int error_counter
= 0;
578 EXPECT_FALSE(custom_dictionary
->MergeDataAndStartSyncing(
580 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
),
581 scoped_ptr
<syncer::SyncChangeProcessor
>(
582 new SyncChangeProcessorDelegate(custom_dictionary2
)),
583 scoped_ptr
<syncer::SyncErrorFactory
>(
584 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
585 EXPECT_EQ(0, error_counter
);
586 EXPECT_FALSE(custom_dictionary
->IsSyncing());
588 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
* 2 + 1,
589 custom_dictionary
->GetWords().size());
590 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
591 custom_dictionary2
->GetWords().size());
593 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
594 custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
595 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
596 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
599 TEST_F(SpellcheckCustomDictionaryTest
, ServerTooBig
) {
600 SpellcheckService
* spellcheck_service
=
601 SpellcheckServiceFactory::GetForContext(&profile_
);
602 SpellcheckCustomDictionary
* custom_dictionary
=
603 spellcheck_service
->GetCustomDictionary();
604 TestingProfile profile2
;
605 SpellcheckService
* spellcheck_service2
=
606 static_cast<SpellcheckService
*>(
607 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
608 &profile2
, &BuildSpellcheckService
));
609 SpellcheckCustomDictionary
* custom_dictionary2
=
610 spellcheck_service2
->GetCustomDictionary();
612 SpellcheckCustomDictionary::Change change
;
613 SpellcheckCustomDictionary::Change change2
;
615 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1;
617 change
.AddWord("foo" + base::Uint64ToString(i
));
618 change2
.AddWord("bar" + base::Uint64ToString(i
));
620 Apply(*custom_dictionary
, change
);
621 Apply(*custom_dictionary2
, change2
);
623 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
624 custom_dictionary
->GetWords().size());
625 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
626 custom_dictionary2
->GetWords().size());
628 int error_counter
= 0;
629 EXPECT_FALSE(custom_dictionary
->MergeDataAndStartSyncing(
631 GetAllSyncDataNoLimit(custom_dictionary2
),
632 scoped_ptr
<syncer::SyncChangeProcessor
>(
633 new SyncChangeProcessorDelegate(custom_dictionary2
)),
634 scoped_ptr
<syncer::SyncErrorFactory
>(
635 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
636 EXPECT_EQ(0, error_counter
);
637 EXPECT_FALSE(custom_dictionary
->IsSyncing());
639 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
* 2 + 2,
640 custom_dictionary
->GetWords().size());
641 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
642 custom_dictionary2
->GetWords().size());
644 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
645 custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
646 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
647 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
650 TEST_F(SpellcheckCustomDictionaryTest
, DictionaryTooBigToStartSyncing
) {
651 SpellcheckService
* spellcheck_service
=
652 SpellcheckServiceFactory::GetForContext(&profile_
);
653 SpellcheckCustomDictionary
* custom_dictionary
=
654 spellcheck_service
->GetCustomDictionary();
655 TestingProfile profile2
;
656 SpellcheckService
* spellcheck_service2
=
657 static_cast<SpellcheckService
*>(
658 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
659 &profile2
, &BuildSpellcheckService
));
660 SpellcheckCustomDictionary
* custom_dictionary2
=
661 spellcheck_service2
->GetCustomDictionary();
663 SpellcheckCustomDictionary::Change change
;
665 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
- 1;
667 change
.AddWord("foo" + base::Uint64ToString(i
));
669 Apply(*custom_dictionary
, change
);
671 custom_dictionary2
->AddWord("bar");
672 custom_dictionary2
->AddWord("baz");
674 int error_counter
= 0;
675 EXPECT_FALSE(custom_dictionary
->MergeDataAndStartSyncing(
677 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
),
678 scoped_ptr
<syncer::SyncChangeProcessor
>(
679 new SyncChangeProcessorDelegate(custom_dictionary2
)),
680 scoped_ptr
<syncer::SyncErrorFactory
>(
681 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
682 EXPECT_EQ(0, error_counter
);
683 EXPECT_FALSE(custom_dictionary
->IsSyncing());
685 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
686 custom_dictionary
->GetWords().size());
687 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
688 custom_dictionary2
->GetWords().size());
690 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
691 custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
692 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
693 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
696 TEST_F(SpellcheckCustomDictionaryTest
, DictionaryTooBigToContiueSyncing
) {
697 SpellcheckService
* spellcheck_service
=
698 SpellcheckServiceFactory::GetForContext(&profile_
);
699 SpellcheckCustomDictionary
* custom_dictionary
=
700 spellcheck_service
->GetCustomDictionary();
701 TestingProfile profile2
;
702 SpellcheckService
* spellcheck_service2
=
703 static_cast<SpellcheckService
*>(
704 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
705 &profile2
, &BuildSpellcheckService
));
706 SpellcheckCustomDictionary
* custom_dictionary2
=
707 spellcheck_service2
->GetCustomDictionary();
709 SpellcheckCustomDictionary::Change change
;
711 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
- 1;
713 change
.AddWord("foo" + base::Uint64ToString(i
));
715 Apply(*custom_dictionary
, change
);
717 int error_counter
= 0;
718 EXPECT_FALSE(custom_dictionary
->MergeDataAndStartSyncing(
720 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
),
721 scoped_ptr
<syncer::SyncChangeProcessor
>(
722 new SyncChangeProcessorDelegate(custom_dictionary2
)),
723 scoped_ptr
<syncer::SyncErrorFactory
>(
724 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
725 EXPECT_EQ(0, error_counter
);
726 EXPECT_TRUE(custom_dictionary
->IsSyncing());
728 custom_dictionary
->AddWord("bar");
729 EXPECT_EQ(0, error_counter
);
730 EXPECT_TRUE(custom_dictionary
->IsSyncing());
732 custom_dictionary
->AddWord("baz");
733 EXPECT_EQ(0, error_counter
);
734 EXPECT_FALSE(custom_dictionary
->IsSyncing());
736 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
737 custom_dictionary
->GetWords().size());
738 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
739 custom_dictionary2
->GetWords().size());
741 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
742 custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
743 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
744 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
747 TEST_F(SpellcheckCustomDictionaryTest
, LoadAfterSyncStart
) {
748 SpellcheckService
* spellcheck_service
=
749 SpellcheckServiceFactory::GetForContext(&profile_
);
750 SpellcheckCustomDictionary
* custom_dictionary
=
751 spellcheck_service
->GetCustomDictionary();
752 TestingProfile profile2
;
753 SpellcheckService
* spellcheck_service2
=
754 static_cast<SpellcheckService
*>(
755 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
756 &profile2
, &BuildSpellcheckService
));
757 SpellcheckCustomDictionary
* custom_dictionary2
=
758 spellcheck_service2
->GetCustomDictionary();
760 custom_dictionary
->AddWord("foo");
762 int error_counter
= 0;
763 EXPECT_FALSE(custom_dictionary
->MergeDataAndStartSyncing(
765 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
),
766 scoped_ptr
<syncer::SyncChangeProcessor
>(
767 new SyncChangeProcessorDelegate(custom_dictionary2
)),
768 scoped_ptr
<syncer::SyncErrorFactory
>(
769 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
770 EXPECT_EQ(0, error_counter
);
771 EXPECT_TRUE(custom_dictionary
->IsSyncing());
773 WordList custom_words
;
774 custom_words
.push_back("bar");
775 OnLoaded(*custom_dictionary
, custom_words
);
776 EXPECT_TRUE(custom_dictionary
->IsSyncing());
778 EXPECT_EQ(2UL, custom_dictionary
->GetWords().size());
779 EXPECT_EQ(2UL, custom_dictionary2
->GetWords().size());
781 EXPECT_EQ(2UL, custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
782 EXPECT_EQ(2UL, custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
785 TEST_F(SpellcheckCustomDictionaryTest
, LoadAfterSyncStartTooBigToSync
) {
786 SpellcheckService
* spellcheck_service
=
787 SpellcheckServiceFactory::GetForContext(&profile_
);
788 SpellcheckCustomDictionary
* custom_dictionary
=
789 spellcheck_service
->GetCustomDictionary();
790 TestingProfile profile2
;
791 SpellcheckService
* spellcheck_service2
=
792 static_cast<SpellcheckService
*>(
793 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
794 &profile2
, &BuildSpellcheckService
));
795 SpellcheckCustomDictionary
* custom_dictionary2
=
796 spellcheck_service2
->GetCustomDictionary();
798 custom_dictionary
->AddWord("foo");
800 int error_counter
= 0;
801 EXPECT_FALSE(custom_dictionary
->MergeDataAndStartSyncing(
803 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
),
804 scoped_ptr
<syncer::SyncChangeProcessor
>(
805 new SyncChangeProcessorDelegate(custom_dictionary2
)),
806 scoped_ptr
<syncer::SyncErrorFactory
>(
807 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
808 EXPECT_EQ(0, error_counter
);
809 EXPECT_TRUE(custom_dictionary
->IsSyncing());
811 WordList custom_words
;
813 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
;
815 custom_words
.push_back("foo" + base::Uint64ToString(i
));
817 OnLoaded(*custom_dictionary
, custom_words
);
818 EXPECT_EQ(0, error_counter
);
819 EXPECT_FALSE(custom_dictionary
->IsSyncing());
821 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
+ 1,
822 custom_dictionary
->GetWords().size());
823 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
824 custom_dictionary2
->GetWords().size());
826 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
827 custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
828 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
829 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
832 TEST_F(SpellcheckCustomDictionaryTest
, LoadDuplicatesAfterSync
) {
833 SpellcheckService
* spellcheck_service
=
834 SpellcheckServiceFactory::GetForContext(&profile_
);
835 SpellcheckCustomDictionary
* custom_dictionary
=
836 spellcheck_service
->GetCustomDictionary();
837 TestingProfile profile2
;
838 SpellcheckService
* spellcheck_service2
=
839 static_cast<SpellcheckService
*>(
840 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
841 &profile2
, &BuildSpellcheckService
));
842 SpellcheckCustomDictionary
* custom_dictionary2
=
843 spellcheck_service2
->GetCustomDictionary();
847 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
/ 2;
849 to_add
.push_back("foo" + base::Uint64ToString(i
));
851 Apply(*custom_dictionary
, SpellcheckCustomDictionary::Change(to_add
));
853 int error_counter
= 0;
854 EXPECT_FALSE(custom_dictionary
->MergeDataAndStartSyncing(
856 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
),
857 scoped_ptr
<syncer::SyncChangeProcessor
>(
858 new SyncChangeProcessorDelegate(custom_dictionary2
)),
859 scoped_ptr
<syncer::SyncErrorFactory
>(
860 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
861 EXPECT_EQ(0, error_counter
);
862 EXPECT_TRUE(custom_dictionary
->IsSyncing());
864 OnLoaded(*custom_dictionary
, to_add
);
865 EXPECT_EQ(0, error_counter
);
866 EXPECT_TRUE(custom_dictionary
->IsSyncing());
868 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
/ 2,
869 custom_dictionary
->GetWords().size());
870 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
/ 2,
871 custom_dictionary2
->GetWords().size());
873 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
/ 2,
874 custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
).size());
875 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
/ 2,
876 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
).size());
879 TEST_F(SpellcheckCustomDictionaryTest
, DictionaryLoadNotification
) {
880 SpellcheckService
* spellcheck_service
=
881 SpellcheckServiceFactory::GetForContext(&profile_
);
882 SpellcheckCustomDictionary
* custom_dictionary
=
883 spellcheck_service
->GetCustomDictionary();
885 DictionaryObserverCounter observer
;
886 custom_dictionary
->AddObserver(&observer
);
888 WordList custom_words
;
889 custom_words
.push_back("foo");
890 custom_words
.push_back("bar");
891 OnLoaded(*custom_dictionary
, custom_words
);
893 EXPECT_GE(observer
.loads(), 1);
894 EXPECT_LE(observer
.loads(), 2);
895 EXPECT_EQ(0, observer
.changes());
897 custom_dictionary
->RemoveObserver(&observer
);
900 TEST_F(SpellcheckCustomDictionaryTest
, DictionaryAddWordNotification
) {
901 SpellcheckService
* spellcheck_service
=
902 SpellcheckServiceFactory::GetForContext(&profile_
);
903 SpellcheckCustomDictionary
* custom_dictionary
=
904 spellcheck_service
->GetCustomDictionary();
906 OnLoaded(*custom_dictionary
, WordList());
908 DictionaryObserverCounter observer
;
909 custom_dictionary
->AddObserver(&observer
);
911 EXPECT_TRUE(custom_dictionary
->AddWord("foo"));
912 EXPECT_TRUE(custom_dictionary
->AddWord("bar"));
913 EXPECT_FALSE(custom_dictionary
->AddWord("bar"));
915 EXPECT_EQ(2, observer
.changes());
917 custom_dictionary
->RemoveObserver(&observer
);
920 TEST_F(SpellcheckCustomDictionaryTest
, DictionaryRemoveWordNotification
) {
921 SpellcheckService
* spellcheck_service
=
922 SpellcheckServiceFactory::GetForContext(&profile_
);
923 SpellcheckCustomDictionary
* custom_dictionary
=
924 spellcheck_service
->GetCustomDictionary();
926 OnLoaded(*custom_dictionary
, WordList());
928 EXPECT_TRUE(custom_dictionary
->AddWord("foo"));
929 EXPECT_TRUE(custom_dictionary
->AddWord("bar"));
931 DictionaryObserverCounter observer
;
932 custom_dictionary
->AddObserver(&observer
);
934 EXPECT_TRUE(custom_dictionary
->RemoveWord("foo"));
935 EXPECT_TRUE(custom_dictionary
->RemoveWord("bar"));
936 EXPECT_FALSE(custom_dictionary
->RemoveWord("baz"));
938 EXPECT_EQ(2, observer
.changes());
940 custom_dictionary
->RemoveObserver(&observer
);
943 TEST_F(SpellcheckCustomDictionaryTest
, DictionarySyncNotification
) {
944 SpellcheckService
* spellcheck_service
=
945 SpellcheckServiceFactory::GetForContext(&profile_
);
946 SpellcheckCustomDictionary
* custom_dictionary
=
947 spellcheck_service
->GetCustomDictionary();
948 TestingProfile profile2
;
949 SpellcheckService
* spellcheck_service2
=
950 static_cast<SpellcheckService
*>(
951 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
952 &profile2
, &BuildSpellcheckService
));
953 SpellcheckCustomDictionary
* custom_dictionary2
=
954 spellcheck_service2
->GetCustomDictionary();
956 OnLoaded(*custom_dictionary
, WordList());
957 OnLoaded(*custom_dictionary2
, WordList());
959 custom_dictionary
->AddWord("foo");
960 custom_dictionary
->AddWord("bar");
961 custom_dictionary2
->AddWord("foo");
962 custom_dictionary2
->AddWord("baz");
964 DictionaryObserverCounter observer
;
965 custom_dictionary
->AddObserver(&observer
);
967 DictionaryObserverCounter observer2
;
968 custom_dictionary2
->AddObserver(&observer2
);
970 int error_counter
= 0;
971 EXPECT_FALSE(custom_dictionary
->MergeDataAndStartSyncing(
973 custom_dictionary2
->GetAllSyncData(syncer::DICTIONARY
),
974 scoped_ptr
<syncer::SyncChangeProcessor
>(
975 new SyncChangeProcessorDelegate(custom_dictionary2
)),
976 scoped_ptr
<syncer::SyncErrorFactory
>(
977 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
978 EXPECT_EQ(0, error_counter
);
979 EXPECT_TRUE(custom_dictionary
->IsSyncing());
981 EXPECT_EQ(1, observer
.changes());
982 EXPECT_EQ(1, observer2
.changes());
984 custom_dictionary
->RemoveObserver(&observer
);
985 custom_dictionary2
->RemoveObserver(&observer2
);
988 // The server has maximum number of words and the client has maximum number of
989 // different words before association time. No new words should be pushed to the
990 // sync server upon association. The client should accept words from the sync
992 TEST_F(SpellcheckCustomDictionaryTest
, DictionarySyncLimit
) {
993 TestingProfile server_profile
;
994 SpellcheckService
* server_spellcheck_service
=
995 static_cast<SpellcheckService
*>(
996 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
997 &server_profile
, &BuildSpellcheckService
));
999 // Here, |server_custom_dictionary| plays the role of the sync server.
1000 SpellcheckCustomDictionary
* server_custom_dictionary
=
1001 server_spellcheck_service
->GetCustomDictionary();
1003 // Upload the maximum number of words to the sync server.
1005 SpellcheckService
* spellcheck_service
=
1006 SpellcheckServiceFactory::GetForContext(&profile_
);
1007 SpellcheckCustomDictionary
* custom_dictionary
=
1008 spellcheck_service
->GetCustomDictionary();
1010 SpellcheckCustomDictionary::Change change
;
1012 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
;
1014 change
.AddWord("foo" + base::Uint64ToString(i
));
1016 Apply(*custom_dictionary
, change
);
1018 int error_counter
= 0;
1019 EXPECT_FALSE(custom_dictionary
->MergeDataAndStartSyncing(
1021 server_custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
),
1022 scoped_ptr
<syncer::SyncChangeProcessor
>(
1023 new SyncChangeProcessorDelegate(server_custom_dictionary
)),
1024 scoped_ptr
<syncer::SyncErrorFactory
>(
1025 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
1026 EXPECT_EQ(0, error_counter
);
1027 EXPECT_TRUE(custom_dictionary
->IsSyncing());
1028 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
1029 custom_dictionary
->GetWords().size());
1032 // The sync server now has the maximum number of words.
1033 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
1034 server_custom_dictionary
->GetWords().size());
1036 // Associate the sync server with a client that also has the maximum number of
1037 // words, but all of these words are different from the ones on the sync
1040 TestingProfile client_profile
;
1041 SpellcheckService
* client_spellcheck_service
=
1042 static_cast<SpellcheckService
*>(
1043 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
1044 &client_profile
, &BuildSpellcheckService
));
1046 // Here, |client_custom_dictionary| plays the role of the client.
1047 SpellcheckCustomDictionary
* client_custom_dictionary
=
1048 client_spellcheck_service
->GetCustomDictionary();
1050 // Add the maximum number of words to the client. These words are all
1051 // different from those on the server.
1052 SpellcheckCustomDictionary::Change change
;
1054 i
< chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
;
1056 change
.AddWord("bar" + base::Uint64ToString(i
));
1058 Apply(*client_custom_dictionary
, change
);
1060 // Associate the server and the client.
1061 int error_counter
= 0;
1062 EXPECT_FALSE(client_custom_dictionary
->MergeDataAndStartSyncing(
1064 server_custom_dictionary
->GetAllSyncData(syncer::DICTIONARY
),
1065 scoped_ptr
<syncer::SyncChangeProcessor
>(
1066 new SyncChangeProcessorDelegate(server_custom_dictionary
)),
1067 scoped_ptr
<syncer::SyncErrorFactory
>(
1068 new SyncErrorFactoryStub(&error_counter
))).error().IsSet());
1069 EXPECT_EQ(0, error_counter
);
1070 EXPECT_FALSE(client_custom_dictionary
->IsSyncing());
1071 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
* 2,
1072 client_custom_dictionary
->GetWords().size());
1075 // The sync server should not receive more words, because it has the maximum
1076 // number of words already.
1077 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS
,
1078 server_custom_dictionary
->GetWords().size());
1081 TEST_F(SpellcheckCustomDictionaryTest
, RecordSizeStatsCorrectly
) {
1083 // Failing consistently on Win7. See crbug.com/230534.
1084 if (base::win::GetVersion() >= base::win::VERSION_VISTA
)
1087 // Record a baseline.
1088 SpellCheckHostMetrics::RecordCustomWordCountStats(123);
1090 // Determine if test failures are due the statistics recorder not being
1091 // available or because the histogram just isn't there: crbug.com/230534.
1092 EXPECT_TRUE(StatisticsRecorder::IsActive());
1094 HistogramBase
* histogram
=
1095 StatisticsRecorder::FindHistogram("SpellCheck.CustomWords");
1096 ASSERT_TRUE(histogram
!= NULL
);
1097 scoped_ptr
<HistogramSamples
> baseline
= histogram
->SnapshotSamples();
1099 // Load the dictionary which should be empty.
1100 base::FilePath path
=
1101 profile_
.GetPath().Append(chrome::kCustomDictionaryFileName
);
1102 WordList loaded_custom_words
= LoadDictionaryFile(path
);
1103 EXPECT_EQ(0u, loaded_custom_words
.size());
1105 // We expect there to be an entry with 0.
1107 StatisticsRecorder::FindHistogram("SpellCheck.CustomWords");
1108 ASSERT_TRUE(histogram
!= NULL
);
1109 scoped_ptr
<HistogramSamples
> samples
= histogram
->SnapshotSamples();
1111 samples
->Subtract(*baseline
);
1112 EXPECT_EQ(0,samples
->sum());
1114 SpellcheckCustomDictionary::Change change
;
1115 change
.AddWord("bar");
1116 change
.AddWord("foo");
1117 UpdateDictionaryFile(change
, path
);
1119 // Load the dictionary again and it should have 2 entries.
1120 loaded_custom_words
= LoadDictionaryFile(path
);
1121 EXPECT_EQ(2u, loaded_custom_words
.size());
1124 StatisticsRecorder::FindHistogram("SpellCheck.CustomWords");
1125 ASSERT_TRUE(histogram
!= NULL
);
1126 scoped_ptr
<HistogramSamples
> samples2
= histogram
->SnapshotSamples();
1128 samples2
->Subtract(*baseline
);
1129 EXPECT_EQ(2,samples2
->sum());
1132 TEST_F(SpellcheckCustomDictionaryTest
, HasWord
) {
1133 SpellcheckService
* spellcheck_service
=
1134 SpellcheckServiceFactory::GetForContext(&profile_
);
1135 SpellcheckCustomDictionary
* custom_dictionary
=
1136 spellcheck_service
->GetCustomDictionary();
1137 OnLoaded(*custom_dictionary
, WordList());
1138 EXPECT_FALSE(custom_dictionary
->HasWord("foo"));
1139 EXPECT_FALSE(custom_dictionary
->HasWord("bar"));
1140 custom_dictionary
->AddWord("foo");
1141 EXPECT_TRUE(custom_dictionary
->HasWord("foo"));
1142 EXPECT_FALSE(custom_dictionary
->HasWord("bar"));