Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / spellchecker / spellcheck_custom_dictionary_unittest.cc
blobdf75fb56ed48fd7e7e797e6856fe431bd756803f
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 <vector>
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"
28 #if defined(OS_WIN)
29 // For version specific disabled tests below (http://crbug.com/230534).
30 #include "base/win/windows_version.h"
31 #endif
33 using base::HistogramBase;
34 using base::HistogramSamples;
35 using base::StatisticsRecorder;
36 using chrome::spellcheck_common::WordList;
37 using chrome::spellcheck_common::WordSet;
39 namespace {
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;
46 std::string word;
47 const WordSet& words = dictionary->GetWords();
48 for (WordSet::const_iterator it = words.begin(); it != words.end(); ++it) {
49 word = *it;
50 sync_pb::EntitySpecifics specifics;
51 specifics.mutable_dictionary()->set_word(word);
52 data.push_back(syncer::SyncData::CreateLocalData(word, word, specifics));
54 return data;
57 } // namespace
59 static BrowserContextKeyedService* BuildSpellcheckService(
60 content::BrowserContext* profile) {
61 return new SpellcheckService(static_cast<Profile*>(profile));
64 class SpellcheckCustomDictionaryTest : public testing::Test {
65 protected:
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.
94 void OnLoaded(
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.
102 void Apply(
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 {
118 public:
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
131 OVERRIDE {
132 return syncer::SyncDataList();
135 private:
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 {
144 public:
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 {
153 (*error_counter_)++;
154 return syncer::SyncError(location,
155 syncer::SyncError::DATATYPE_ERROR,
156 message,
157 syncer::DICTIONARY);
160 private:
161 int* error_counter_;
162 DISALLOW_COPY_AND_ASSIGN(SyncErrorFactoryStub);
165 // Counts the number of notifications for dictionary load and change.
166 class DictionaryObserverCounter : public SpellcheckCustomDictionary::Observer {
167 public:
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_++; }
179 private:
180 int loads_;
181 int 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.
191 WordList expected;
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);
211 expected.clear();
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();
228 WordSet expected1;
229 WordSet expected2;
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);
253 std::string content;
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
260 // with two words.
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);
269 WordList expected;
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
276 // trimmed.
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);
287 WordList expected;
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);
304 WordList expected;
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);
312 content.clear();
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;
357 for (size_t i = 0;
358 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS - 1;
359 i++) {
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(
403 FROM_HERE,
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(
414 FROM_HERE,
415 syncer::SyncChange::ACTION_ADD,
416 syncer::SyncData::CreateLocalData(word, word, specifics)));
419 // Add valid word.
420 std::string word = "baz";
421 sync_pb::EntitySpecifics specifics;
422 specifics.mutable_dictionary()->set_word(word);
423 changes.push_back(syncer::SyncChange(
424 FROM_HERE,
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(
434 FROM_HERE,
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(
444 FROM_HERE,
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;
472 for (size_t i = 0;
473 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS / 2;
474 ++i) {
475 change.AddWord("foo" + base::Uint64ToString(i));
477 Apply(*custom_dictionary, change);
479 SpellcheckCustomDictionary::Change change2;
480 for (size_t i = 0;
481 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS / 2;
482 ++i) {
483 change2.AddWord("bar" + base::Uint64ToString(i));
485 Apply(*custom_dictionary2, change2);
487 int error_counter = 0;
488 EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
489 syncer::DICTIONARY,
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;
518 for (size_t i = 0;
519 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1;
520 ++i) {
521 change.AddWord("foo" + base::Uint64ToString(i));
523 Apply(*custom_dictionary, change);
525 int error_counter = 0;
526 EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
527 syncer::DICTIONARY,
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;
562 for (size_t i = 0;
563 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS;
564 ++i) {
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(
579 syncer::DICTIONARY,
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;
614 for (size_t i = 0;
615 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1;
616 ++i) {
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(
630 syncer::DICTIONARY,
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;
664 for (size_t i = 0;
665 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS - 1;
666 ++i) {
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(
676 syncer::DICTIONARY,
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;
710 for (size_t i = 0;
711 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS - 1;
712 ++i) {
713 change.AddWord("foo" + base::Uint64ToString(i));
715 Apply(*custom_dictionary, change);
717 int error_counter = 0;
718 EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
719 syncer::DICTIONARY,
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(
764 syncer::DICTIONARY,
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(
802 syncer::DICTIONARY,
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;
812 for (size_t i = 0;
813 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS;
814 ++i) {
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();
845 WordList to_add;
846 for (size_t i = 0;
847 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS / 2;
848 ++i) {
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(
855 syncer::DICTIONARY,
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(
972 syncer::DICTIONARY,
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
991 // server, however.
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;
1011 for (size_t i = 0;
1012 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS;
1013 ++i) {
1014 change.AddWord("foo" + base::Uint64ToString(i));
1016 Apply(*custom_dictionary, change);
1018 int error_counter = 0;
1019 EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
1020 syncer::DICTIONARY,
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
1038 // server.
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;
1053 for (size_t i = 0;
1054 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS;
1055 ++i) {
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(
1063 syncer::DICTIONARY,
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) {
1082 #if defined(OS_WIN)
1083 // Failing consistently on Win7. See crbug.com/230534.
1084 if (base::win::GetVersion() >= base::win::VERSION_VISTA)
1085 return;
1086 #endif
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.
1106 histogram =
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());
1123 histogram =
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"));