// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include #include "base/scoped_temp_dir.h" #include "chrome/browser/spellchecker/spellcheck_factory.h" #include "chrome/browser/spellchecker/spellcheck_host.h" #include "chrome/browser/spellchecker/spellcheck_profile.h" #include "chrome/test/base/testing_profile.h" #include "content/public/test/test_browser_thread.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" using content::BrowserThread; namespace { class MockSpellCheckHost : public SpellCheckHost { public: MOCK_METHOD0(UnsetProfile, void()); MOCK_METHOD1(InitForRenderer, void(content::RenderProcessHost* process)); MOCK_METHOD1(AddWord, void(const std::string& word)); MOCK_CONST_METHOD0(GetDictionaryFile, const base::PlatformFile&()); MOCK_CONST_METHOD0(GetCustomWords, const SpellCheckProfile::CustomWordList&()); MOCK_CONST_METHOD0(GetLastAddedFile, const std::string&()); MOCK_CONST_METHOD0(GetLanguage, const std::string&()); MOCK_CONST_METHOD0(IsUsingPlatformChecker, bool()); MOCK_CONST_METHOD0(GetMetrics, SpellCheckHostMetrics*()); MOCK_CONST_METHOD0(IsReady, bool()); }; class TestingSpellCheckProfile : public SpellCheckProfile { public: explicit TestingSpellCheckProfile(Profile* profile) : SpellCheckProfile(profile), create_host_calls_(0) { } virtual SpellCheckHost* CreateHost( SpellCheckProfileProvider* profile, const std::string& language, net::URLRequestContextGetter* request_context, SpellCheckHostMetrics* metrics) { create_host_calls_++; return returning_from_create_.release(); } virtual bool IsTesting() const { return true; } bool IsCreatedHostReady() { return !!GetHost(); } void SetHostToBeCreated(MockSpellCheckHost* host) { EXPECT_CALL(*host, UnsetProfile()).Times(1); EXPECT_CALL(*host, IsReady()).WillRepeatedly(testing::Return(true)); returning_from_create_.reset(host); } size_t create_host_calls_; scoped_ptr returning_from_create_; }; ProfileKeyedService* BuildTestingSpellCheckProfile(Profile* profile) { return new TestingSpellCheckProfile(profile); } class SpellCheckProfileTest : public testing::Test { protected: SpellCheckProfileTest() : file_thread_(BrowserThread::FILE), profile_(new TestingProfile()) { target_ = BuildSpellCheckProfileWith(profile_.get()); } static TestingSpellCheckProfile* BuildSpellCheckProfileWith( TestingProfile* profile) { return static_cast( SpellCheckFactory::GetInstance()->SetTestingFactoryAndUse( profile, &BuildTestingSpellCheckProfile)); } // SpellCheckHost will be deleted on FILE thread. content::TestBrowserThread file_thread_; scoped_ptr profile_; // Our normal profile, created as part of test startup. TestingSpellCheckProfile* target_; }; } // namespace TEST_F(SpellCheckProfileTest, ReinitializeEnabled) { scoped_ptr host(new MockSpellCheckHost()); target_->SetHostToBeCreated(host.release()); // The first call should create host. SpellCheckProfile::ReinitializeResult result1 = target_->ReinitializeHostImpl(false, true, "", NULL); EXPECT_EQ(target_->create_host_calls_, 1U); EXPECT_EQ(result1, SpellCheckProfile::REINITIALIZE_CREATED_HOST); // The second call should be ignored. SpellCheckProfile::ReinitializeResult result2 = target_->ReinitializeHostImpl(false, true, "", NULL); EXPECT_EQ(result2, SpellCheckProfile::REINITIALIZE_DID_NOTHING); EXPECT_EQ(target_->create_host_calls_, 1U); // Host should become ready after the notification. EXPECT_FALSE(target_->IsCreatedHostReady()); target_->SpellCheckHostInitialized(0); EXPECT_TRUE(target_->IsCreatedHostReady()); } TEST_F(SpellCheckProfileTest, ReinitializeDisabled) { scoped_ptr host(new MockSpellCheckHost()); target_->returning_from_create_.reset(host.release()); // If enabled is false, nothing should happen SpellCheckProfile::ReinitializeResult result1 = target_->ReinitializeHostImpl(false, false, "", NULL); EXPECT_EQ(target_->create_host_calls_, 0U); EXPECT_EQ(result1, SpellCheckProfile::REINITIALIZE_DID_NOTHING); // Nothing should happen even if forced. SpellCheckProfile::ReinitializeResult result2 = target_->ReinitializeHostImpl(true, false, "", NULL); EXPECT_EQ(target_->create_host_calls_, 0U); EXPECT_EQ(result2, SpellCheckProfile::REINITIALIZE_DID_NOTHING); } TEST_F(SpellCheckProfileTest, ReinitializeRemove) { scoped_ptr host(new MockSpellCheckHost()); target_->SetHostToBeCreated(host.release()); // At first, create the host. SpellCheckProfile::ReinitializeResult result1 = target_->ReinitializeHostImpl(false, true, "", NULL); target_->SpellCheckHostInitialized(0); EXPECT_EQ(result1, SpellCheckProfile::REINITIALIZE_CREATED_HOST); EXPECT_TRUE(target_->IsCreatedHostReady()); // Then the host should be deleted if it's forced to be disabled. SpellCheckProfile::ReinitializeResult result2 = target_->ReinitializeHostImpl(true, false, "", NULL); target_->SpellCheckHostInitialized(0); EXPECT_EQ(result2, SpellCheckProfile::REINITIALIZE_REMOVED_HOST); EXPECT_FALSE(target_->IsCreatedHostReady()); } TEST_F(SpellCheckProfileTest, ReinitializeRecreate) { scoped_ptr host1(new MockSpellCheckHost()); target_->SetHostToBeCreated(host1.release()); // At first, create the host. SpellCheckProfile::ReinitializeResult result1 = target_->ReinitializeHostImpl(false, true, "", NULL); target_->SpellCheckHostInitialized(0); EXPECT_EQ(target_->create_host_calls_, 1U); EXPECT_EQ(result1, SpellCheckProfile::REINITIALIZE_CREATED_HOST); EXPECT_TRUE(target_->IsCreatedHostReady()); // Then the host should be re-created if it's forced to recreate. scoped_ptr host2(new MockSpellCheckHost()); target_->SetHostToBeCreated(host2.release()); SpellCheckProfile::ReinitializeResult result2 = target_->ReinitializeHostImpl(true, true, "", NULL); target_->SpellCheckHostInitialized(0); EXPECT_EQ(target_->create_host_calls_, 2U); EXPECT_EQ(result2, SpellCheckProfile::REINITIALIZE_CREATED_HOST); EXPECT_TRUE(target_->IsCreatedHostReady()); } TEST_F(SpellCheckProfileTest, SpellCheckHostInitializedWithCustomWords) { scoped_ptr host(new MockSpellCheckHost()); target_->SetHostToBeCreated(host.release()); target_->ReinitializeHostImpl(false, true, "", NULL); scoped_ptr loaded_custom_words (new SpellCheckProfile::CustomWordList()); loaded_custom_words->push_back("foo"); loaded_custom_words->push_back("bar"); SpellCheckProfile::CustomWordList expected(*loaded_custom_words); target_->SpellCheckHostInitialized(loaded_custom_words.release()); EXPECT_EQ(target_->GetCustomWords(), expected); } TEST_F(SpellCheckProfileTest, CustomWordAddedLocally) { scoped_ptr host(new MockSpellCheckHost()); target_->SetHostToBeCreated(host.release()); target_->ReinitializeHostImpl(false, true, "", NULL); scoped_ptr loaded_custom_words (new SpellCheckProfile::CustomWordList()); target_->SpellCheckHostInitialized(NULL); SpellCheckProfile::CustomWordList expected; EXPECT_EQ(target_->GetCustomWords(), expected); target_->CustomWordAddedLocally("foo"); expected.push_back("foo"); EXPECT_EQ(target_->GetCustomWords(), expected); target_->CustomWordAddedLocally("bar"); expected.push_back("bar"); EXPECT_EQ(target_->GetCustomWords(), expected); } TEST_F(SpellCheckProfileTest, SaveAndLoad) { scoped_ptr host(new MockSpellCheckHost()); target_->SetHostToBeCreated(host.release()); target_->ReinitializeHostImpl(false, true, "", NULL); scoped_ptr loaded_custom_words( new SpellCheckProfile::CustomWordList()); target_->LoadCustomDictionary(loaded_custom_words.get()); // The custom word list should be empty now. SpellCheckProfile::CustomWordList expected; EXPECT_EQ(*loaded_custom_words, expected); target_->WriteWordToCustomDictionary("foo"); expected.push_back("foo"); target_->WriteWordToCustomDictionary("bar"); expected.push_back("bar"); // The custom word list should include written words. target_->LoadCustomDictionary(loaded_custom_words.get()); EXPECT_EQ(*loaded_custom_words, expected); // Load in another instance of SpellCheckProfile. // The result should be the same. scoped_ptr host2(new MockSpellCheckHost()); TestingSpellCheckProfile* target2 = BuildSpellCheckProfileWith(profile_.get()); target2->SetHostToBeCreated(host2.release()); target2->ReinitializeHostImpl(false, true, "", NULL); scoped_ptr loaded_custom_words2( new SpellCheckProfile::CustomWordList()); target2->LoadCustomDictionary(loaded_custom_words2.get()); EXPECT_EQ(*loaded_custom_words2, expected); } TEST_F(SpellCheckProfileTest, MultiProfile) { scoped_ptr host1(new MockSpellCheckHost()); scoped_ptr host2(new MockSpellCheckHost()); TestingProfile profile2; TestingSpellCheckProfile* target2 = BuildSpellCheckProfileWith(&profile2); target_->SetHostToBeCreated(host1.release()); target_->ReinitializeHostImpl(false, true, "", NULL); target2->SetHostToBeCreated(host2.release()); target2->ReinitializeHostImpl(false, true, "", NULL); SpellCheckProfile::CustomWordList expected1; SpellCheckProfile::CustomWordList expected2; target_->WriteWordToCustomDictionary("foo"); target_->WriteWordToCustomDictionary("bar"); expected1.push_back("foo"); expected1.push_back("bar"); target2->WriteWordToCustomDictionary("hoge"); target2->WriteWordToCustomDictionary("fuga"); expected2.push_back("hoge"); expected2.push_back("fuga"); SpellCheckProfile::CustomWordList actual1; target_->LoadCustomDictionary(&actual1); EXPECT_EQ(actual1, expected1); SpellCheckProfile::CustomWordList actual2; target2->LoadCustomDictionary(&actual2); EXPECT_EQ(actual2, expected2); }