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