| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <vector> | 5 #include <vector> |
| 6 | 6 |
| 7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
| 8 #include "base/string_number_conversions.h" |
| 8 #include "chrome/browser/spellchecker/spellcheck_custom_dictionary.h" | 9 #include "chrome/browser/spellchecker/spellcheck_custom_dictionary.h" |
| 9 #include "chrome/browser/spellchecker/spellcheck_factory.h" | 10 #include "chrome/browser/spellchecker/spellcheck_factory.h" |
| 10 #include "chrome/browser/spellchecker/spellcheck_service.h" | 11 #include "chrome/browser/spellchecker/spellcheck_service.h" |
| 11 #include "chrome/common/chrome_constants.h" | 12 #include "chrome/common/chrome_constants.h" |
| 12 #include "chrome/common/spellcheck_common.h" | 13 #include "chrome/common/spellcheck_common.h" |
| 13 #include "chrome/test/base/testing_profile.h" | 14 #include "chrome/test/base/testing_profile.h" |
| 14 #include "content/public/test/test_browser_thread.h" | 15 #include "content/public/test/test_browser_thread.h" |
| 16 #include "sync/api/sync_change.h" |
| 17 #include "sync/api/sync_data.h" |
| 18 #include "sync/api/sync_error_factory.h" |
| 19 #include "sync/api/sync_error_factory_mock.h" |
| 20 #include "sync/protocol/sync.pb.h" |
| 15 #include "testing/gmock/include/gmock/gmock.h" | 21 #include "testing/gmock/include/gmock/gmock.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 23 |
| 18 using content::BrowserThread; | 24 using content::BrowserThread; |
| 19 using chrome::spellcheck_common::WordList; | 25 using chrome::spellcheck_common::WordList; |
| 20 | 26 |
| 21 static ProfileKeyedService* BuildSpellcheckService(Profile* profile) { | 27 static ProfileKeyedService* BuildSpellcheckService(Profile* profile) { |
| 22 return new SpellcheckService(profile); | 28 return new SpellcheckService(profile); |
| 23 } | 29 } |
| 24 | 30 |
| 25 class SpellcheckCustomDictionaryTest : public testing::Test { | 31 class SpellcheckCustomDictionaryTest : public testing::Test { |
| 26 protected: | 32 protected: |
| 27 SpellcheckCustomDictionaryTest() | 33 SpellcheckCustomDictionaryTest() |
| 28 : ui_thread_(BrowserThread::UI, &message_loop_), | 34 : ui_thread_(BrowserThread::UI, &message_loop_), |
| 29 file_thread_(BrowserThread::FILE, &message_loop_), | 35 file_thread_(BrowserThread::FILE, &message_loop_), |
| 30 profile_(new TestingProfile()) { | 36 profile_(new TestingProfile) { |
| 31 } | 37 } |
| 32 | 38 |
| 33 void SetUp() OVERRIDE { | 39 void SetUp() OVERRIDE { |
| 34 // Use SetTestingFactoryAndUse to force creation and initialization. | 40 // Use SetTestingFactoryAndUse to force creation and initialization. |
| 35 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse( | 41 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
| 36 profile_.get(), &BuildSpellcheckService); | 42 profile_.get(), &BuildSpellcheckService); |
| 37 } | 43 } |
| 38 | 44 |
| 39 void TearDown() OVERRIDE { | 45 void TearDown() OVERRIDE { |
| 40 MessageLoop::current()->RunUntilIdle(); | 46 MessageLoop::current()->RunUntilIdle(); |
| 41 } | 47 } |
| 42 | 48 |
| 43 MessageLoop message_loop_; | 49 MessageLoop message_loop_; |
| 44 content::TestBrowserThread ui_thread_; | 50 content::TestBrowserThread ui_thread_; |
| 45 content::TestBrowserThread file_thread_; | 51 content::TestBrowserThread file_thread_; |
| 46 | 52 |
| 47 scoped_ptr<TestingProfile> profile_; | 53 scoped_ptr<TestingProfile> profile_; |
| 48 }; | 54 }; |
| 49 | 55 |
| 50 TEST_F(SpellcheckCustomDictionaryTest, SpellcheckSetCustomWordList) { | 56 // A wrapper around SpellcheckCustomDictionary that does not own the wrapped |
| 51 SpellcheckService* spellcheck_service = | 57 // object. An instance of this class can be inside of a scoped pointer safely |
| 52 SpellcheckServiceFactory::GetForProfile(profile_.get()); | 58 // while the dictionary is managed by another scoped pointer. |
| 59 class SyncChangeProcessorDelegate : public syncer::SyncChangeProcessor { |
| 60 public: |
| 61 explicit SyncChangeProcessorDelegate(SpellcheckCustomDictionary* dictionary) |
| 62 : dictionary_(dictionary) {} |
| 63 virtual ~SyncChangeProcessorDelegate() {} |
| 53 | 64 |
| 54 WordList loaded_custom_words; | 65 // Overridden from syncer::SyncChangeProcessor: |
| 55 loaded_custom_words.push_back("foo"); | 66 virtual syncer::SyncError ProcessSyncChanges( |
| 56 loaded_custom_words.push_back("bar"); | 67 const tracked_objects::Location& from_here, |
| 57 WordList expected(loaded_custom_words); | 68 const syncer::SyncChangeList& change_list) OVERRIDE { |
| 58 SpellcheckCustomDictionary* custom_dictionary = | 69 return dictionary_->ProcessSyncChanges(from_here, change_list); |
| 59 spellcheck_service->GetCustomDictionary(); | 70 } |
| 60 custom_dictionary->SetCustomWordList(&loaded_custom_words); | 71 |
| 61 EXPECT_EQ(custom_dictionary->GetWords(), expected); | 72 private: |
| 62 } | 73 SpellcheckCustomDictionary* dictionary_; |
| 74 DISALLOW_COPY_AND_ASSIGN(SyncChangeProcessorDelegate); |
| 75 }; |
| 76 |
| 77 // An implementation of SyncErrorFactory that does not upload the error message |
| 78 // and updates an outside error counter. This lets us know the number of error |
| 79 // messages in an instance of this class after that instance is deleted. |
| 80 class SyncErrorFactoryStub : public syncer::SyncErrorFactory { |
| 81 public: |
| 82 explicit SyncErrorFactoryStub(int* error_counter) |
| 83 : error_counter_(error_counter) {} |
| 84 virtual ~SyncErrorFactoryStub() {} |
| 85 |
| 86 // Overridden from syncer::SyncErrorFactory: |
| 87 virtual syncer::SyncError CreateAndUploadError( |
| 88 const tracked_objects::Location& location, |
| 89 const std::string& message) OVERRIDE { |
| 90 (*error_counter_)++; |
| 91 return syncer::SyncError(location, message, syncer::DICTIONARY); |
| 92 } |
| 93 |
| 94 private: |
| 95 int* error_counter_; |
| 96 DISALLOW_COPY_AND_ASSIGN(SyncErrorFactoryStub); |
| 97 }; |
| 98 |
| 99 // Counts the number of notifications for dictionary load and change. |
| 100 class DictionaryObserverCounter : public SpellcheckCustomDictionary::Observer { |
| 101 public: |
| 102 DictionaryObserverCounter() : loads_(0), changes_(0) {} |
| 103 virtual ~DictionaryObserverCounter() {} |
| 104 |
| 105 int loads() const { return loads_; } |
| 106 int changes() const { return changes_; } |
| 107 |
| 108 // Overridden from SpellcheckCustomDictionary::Observer: |
| 109 virtual void OnCustomDictionaryLoaded() OVERRIDE { loads_++; } |
| 110 virtual void OnCustomDictionaryChanged( |
| 111 const SpellcheckCustomDictionary::Change* change) OVERRIDE { changes_++; } |
| 112 |
| 113 private: |
| 114 int loads_; |
| 115 int changes_; |
| 116 DISALLOW_COPY_AND_ASSIGN(DictionaryObserverCounter); |
| 117 }; |
| 63 | 118 |
| 64 TEST_F(SpellcheckCustomDictionaryTest, CustomWordAddedAndRemovedLocally) { | 119 TEST_F(SpellcheckCustomDictionaryTest, CustomWordAddedAndRemovedLocally) { |
| 65 SpellcheckService* spellcheck_service = | 120 SpellcheckService* spellcheck_service = |
| 66 SpellcheckServiceFactory::GetForProfile(profile_.get()); | 121 SpellcheckServiceFactory::GetForProfile(profile_.get()); |
| 67 | 122 |
| 68 WordList loaded_custom_words; | 123 WordList loaded_custom_words; |
| 69 SpellcheckCustomDictionary* custom_dictionary = | 124 SpellcheckCustomDictionary* custom_dictionary = |
| 70 spellcheck_service->GetCustomDictionary(); | 125 spellcheck_service->GetCustomDictionary(); |
| 71 WordList expected; | 126 WordList expected; |
| 72 EXPECT_EQ(custom_dictionary->GetWords(), expected); | 127 EXPECT_EQ(custom_dictionary->GetWords(), expected); |
| 128 |
| 73 custom_dictionary->CustomWordAddedLocally("foo"); | 129 custom_dictionary->CustomWordAddedLocally("foo"); |
| 74 expected.push_back("foo"); | 130 expected.push_back("foo"); |
| 75 EXPECT_EQ(custom_dictionary->GetWords(), expected); | 131 EXPECT_EQ(custom_dictionary->GetWords(), expected); |
| 132 |
| 76 custom_dictionary->CustomWordAddedLocally("bar"); | 133 custom_dictionary->CustomWordAddedLocally("bar"); |
| 77 expected.push_back("bar"); | 134 expected.push_back("bar"); |
| 135 std::sort(expected.begin(), expected.end()); |
| 78 EXPECT_EQ(custom_dictionary->GetWords(), expected); | 136 EXPECT_EQ(custom_dictionary->GetWords(), expected); |
| 79 | 137 |
| 80 custom_dictionary->CustomWordRemovedLocally("foo"); | 138 custom_dictionary->CustomWordRemovedLocally("foo"); |
| 81 custom_dictionary->CustomWordRemovedLocally("bar"); | 139 custom_dictionary->CustomWordRemovedLocally("bar"); |
| 82 expected.clear(); | 140 expected.clear(); |
| 83 EXPECT_EQ(custom_dictionary->GetWords(), expected); | 141 EXPECT_EQ(custom_dictionary->GetWords(), expected); |
| 84 } | 142 } |
| 85 | 143 |
| 86 TEST_F(SpellcheckCustomDictionaryTest, SaveAndLoad) { | 144 TEST_F(SpellcheckCustomDictionaryTest, SaveAndLoad) { |
| 87 SpellcheckService* spellcheck_service = | 145 FilePath path = profile_->GetPath().Append(chrome::kCustomDictionaryFileName); |
| 88 SpellcheckServiceFactory::GetForProfile(profile_.get()); | 146 scoped_ptr<WordList> loaded_custom_words = |
| 89 SpellcheckCustomDictionary* custom_dictionary = | 147 custom_dictionary::LoadDictionary(path); |
| 90 spellcheck_service->GetCustomDictionary(); | |
| 91 | |
| 92 WordList loaded_custom_words; | |
| 93 custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words); | |
| 94 | 148 |
| 95 // The custom word list should be empty now. | 149 // The custom word list should be empty now. |
| 96 WordList expected; | 150 WordList expected; |
| 97 EXPECT_EQ(loaded_custom_words, expected); | 151 EXPECT_EQ(expected, *(loaded_custom_words.get())); |
| 98 | 152 |
| 99 custom_dictionary->WriteWordToCustomDictionary("foo"); | 153 custom_dictionary::WriteWordToCustomDictionary("foo", path); |
| 100 expected.push_back("foo"); | 154 expected.push_back("foo"); |
| 101 | 155 |
| 102 custom_dictionary->WriteWordToCustomDictionary("bar"); | 156 custom_dictionary::WriteWordToCustomDictionary("bar", path); |
| 103 expected.push_back("bar"); | 157 expected.push_back("bar"); |
| 104 | 158 |
| 105 // The custom word list should include written words. | 159 // The custom word list should include written words. |
| 106 custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words); | 160 loaded_custom_words = custom_dictionary::LoadDictionary(path); |
| 107 std::sort(expected.begin(), expected.end()); | 161 std::sort(expected.begin(), expected.end()); |
| 108 EXPECT_EQ(loaded_custom_words, expected); | 162 EXPECT_EQ(expected, *(loaded_custom_words.get())); |
| 109 | 163 |
| 110 // Load in another instance of SpellCheckService. | 164 custom_dictionary::EraseWordFromCustomDictionary("foo", path); |
| 111 // The result should be the same. | 165 custom_dictionary::EraseWordFromCustomDictionary("bar", path); |
| 112 SpellcheckService spellcheck_service2(profile_.get()); | 166 loaded_custom_words = custom_dictionary::LoadDictionary(path); |
| 113 WordList loaded_custom_words2; | |
| 114 spellcheck_service2.GetCustomDictionary()-> | |
| 115 LoadDictionaryIntoCustomWordList(&loaded_custom_words2); | |
| 116 EXPECT_EQ(loaded_custom_words2, expected); | |
| 117 | |
| 118 custom_dictionary->EraseWordFromCustomDictionary("foo"); | |
| 119 custom_dictionary->EraseWordFromCustomDictionary("bar"); | |
| 120 custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words); | |
| 121 expected.clear(); | 167 expected.clear(); |
| 122 EXPECT_EQ(loaded_custom_words, expected); | 168 EXPECT_EQ(expected, *(loaded_custom_words.get())); |
| 123 | 169 |
| 124 // Flush the loop now to prevent service init tasks from being run during | 170 // Flush the loop now to prevent service init tasks from being run during |
| 125 // TearDown(); | 171 // TearDown(); |
| 126 MessageLoop::current()->RunUntilIdle(); | 172 MessageLoop::current()->RunUntilIdle(); |
| 127 } | 173 } |
| 128 | 174 |
| 129 TEST_F(SpellcheckCustomDictionaryTest, MultiProfile) { | 175 TEST_F(SpellcheckCustomDictionaryTest, MultiProfile) { |
| 130 SpellcheckService* spellcheck_service = | 176 SpellcheckService* spellcheck_service = |
| 131 SpellcheckServiceFactory::GetForProfile(profile_.get()); | 177 SpellcheckServiceFactory::GetForProfile(profile_.get()); |
| 132 SpellcheckCustomDictionary* custom_dictionary = | 178 SpellcheckCustomDictionary* custom_dictionary = |
| 133 spellcheck_service->GetCustomDictionary(); | 179 spellcheck_service->GetCustomDictionary(); |
| 134 TestingProfile profile2; | 180 TestingProfile profile2; |
| 135 SpellcheckService* spellcheck_service2 = | 181 SpellcheckService* spellcheck_service2 = |
| 136 static_cast<SpellcheckService*>( | 182 static_cast<SpellcheckService*>( |
| 137 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse( | 183 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
| 138 &profile2, &BuildSpellcheckService)); | 184 &profile2, &BuildSpellcheckService)); |
| 139 SpellcheckCustomDictionary* custom_dictionary2 = | 185 SpellcheckCustomDictionary* custom_dictionary2 = |
| 140 spellcheck_service2->GetCustomDictionary(); | 186 spellcheck_service2->GetCustomDictionary(); |
| 141 | 187 |
| 142 WordList expected1; | 188 WordList expected1; |
| 143 WordList expected2; | 189 WordList expected2; |
| 144 | 190 |
| 145 custom_dictionary->WriteWordToCustomDictionary("foo"); | 191 custom_dictionary->CustomWordAddedLocally("foo"); |
| 146 custom_dictionary->WriteWordToCustomDictionary("bar"); | 192 custom_dictionary->CustomWordAddedLocally("bar"); |
| 147 expected1.push_back("foo"); | 193 expected1.push_back("foo"); |
| 148 expected1.push_back("bar"); | 194 expected1.push_back("bar"); |
| 149 | 195 |
| 150 custom_dictionary2->WriteWordToCustomDictionary("hoge"); | 196 custom_dictionary2->CustomWordAddedLocally("hoge"); |
| 151 custom_dictionary2->WriteWordToCustomDictionary("fuga"); | 197 custom_dictionary2->CustomWordAddedLocally("fuga"); |
| 152 expected2.push_back("hoge"); | 198 expected2.push_back("hoge"); |
| 153 expected2.push_back("fuga"); | 199 expected2.push_back("fuga"); |
| 154 | 200 |
| 155 WordList actual1; | 201 WordList actual1 = custom_dictionary->GetWords(); |
| 156 custom_dictionary->LoadDictionaryIntoCustomWordList(&actual1); | 202 std::sort(actual1.begin(), actual1.end()); |
| 157 std::sort(expected1.begin(), expected1.end()); | 203 std::sort(expected1.begin(), expected1.end()); |
| 158 EXPECT_EQ(actual1, expected1); | 204 EXPECT_EQ(actual1, expected1); |
| 159 | 205 |
| 160 WordList actual2; | 206 WordList actual2 = custom_dictionary2->GetWords(); |
| 161 custom_dictionary2->LoadDictionaryIntoCustomWordList(&actual2); | 207 std::sort(actual2.begin(), actual2.end()); |
| 162 std::sort(expected2.begin(), expected2.end()); | 208 std::sort(expected2.begin(), expected2.end()); |
| 163 EXPECT_EQ(actual2, expected2); | 209 EXPECT_EQ(actual2, expected2); |
| 164 | 210 |
| 165 // Flush the loop now to prevent service init tasks from being run during | 211 // Flush the loop now to prevent service init tasks from being run during |
| 166 // TearDown(); | 212 // TearDown(); |
| 167 MessageLoop::current()->RunUntilIdle(); | 213 MessageLoop::current()->RunUntilIdle(); |
| 168 } | 214 } |
| 169 | 215 |
| 170 // Legacy empty dictionary should be converted to new format empty dicitonary. | 216 // Legacy empty dictionary should be converted to new format empty dictionary. |
| 171 TEST_F(SpellcheckCustomDictionaryTest, LegacyEmptyDictionaryShouldBeConverted) { | 217 TEST_F(SpellcheckCustomDictionaryTest, LegacyEmptyDictionaryShouldBeConverted) { |
| 172 FilePath dictionary_path( | 218 FilePath path = profile_->GetPath().Append(chrome::kCustomDictionaryFileName); |
| 173 profile_->GetPath().Append(chrome::kCustomDictionaryFileName)); | |
| 174 SpellcheckService* spellcheck_service = | |
| 175 SpellcheckServiceFactory::GetForProfile(profile_.get()); | |
| 176 SpellcheckCustomDictionary* custom_dictionary = | |
| 177 spellcheck_service->GetCustomDictionary(); | |
| 178 WordList loaded_custom_words; | |
| 179 | 219 |
| 180 std::string content; | 220 std::string content; |
| 181 file_util::WriteFile(dictionary_path, content.c_str(), content.length()); | 221 file_util::WriteFile(path, content.c_str(), content.length()); |
| 182 custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words); | 222 scoped_ptr<WordList> loaded_custom_words = |
| 183 EXPECT_TRUE(loaded_custom_words.empty()); | 223 custom_dictionary::LoadDictionary(path); |
| 224 EXPECT_TRUE(loaded_custom_words->empty()); |
| 184 | 225 |
| 185 // Flush the loop now to prevent service init tasks from being run during | 226 // Flush the loop now to prevent service init tasks from being run during |
| 186 // TearDown(); | 227 // TearDown(); |
| 187 MessageLoop::current()->RunUntilIdle(); | 228 MessageLoop::current()->RunUntilIdle(); |
| 188 } | 229 } |
| 189 | 230 |
| 190 // Legacy dictionary with two words should be converted to new format dictionary | 231 // Legacy dictionary with two words should be converted to new format dictionary |
| 191 // with two words. | 232 // with two words. |
| 192 TEST_F(SpellcheckCustomDictionaryTest, | 233 TEST_F(SpellcheckCustomDictionaryTest, |
| 193 LegacyDictionaryWithTwoWordsShouldBeConverted) { | 234 LegacyDictionaryWithTwoWordsShouldBeConverted) { |
| 194 FilePath dictionary_path( | 235 FilePath path = profile_->GetPath().Append(chrome::kCustomDictionaryFileName); |
| 195 profile_->GetPath().Append(chrome::kCustomDictionaryFileName)); | |
| 196 SpellcheckService* spellcheck_service = | |
| 197 SpellcheckServiceFactory::GetForProfile(profile_.get()); | |
| 198 SpellcheckCustomDictionary* custom_dictionary = | |
| 199 spellcheck_service->GetCustomDictionary(); | |
| 200 WordList loaded_custom_words; | |
| 201 WordList expected; | |
| 202 | 236 |
| 203 std::string content = "foo\nbar"; | 237 std::string content = "foo\nbar"; |
| 204 file_util::WriteFile(dictionary_path, content.c_str(), content.length()); | 238 file_util::WriteFile(path, content.c_str(), content.length()); |
| 205 custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words); | 239 scoped_ptr<WordList> loaded_custom_words = |
| 240 custom_dictionary::LoadDictionary(path); |
| 241 WordList expected; |
| 206 expected.push_back("bar"); | 242 expected.push_back("bar"); |
| 207 expected.push_back("foo"); | 243 expected.push_back("foo"); |
| 208 EXPECT_EQ(expected, loaded_custom_words); | 244 EXPECT_EQ(expected, *(loaded_custom_words.get())); |
| 209 | 245 |
| 210 // Flush the loop now to prevent service init tasks from being run during | 246 // Flush the loop now to prevent service init tasks from being run during |
| 211 // TearDown(); | 247 // TearDown(); |
| 212 MessageLoop::current()->RunUntilIdle(); | 248 MessageLoop::current()->RunUntilIdle(); |
| 213 } | 249 } |
| 214 | 250 |
| 215 // Words with spaces are illegal and should be removed. | 251 // Words with spaces are illegal and should be removed. |
| 216 TEST_F(SpellcheckCustomDictionaryTest, | 252 TEST_F(SpellcheckCustomDictionaryTest, |
| 217 IllegalWordsShouldBeRemovedFromDictionary) { | 253 IllegalWordsShouldBeRemovedFromDictionary) { |
| 218 FilePath dictionary_path( | 254 FilePath path = profile_->GetPath().Append(chrome::kCustomDictionaryFileName); |
| 219 profile_->GetPath().Append(chrome::kCustomDictionaryFileName)); | 255 |
| 220 SpellcheckService* spellcheck_service = | 256 std::string content = "foo\nfoo bar\nbar\nfoo bar"; |
| 221 SpellcheckServiceFactory::GetForProfile(profile_.get()); | 257 file_util::WriteFile(path, content.c_str(), content.length()); |
| 222 SpellcheckCustomDictionary* custom_dictionary = | 258 scoped_ptr<WordList> loaded_custom_words = |
| 223 spellcheck_service->GetCustomDictionary(); | 259 custom_dictionary::LoadDictionary(path); |
| 224 WordList loaded_custom_words; | |
| 225 WordList expected; | 260 WordList expected; |
| 226 | |
| 227 std::string content = "foo\nfoo bar\nbar\nfoo bar"; | |
| 228 file_util::WriteFile(dictionary_path, content.c_str(), content.length()); | |
| 229 custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words); | |
| 230 expected.push_back("bar"); | 261 expected.push_back("bar"); |
| 231 expected.push_back("foo"); | 262 expected.push_back("foo"); |
| 232 EXPECT_EQ(expected, loaded_custom_words); | 263 EXPECT_EQ(expected, *(loaded_custom_words.get())); |
| 233 | 264 |
| 234 // Flush the loop now to prevent service init tasks from being run during | 265 // Flush the loop now to prevent service init tasks from being run during |
| 235 // TearDown(); | 266 // TearDown(); |
| 236 MessageLoop::current()->RunUntilIdle(); | 267 MessageLoop::current()->RunUntilIdle(); |
| 237 } | 268 } |
| 238 | 269 |
| 239 // Write to dicitonary should backup previous version and write the word to the | 270 // Write to dictionary should backup previous version and write the word to the |
| 240 // end of the dictionary. If the dictionary file is corrupted on disk, the | 271 // end of the dictionary. If the dictionary file is corrupted on disk, the |
| 241 // previous version should be reloaded. | 272 // previous version should be reloaded. |
| 242 TEST_F(SpellcheckCustomDictionaryTest, CorruptedWriteShouldBeRecovered) { | 273 TEST_F(SpellcheckCustomDictionaryTest, CorruptedWriteShouldBeRecovered) { |
| 243 FilePath dictionary_path( | 274 FilePath path = profile_->GetPath().Append(chrome::kCustomDictionaryFileName); |
| 244 profile_->GetPath().Append(chrome::kCustomDictionaryFileName)); | 275 |
| 245 SpellcheckService* spellcheck_service = | 276 std::string content = "foo\nbar"; |
| 246 SpellcheckServiceFactory::GetForProfile(profile_.get()); | 277 file_util::WriteFile(path, content.c_str(), content.length()); |
| 247 SpellcheckCustomDictionary* custom_dictionary = | 278 scoped_ptr<WordList> loaded_custom_words = |
| 248 spellcheck_service->GetCustomDictionary(); | 279 custom_dictionary::LoadDictionary(path); |
| 249 WordList loaded_custom_words; | |
| 250 WordList expected; | 280 WordList expected; |
| 251 | |
| 252 std::string content = "foo\nbar"; | |
| 253 file_util::WriteFile(dictionary_path, content.c_str(), content.length()); | |
| 254 custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words); | |
| 255 expected.push_back("bar"); | 281 expected.push_back("bar"); |
| 256 expected.push_back("foo"); | 282 expected.push_back("foo"); |
| 257 EXPECT_EQ(expected, loaded_custom_words); | 283 EXPECT_EQ(expected, *(loaded_custom_words.get())); |
| 258 | 284 |
| 259 custom_dictionary->WriteWordToCustomDictionary("baz"); | 285 custom_dictionary::WriteWordToCustomDictionary("baz", path); |
| 260 content.clear(); | 286 content.clear(); |
| 261 file_util::ReadFileToString(dictionary_path, &content); | 287 file_util::ReadFileToString(path, &content); |
| 262 content.append("corruption"); | 288 content.append("corruption"); |
| 263 file_util::WriteFile(dictionary_path, content.c_str(), content.length()); | 289 file_util::WriteFile(path, content.c_str(), content.length()); |
| 264 custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words); | 290 loaded_custom_words = custom_dictionary::LoadDictionary(path); |
| 265 EXPECT_EQ(expected, loaded_custom_words); | 291 EXPECT_EQ(expected, *(loaded_custom_words.get())); |
| 266 | 292 |
| 267 // Flush the loop now to prevent service init tasks from being run during | 293 // Flush the loop now to prevent service init tasks from being run during |
| 268 // TearDown(); | 294 // TearDown(); |
| 295 MessageLoop::current()->RunUntilIdle(); |
| 296 } |
| 297 |
| 298 TEST_F(SpellcheckCustomDictionaryTest, |
| 299 GetAllSyncDataAccuratelyReflectsDictionaryState) { |
| 300 SpellcheckCustomDictionary* dictionary = |
| 301 SpellcheckServiceFactory::GetForProfile( |
| 302 profile_.get())->GetCustomDictionary(); |
| 303 |
| 304 syncer::SyncDataList data = dictionary->GetAllSyncData(syncer::DICTIONARY); |
| 305 EXPECT_TRUE(data.empty()); |
| 306 |
| 307 SpellcheckCustomDictionary::Change::Result result; |
| 308 result = dictionary->CustomWordAddedLocally("foo"); |
| 309 EXPECT_FALSE(result.detected_duplicate_words()); |
| 310 EXPECT_FALSE(result.detected_invalid_words()); |
| 311 |
| 312 result = dictionary->CustomWordAddedLocally("bar"); |
| 313 EXPECT_FALSE(result.detected_duplicate_words()); |
| 314 EXPECT_FALSE(result.detected_invalid_words()); |
| 315 |
| 316 data = dictionary->GetAllSyncData(syncer::DICTIONARY); |
| 317 EXPECT_EQ(2UL, data.size()); |
| 318 std::vector<std::string> words; |
| 319 words.push_back("bar"); |
| 320 words.push_back("foo"); |
| 321 for (size_t i = 0; i < data.size(); i++) { |
| 322 EXPECT_TRUE(data[i].GetSpecifics().has_dictionary()); |
| 323 EXPECT_EQ(syncer::DICTIONARY, data[i].GetDataType()); |
| 324 EXPECT_EQ(words[i], data[i].GetTag()); |
| 325 EXPECT_EQ(words[i], data[i].GetSpecifics().dictionary().word()); |
| 326 } |
| 327 |
| 328 result = dictionary->CustomWordRemovedLocally("foo"); |
| 329 EXPECT_FALSE(result.detected_missing_words()); |
| 330 |
| 331 result = dictionary->CustomWordRemovedLocally("bar"); |
| 332 EXPECT_FALSE(result.detected_missing_words()); |
| 333 |
| 334 data = dictionary->GetAllSyncData(syncer::DICTIONARY); |
| 335 EXPECT_TRUE(data.empty()); |
| 336 |
| 337 // Flush the loop now to prevent service init tasks from being run during |
| 338 // TearDown(); |
| 339 MessageLoop::current()->RunUntilIdle(); |
| 340 } |
| 341 |
| 342 TEST_F(SpellcheckCustomDictionaryTest, GetAllSyncDataHasLimit) { |
| 343 SpellcheckCustomDictionary* dictionary = |
| 344 SpellcheckServiceFactory::GetForProfile( |
| 345 profile_.get())->GetCustomDictionary(); |
| 346 |
| 347 SpellcheckCustomDictionary::Change::Result result; |
| 348 for (size_t i = 0; |
| 349 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS - 1; |
| 350 i++) { |
| 351 result = dictionary->CustomWordAddedLocally( |
| 352 "foo" + base::Uint64ToString(i)); |
| 353 EXPECT_FALSE(result.detected_duplicate_words()); |
| 354 EXPECT_FALSE(result.detected_invalid_words()); |
| 355 } |
| 356 EXPECT_EQ( |
| 357 chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS - 1, |
| 358 dictionary->GetWords().size()); |
| 359 EXPECT_EQ( |
| 360 chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS - 1, |
| 361 dictionary->GetAllSyncData(syncer::DICTIONARY).size()); |
| 362 |
| 363 dictionary->CustomWordAddedLocally("baz"); |
| 364 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
| 365 dictionary->GetWords().size()); |
| 366 EXPECT_EQ( |
| 367 chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
| 368 dictionary->GetAllSyncData(syncer::DICTIONARY).size()); |
| 369 |
| 370 dictionary->CustomWordAddedLocally("bar"); |
| 371 EXPECT_EQ( |
| 372 chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS + 1, |
| 373 dictionary->GetWords().size()); |
| 374 EXPECT_EQ( |
| 375 chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
| 376 dictionary->GetAllSyncData(syncer::DICTIONARY).size()); |
| 377 |
| 378 dictionary->CustomWordAddedLocally("snafoo"); |
| 379 EXPECT_EQ( |
| 380 chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS + 2, |
| 381 dictionary->GetWords().size()); |
| 382 EXPECT_EQ( |
| 383 chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
| 384 dictionary->GetAllSyncData(syncer::DICTIONARY).size()); |
| 385 |
| 386 // Flush the loop now to prevent service init tasks from being run during |
| 387 // TearDown(); |
| 388 MessageLoop::current()->RunUntilIdle(); |
| 389 } |
| 390 |
| 391 TEST_F(SpellcheckCustomDictionaryTest, ProcessSyncChanges) { |
| 392 SpellcheckService* spellcheck_service = |
| 393 SpellcheckServiceFactory::GetForProfile(profile_.get()); |
| 394 SpellcheckCustomDictionary* dictionary = |
| 395 spellcheck_service->GetCustomDictionary(); |
| 396 |
| 397 dictionary->CustomWordAddedLocally("foo"); |
| 398 dictionary->CustomWordAddedLocally("bar"); |
| 399 |
| 400 syncer::SyncChangeList changes; |
| 401 { |
| 402 // Add existing word. |
| 403 std::string word = "foo"; |
| 404 sync_pb::EntitySpecifics specifics; |
| 405 specifics.mutable_dictionary()->set_word(word); |
| 406 changes.push_back(syncer::SyncChange( |
| 407 FROM_HERE, |
| 408 syncer::SyncChange::ACTION_ADD, |
| 409 syncer::SyncData::CreateLocalData(word, word, specifics))); |
| 410 } |
| 411 { |
| 412 // Add invalid word. |
| 413 std::string word = "foo bar"; |
| 414 sync_pb::EntitySpecifics specifics; |
| 415 specifics.mutable_dictionary()->set_word(word); |
| 416 changes.push_back(syncer::SyncChange( |
| 417 FROM_HERE, |
| 418 syncer::SyncChange::ACTION_ADD, |
| 419 syncer::SyncData::CreateLocalData(word, word, specifics))); |
| 420 } |
| 421 { |
| 422 // Add valid word. |
| 423 std::string word = "baz"; |
| 424 sync_pb::EntitySpecifics specifics; |
| 425 specifics.mutable_dictionary()->set_word(word); |
| 426 changes.push_back(syncer::SyncChange( |
| 427 FROM_HERE, |
| 428 syncer::SyncChange::ACTION_ADD, |
| 429 syncer::SyncData::CreateLocalData(word, word, specifics))); |
| 430 } |
| 431 { |
| 432 // Remove missing word. |
| 433 std::string word = "snafoo"; |
| 434 sync_pb::EntitySpecifics specifics; |
| 435 specifics.mutable_dictionary()->set_word(word); |
| 436 changes.push_back(syncer::SyncChange( |
| 437 FROM_HERE, |
| 438 syncer::SyncChange::ACTION_DELETE, |
| 439 syncer::SyncData::CreateLocalData(word, word, specifics))); |
| 440 } |
| 441 { |
| 442 // Remove existing word. |
| 443 std::string word = "bar"; |
| 444 sync_pb::EntitySpecifics specifics; |
| 445 specifics.mutable_dictionary()->set_word(word); |
| 446 changes.push_back(syncer::SyncChange( |
| 447 FROM_HERE, |
| 448 syncer::SyncChange::ACTION_DELETE, |
| 449 syncer::SyncData::CreateLocalData(word, word, specifics))); |
| 450 } |
| 451 |
| 452 EXPECT_FALSE(dictionary->ProcessSyncChanges(FROM_HERE, changes).IsSet()); |
| 453 |
| 454 const chrome::spellcheck_common::WordList& words = dictionary->GetWords(); |
| 455 EXPECT_EQ(2UL, words.size()); |
| 456 EXPECT_EQ(words.end(), std::find(words.begin(), words.end(), "bar")); |
| 457 EXPECT_NE(words.end(), std::find(words.begin(), words.end(), "foo")); |
| 458 EXPECT_NE(words.end(), std::find(words.begin(), words.end(), "baz")); |
| 459 |
| 460 // Flush the loop now to prevent service init tasks from being run during |
| 461 // TearDown(); |
| 462 MessageLoop::current()->RunUntilIdle(); |
| 463 } |
| 464 |
| 465 TEST_F(SpellcheckCustomDictionaryTest, MergeDataAndStartSyncing) { |
| 466 SpellcheckService* spellcheck_service = |
| 467 SpellcheckServiceFactory::GetForProfile(profile_.get()); |
| 468 SpellcheckCustomDictionary* custom_dictionary = |
| 469 spellcheck_service->GetCustomDictionary(); |
| 470 TestingProfile profile2; |
| 471 SpellcheckService* spellcheck_service2 = |
| 472 static_cast<SpellcheckService*>( |
| 473 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
| 474 &profile2, &BuildSpellcheckService)); |
| 475 SpellcheckCustomDictionary* custom_dictionary2 = |
| 476 spellcheck_service2->GetCustomDictionary(); |
| 477 |
| 478 for (size_t i = 0; |
| 479 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS / 2; |
| 480 ++i) { |
| 481 custom_dictionary->CustomWordAddedLocally("foo" + base::Uint64ToString(i)); |
| 482 } |
| 483 for (size_t i = 0; |
| 484 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS / 2; |
| 485 ++i) { |
| 486 custom_dictionary2->CustomWordAddedLocally("bar" + base::Uint64ToString(i)); |
| 487 } |
| 488 |
| 489 int error_counter = 0; |
| 490 EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing( |
| 491 syncer::DICTIONARY, |
| 492 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY), |
| 493 scoped_ptr<syncer::SyncChangeProcessor>( |
| 494 new SyncChangeProcessorDelegate(custom_dictionary2)), |
| 495 scoped_ptr<syncer::SyncErrorFactory>( |
| 496 new SyncErrorFactoryStub(&error_counter))).error().IsSet()); |
| 497 EXPECT_EQ(0, error_counter); |
| 498 |
| 499 WordList words = custom_dictionary->GetWords(); |
| 500 WordList words2 = custom_dictionary2->GetWords(); |
| 501 EXPECT_EQ(words.size(), words2.size()); |
| 502 |
| 503 std::sort(words.begin(), words.end()); |
| 504 std::sort(words2.begin(), words2.end()); |
| 505 for (size_t i = 0; i < words.size(); ++i) |
| 506 EXPECT_EQ(words[i], words2[i]); |
| 507 |
| 508 // Flush the loop now to prevent service init tasks from being run during |
| 509 // TearDown(); |
| 510 MessageLoop::current()->RunUntilIdle(); |
| 511 } |
| 512 |
| 513 TEST_F(SpellcheckCustomDictionaryTest, DictionaryTooBigBeforeSyncing) { |
| 514 SpellcheckService* spellcheck_service = |
| 515 SpellcheckServiceFactory::GetForProfile(profile_.get()); |
| 516 SpellcheckCustomDictionary* custom_dictionary = |
| 517 spellcheck_service->GetCustomDictionary(); |
| 518 TestingProfile profile2; |
| 519 SpellcheckService* spellcheck_service2 = |
| 520 static_cast<SpellcheckService*>( |
| 521 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
| 522 &profile2, &BuildSpellcheckService)); |
| 523 SpellcheckCustomDictionary* custom_dictionary2 = |
| 524 spellcheck_service2->GetCustomDictionary(); |
| 525 |
| 526 for (size_t i = 0; |
| 527 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS + 1; |
| 528 ++i) { |
| 529 custom_dictionary->CustomWordAddedLocally("foo" + base::Uint64ToString(i)); |
| 530 } |
| 531 |
| 532 int error_counter = 0; |
| 533 EXPECT_TRUE(custom_dictionary->MergeDataAndStartSyncing( |
| 534 syncer::DICTIONARY, |
| 535 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY), |
| 536 scoped_ptr<syncer::SyncChangeProcessor>( |
| 537 new SyncChangeProcessorDelegate(custom_dictionary2)), |
| 538 scoped_ptr<syncer::SyncErrorFactory>( |
| 539 new SyncErrorFactoryStub(&error_counter))).error().IsSet()); |
| 540 EXPECT_EQ(1, error_counter); |
| 541 |
| 542 EXPECT_EQ( |
| 543 chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS + 1, |
| 544 custom_dictionary->GetWords().size()); |
| 545 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
| 546 custom_dictionary2->GetWords().size()); |
| 547 |
| 548 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
| 549 custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size()); |
| 550 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
| 551 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY).size()); |
| 552 |
| 553 // Flush the loop now to prevent service init tasks from being run during |
| 554 // TearDown(); |
| 555 MessageLoop::current()->RunUntilIdle(); |
| 556 } |
| 557 |
| 558 TEST_F(SpellcheckCustomDictionaryTest, DictionaryTooBigToStartSyncing) { |
| 559 SpellcheckService* spellcheck_service = |
| 560 SpellcheckServiceFactory::GetForProfile(profile_.get()); |
| 561 SpellcheckCustomDictionary* custom_dictionary = |
| 562 spellcheck_service->GetCustomDictionary(); |
| 563 TestingProfile profile2; |
| 564 SpellcheckService* spellcheck_service2 = |
| 565 static_cast<SpellcheckService*>( |
| 566 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
| 567 &profile2, &BuildSpellcheckService)); |
| 568 SpellcheckCustomDictionary* custom_dictionary2 = |
| 569 spellcheck_service2->GetCustomDictionary(); |
| 570 |
| 571 for (size_t i = 0; |
| 572 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS - 1; |
| 573 ++i) { |
| 574 custom_dictionary->CustomWordAddedLocally("foo" + base::Uint64ToString(i)); |
| 575 } |
| 576 custom_dictionary2->CustomWordAddedLocally("bar"); |
| 577 custom_dictionary2->CustomWordAddedLocally("baz"); |
| 578 |
| 579 int error_counter = 0; |
| 580 EXPECT_TRUE(custom_dictionary->MergeDataAndStartSyncing( |
| 581 syncer::DICTIONARY, |
| 582 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY), |
| 583 scoped_ptr<syncer::SyncChangeProcessor>( |
| 584 new SyncChangeProcessorDelegate(custom_dictionary2)), |
| 585 scoped_ptr<syncer::SyncErrorFactory>( |
| 586 new SyncErrorFactoryStub(&error_counter))).error().IsSet()); |
| 587 EXPECT_EQ(1, error_counter); |
| 588 |
| 589 EXPECT_EQ( |
| 590 chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS + 1, |
| 591 custom_dictionary->GetWords().size()); |
| 592 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
| 593 custom_dictionary2->GetWords().size()); |
| 594 |
| 595 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
| 596 custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size()); |
| 597 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
| 598 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY).size()); |
| 599 |
| 600 // Flush the loop now to prevent service init tasks from being run during |
| 601 // TearDown(); |
| 602 MessageLoop::current()->RunUntilIdle(); |
| 603 } |
| 604 |
| 605 TEST_F(SpellcheckCustomDictionaryTest, DictionaryTooBigToContiueSyncing) { |
| 606 SpellcheckService* spellcheck_service = |
| 607 SpellcheckServiceFactory::GetForProfile(profile_.get()); |
| 608 SpellcheckCustomDictionary* custom_dictionary = |
| 609 spellcheck_service->GetCustomDictionary(); |
| 610 TestingProfile profile2; |
| 611 SpellcheckService* spellcheck_service2 = |
| 612 static_cast<SpellcheckService*>( |
| 613 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
| 614 &profile2, &BuildSpellcheckService)); |
| 615 SpellcheckCustomDictionary* custom_dictionary2 = |
| 616 spellcheck_service2->GetCustomDictionary(); |
| 617 |
| 618 for (size_t i = 0; |
| 619 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS - 1; |
| 620 ++i) { |
| 621 custom_dictionary->CustomWordAddedLocally("foo" + base::Uint64ToString(i)); |
| 622 } |
| 623 |
| 624 int error_counter = 0; |
| 625 EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing( |
| 626 syncer::DICTIONARY, |
| 627 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY), |
| 628 scoped_ptr<syncer::SyncChangeProcessor>( |
| 629 new SyncChangeProcessorDelegate(custom_dictionary2)), |
| 630 scoped_ptr<syncer::SyncErrorFactory>( |
| 631 new SyncErrorFactoryStub(&error_counter))).error().IsSet()); |
| 632 EXPECT_EQ(0, error_counter); |
| 633 |
| 634 custom_dictionary->CustomWordAddedLocally("bar"); |
| 635 EXPECT_EQ(0, error_counter); |
| 636 |
| 637 custom_dictionary->CustomWordAddedLocally("baz"); |
| 638 EXPECT_EQ(1, error_counter); |
| 639 |
| 640 EXPECT_EQ( |
| 641 chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS + 1, |
| 642 custom_dictionary->GetWords().size()); |
| 643 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
| 644 custom_dictionary2->GetWords().size()); |
| 645 |
| 646 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
| 647 custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size()); |
| 648 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
| 649 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY).size()); |
| 650 |
| 651 // Flush the loop now to prevent service init tasks from being run during |
| 652 // TearDown(); |
| 653 MessageLoop::current()->RunUntilIdle(); |
| 654 } |
| 655 |
| 656 TEST_F(SpellcheckCustomDictionaryTest, LoadAfterSyncStart) { |
| 657 SpellcheckService* spellcheck_service = |
| 658 SpellcheckServiceFactory::GetForProfile(profile_.get()); |
| 659 SpellcheckCustomDictionary* custom_dictionary = |
| 660 spellcheck_service->GetCustomDictionary(); |
| 661 TestingProfile profile2; |
| 662 SpellcheckService* spellcheck_service2 = |
| 663 static_cast<SpellcheckService*>( |
| 664 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
| 665 &profile2, &BuildSpellcheckService)); |
| 666 SpellcheckCustomDictionary* custom_dictionary2 = |
| 667 spellcheck_service2->GetCustomDictionary(); |
| 668 |
| 669 custom_dictionary->CustomWordAddedLocally("foo"); |
| 670 |
| 671 int error_counter = 0; |
| 672 EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing( |
| 673 syncer::DICTIONARY, |
| 674 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY), |
| 675 scoped_ptr<syncer::SyncChangeProcessor>( |
| 676 new SyncChangeProcessorDelegate(custom_dictionary2)), |
| 677 scoped_ptr<syncer::SyncErrorFactory>( |
| 678 new SyncErrorFactoryStub(&error_counter))).error().IsSet()); |
| 679 EXPECT_EQ(0, error_counter); |
| 680 EXPECT_TRUE(custom_dictionary->IsSyncing()); |
| 681 |
| 682 scoped_ptr<WordList> custom_words(new WordList); |
| 683 custom_words->push_back("bar"); |
| 684 custom_dictionary->OnLoaded(custom_words.Pass()); |
| 685 EXPECT_TRUE(custom_dictionary->IsSyncing()); |
| 686 |
| 687 EXPECT_EQ(2UL, custom_dictionary->GetWords().size()); |
| 688 EXPECT_EQ(2UL, custom_dictionary2->GetWords().size()); |
| 689 |
| 690 EXPECT_EQ(2UL, custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size()); |
| 691 EXPECT_EQ(2UL, custom_dictionary2->GetAllSyncData(syncer::DICTIONARY).size()); |
| 692 |
| 693 // Flush the loop now to prevent service init tasks from being run during |
| 694 // TearDown(); |
| 695 MessageLoop::current()->RunUntilIdle(); |
| 696 } |
| 697 |
| 698 TEST_F(SpellcheckCustomDictionaryTest, LoadAfterSyncStartTooBigToSync) { |
| 699 SpellcheckService* spellcheck_service = |
| 700 SpellcheckServiceFactory::GetForProfile(profile_.get()); |
| 701 SpellcheckCustomDictionary* custom_dictionary = |
| 702 spellcheck_service->GetCustomDictionary(); |
| 703 TestingProfile profile2; |
| 704 SpellcheckService* spellcheck_service2 = |
| 705 static_cast<SpellcheckService*>( |
| 706 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
| 707 &profile2, &BuildSpellcheckService)); |
| 708 SpellcheckCustomDictionary* custom_dictionary2 = |
| 709 spellcheck_service2->GetCustomDictionary(); |
| 710 |
| 711 custom_dictionary->CustomWordAddedLocally("foo"); |
| 712 |
| 713 int error_counter = 0; |
| 714 EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing( |
| 715 syncer::DICTIONARY, |
| 716 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY), |
| 717 scoped_ptr<syncer::SyncChangeProcessor>( |
| 718 new SyncChangeProcessorDelegate(custom_dictionary2)), |
| 719 scoped_ptr<syncer::SyncErrorFactory>( |
| 720 new SyncErrorFactoryStub(&error_counter))).error().IsSet()); |
| 721 EXPECT_EQ(0, error_counter); |
| 722 EXPECT_TRUE(custom_dictionary->IsSyncing()); |
| 723 |
| 724 scoped_ptr<WordList> custom_words(new WordList); |
| 725 for (size_t i = 0; |
| 726 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS; |
| 727 ++i) { |
| 728 custom_words->push_back("foo" + base::Uint64ToString(i)); |
| 729 } |
| 730 custom_dictionary->OnLoaded(custom_words.Pass()); |
| 731 EXPECT_EQ(1, error_counter); |
| 732 EXPECT_FALSE(custom_dictionary->IsSyncing()); |
| 733 |
| 734 EXPECT_EQ( |
| 735 chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS + 1, |
| 736 custom_dictionary->GetWords().size()); |
| 737 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
| 738 custom_dictionary2->GetWords().size()); |
| 739 |
| 740 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
| 741 custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size()); |
| 742 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS, |
| 743 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY).size()); |
| 744 |
| 745 // Flush the loop now to prevent service init tasks from being run during |
| 746 // TearDown(); |
| 747 MessageLoop::current()->RunUntilIdle(); |
| 748 } |
| 749 |
| 750 TEST_F(SpellcheckCustomDictionaryTest, LoadDuplicatesAfterSync) { |
| 751 SpellcheckService* spellcheck_service = |
| 752 SpellcheckServiceFactory::GetForProfile(profile_.get()); |
| 753 SpellcheckCustomDictionary* custom_dictionary = |
| 754 spellcheck_service->GetCustomDictionary(); |
| 755 TestingProfile profile2; |
| 756 SpellcheckService* spellcheck_service2 = |
| 757 static_cast<SpellcheckService*>( |
| 758 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
| 759 &profile2, &BuildSpellcheckService)); |
| 760 SpellcheckCustomDictionary* custom_dictionary2 = |
| 761 spellcheck_service2->GetCustomDictionary(); |
| 762 |
| 763 for (size_t i = 0; |
| 764 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS / 2; |
| 765 ++i) { |
| 766 custom_dictionary->CustomWordAddedLocally("foo" + base::Uint64ToString(i)); |
| 767 } |
| 768 |
| 769 int error_counter = 0; |
| 770 EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing( |
| 771 syncer::DICTIONARY, |
| 772 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY), |
| 773 scoped_ptr<syncer::SyncChangeProcessor>( |
| 774 new SyncChangeProcessorDelegate(custom_dictionary2)), |
| 775 scoped_ptr<syncer::SyncErrorFactory>( |
| 776 new SyncErrorFactoryStub(&error_counter))).error().IsSet()); |
| 777 EXPECT_EQ(0, error_counter); |
| 778 EXPECT_TRUE(custom_dictionary->IsSyncing()); |
| 779 |
| 780 scoped_ptr<WordList> custom_words(new WordList); |
| 781 for (size_t i = 0; |
| 782 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS / 2; |
| 783 ++i) { |
| 784 custom_words->push_back("foo" + base::Uint64ToString(i)); |
| 785 } |
| 786 custom_dictionary->OnLoaded(custom_words.Pass()); |
| 787 EXPECT_EQ(0, error_counter); |
| 788 EXPECT_TRUE(custom_dictionary->IsSyncing()); |
| 789 |
| 790 EXPECT_EQ( |
| 791 chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS / 2, |
| 792 custom_dictionary->GetWords().size()); |
| 793 EXPECT_EQ( |
| 794 chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS / 2, |
| 795 custom_dictionary2->GetWords().size()); |
| 796 |
| 797 EXPECT_EQ( |
| 798 chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS / 2, |
| 799 custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size()); |
| 800 EXPECT_EQ( |
| 801 chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_SIZE_IN_WORDS / 2, |
| 802 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY).size()); |
| 803 |
| 804 // Flush the loop now to prevent service init tasks from being run during |
| 805 // TearDown(); |
| 806 MessageLoop::current()->RunUntilIdle(); |
| 807 } |
| 808 |
| 809 TEST_F(SpellcheckCustomDictionaryTest, DictionaryLoadNotification) { |
| 810 SpellcheckService* spellcheck_service = |
| 811 SpellcheckServiceFactory::GetForProfile(profile_.get()); |
| 812 SpellcheckCustomDictionary* custom_dictionary = |
| 813 spellcheck_service->GetCustomDictionary(); |
| 814 |
| 815 DictionaryObserverCounter observer; |
| 816 custom_dictionary->AddObserver(&observer); |
| 817 |
| 818 scoped_ptr<WordList> custom_words(new WordList); |
| 819 custom_words->push_back("foo"); |
| 820 custom_words->push_back("bar"); |
| 821 custom_dictionary->OnLoaded(custom_words.Pass()); |
| 822 |
| 823 EXPECT_GE(observer.loads(), 1); |
| 824 EXPECT_LE(observer.loads(), 2); |
| 825 EXPECT_EQ(0, observer.changes()); |
| 826 |
| 827 custom_dictionary->RemoveObserver(&observer); |
| 828 |
| 829 // Flush the loop now to prevent service init tasks from being run during |
| 830 // TearDown(); |
| 831 MessageLoop::current()->RunUntilIdle(); |
| 832 } |
| 833 |
| 834 TEST_F(SpellcheckCustomDictionaryTest, DictionaryAddWordNotification) { |
| 835 SpellcheckService* spellcheck_service = |
| 836 SpellcheckServiceFactory::GetForProfile(profile_.get()); |
| 837 SpellcheckCustomDictionary* custom_dictionary = |
| 838 spellcheck_service->GetCustomDictionary(); |
| 839 |
| 840 custom_dictionary->OnLoaded(scoped_ptr<WordList>(new WordList)); |
| 841 |
| 842 DictionaryObserverCounter observer; |
| 843 custom_dictionary->AddObserver(&observer); |
| 844 |
| 845 custom_dictionary->AddWord("foo"); |
| 846 custom_dictionary->AddWord("bar"); |
| 847 custom_dictionary->AddWord("bar"); |
| 848 |
| 849 EXPECT_EQ(2, observer.changes()); |
| 850 |
| 851 custom_dictionary->RemoveObserver(&observer); |
| 852 |
| 853 // Flush the loop now to prevent service init tasks from being run during |
| 854 // TearDown(); |
| 855 MessageLoop::current()->RunUntilIdle(); |
| 856 } |
| 857 |
| 858 TEST_F(SpellcheckCustomDictionaryTest, DictionaryWordAddedLocallyNotification) { |
| 859 SpellcheckService* spellcheck_service = |
| 860 SpellcheckServiceFactory::GetForProfile(profile_.get()); |
| 861 SpellcheckCustomDictionary* custom_dictionary = |
| 862 spellcheck_service->GetCustomDictionary(); |
| 863 |
| 864 custom_dictionary->OnLoaded(scoped_ptr<WordList>(new WordList)); |
| 865 |
| 866 DictionaryObserverCounter observer; |
| 867 custom_dictionary->AddObserver(&observer); |
| 868 |
| 869 custom_dictionary->CustomWordAddedLocally("foo"); |
| 870 custom_dictionary->CustomWordAddedLocally("bar"); |
| 871 custom_dictionary->CustomWordAddedLocally("bar"); |
| 872 |
| 873 EXPECT_EQ(2, observer.changes()); |
| 874 |
| 875 custom_dictionary->RemoveObserver(&observer); |
| 876 |
| 877 // Flush the loop now to prevent service init tasks from being run during |
| 878 // TearDown(); |
| 879 MessageLoop::current()->RunUntilIdle(); |
| 880 } |
| 881 |
| 882 TEST_F(SpellcheckCustomDictionaryTest, DictionaryRemoveWordNotification) { |
| 883 SpellcheckService* spellcheck_service = |
| 884 SpellcheckServiceFactory::GetForProfile(profile_.get()); |
| 885 SpellcheckCustomDictionary* custom_dictionary = |
| 886 spellcheck_service->GetCustomDictionary(); |
| 887 |
| 888 custom_dictionary->OnLoaded(scoped_ptr<WordList>(new WordList)); |
| 889 |
| 890 custom_dictionary->AddWord("foo"); |
| 891 custom_dictionary->AddWord("bar"); |
| 892 |
| 893 DictionaryObserverCounter observer; |
| 894 custom_dictionary->AddObserver(&observer); |
| 895 |
| 896 custom_dictionary->RemoveWord("foo"); |
| 897 custom_dictionary->RemoveWord("bar"); |
| 898 custom_dictionary->RemoveWord("baz"); |
| 899 |
| 900 EXPECT_EQ(2, observer.changes()); |
| 901 |
| 902 custom_dictionary->RemoveObserver(&observer); |
| 903 |
| 904 // Flush the loop now to prevent service init tasks from being run during |
| 905 // TearDown(); |
| 906 MessageLoop::current()->RunUntilIdle(); |
| 907 } |
| 908 |
| 909 TEST_F(SpellcheckCustomDictionaryTest, |
| 910 DictionaryWordRemovedLocallyNotification) { |
| 911 SpellcheckService* spellcheck_service = |
| 912 SpellcheckServiceFactory::GetForProfile(profile_.get()); |
| 913 SpellcheckCustomDictionary* custom_dictionary = |
| 914 spellcheck_service->GetCustomDictionary(); |
| 915 |
| 916 custom_dictionary->OnLoaded(scoped_ptr<WordList>(new WordList)); |
| 917 |
| 918 custom_dictionary->CustomWordAddedLocally("foo"); |
| 919 custom_dictionary->CustomWordAddedLocally("bar"); |
| 920 |
| 921 DictionaryObserverCounter observer; |
| 922 custom_dictionary->AddObserver(&observer); |
| 923 |
| 924 custom_dictionary->CustomWordRemovedLocally("foo"); |
| 925 custom_dictionary->CustomWordRemovedLocally("bar"); |
| 926 custom_dictionary->CustomWordRemovedLocally("baz"); |
| 927 |
| 928 EXPECT_EQ(2, observer.changes()); |
| 929 |
| 930 custom_dictionary->RemoveObserver(&observer); |
| 931 |
| 932 // Flush the loop now to prevent service init tasks from being run during |
| 933 // TearDown(); |
| 934 MessageLoop::current()->RunUntilIdle(); |
| 935 } |
| 936 |
| 937 TEST_F(SpellcheckCustomDictionaryTest, DictionarySyncNotification) { |
| 938 SpellcheckService* spellcheck_service = |
| 939 SpellcheckServiceFactory::GetForProfile(profile_.get()); |
| 940 SpellcheckCustomDictionary* custom_dictionary = |
| 941 spellcheck_service->GetCustomDictionary(); |
| 942 TestingProfile profile2; |
| 943 SpellcheckService* spellcheck_service2 = |
| 944 static_cast<SpellcheckService*>( |
| 945 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
| 946 &profile2, &BuildSpellcheckService)); |
| 947 SpellcheckCustomDictionary* custom_dictionary2 = |
| 948 spellcheck_service2->GetCustomDictionary(); |
| 949 |
| 950 custom_dictionary->OnLoaded(scoped_ptr<WordList>(new WordList)); |
| 951 custom_dictionary2->OnLoaded(scoped_ptr<WordList>(new WordList)); |
| 952 |
| 953 custom_dictionary->CustomWordAddedLocally("foo"); |
| 954 custom_dictionary->CustomWordAddedLocally("bar"); |
| 955 custom_dictionary2->CustomWordAddedLocally("foo"); |
| 956 custom_dictionary2->CustomWordAddedLocally("baz"); |
| 957 |
| 958 DictionaryObserverCounter observer; |
| 959 custom_dictionary->AddObserver(&observer); |
| 960 |
| 961 DictionaryObserverCounter observer2; |
| 962 custom_dictionary2->AddObserver(&observer2); |
| 963 |
| 964 int error_counter = 0; |
| 965 EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing( |
| 966 syncer::DICTIONARY, |
| 967 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY), |
| 968 scoped_ptr<syncer::SyncChangeProcessor>( |
| 969 new SyncChangeProcessorDelegate(custom_dictionary2)), |
| 970 scoped_ptr<syncer::SyncErrorFactory>( |
| 971 new SyncErrorFactoryStub(&error_counter))).error().IsSet()); |
| 972 EXPECT_EQ(0, error_counter); |
| 973 EXPECT_TRUE(custom_dictionary->IsSyncing()); |
| 974 |
| 975 EXPECT_EQ(1, observer.changes()); |
| 976 EXPECT_EQ(1, observer2.changes()); |
| 977 |
| 978 custom_dictionary->RemoveObserver(&observer); |
| 979 custom_dictionary2->RemoveObserver(&observer2); |
| 980 |
| 981 // Flush the loop now to prevent service init tasks from being run during |
| 982 // TearDown(); |
| 269 MessageLoop::current()->RunUntilIdle(); | 983 MessageLoop::current()->RunUntilIdle(); |
| 270 } | 984 } |
| OLD | NEW |