Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4518)

Unified Diff: chrome/browser/spellchecker/spellcheck_custom_dictionary_unittest.cc

Issue 11445002: Sync user's custom spellcheck dictionary (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fix compile on some platforms Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/spellchecker/spellcheck_custom_dictionary_unittest.cc
diff --git a/chrome/browser/spellchecker/spellcheck_custom_dictionary_unittest.cc b/chrome/browser/spellchecker/spellcheck_custom_dictionary_unittest.cc
index c890afcaa654000c8bbbc5d2976d013fce33c5bf..9bc09ba2cce32c8b8764a33f0e66a32b19d8b17f 100644
--- a/chrome/browser/spellchecker/spellcheck_custom_dictionary_unittest.cc
+++ b/chrome/browser/spellchecker/spellcheck_custom_dictionary_unittest.cc
@@ -5,6 +5,7 @@
#include <vector>
#include "base/file_util.h"
+#include "base/string_number_conversions.h"
#include "chrome/browser/spellchecker/spellcheck_custom_dictionary.h"
#include "chrome/browser/spellchecker/spellcheck_factory.h"
#include "chrome/browser/spellchecker/spellcheck_service.h"
@@ -12,12 +13,38 @@
#include "chrome/common/spellcheck_common.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/test/test_browser_thread.h"
+#include "sync/api/sync_change.h"
+#include "sync/api/sync_data.h"
+#include "sync/api/sync_error_factory.h"
+#include "sync/api/sync_error_factory_mock.h"
+#include "sync/protocol/sync.pb.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using content::BrowserThread;
using chrome::spellcheck_common::WordList;
+namespace {
+
+// Get all sync data for the custom dictionary without limiting to maximum
+// number of syncable words.
+syncer::SyncDataList GetAllSyncDataNoLimit(
+ const SpellcheckCustomDictionary* dictionary) {
+ syncer::SyncDataList data;
+ std::string word;
+ for (WordList::const_iterator it = dictionary->GetWords().begin();
+ it != dictionary->GetWords().end();
+ ++it) {
+ word = *it;
+ sync_pb::EntitySpecifics specifics;
+ specifics.mutable_dictionary()->set_word(word);
+ data.push_back(syncer::SyncData::CreateLocalData(word, word, specifics));
+ }
+ return data;
+}
+
+} // namespace
+
static ProfileKeyedService* BuildSpellcheckService(Profile* profile) {
return new SpellcheckService(profile);
}
@@ -27,7 +54,7 @@ class SpellcheckCustomDictionaryTest : public testing::Test {
SpellcheckCustomDictionaryTest()
: ui_thread_(BrowserThread::UI, &message_loop_),
file_thread_(BrowserThread::FILE, &message_loop_),
- profile_(new TestingProfile()) {
+ profile_(new TestingProfile) {
}
void SetUp() OVERRIDE {
@@ -40,6 +67,39 @@ class SpellcheckCustomDictionaryTest : public testing::Test {
MessageLoop::current()->RunUntilIdle();
}
+ // A wrapper around SpellcheckCustomDictionary::LoadDictionaryFile private
+ // function to avoid a large number of FRIEND_TEST declarations in
+ // SpellcheckCustomDictionary.
+ chrome::spellcheck_common::WordList LoadDictionaryFile(const FilePath& path) {
+ return SpellcheckCustomDictionary::LoadDictionaryFile(path);
+ }
+
+ // A wrapper around SpellcheckCustomDictionary::UpdateDictionaryFile private
+ // function to avoid a large number of FRIEND_TEST declarations in
+ // SpellcheckCustomDictionary.
+ void UpdateDictionaryFile(
+ const SpellcheckCustomDictionary::Change& dictionary_change,
+ const FilePath& path) {
+ SpellcheckCustomDictionary::UpdateDictionaryFile(dictionary_change, path);
+ }
+
+ // A wrapper around SpellcheckCustomDictionary::OnLoaded private method to
+ // avoid a large number of FRIEND_TEST declarations in
+ // SpellcheckCustomDictionary.
+ void OnLoaded(
+ SpellcheckCustomDictionary& dictionary,
+ const chrome::spellcheck_common::WordList& custom_words) {
+ dictionary.OnLoaded(custom_words);
+ }
+
+ // A wrapper around SpellcheckCustomDictionary::Apply private method to avoid
+ // a large number of FRIEND_TEST declarations in SpellcheckCustomDictionary.
+ void Apply(
+ SpellcheckCustomDictionary& dictionary,
+ const SpellcheckCustomDictionary::Change& change) {
+ return dictionary.Apply(change);
+ }
+
MessageLoop message_loop_;
content::TestBrowserThread ui_thread_;
content::TestBrowserThread file_thread_;
@@ -47,79 +107,96 @@ class SpellcheckCustomDictionaryTest : public testing::Test {
scoped_ptr<TestingProfile> profile_;
};
-TEST_F(SpellcheckCustomDictionaryTest, SpellcheckSetCustomWordList) {
- SpellcheckService* spellcheck_service =
- SpellcheckServiceFactory::GetForProfile(profile_.get());
+// A wrapper around SpellcheckCustomDictionary that does not own the wrapped
+// object. An instance of this class can be inside of a scoped pointer safely
+// while the dictionary is managed by another scoped pointer.
+class SyncChangeProcessorDelegate : public syncer::SyncChangeProcessor {
+ public:
+ explicit SyncChangeProcessorDelegate(SpellcheckCustomDictionary* dictionary)
+ : dictionary_(dictionary) {}
+ virtual ~SyncChangeProcessorDelegate() {}
- WordList loaded_custom_words;
- loaded_custom_words.push_back("foo");
- loaded_custom_words.push_back("bar");
- WordList expected(loaded_custom_words);
- SpellcheckCustomDictionary* custom_dictionary =
- spellcheck_service->GetCustomDictionary();
- custom_dictionary->SetCustomWordList(&loaded_custom_words);
- EXPECT_EQ(custom_dictionary->GetWords(), expected);
-}
+ // Overridden from syncer::SyncChangeProcessor:
+ virtual syncer::SyncError ProcessSyncChanges(
+ const tracked_objects::Location& from_here,
+ const syncer::SyncChangeList& change_list) OVERRIDE {
+ return dictionary_->ProcessSyncChanges(from_here, change_list);
+ }
-TEST_F(SpellcheckCustomDictionaryTest, CustomWordAddedAndRemovedLocally) {
- SpellcheckService* spellcheck_service =
- SpellcheckServiceFactory::GetForProfile(profile_.get());
+ private:
+ SpellcheckCustomDictionary* dictionary_;
+ DISALLOW_COPY_AND_ASSIGN(SyncChangeProcessorDelegate);
+};
- WordList loaded_custom_words;
- SpellcheckCustomDictionary* custom_dictionary =
- spellcheck_service->GetCustomDictionary();
- WordList expected;
- EXPECT_EQ(custom_dictionary->GetWords(), expected);
- custom_dictionary->CustomWordAddedLocally("foo");
- expected.push_back("foo");
- EXPECT_EQ(custom_dictionary->GetWords(), expected);
- custom_dictionary->CustomWordAddedLocally("bar");
- expected.push_back("bar");
- EXPECT_EQ(custom_dictionary->GetWords(), expected);
+// An implementation of SyncErrorFactory that does not upload the error message
+// and updates an outside error counter. This lets us know the number of error
+// messages in an instance of this class after that instance is deleted.
+class SyncErrorFactoryStub : public syncer::SyncErrorFactory {
+ public:
+ explicit SyncErrorFactoryStub(int* error_counter)
+ : error_counter_(error_counter) {}
+ virtual ~SyncErrorFactoryStub() {}
- custom_dictionary->CustomWordRemovedLocally("foo");
- custom_dictionary->CustomWordRemovedLocally("bar");
- expected.clear();
- EXPECT_EQ(custom_dictionary->GetWords(), expected);
-}
+ // Overridden from syncer::SyncErrorFactory:
+ virtual syncer::SyncError CreateAndUploadError(
+ const tracked_objects::Location& location,
+ const std::string& message) OVERRIDE {
+ (*error_counter_)++;
+ return syncer::SyncError(location, message, syncer::DICTIONARY);
+ }
-TEST_F(SpellcheckCustomDictionaryTest, SaveAndLoad) {
- SpellcheckService* spellcheck_service =
- SpellcheckServiceFactory::GetForProfile(profile_.get());
- SpellcheckCustomDictionary* custom_dictionary =
- spellcheck_service->GetCustomDictionary();
+ private:
+ int* error_counter_;
+ DISALLOW_COPY_AND_ASSIGN(SyncErrorFactoryStub);
+};
+
+// Counts the number of notifications for dictionary load and change.
+class DictionaryObserverCounter : public SpellcheckCustomDictionary::Observer {
+ public:
+ DictionaryObserverCounter() : loads_(0), changes_(0) {}
+ virtual ~DictionaryObserverCounter() {}
+
+ int loads() const { return loads_; }
+ int changes() const { return changes_; }
+
+ // Overridden from SpellcheckCustomDictionary::Observer:
+ virtual void OnCustomDictionaryLoaded() OVERRIDE { loads_++; }
+ virtual void OnCustomDictionaryChanged(
+ const SpellcheckCustomDictionary::Change& change) OVERRIDE { changes_++; }
- WordList loaded_custom_words;
- custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words);
+ private:
+ int loads_;
+ int changes_;
+ DISALLOW_COPY_AND_ASSIGN(DictionaryObserverCounter);
+};
+
+TEST_F(SpellcheckCustomDictionaryTest, SaveAndLoad) {
+ FilePath path = profile_->GetPath().Append(chrome::kCustomDictionaryFileName);
+ WordList loaded_custom_words = LoadDictionaryFile(path);
// The custom word list should be empty now.
WordList expected;
- EXPECT_EQ(loaded_custom_words, expected);
+ EXPECT_EQ(expected, loaded_custom_words);
- custom_dictionary->WriteWordToCustomDictionary("foo");
- expected.push_back("foo");
+ SpellcheckCustomDictionary::Change change;
+ change.AddWord("bar");
+ change.AddWord("foo");
- custom_dictionary->WriteWordToCustomDictionary("bar");
+ UpdateDictionaryFile(change, path);
expected.push_back("bar");
+ expected.push_back("foo");
// The custom word list should include written words.
- custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words);
- std::sort(expected.begin(), expected.end());
- EXPECT_EQ(loaded_custom_words, expected);
-
- // Load in another instance of SpellCheckService.
- // The result should be the same.
- SpellcheckService spellcheck_service2(profile_.get());
- WordList loaded_custom_words2;
- spellcheck_service2.GetCustomDictionary()->
- LoadDictionaryIntoCustomWordList(&loaded_custom_words2);
- EXPECT_EQ(loaded_custom_words2, expected);
-
- custom_dictionary->EraseWordFromCustomDictionary("foo");
- custom_dictionary->EraseWordFromCustomDictionary("bar");
- custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words);
+ loaded_custom_words = LoadDictionaryFile(path);
+ EXPECT_EQ(expected, loaded_custom_words);
+
+ change = SpellcheckCustomDictionary::Change();
+ change.RemoveWord("bar");
+ change.RemoveWord("foo");
+ UpdateDictionaryFile(change, path);
+ loaded_custom_words = LoadDictionaryFile(path);
expected.clear();
- EXPECT_EQ(loaded_custom_words, expected);
+ EXPECT_EQ(expected, loaded_custom_words);
// Flush the loop now to prevent service init tasks from being run during
// TearDown();
@@ -142,23 +219,23 @@ TEST_F(SpellcheckCustomDictionaryTest, MultiProfile) {
WordList expected1;
WordList expected2;
- custom_dictionary->WriteWordToCustomDictionary("foo");
- custom_dictionary->WriteWordToCustomDictionary("bar");
+ custom_dictionary->AddWord("foo");
+ custom_dictionary->AddWord("bar");
expected1.push_back("foo");
expected1.push_back("bar");
- custom_dictionary2->WriteWordToCustomDictionary("hoge");
- custom_dictionary2->WriteWordToCustomDictionary("fuga");
+ custom_dictionary2->AddWord("hoge");
+ custom_dictionary2->AddWord("fuga");
expected2.push_back("hoge");
expected2.push_back("fuga");
- WordList actual1;
- custom_dictionary->LoadDictionaryIntoCustomWordList(&actual1);
+ WordList actual1 = custom_dictionary->GetWords();
+ std::sort(actual1.begin(), actual1.end());
std::sort(expected1.begin(), expected1.end());
EXPECT_EQ(actual1, expected1);
- WordList actual2;
- custom_dictionary2->LoadDictionaryIntoCustomWordList(&actual2);
+ WordList actual2 = custom_dictionary2->GetWords();
+ std::sort(actual2.begin(), actual2.end());
std::sort(expected2.begin(), expected2.end());
EXPECT_EQ(actual2, expected2);
@@ -167,19 +244,13 @@ TEST_F(SpellcheckCustomDictionaryTest, MultiProfile) {
MessageLoop::current()->RunUntilIdle();
}
-// Legacy empty dictionary should be converted to new format empty dicitonary.
+// Legacy empty dictionary should be converted to new format empty dictionary.
TEST_F(SpellcheckCustomDictionaryTest, LegacyEmptyDictionaryShouldBeConverted) {
- FilePath dictionary_path(
- profile_->GetPath().Append(chrome::kCustomDictionaryFileName));
- SpellcheckService* spellcheck_service =
- SpellcheckServiceFactory::GetForProfile(profile_.get());
- SpellcheckCustomDictionary* custom_dictionary =
- spellcheck_service->GetCustomDictionary();
- WordList loaded_custom_words;
+ FilePath path = profile_->GetPath().Append(chrome::kCustomDictionaryFileName);
std::string content;
- file_util::WriteFile(dictionary_path, content.c_str(), content.length());
- custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words);
+ file_util::WriteFile(path, content.c_str(), content.length());
+ WordList loaded_custom_words = LoadDictionaryFile(path);
EXPECT_TRUE(loaded_custom_words.empty());
// Flush the loop now to prevent service init tasks from being run during
@@ -191,18 +262,12 @@ TEST_F(SpellcheckCustomDictionaryTest, LegacyEmptyDictionaryShouldBeConverted) {
// with two words.
TEST_F(SpellcheckCustomDictionaryTest,
LegacyDictionaryWithTwoWordsShouldBeConverted) {
- FilePath dictionary_path(
- profile_->GetPath().Append(chrome::kCustomDictionaryFileName));
- SpellcheckService* spellcheck_service =
- SpellcheckServiceFactory::GetForProfile(profile_.get());
- SpellcheckCustomDictionary* custom_dictionary =
- spellcheck_service->GetCustomDictionary();
- WordList loaded_custom_words;
- WordList expected;
+ FilePath path = profile_->GetPath().Append(chrome::kCustomDictionaryFileName);
- std::string content = "foo\nbar";
- file_util::WriteFile(dictionary_path, content.c_str(), content.length());
- custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words);
+ std::string content = "foo\nbar\nfoo\n";
+ file_util::WriteFile(path, content.c_str(), content.length());
+ WordList loaded_custom_words = LoadDictionaryFile(path);
+ WordList expected;
expected.push_back("bar");
expected.push_back("foo");
EXPECT_EQ(expected, loaded_custom_words);
@@ -215,18 +280,12 @@ TEST_F(SpellcheckCustomDictionaryTest,
// Words with spaces are illegal and should be removed.
TEST_F(SpellcheckCustomDictionaryTest,
IllegalWordsShouldBeRemovedFromDictionary) {
- FilePath dictionary_path(
- profile_->GetPath().Append(chrome::kCustomDictionaryFileName));
- SpellcheckService* spellcheck_service =
- SpellcheckServiceFactory::GetForProfile(profile_.get());
- SpellcheckCustomDictionary* custom_dictionary =
- spellcheck_service->GetCustomDictionary();
- WordList loaded_custom_words;
- WordList expected;
+ FilePath path = profile_->GetPath().Append(chrome::kCustomDictionaryFileName);
std::string content = "foo\nfoo bar\nbar\nfoo bar";
- file_util::WriteFile(dictionary_path, content.c_str(), content.length());
- custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words);
+ file_util::WriteFile(path, content.c_str(), content.length());
+ WordList loaded_custom_words = LoadDictionaryFile(path);
+ WordList expected;
expected.push_back("bar");
expected.push_back("foo");
EXPECT_EQ(expected, loaded_custom_words);
@@ -236,35 +295,866 @@ TEST_F(SpellcheckCustomDictionaryTest,
MessageLoop::current()->RunUntilIdle();
}
-// Write to dicitonary should backup previous version and write the word to the
+// Write to dictionary should backup previous version and write the word to the
// end of the dictionary. If the dictionary file is corrupted on disk, the
// previous version should be reloaded.
TEST_F(SpellcheckCustomDictionaryTest, CorruptedWriteShouldBeRecovered) {
- FilePath dictionary_path(
- profile_->GetPath().Append(chrome::kCustomDictionaryFileName));
- SpellcheckService* spellcheck_service =
- SpellcheckServiceFactory::GetForProfile(profile_.get());
- SpellcheckCustomDictionary* custom_dictionary =
- spellcheck_service->GetCustomDictionary();
- WordList loaded_custom_words;
- WordList expected;
+ FilePath path = profile_->GetPath().Append(chrome::kCustomDictionaryFileName);
std::string content = "foo\nbar";
- file_util::WriteFile(dictionary_path, content.c_str(), content.length());
- custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words);
+ file_util::WriteFile(path, content.c_str(), content.length());
+ WordList loaded_custom_words = LoadDictionaryFile(path);
+ WordList expected;
expected.push_back("bar");
expected.push_back("foo");
EXPECT_EQ(expected, loaded_custom_words);
- custom_dictionary->WriteWordToCustomDictionary("baz");
+ SpellcheckCustomDictionary::Change change;
+ change.AddWord("baz");
+ UpdateDictionaryFile(change, path);
content.clear();
- file_util::ReadFileToString(dictionary_path, &content);
+ file_util::ReadFileToString(path, &content);
content.append("corruption");
- file_util::WriteFile(dictionary_path, content.c_str(), content.length());
- custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words);
+ file_util::WriteFile(path, content.c_str(), content.length());
+ loaded_custom_words = LoadDictionaryFile(path);
EXPECT_EQ(expected, loaded_custom_words);
// Flush the loop now to prevent service init tasks from being run during
// TearDown();
MessageLoop::current()->RunUntilIdle();
}
+
+TEST_F(SpellcheckCustomDictionaryTest,
+ GetAllSyncDataAccuratelyReflectsDictionaryState) {
+ SpellcheckCustomDictionary* dictionary =
+ SpellcheckServiceFactory::GetForProfile(
+ profile_.get())->GetCustomDictionary();
+
+ syncer::SyncDataList data = dictionary->GetAllSyncData(syncer::DICTIONARY);
+ EXPECT_TRUE(data.empty());
+
+ EXPECT_TRUE(dictionary->AddWord("foo"));
+ EXPECT_TRUE(dictionary->AddWord("bar"));
+
+ data = dictionary->GetAllSyncData(syncer::DICTIONARY);
+ EXPECT_EQ(2UL, data.size());
+ std::vector<std::string> words;
+ words.push_back("foo");
+ words.push_back("bar");
+ for (size_t i = 0; i < data.size(); i++) {
+ EXPECT_TRUE(data[i].GetSpecifics().has_dictionary());
+ EXPECT_EQ(syncer::DICTIONARY, data[i].GetDataType());
+ EXPECT_EQ(words[i], data[i].GetTag());
+ EXPECT_EQ(words[i], data[i].GetSpecifics().dictionary().word());
+ }
+
+ EXPECT_TRUE(dictionary->RemoveWord("foo"));
+ EXPECT_TRUE(dictionary->RemoveWord("bar"));
+
+ data = dictionary->GetAllSyncData(syncer::DICTIONARY);
+ EXPECT_TRUE(data.empty());
+
+ // Flush the loop now to prevent service init tasks from being run during
+ // TearDown();
+ MessageLoop::current()->RunUntilIdle();
+}
+
+TEST_F(SpellcheckCustomDictionaryTest, GetAllSyncDataHasLimit) {
+ SpellcheckCustomDictionary* dictionary =
+ SpellcheckServiceFactory::GetForProfile(
+ profile_.get())->GetCustomDictionary();
+
+ SpellcheckCustomDictionary::Change change;
+ for (size_t i = 0;
+ i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS - 1;
+ i++) {
+ change.AddWord("foo" + base::Uint64ToString(i));
+ }
+ Apply(*dictionary, change);
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS - 1,
+ dictionary->GetWords().size());
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS - 1,
+ dictionary->GetAllSyncData(syncer::DICTIONARY).size());
+
+ dictionary->AddWord("baz");
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ dictionary->GetWords().size());
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ dictionary->GetAllSyncData(syncer::DICTIONARY).size());
+
+ dictionary->AddWord("bar");
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1,
+ dictionary->GetWords().size());
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ dictionary->GetAllSyncData(syncer::DICTIONARY).size());
+
+ dictionary->AddWord("snafoo");
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 2,
+ dictionary->GetWords().size());
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ dictionary->GetAllSyncData(syncer::DICTIONARY).size());
+
+ // Flush the loop now to prevent service init tasks from being run during
+ // TearDown();
+ MessageLoop::current()->RunUntilIdle();
+}
+
+TEST_F(SpellcheckCustomDictionaryTest, ProcessSyncChanges) {
+ SpellcheckService* spellcheck_service =
+ SpellcheckServiceFactory::GetForProfile(profile_.get());
+ SpellcheckCustomDictionary* dictionary =
+ spellcheck_service->GetCustomDictionary();
+
+ dictionary->AddWord("foo");
+ dictionary->AddWord("bar");
+
+ syncer::SyncChangeList changes;
+ {
+ // Add existing word.
+ std::string word = "foo";
+ sync_pb::EntitySpecifics specifics;
+ specifics.mutable_dictionary()->set_word(word);
+ changes.push_back(syncer::SyncChange(
+ FROM_HERE,
+ syncer::SyncChange::ACTION_ADD,
+ syncer::SyncData::CreateLocalData(word, word, specifics)));
+ }
+ {
+ // Add invalid word.
+ std::string word = "foo bar";
+ sync_pb::EntitySpecifics specifics;
+ specifics.mutable_dictionary()->set_word(word);
+ changes.push_back(syncer::SyncChange(
+ FROM_HERE,
+ syncer::SyncChange::ACTION_ADD,
+ syncer::SyncData::CreateLocalData(word, word, specifics)));
+ }
+ {
+ // Add valid word.
+ std::string word = "baz";
+ sync_pb::EntitySpecifics specifics;
+ specifics.mutable_dictionary()->set_word(word);
+ changes.push_back(syncer::SyncChange(
+ FROM_HERE,
+ syncer::SyncChange::ACTION_ADD,
+ syncer::SyncData::CreateLocalData(word, word, specifics)));
+ }
+ {
+ // Remove missing word.
+ std::string word = "snafoo";
+ sync_pb::EntitySpecifics specifics;
+ specifics.mutable_dictionary()->set_word(word);
+ changes.push_back(syncer::SyncChange(
+ FROM_HERE,
+ syncer::SyncChange::ACTION_DELETE,
+ syncer::SyncData::CreateLocalData(word, word, specifics)));
+ }
+ {
+ // Remove existing word.
+ std::string word = "bar";
+ sync_pb::EntitySpecifics specifics;
+ specifics.mutable_dictionary()->set_word(word);
+ changes.push_back(syncer::SyncChange(
+ FROM_HERE,
+ syncer::SyncChange::ACTION_DELETE,
+ syncer::SyncData::CreateLocalData(word, word, specifics)));
+ }
+
+ EXPECT_FALSE(dictionary->ProcessSyncChanges(FROM_HERE, changes).IsSet());
+
+ const chrome::spellcheck_common::WordList& words = dictionary->GetWords();
+ EXPECT_EQ(2UL, words.size());
+ EXPECT_EQ(words.end(), std::find(words.begin(), words.end(), "bar"));
+ EXPECT_NE(words.end(), std::find(words.begin(), words.end(), "foo"));
+ EXPECT_NE(words.end(), std::find(words.begin(), words.end(), "baz"));
+
+ // Flush the loop now to prevent service init tasks from being run during
+ // TearDown();
+ MessageLoop::current()->RunUntilIdle();
+}
+
+TEST_F(SpellcheckCustomDictionaryTest, MergeDataAndStartSyncing) {
+ SpellcheckService* spellcheck_service =
+ SpellcheckServiceFactory::GetForProfile(profile_.get());
+ SpellcheckCustomDictionary* custom_dictionary =
+ spellcheck_service->GetCustomDictionary();
+ TestingProfile profile2;
+ SpellcheckService* spellcheck_service2 =
+ static_cast<SpellcheckService*>(
+ SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+ &profile2, &BuildSpellcheckService));
+ SpellcheckCustomDictionary* custom_dictionary2 =
+ spellcheck_service2->GetCustomDictionary();
+
+ SpellcheckCustomDictionary::Change change;
+ for (size_t i = 0;
+ i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS / 2;
+ ++i) {
+ change.AddWord("foo" + base::Uint64ToString(i));
+ }
+ Apply(*custom_dictionary, change);
+
+ SpellcheckCustomDictionary::Change change2;
+ for (size_t i = 0;
+ i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS / 2;
+ ++i) {
+ change2.AddWord("bar" + base::Uint64ToString(i));
+ }
+ Apply(*custom_dictionary2, change2);
+
+ int error_counter = 0;
+ EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
+ syncer::DICTIONARY,
+ custom_dictionary2->GetAllSyncData(syncer::DICTIONARY),
+ scoped_ptr<syncer::SyncChangeProcessor>(
+ new SyncChangeProcessorDelegate(custom_dictionary2)),
+ scoped_ptr<syncer::SyncErrorFactory>(
+ new SyncErrorFactoryStub(&error_counter))).error().IsSet());
+ EXPECT_EQ(0, error_counter);
+ EXPECT_TRUE(custom_dictionary->IsSyncing());
+
+ WordList words = custom_dictionary->GetWords();
+ WordList words2 = custom_dictionary2->GetWords();
+ EXPECT_EQ(words.size(), words2.size());
+
+ std::sort(words.begin(), words.end());
+ std::sort(words2.begin(), words2.end());
+ EXPECT_EQ(words, words2);
+
+ // Flush the loop now to prevent service init tasks from being run during
+ // TearDown();
+ MessageLoop::current()->RunUntilIdle();
+}
+
+TEST_F(SpellcheckCustomDictionaryTest, DictionaryTooBigBeforeSyncing) {
+ SpellcheckService* spellcheck_service =
+ SpellcheckServiceFactory::GetForProfile(profile_.get());
+ SpellcheckCustomDictionary* custom_dictionary =
+ spellcheck_service->GetCustomDictionary();
+ TestingProfile profile2;
+ SpellcheckService* spellcheck_service2 =
+ static_cast<SpellcheckService*>(
+ SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+ &profile2, &BuildSpellcheckService));
+ SpellcheckCustomDictionary* custom_dictionary2 =
+ spellcheck_service2->GetCustomDictionary();
+
+ SpellcheckCustomDictionary::Change change;
+ for (size_t i = 0;
+ i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1;
+ ++i) {
+ change.AddWord("foo" + base::Uint64ToString(i));
+ }
+ Apply(*custom_dictionary, change);
+
+ int error_counter = 0;
+ EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
+ syncer::DICTIONARY,
+ custom_dictionary2->GetAllSyncData(syncer::DICTIONARY),
+ scoped_ptr<syncer::SyncChangeProcessor>(
+ new SyncChangeProcessorDelegate(custom_dictionary2)),
+ scoped_ptr<syncer::SyncErrorFactory>(
+ new SyncErrorFactoryStub(&error_counter))).error().IsSet());
+ EXPECT_EQ(0, error_counter);
+ EXPECT_FALSE(custom_dictionary->IsSyncing());
+
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1,
+ custom_dictionary->GetWords().size());
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ custom_dictionary2->GetWords().size());
+
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size());
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ custom_dictionary2->GetAllSyncData(syncer::DICTIONARY).size());
+
+ // Flush the loop now to prevent service init tasks from being run during
+ // TearDown();
+ MessageLoop::current()->RunUntilIdle();
+}
+
+TEST_F(SpellcheckCustomDictionaryTest, DictionaryTooBigAndServerFull) {
+ SpellcheckService* spellcheck_service =
+ SpellcheckServiceFactory::GetForProfile(profile_.get());
+ SpellcheckCustomDictionary* custom_dictionary =
+ spellcheck_service->GetCustomDictionary();
+ TestingProfile profile2;
+ SpellcheckService* spellcheck_service2 =
+ static_cast<SpellcheckService*>(
+ SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+ &profile2, &BuildSpellcheckService));
+ SpellcheckCustomDictionary* custom_dictionary2 =
+ spellcheck_service2->GetCustomDictionary();
+
+ SpellcheckCustomDictionary::Change change;
+ SpellcheckCustomDictionary::Change change2;
+ for (size_t i = 0;
+ i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS;
+ ++i) {
+ change.AddWord("foo" + base::Uint64ToString(i));
+ change2.AddWord("bar" + base::Uint64ToString(i));
+ }
+ change.AddWord("foo");
+ Apply(*custom_dictionary, change);
+ Apply(*custom_dictionary2, change2);
+
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1,
+ custom_dictionary->GetWords().size());
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ custom_dictionary2->GetWords().size());
+
+ int error_counter = 0;
+ EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
+ syncer::DICTIONARY,
+ custom_dictionary2->GetAllSyncData(syncer::DICTIONARY),
+ scoped_ptr<syncer::SyncChangeProcessor>(
+ new SyncChangeProcessorDelegate(custom_dictionary2)),
+ scoped_ptr<syncer::SyncErrorFactory>(
+ new SyncErrorFactoryStub(&error_counter))).error().IsSet());
+ EXPECT_EQ(0, error_counter);
+ EXPECT_FALSE(custom_dictionary->IsSyncing());
+
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS * 2 + 1,
+ custom_dictionary->GetWords().size());
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ custom_dictionary2->GetWords().size());
+
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size());
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ custom_dictionary2->GetAllSyncData(syncer::DICTIONARY).size());
+
+ // Flush the loop now to prevent service init tasks from being run during
+ // TearDown();
+ MessageLoop::current()->RunUntilIdle();
+}
+
+TEST_F(SpellcheckCustomDictionaryTest, ServerTooBig) {
+ SpellcheckService* spellcheck_service =
+ SpellcheckServiceFactory::GetForProfile(profile_.get());
+ SpellcheckCustomDictionary* custom_dictionary =
+ spellcheck_service->GetCustomDictionary();
+ TestingProfile profile2;
+ SpellcheckService* spellcheck_service2 =
+ static_cast<SpellcheckService*>(
+ SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+ &profile2, &BuildSpellcheckService));
+ SpellcheckCustomDictionary* custom_dictionary2 =
+ spellcheck_service2->GetCustomDictionary();
+
+ SpellcheckCustomDictionary::Change change;
+ SpellcheckCustomDictionary::Change change2;
+ for (size_t i = 0;
+ i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1;
+ ++i) {
+ change.AddWord("foo" + base::Uint64ToString(i));
+ change2.AddWord("bar" + base::Uint64ToString(i));
+ }
+ Apply(*custom_dictionary, change);
+ Apply(*custom_dictionary2, change2);
+
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1,
+ custom_dictionary->GetWords().size());
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1,
+ custom_dictionary2->GetWords().size());
+
+ int error_counter = 0;
+ EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
+ syncer::DICTIONARY,
+ GetAllSyncDataNoLimit(custom_dictionary2),
+ scoped_ptr<syncer::SyncChangeProcessor>(
+ new SyncChangeProcessorDelegate(custom_dictionary2)),
+ scoped_ptr<syncer::SyncErrorFactory>(
+ new SyncErrorFactoryStub(&error_counter))).error().IsSet());
+ EXPECT_EQ(0, error_counter);
+ EXPECT_FALSE(custom_dictionary->IsSyncing());
+
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS * 2 + 2,
+ custom_dictionary->GetWords().size());
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1,
+ custom_dictionary2->GetWords().size());
+
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size());
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ custom_dictionary2->GetAllSyncData(syncer::DICTIONARY).size());
+
+ // Flush the loop now to prevent service init tasks from being run during
+ // TearDown();
+ MessageLoop::current()->RunUntilIdle();
+}
+
+TEST_F(SpellcheckCustomDictionaryTest, DictionaryTooBigToStartSyncing) {
+ SpellcheckService* spellcheck_service =
+ SpellcheckServiceFactory::GetForProfile(profile_.get());
+ SpellcheckCustomDictionary* custom_dictionary =
+ spellcheck_service->GetCustomDictionary();
+ TestingProfile profile2;
+ SpellcheckService* spellcheck_service2 =
+ static_cast<SpellcheckService*>(
+ SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+ &profile2, &BuildSpellcheckService));
+ SpellcheckCustomDictionary* custom_dictionary2 =
+ spellcheck_service2->GetCustomDictionary();
+
+ SpellcheckCustomDictionary::Change change;
+ for (size_t i = 0;
+ i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS - 1;
+ ++i) {
+ change.AddWord("foo" + base::Uint64ToString(i));
+ }
+ Apply(*custom_dictionary, change);
+
+ custom_dictionary2->AddWord("bar");
+ custom_dictionary2->AddWord("baz");
+
+ int error_counter = 0;
+ EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
+ syncer::DICTIONARY,
+ custom_dictionary2->GetAllSyncData(syncer::DICTIONARY),
+ scoped_ptr<syncer::SyncChangeProcessor>(
+ new SyncChangeProcessorDelegate(custom_dictionary2)),
+ scoped_ptr<syncer::SyncErrorFactory>(
+ new SyncErrorFactoryStub(&error_counter))).error().IsSet());
+ EXPECT_EQ(0, error_counter);
+ EXPECT_FALSE(custom_dictionary->IsSyncing());
+
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1,
+ custom_dictionary->GetWords().size());
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ custom_dictionary2->GetWords().size());
+
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size());
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ custom_dictionary2->GetAllSyncData(syncer::DICTIONARY).size());
+
+ // Flush the loop now to prevent service init tasks from being run during
+ // TearDown();
+ MessageLoop::current()->RunUntilIdle();
+}
+
+TEST_F(SpellcheckCustomDictionaryTest, DictionaryTooBigToContiueSyncing) {
+ SpellcheckService* spellcheck_service =
+ SpellcheckServiceFactory::GetForProfile(profile_.get());
+ SpellcheckCustomDictionary* custom_dictionary =
+ spellcheck_service->GetCustomDictionary();
+ TestingProfile profile2;
+ SpellcheckService* spellcheck_service2 =
+ static_cast<SpellcheckService*>(
+ SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+ &profile2, &BuildSpellcheckService));
+ SpellcheckCustomDictionary* custom_dictionary2 =
+ spellcheck_service2->GetCustomDictionary();
+
+ SpellcheckCustomDictionary::Change change;
+ for (size_t i = 0;
+ i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS - 1;
+ ++i) {
+ change.AddWord("foo" + base::Uint64ToString(i));
+ }
+ Apply(*custom_dictionary, change);
+
+ int error_counter = 0;
+ EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
+ syncer::DICTIONARY,
+ custom_dictionary2->GetAllSyncData(syncer::DICTIONARY),
+ scoped_ptr<syncer::SyncChangeProcessor>(
+ new SyncChangeProcessorDelegate(custom_dictionary2)),
+ scoped_ptr<syncer::SyncErrorFactory>(
+ new SyncErrorFactoryStub(&error_counter))).error().IsSet());
+ EXPECT_EQ(0, error_counter);
+ EXPECT_TRUE(custom_dictionary->IsSyncing());
+
+ custom_dictionary->AddWord("bar");
+ EXPECT_EQ(0, error_counter);
+ EXPECT_TRUE(custom_dictionary->IsSyncing());
+
+ custom_dictionary->AddWord("baz");
+ EXPECT_EQ(0, error_counter);
+ EXPECT_FALSE(custom_dictionary->IsSyncing());
+
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1,
+ custom_dictionary->GetWords().size());
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ custom_dictionary2->GetWords().size());
+
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size());
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ custom_dictionary2->GetAllSyncData(syncer::DICTIONARY).size());
+
+ // Flush the loop now to prevent service init tasks from being run during
+ // TearDown();
+ MessageLoop::current()->RunUntilIdle();
+}
+
+TEST_F(SpellcheckCustomDictionaryTest, LoadAfterSyncStart) {
+ SpellcheckService* spellcheck_service =
+ SpellcheckServiceFactory::GetForProfile(profile_.get());
+ SpellcheckCustomDictionary* custom_dictionary =
+ spellcheck_service->GetCustomDictionary();
+ TestingProfile profile2;
+ SpellcheckService* spellcheck_service2 =
+ static_cast<SpellcheckService*>(
+ SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+ &profile2, &BuildSpellcheckService));
+ SpellcheckCustomDictionary* custom_dictionary2 =
+ spellcheck_service2->GetCustomDictionary();
+
+ custom_dictionary->AddWord("foo");
+
+ int error_counter = 0;
+ EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
+ syncer::DICTIONARY,
+ custom_dictionary2->GetAllSyncData(syncer::DICTIONARY),
+ scoped_ptr<syncer::SyncChangeProcessor>(
+ new SyncChangeProcessorDelegate(custom_dictionary2)),
+ scoped_ptr<syncer::SyncErrorFactory>(
+ new SyncErrorFactoryStub(&error_counter))).error().IsSet());
+ EXPECT_EQ(0, error_counter);
+ EXPECT_TRUE(custom_dictionary->IsSyncing());
+
+ WordList custom_words;
+ custom_words.push_back("bar");
+ OnLoaded(*custom_dictionary, custom_words);
+ EXPECT_TRUE(custom_dictionary->IsSyncing());
+
+ EXPECT_EQ(2UL, custom_dictionary->GetWords().size());
+ EXPECT_EQ(2UL, custom_dictionary2->GetWords().size());
+
+ EXPECT_EQ(2UL, custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size());
+ EXPECT_EQ(2UL, custom_dictionary2->GetAllSyncData(syncer::DICTIONARY).size());
+
+ // Flush the loop now to prevent service init tasks from being run during
+ // TearDown();
+ MessageLoop::current()->RunUntilIdle();
+}
+
+TEST_F(SpellcheckCustomDictionaryTest, LoadAfterSyncStartTooBigToSync) {
+ SpellcheckService* spellcheck_service =
+ SpellcheckServiceFactory::GetForProfile(profile_.get());
+ SpellcheckCustomDictionary* custom_dictionary =
+ spellcheck_service->GetCustomDictionary();
+ TestingProfile profile2;
+ SpellcheckService* spellcheck_service2 =
+ static_cast<SpellcheckService*>(
+ SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+ &profile2, &BuildSpellcheckService));
+ SpellcheckCustomDictionary* custom_dictionary2 =
+ spellcheck_service2->GetCustomDictionary();
+
+ custom_dictionary->AddWord("foo");
+
+ int error_counter = 0;
+ EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
+ syncer::DICTIONARY,
+ custom_dictionary2->GetAllSyncData(syncer::DICTIONARY),
+ scoped_ptr<syncer::SyncChangeProcessor>(
+ new SyncChangeProcessorDelegate(custom_dictionary2)),
+ scoped_ptr<syncer::SyncErrorFactory>(
+ new SyncErrorFactoryStub(&error_counter))).error().IsSet());
+ EXPECT_EQ(0, error_counter);
+ EXPECT_TRUE(custom_dictionary->IsSyncing());
+
+ WordList custom_words;
+ for (size_t i = 0;
+ i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS;
+ ++i) {
+ custom_words.push_back("foo" + base::Uint64ToString(i));
+ }
+ OnLoaded(*custom_dictionary, custom_words);
+ EXPECT_EQ(0, error_counter);
+ EXPECT_FALSE(custom_dictionary->IsSyncing());
+
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1,
+ custom_dictionary->GetWords().size());
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ custom_dictionary2->GetWords().size());
+
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size());
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ custom_dictionary2->GetAllSyncData(syncer::DICTIONARY).size());
+
+ // Flush the loop now to prevent service init tasks from being run during
+ // TearDown();
+ MessageLoop::current()->RunUntilIdle();
+}
+
+TEST_F(SpellcheckCustomDictionaryTest, LoadDuplicatesAfterSync) {
+ SpellcheckService* spellcheck_service =
+ SpellcheckServiceFactory::GetForProfile(profile_.get());
+ SpellcheckCustomDictionary* custom_dictionary =
+ spellcheck_service->GetCustomDictionary();
+ TestingProfile profile2;
+ SpellcheckService* spellcheck_service2 =
+ static_cast<SpellcheckService*>(
+ SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+ &profile2, &BuildSpellcheckService));
+ SpellcheckCustomDictionary* custom_dictionary2 =
+ spellcheck_service2->GetCustomDictionary();
+
+ WordList to_add;
+ for (size_t i = 0;
+ i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS / 2;
+ ++i) {
+ to_add.push_back("foo" + base::Uint64ToString(i));
+ }
+ Apply(*custom_dictionary, SpellcheckCustomDictionary::Change(to_add));
+
+ int error_counter = 0;
+ EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
+ syncer::DICTIONARY,
+ custom_dictionary2->GetAllSyncData(syncer::DICTIONARY),
+ scoped_ptr<syncer::SyncChangeProcessor>(
+ new SyncChangeProcessorDelegate(custom_dictionary2)),
+ scoped_ptr<syncer::SyncErrorFactory>(
+ new SyncErrorFactoryStub(&error_counter))).error().IsSet());
+ EXPECT_EQ(0, error_counter);
+ EXPECT_TRUE(custom_dictionary->IsSyncing());
+
+ OnLoaded(*custom_dictionary, to_add);
+ EXPECT_EQ(0, error_counter);
+ EXPECT_TRUE(custom_dictionary->IsSyncing());
+
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS / 2,
+ custom_dictionary->GetWords().size());
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS / 2,
+ custom_dictionary2->GetWords().size());
+
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS / 2,
+ custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size());
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS / 2,
+ custom_dictionary2->GetAllSyncData(syncer::DICTIONARY).size());
+
+ // Flush the loop now to prevent service init tasks from being run during
+ // TearDown();
+ MessageLoop::current()->RunUntilIdle();
+}
+
+TEST_F(SpellcheckCustomDictionaryTest, DictionaryLoadNotification) {
+ SpellcheckService* spellcheck_service =
+ SpellcheckServiceFactory::GetForProfile(profile_.get());
+ SpellcheckCustomDictionary* custom_dictionary =
+ spellcheck_service->GetCustomDictionary();
+
+ DictionaryObserverCounter observer;
+ custom_dictionary->AddObserver(&observer);
+
+ WordList custom_words;
+ custom_words.push_back("foo");
+ custom_words.push_back("bar");
+ OnLoaded(*custom_dictionary, custom_words);
+
+ EXPECT_GE(observer.loads(), 1);
+ EXPECT_LE(observer.loads(), 2);
+ EXPECT_EQ(0, observer.changes());
+
+ custom_dictionary->RemoveObserver(&observer);
+
+ // Flush the loop now to prevent service init tasks from being run during
+ // TearDown();
+ MessageLoop::current()->RunUntilIdle();
+}
+
+TEST_F(SpellcheckCustomDictionaryTest, DictionaryAddWordNotification) {
+ SpellcheckService* spellcheck_service =
+ SpellcheckServiceFactory::GetForProfile(profile_.get());
+ SpellcheckCustomDictionary* custom_dictionary =
+ spellcheck_service->GetCustomDictionary();
+
+ OnLoaded(*custom_dictionary, WordList());
+
+ DictionaryObserverCounter observer;
+ custom_dictionary->AddObserver(&observer);
+
+ EXPECT_TRUE(custom_dictionary->AddWord("foo"));
+ EXPECT_TRUE(custom_dictionary->AddWord("bar"));
+ EXPECT_FALSE(custom_dictionary->AddWord("bar"));
+
+ EXPECT_EQ(2, observer.changes());
+
+ custom_dictionary->RemoveObserver(&observer);
+
+ // Flush the loop now to prevent service init tasks from being run during
+ // TearDown();
+ MessageLoop::current()->RunUntilIdle();
+}
+
+TEST_F(SpellcheckCustomDictionaryTest, DictionaryRemoveWordNotification) {
+ SpellcheckService* spellcheck_service =
+ SpellcheckServiceFactory::GetForProfile(profile_.get());
+ SpellcheckCustomDictionary* custom_dictionary =
+ spellcheck_service->GetCustomDictionary();
+
+ OnLoaded(*custom_dictionary, WordList());
+
+ EXPECT_TRUE(custom_dictionary->AddWord("foo"));
+ EXPECT_TRUE(custom_dictionary->AddWord("bar"));
+
+ DictionaryObserverCounter observer;
+ custom_dictionary->AddObserver(&observer);
+
+ EXPECT_TRUE(custom_dictionary->RemoveWord("foo"));
+ EXPECT_TRUE(custom_dictionary->RemoveWord("bar"));
+ EXPECT_FALSE(custom_dictionary->RemoveWord("baz"));
+
+ EXPECT_EQ(2, observer.changes());
+
+ custom_dictionary->RemoveObserver(&observer);
+
+ // Flush the loop now to prevent service init tasks from being run during
+ // TearDown();
+ MessageLoop::current()->RunUntilIdle();
+}
+
+TEST_F(SpellcheckCustomDictionaryTest, DictionarySyncNotification) {
+ SpellcheckService* spellcheck_service =
+ SpellcheckServiceFactory::GetForProfile(profile_.get());
+ SpellcheckCustomDictionary* custom_dictionary =
+ spellcheck_service->GetCustomDictionary();
+ TestingProfile profile2;
+ SpellcheckService* spellcheck_service2 =
+ static_cast<SpellcheckService*>(
+ SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+ &profile2, &BuildSpellcheckService));
+ SpellcheckCustomDictionary* custom_dictionary2 =
+ spellcheck_service2->GetCustomDictionary();
+
+ OnLoaded(*custom_dictionary, WordList());
+ OnLoaded(*custom_dictionary2, WordList());
+
+ custom_dictionary->AddWord("foo");
+ custom_dictionary->AddWord("bar");
+ custom_dictionary2->AddWord("foo");
+ custom_dictionary2->AddWord("baz");
+
+ DictionaryObserverCounter observer;
+ custom_dictionary->AddObserver(&observer);
+
+ DictionaryObserverCounter observer2;
+ custom_dictionary2->AddObserver(&observer2);
+
+ int error_counter = 0;
+ EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
+ syncer::DICTIONARY,
+ custom_dictionary2->GetAllSyncData(syncer::DICTIONARY),
+ scoped_ptr<syncer::SyncChangeProcessor>(
+ new SyncChangeProcessorDelegate(custom_dictionary2)),
+ scoped_ptr<syncer::SyncErrorFactory>(
+ new SyncErrorFactoryStub(&error_counter))).error().IsSet());
+ EXPECT_EQ(0, error_counter);
+ EXPECT_TRUE(custom_dictionary->IsSyncing());
+
+ EXPECT_EQ(1, observer.changes());
+ EXPECT_EQ(1, observer2.changes());
+
+ custom_dictionary->RemoveObserver(&observer);
+ custom_dictionary2->RemoveObserver(&observer2);
+
+ // Flush the loop now to prevent service init tasks from being run during
+ // TearDown();
+ MessageLoop::current()->RunUntilIdle();
+}
+
+// The server has maximum number of words and the client has maximum number of
+// different words before association time. No new words should be pushed to the
+// sync server upon association. The client should accept words from the sync
+// server, however.
+TEST_F(SpellcheckCustomDictionaryTest, DictionarySyncLimit) {
+ TestingProfile server_profile;
+ SpellcheckService* server_spellcheck_service =
+ static_cast<SpellcheckService*>(
+ SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+ &server_profile, &BuildSpellcheckService));
+
+ // Here, |server_custom_dictionary| plays the role of the sync server.
+ SpellcheckCustomDictionary* server_custom_dictionary =
+ server_spellcheck_service->GetCustomDictionary();
+
+ // Upload the maximum number of words to the sync server.
+ {
+ SpellcheckService* spellcheck_service =
+ SpellcheckServiceFactory::GetForProfile(profile_.get());
+ SpellcheckCustomDictionary* custom_dictionary =
+ spellcheck_service->GetCustomDictionary();
+
+ SpellcheckCustomDictionary::Change change;
+ for (size_t i = 0;
+ i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS;
+ ++i) {
+ change.AddWord("foo" + base::Uint64ToString(i));
+ }
+ Apply(*custom_dictionary, change);
+
+ int error_counter = 0;
+ EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
+ syncer::DICTIONARY,
+ server_custom_dictionary->GetAllSyncData(syncer::DICTIONARY),
+ scoped_ptr<syncer::SyncChangeProcessor>(
+ new SyncChangeProcessorDelegate(server_custom_dictionary)),
+ scoped_ptr<syncer::SyncErrorFactory>(
+ new SyncErrorFactoryStub(&error_counter))).error().IsSet());
+ EXPECT_EQ(0, error_counter);
+ EXPECT_TRUE(custom_dictionary->IsSyncing());
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ custom_dictionary->GetWords().size());
+ }
+
+ // The sync server now has the maximum number of words.
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ server_custom_dictionary->GetWords().size());
+
+ // Associate the sync server with a client that also has the maximum number of
+ // words, but all of these words are different from the ones on the sync
+ // server.
+ {
+ TestingProfile client_profile;
+ SpellcheckService* client_spellcheck_service =
+ static_cast<SpellcheckService*>(
+ SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+ &client_profile, &BuildSpellcheckService));
+
+ // Here, |client_custom_dictionary| plays the role of the client.
+ SpellcheckCustomDictionary* client_custom_dictionary =
+ client_spellcheck_service->GetCustomDictionary();
+
+ // Add the maximum number of words to the client. These words are all
+ // different from those on the server.
+ SpellcheckCustomDictionary::Change change;
+ for (size_t i = 0;
+ i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS;
+ ++i) {
+ change.AddWord("bar" + base::Uint64ToString(i));
+ }
+ Apply(*client_custom_dictionary, change);
+
+ // Associate the server and the client.
+ int error_counter = 0;
+ EXPECT_FALSE(client_custom_dictionary->MergeDataAndStartSyncing(
+ syncer::DICTIONARY,
+ server_custom_dictionary->GetAllSyncData(syncer::DICTIONARY),
+ scoped_ptr<syncer::SyncChangeProcessor>(
+ new SyncChangeProcessorDelegate(server_custom_dictionary)),
+ scoped_ptr<syncer::SyncErrorFactory>(
+ new SyncErrorFactoryStub(&error_counter))).error().IsSet());
+ EXPECT_EQ(0, error_counter);
+ EXPECT_FALSE(client_custom_dictionary->IsSyncing());
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS * 2,
+ client_custom_dictionary->GetWords().size());
+
+ // Flush the loop now to prevent service init tasks from being run during
+ // TearDown();
+ MessageLoop::current()->RunUntilIdle();
+ }
+
+ // The sync server should not receive more words, because it has the maximum
+ // number of words already.
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
+ server_custom_dictionary->GetWords().size());
+
+ // Flush the loop now to prevent service init tasks from being run during
+ // TearDown();
+ MessageLoop::current()->RunUntilIdle();
+}

Powered by Google App Engine
This is Rietveld 408576698