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(); |
+} |