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..ed4181d3c3f705b9f31d05dcb2ebc27c791b2d33 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,6 +13,11 @@ |
#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" |
@@ -27,7 +33,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 { |
@@ -47,19 +53,68 @@ 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() {} |
+ |
+ // 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); |
+ } |
- 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); |
-} |
+ private: |
+ SpellcheckCustomDictionary* dictionary_; |
+ DISALLOW_COPY_AND_ASSIGN(SyncChangeProcessorDelegate); |
+}; |
+ |
+// 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() {} |
+ |
+ // 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); |
+ } |
+ |
+ 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_++; } |
+ |
+ private: |
+ int loads_; |
+ int changes_; |
+ DISALLOW_COPY_AND_ASSIGN(DictionaryObserverCounter); |
+}; |
TEST_F(SpellcheckCustomDictionaryTest, CustomWordAddedAndRemovedLocally) { |
SpellcheckService* spellcheck_service = |
@@ -70,11 +125,14 @@ TEST_F(SpellcheckCustomDictionaryTest, CustomWordAddedAndRemovedLocally) { |
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"); |
+ std::sort(expected.begin(), expected.end()); |
EXPECT_EQ(custom_dictionary->GetWords(), expected); |
custom_dictionary->CustomWordRemovedLocally("foo"); |
@@ -84,42 +142,30 @@ TEST_F(SpellcheckCustomDictionaryTest, CustomWordAddedAndRemovedLocally) { |
} |
TEST_F(SpellcheckCustomDictionaryTest, SaveAndLoad) { |
- SpellcheckService* spellcheck_service = |
- SpellcheckServiceFactory::GetForProfile(profile_.get()); |
- SpellcheckCustomDictionary* custom_dictionary = |
- spellcheck_service->GetCustomDictionary(); |
- |
- WordList loaded_custom_words; |
- custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words); |
+ FilePath path = profile_->GetPath().Append(chrome::kCustomDictionaryFileName); |
+ scoped_ptr<WordList> loaded_custom_words = |
+ custom_dictionary::LoadDictionary(path); |
// The custom word list should be empty now. |
WordList expected; |
- EXPECT_EQ(loaded_custom_words, expected); |
+ EXPECT_EQ(expected, *(loaded_custom_words.get())); |
- custom_dictionary->WriteWordToCustomDictionary("foo"); |
+ custom_dictionary::WriteWordToCustomDictionary("foo", path); |
expected.push_back("foo"); |
- custom_dictionary->WriteWordToCustomDictionary("bar"); |
+ custom_dictionary::WriteWordToCustomDictionary("bar", path); |
expected.push_back("bar"); |
// The custom word list should include written words. |
- custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words); |
+ loaded_custom_words = custom_dictionary::LoadDictionary(path); |
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); |
+ EXPECT_EQ(expected, *(loaded_custom_words.get())); |
+ |
+ custom_dictionary::EraseWordFromCustomDictionary("foo", path); |
+ custom_dictionary::EraseWordFromCustomDictionary("bar", path); |
+ loaded_custom_words = custom_dictionary::LoadDictionary(path); |
expected.clear(); |
- EXPECT_EQ(loaded_custom_words, expected); |
+ EXPECT_EQ(expected, *(loaded_custom_words.get())); |
// Flush the loop now to prevent service init tasks from being run during |
// TearDown(); |
@@ -142,23 +188,23 @@ TEST_F(SpellcheckCustomDictionaryTest, MultiProfile) { |
WordList expected1; |
WordList expected2; |
- custom_dictionary->WriteWordToCustomDictionary("foo"); |
- custom_dictionary->WriteWordToCustomDictionary("bar"); |
+ custom_dictionary->CustomWordAddedLocally("foo"); |
+ custom_dictionary->CustomWordAddedLocally("bar"); |
expected1.push_back("foo"); |
expected1.push_back("bar"); |
- custom_dictionary2->WriteWordToCustomDictionary("hoge"); |
- custom_dictionary2->WriteWordToCustomDictionary("fuga"); |
+ custom_dictionary2->CustomWordAddedLocally("hoge"); |
+ custom_dictionary2->CustomWordAddedLocally("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,20 +213,15 @@ 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); |
- EXPECT_TRUE(loaded_custom_words.empty()); |
+ file_util::WriteFile(path, content.c_str(), content.length()); |
+ scoped_ptr<WordList> loaded_custom_words = |
+ custom_dictionary::LoadDictionary(path); |
+ EXPECT_TRUE(loaded_custom_words->empty()); |
// Flush the loop now to prevent service init tasks from being run during |
// TearDown(); |
@@ -191,21 +232,16 @@ 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); |
+ file_util::WriteFile(path, content.c_str(), content.length()); |
+ scoped_ptr<WordList> loaded_custom_words = |
+ custom_dictionary::LoadDictionary(path); |
+ WordList expected; |
expected.push_back("bar"); |
expected.push_back("foo"); |
- EXPECT_EQ(expected, loaded_custom_words); |
+ EXPECT_EQ(expected, *(loaded_custom_words.get())); |
// Flush the loop now to prevent service init tasks from being run during |
// TearDown(); |
@@ -215,54 +251,732 @@ 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()); |
+ scoped_ptr<WordList> loaded_custom_words = |
+ custom_dictionary::LoadDictionary(path); |
+ WordList expected; |
expected.push_back("bar"); |
expected.push_back("foo"); |
- EXPECT_EQ(expected, loaded_custom_words); |
+ EXPECT_EQ(expected, *(loaded_custom_words.get())); |
// Flush the loop now to prevent service init tasks from being run during |
// TearDown(); |
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()); |
+ scoped_ptr<WordList> loaded_custom_words = |
+ custom_dictionary::LoadDictionary(path); |
+ WordList expected; |
expected.push_back("bar"); |
expected.push_back("foo"); |
- EXPECT_EQ(expected, loaded_custom_words); |
+ EXPECT_EQ(expected, *(loaded_custom_words.get())); |
- custom_dictionary->WriteWordToCustomDictionary("baz"); |
+ custom_dictionary::WriteWordToCustomDictionary("baz", 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); |
- EXPECT_EQ(expected, loaded_custom_words); |
+ file_util::WriteFile(path, content.c_str(), content.length()); |
+ loaded_custom_words = custom_dictionary::LoadDictionary(path); |
+ EXPECT_EQ(expected, *(loaded_custom_words.get())); |
+ |
+ // 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()); |
+ |
+ SpellcheckCustomDictionary::Change::Result result; |
+ result = dictionary->CustomWordAddedLocally("foo"); |
+ EXPECT_FALSE(result.detected_duplicate_words()); |
+ EXPECT_FALSE(result.detected_invalid_words()); |
+ |
+ result = dictionary->CustomWordAddedLocally("bar"); |
+ EXPECT_FALSE(result.detected_duplicate_words()); |
+ EXPECT_FALSE(result.detected_invalid_words()); |
+ |
+ data = dictionary->GetAllSyncData(syncer::DICTIONARY); |
+ EXPECT_EQ(2UL, data.size()); |
+ std::vector<std::string> words; |
+ words.push_back("bar"); |
+ words.push_back("foo"); |
+ 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()); |
+ } |
+ |
+ result = dictionary->CustomWordRemovedLocally("foo"); |
+ EXPECT_FALSE(result.detected_missing_words()); |
+ |
+ result = dictionary->CustomWordRemovedLocally("bar"); |
+ EXPECT_FALSE(result.detected_missing_words()); |
+ |
+ 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::Result result; |
+ for (size_t i = 0; |
+ i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS - 1; |
+ i++) { |
+ result = dictionary->CustomWordAddedLocally( |
+ "foo" + base::Uint64ToString(i)); |
+ EXPECT_FALSE(result.detected_duplicate_words()); |
+ EXPECT_FALSE(result.detected_invalid_words()); |
+ } |
+ EXPECT_EQ( |
+ chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS - 1, |
+ dictionary->GetWords().size()); |
+ EXPECT_EQ( |
+ chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS - 1, |
+ dictionary->GetAllSyncData(syncer::DICTIONARY).size()); |
+ |
+ dictionary->CustomWordAddedLocally("baz"); |
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
+ dictionary->GetWords().size()); |
+ EXPECT_EQ( |
+ chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
+ dictionary->GetAllSyncData(syncer::DICTIONARY).size()); |
+ |
+ dictionary->CustomWordAddedLocally("bar"); |
+ EXPECT_EQ( |
+ chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS + 1, |
+ dictionary->GetWords().size()); |
+ EXPECT_EQ( |
+ chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
+ dictionary->GetAllSyncData(syncer::DICTIONARY).size()); |
+ |
+ dictionary->CustomWordAddedLocally("snafoo"); |
+ EXPECT_EQ( |
+ chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS + 2, |
+ dictionary->GetWords().size()); |
+ EXPECT_EQ( |
+ chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_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->CustomWordAddedLocally("foo"); |
+ dictionary->CustomWordAddedLocally("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(); |
+ |
+ for (size_t i = 0; |
+ i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS / 2; |
+ ++i) { |
+ custom_dictionary->CustomWordAddedLocally("foo" + base::Uint64ToString(i)); |
+ } |
+ for (size_t i = 0; |
+ i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS / 2; |
+ ++i) { |
+ custom_dictionary2->CustomWordAddedLocally("bar" + base::Uint64ToString(i)); |
+ } |
+ |
+ 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); |
+ |
+ 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()); |
+ for (size_t i = 0; i < words.size(); ++i) |
+ EXPECT_EQ(words[i], words2[i]); |
+ |
+ // 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(); |
+ |
+ for (size_t i = 0; |
+ i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS + 1; |
+ ++i) { |
+ custom_dictionary->CustomWordAddedLocally("foo" + base::Uint64ToString(i)); |
+ } |
+ |
+ int error_counter = 0; |
+ EXPECT_TRUE(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(1, error_counter); |
+ |
+ EXPECT_EQ( |
+ chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS + 1, |
+ custom_dictionary->GetWords().size()); |
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
+ custom_dictionary2->GetWords().size()); |
+ |
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
+ custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size()); |
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_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(); |
+ |
+ for (size_t i = 0; |
+ i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS - 1; |
+ ++i) { |
+ custom_dictionary->CustomWordAddedLocally("foo" + base::Uint64ToString(i)); |
+ } |
+ custom_dictionary2->CustomWordAddedLocally("bar"); |
+ custom_dictionary2->CustomWordAddedLocally("baz"); |
+ |
+ int error_counter = 0; |
+ EXPECT_TRUE(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(1, error_counter); |
+ |
+ EXPECT_EQ( |
+ chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS + 1, |
+ custom_dictionary->GetWords().size()); |
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
+ custom_dictionary2->GetWords().size()); |
+ |
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
+ custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size()); |
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_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(); |
+ |
+ for (size_t i = 0; |
+ i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS - 1; |
+ ++i) { |
+ custom_dictionary->CustomWordAddedLocally("foo" + base::Uint64ToString(i)); |
+ } |
+ |
+ 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); |
+ |
+ custom_dictionary->CustomWordAddedLocally("bar"); |
+ EXPECT_EQ(0, error_counter); |
+ |
+ custom_dictionary->CustomWordAddedLocally("baz"); |
+ EXPECT_EQ(1, error_counter); |
+ |
+ EXPECT_EQ( |
+ chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS + 1, |
+ custom_dictionary->GetWords().size()); |
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
+ custom_dictionary2->GetWords().size()); |
+ |
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
+ custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size()); |
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_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->CustomWordAddedLocally("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()); |
+ |
+ scoped_ptr<WordList> custom_words(new WordList); |
+ custom_words->push_back("bar"); |
+ custom_dictionary->OnLoaded(custom_words.Pass()); |
+ 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->CustomWordAddedLocally("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()); |
+ |
+ scoped_ptr<WordList> custom_words(new WordList); |
+ for (size_t i = 0; |
+ i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS; |
+ ++i) { |
+ custom_words->push_back("foo" + base::Uint64ToString(i)); |
+ } |
+ custom_dictionary->OnLoaded(custom_words.Pass()); |
+ EXPECT_EQ(1, error_counter); |
+ EXPECT_FALSE(custom_dictionary->IsSyncing()); |
+ |
+ EXPECT_EQ( |
+ chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS + 1, |
+ custom_dictionary->GetWords().size()); |
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
+ custom_dictionary2->GetWords().size()); |
+ |
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
+ custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size()); |
+ EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_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(); |
+ |
+ for (size_t i = 0; |
+ i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS / 2; |
+ ++i) { |
+ custom_dictionary->CustomWordAddedLocally("foo" + base::Uint64ToString(i)); |
+ } |
+ |
+ 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()); |
+ |
+ scoped_ptr<WordList> custom_words(new WordList); |
+ for (size_t i = 0; |
+ i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS / 2; |
+ ++i) { |
+ custom_words->push_back("foo" + base::Uint64ToString(i)); |
+ } |
+ custom_dictionary->OnLoaded(custom_words.Pass()); |
+ EXPECT_EQ(0, error_counter); |
+ EXPECT_TRUE(custom_dictionary->IsSyncing()); |
+ |
+ EXPECT_EQ( |
+ chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS / 2, |
+ custom_dictionary->GetWords().size()); |
+ EXPECT_EQ( |
+ chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS / 2, |
+ custom_dictionary2->GetWords().size()); |
+ |
+ EXPECT_EQ( |
+ chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS / 2, |
+ custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size()); |
+ EXPECT_EQ( |
+ chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_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); |
+ |
+ scoped_ptr<WordList> custom_words(new WordList); |
+ custom_words->push_back("foo"); |
+ custom_words->push_back("bar"); |
+ custom_dictionary->OnLoaded(custom_words.Pass()); |
+ |
+ 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(); |
+ |
+ custom_dictionary->OnLoaded(scoped_ptr<WordList>(new WordList)); |
+ |
+ DictionaryObserverCounter observer; |
+ custom_dictionary->AddObserver(&observer); |
+ |
+ custom_dictionary->AddWord("foo"); |
+ custom_dictionary->AddWord("bar"); |
+ 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, DictionaryWordAddedLocallyNotification) { |
+ SpellcheckService* spellcheck_service = |
+ SpellcheckServiceFactory::GetForProfile(profile_.get()); |
+ SpellcheckCustomDictionary* custom_dictionary = |
+ spellcheck_service->GetCustomDictionary(); |
+ |
+ custom_dictionary->OnLoaded(scoped_ptr<WordList>(new WordList)); |
+ |
+ DictionaryObserverCounter observer; |
+ custom_dictionary->AddObserver(&observer); |
+ |
+ custom_dictionary->CustomWordAddedLocally("foo"); |
+ custom_dictionary->CustomWordAddedLocally("bar"); |
+ custom_dictionary->CustomWordAddedLocally("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(); |
+ |
+ custom_dictionary->OnLoaded(scoped_ptr<WordList>(new WordList)); |
+ |
+ custom_dictionary->AddWord("foo"); |
+ custom_dictionary->AddWord("bar"); |
+ |
+ DictionaryObserverCounter observer; |
+ custom_dictionary->AddObserver(&observer); |
+ |
+ custom_dictionary->RemoveWord("foo"); |
+ custom_dictionary->RemoveWord("bar"); |
+ 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, |
+ DictionaryWordRemovedLocallyNotification) { |
+ SpellcheckService* spellcheck_service = |
+ SpellcheckServiceFactory::GetForProfile(profile_.get()); |
+ SpellcheckCustomDictionary* custom_dictionary = |
+ spellcheck_service->GetCustomDictionary(); |
+ |
+ custom_dictionary->OnLoaded(scoped_ptr<WordList>(new WordList)); |
+ |
+ custom_dictionary->CustomWordAddedLocally("foo"); |
+ custom_dictionary->CustomWordAddedLocally("bar"); |
+ |
+ DictionaryObserverCounter observer; |
+ custom_dictionary->AddObserver(&observer); |
+ |
+ custom_dictionary->CustomWordRemovedLocally("foo"); |
+ custom_dictionary->CustomWordRemovedLocally("bar"); |
+ custom_dictionary->CustomWordRemovedLocally("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(); |
+ |
+ custom_dictionary->OnLoaded(scoped_ptr<WordList>(new WordList)); |
+ custom_dictionary2->OnLoaded(scoped_ptr<WordList>(new WordList)); |
+ |
+ custom_dictionary->CustomWordAddedLocally("foo"); |
+ custom_dictionary->CustomWordAddedLocally("bar"); |
+ custom_dictionary2->CustomWordAddedLocally("foo"); |
+ custom_dictionary2->CustomWordAddedLocally("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(); |