blob: 8b9ef8fe6b768f183a70fef516e0605b8c310597 [file] [log] [blame]
// 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 <vector>
#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<SpellCheckHost> 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<TestingSpellCheckProfile*>(
SpellCheckFactory::GetInstance()->SetTestingFactoryAndUse(
profile, &BuildTestingSpellCheckProfile));
}
// SpellCheckHost will be deleted on FILE thread.
content::TestBrowserThread file_thread_;
scoped_ptr<TestingProfile> profile_;
// Our normal profile, created as part of test startup.
TestingSpellCheckProfile* target_;
};
} // namespace
TEST_F(SpellCheckProfileTest, ReinitializeEnabled) {
scoped_ptr<MockSpellCheckHost> 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<MockSpellCheckHost> 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<MockSpellCheckHost> 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<MockSpellCheckHost> 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<MockSpellCheckHost> 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<MockSpellCheckHost> host(new MockSpellCheckHost());
target_->SetHostToBeCreated(host.release());
target_->ReinitializeHostImpl(false, true, "", NULL);
scoped_ptr<SpellCheckProfile::CustomWordList> 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<MockSpellCheckHost> host(new MockSpellCheckHost());
target_->SetHostToBeCreated(host.release());
target_->ReinitializeHostImpl(false, true, "", NULL);
scoped_ptr<SpellCheckProfile::CustomWordList> 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<MockSpellCheckHost> host(new MockSpellCheckHost());
target_->SetHostToBeCreated(host.release());
target_->ReinitializeHostImpl(false, true, "", NULL);
scoped_ptr<SpellCheckProfile::CustomWordList> 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<MockSpellCheckHost> host2(new MockSpellCheckHost());
TestingSpellCheckProfile* target2 =
BuildSpellCheckProfileWith(profile_.get());
target2->SetHostToBeCreated(host2.release());
target2->ReinitializeHostImpl(false, true, "", NULL);
scoped_ptr<SpellCheckProfile::CustomWordList> loaded_custom_words2(
new SpellCheckProfile::CustomWordList());
target2->LoadCustomDictionary(loaded_custom_words2.get());
EXPECT_EQ(*loaded_custom_words2, expected);
}
TEST_F(SpellCheckProfileTest, MultiProfile) {
scoped_ptr<MockSpellCheckHost> host1(new MockSpellCheckHost());
scoped_ptr<MockSpellCheckHost> 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);
}