Chromium Code Reviews| 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..339624d700a484978b44ad6e71be9c2f5f35d774 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,21 @@ |
| #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 { |
| +const size_t LIMIT = 1300; |
|
groby-ooo-7-16
2012/12/19 22:16:00
Please document. Or use a shared constant.
please use gerrit instead
2012/12/22 03:20:19
Done. Using constant in chrome::spellcheck_common.
|
| +} |
| + |
| static ProfileKeyedService* BuildSpellcheckService(Profile* profile) { |
| return new SpellcheckService(profile); |
| } |
| @@ -27,7 +37,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 { |
| @@ -84,40 +94,31 @@ TEST_F(SpellcheckCustomDictionaryTest, CustomWordAddedAndRemovedLocally) { |
| } |
| TEST_F(SpellcheckCustomDictionaryTest, SaveAndLoad) { |
| - SpellcheckService* spellcheck_service = |
| - SpellcheckServiceFactory::GetForProfile(profile_.get()); |
| - SpellcheckCustomDictionary* custom_dictionary = |
| - spellcheck_service->GetCustomDictionary(); |
| - |
| + FilePath path = profile_->GetPath().Append(chrome::kCustomDictionaryFileName); |
| WordList loaded_custom_words; |
| - custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words); |
| + SpellcheckCustomDictionary::LoadDictionaryIntoCustomWordList( |
| + &loaded_custom_words, path); |
| // The custom word list should be empty now. |
| WordList expected; |
| EXPECT_EQ(loaded_custom_words, expected); |
| - custom_dictionary->WriteWordToCustomDictionary("foo"); |
| + SpellcheckCustomDictionary::WriteWordToCustomDictionary("foo", path); |
| expected.push_back("foo"); |
| - custom_dictionary->WriteWordToCustomDictionary("bar"); |
| + SpellcheckCustomDictionary::WriteWordToCustomDictionary("bar", path); |
| expected.push_back("bar"); |
| // The custom word list should include written words. |
| - custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words); |
| + SpellcheckCustomDictionary::LoadDictionaryIntoCustomWordList( |
| + &loaded_custom_words, 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); |
| + SpellcheckCustomDictionary::EraseWordFromCustomDictionary("foo", path); |
| + SpellcheckCustomDictionary::EraseWordFromCustomDictionary("bar", path); |
| + SpellcheckCustomDictionary::LoadDictionaryIntoCustomWordList( |
| + &loaded_custom_words, path); |
| expected.clear(); |
| EXPECT_EQ(loaded_custom_words, expected); |
| @@ -142,23 +143,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,19 +168,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(); |
| + FilePath path = profile_->GetPath().Append(chrome::kCustomDictionaryFileName); |
| WordList loaded_custom_words; |
| 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()); |
| + SpellcheckCustomDictionary::LoadDictionaryIntoCustomWordList( |
| + &loaded_custom_words, path); |
| EXPECT_TRUE(loaded_custom_words.empty()); |
| // Flush the loop now to prevent service init tasks from being run during |
| @@ -191,18 +188,14 @@ 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(); |
| + FilePath path = profile_->GetPath().Append(chrome::kCustomDictionaryFileName); |
| WordList loaded_custom_words; |
| WordList expected; |
| 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()); |
| + SpellcheckCustomDictionary::LoadDictionaryIntoCustomWordList( |
| + &loaded_custom_words, path); |
| expected.push_back("bar"); |
| expected.push_back("foo"); |
| EXPECT_EQ(expected, loaded_custom_words); |
| @@ -215,18 +208,14 @@ 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(); |
| + FilePath path = profile_->GetPath().Append(chrome::kCustomDictionaryFileName); |
| WordList loaded_custom_words; |
| WordList expected; |
| 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()); |
| + SpellcheckCustomDictionary::LoadDictionaryIntoCustomWordList( |
| + &loaded_custom_words, path); |
| expected.push_back("bar"); |
| expected.push_back("foo"); |
| EXPECT_EQ(expected, loaded_custom_words); |
| @@ -236,35 +225,207 @@ 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(); |
| + FilePath path = profile_->GetPath().Append(chrome::kCustomDictionaryFileName); |
| WordList loaded_custom_words; |
| WordList expected; |
| 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()); |
| + SpellcheckCustomDictionary::LoadDictionaryIntoCustomWordList( |
| + &loaded_custom_words, path); |
| expected.push_back("bar"); |
| expected.push_back("foo"); |
| EXPECT_EQ(expected, loaded_custom_words); |
| - custom_dictionary->WriteWordToCustomDictionary("baz"); |
| + SpellcheckCustomDictionary::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); |
| + file_util::WriteFile(path, content.c_str(), content.length()); |
| + SpellcheckCustomDictionary::LoadDictionaryIntoCustomWordList( |
| + &loaded_custom_words, 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->CustomWordAddedLocally("foo")); |
| + EXPECT_TRUE(dictionary->CustomWordAddedLocally("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->CustomWordRemovedLocally("foo")); |
| + EXPECT_TRUE(dictionary->CustomWordRemovedLocally("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(); |
|
groby-ooo-7-16
2012/12/19 22:16:00
Why not run them during TearDown()? It seems _ever
please use gerrit instead
2012/12/22 03:20:19
We need to run RunUntilIdle here before the spellc
|
| +} |
| + |
| +TEST_F(SpellcheckCustomDictionaryTest, GetAllSyncDataHasLimit) { |
| + SpellcheckCustomDictionary* dictionary = |
| + SpellcheckServiceFactory::GetForProfile( |
| + profile_.get())->GetCustomDictionary(); |
| + |
| + for (size_t i = 0; i < LIMIT - 1; i++) { |
| + EXPECT_TRUE(dictionary->CustomWordAddedLocally( |
| + "foo" + base::Uint64ToString(i))); |
| + } |
| + EXPECT_EQ(LIMIT - 1, dictionary->GetWords().size()); |
| + EXPECT_EQ(LIMIT - 1, dictionary->GetAllSyncData(syncer::DICTIONARY).size()); |
| + |
| + EXPECT_TRUE(dictionary->CustomWordAddedLocally("baz")); |
| + EXPECT_EQ(LIMIT, dictionary->GetWords().size()); |
| + EXPECT_EQ(LIMIT, dictionary->GetAllSyncData(syncer::DICTIONARY).size()); |
| + |
| + EXPECT_TRUE(dictionary->CustomWordAddedLocally("bar")); |
| + EXPECT_EQ(LIMIT + 1, dictionary->GetWords().size()); |
| + EXPECT_EQ(LIMIT, dictionary->GetAllSyncData(syncer::DICTIONARY).size()); |
| + |
| + EXPECT_TRUE(dictionary->CustomWordAddedLocally("snafoo")); |
| + EXPECT_EQ(LIMIT + 2, dictionary->GetWords().size()); |
| + EXPECT_EQ(LIMIT, 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(); |
| + |
| + custom_dictionary->AddWord("foo"); |
| + custom_dictionary2->AddWord("bar"); |
| + custom_dictionary2->AddWord("baz"); |
| + |
| + EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing( |
| + syncer::DICTIONARY, |
| + custom_dictionary2->GetAllSyncData(syncer::DICTIONARY), |
| + scoped_ptr<syncer::SyncChangeProcessor>(custom_dictionary2), |
| + scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock)). |
| + error().IsSet()); |
| + custom_dictionary->StopSyncingForTesting(); |
| + |
| + 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(); |
| +} |