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

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

Issue 11445002: Sync user's custom spellcheck dictionary (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/spellchecker/spellcheck_custom_dictionary_unittest.cc
diff --git a/chrome/browser/spellchecker/spellcheck_custom_dictionary_unittest.cc b/chrome/browser/spellchecker/spellcheck_custom_dictionary_unittest.cc
index c890afcaa654000c8bbbc5d2976d013fce33c5bf..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();
+}

Powered by Google App Engine
This is Rietveld 408576698