123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- // Copyright (c) 2011 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 <stddef.h>
- #include "base/bind.h"
- #include "base/callback.h"
- #include "components/prefs/mock_pref_change_callback.h"
- #include "components/prefs/pref_notifier_impl.h"
- #include "components/prefs/pref_observer.h"
- #include "components/prefs/pref_registry_simple.h"
- #include "components/prefs/pref_service.h"
- #include "components/prefs/pref_value_store.h"
- #include "components/prefs/testing_pref_service.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- using testing::_;
- using testing::Field;
- using testing::Invoke;
- using testing::Mock;
- using testing::Truly;
- namespace {
- const char kChangedPref[] = "changed_pref";
- const char kUnchangedPref[] = "unchanged_pref";
- class MockPrefInitObserver {
- public:
- MOCK_METHOD1(OnInitializationCompleted, void(bool));
- };
- // This is an unmodified PrefNotifierImpl, except we make
- // OnPreferenceChanged public for tests.
- class TestingPrefNotifierImpl : public PrefNotifierImpl {
- public:
- explicit TestingPrefNotifierImpl(PrefService* service)
- : PrefNotifierImpl(service) {
- }
- // Make public for tests.
- using PrefNotifierImpl::OnPreferenceChanged;
- };
- // Mock PrefNotifier that allows tracking of observers and notifications.
- class MockPrefNotifier : public PrefNotifierImpl {
- public:
- explicit MockPrefNotifier(PrefService* pref_service)
- : PrefNotifierImpl(pref_service) {}
- ~MockPrefNotifier() override {}
- MOCK_METHOD1(FireObservers, void(const std::string& path));
- size_t CountObserver(const std::string& path, PrefObserver* obs) {
- auto observer_iterator = pref_observers()->find(path);
- if (observer_iterator == pref_observers()->end())
- return false;
- size_t count = 0;
- for (auto& existing_obs : *observer_iterator->second) {
- if (&existing_obs == obs)
- count++;
- }
- return count;
- }
- // Make public for tests below.
- using PrefNotifierImpl::OnPreferenceChanged;
- using PrefNotifierImpl::OnInitializationCompleted;
- };
- class PrefObserverMock : public PrefObserver {
- public:
- PrefObserverMock() {}
- virtual ~PrefObserverMock() {}
- MOCK_METHOD2(OnPreferenceChanged, void(PrefService*, const std::string&));
- };
- // Test fixture class.
- class PrefNotifierTest : public testing::Test {
- protected:
- void SetUp() override {
- pref_service_.registry()->RegisterBooleanPref(kChangedPref, true);
- pref_service_.registry()->RegisterBooleanPref(kUnchangedPref, true);
- }
- TestingPrefServiceSimple pref_service_;
- PrefObserverMock obs1_;
- PrefObserverMock obs2_;
- };
- TEST_F(PrefNotifierTest, OnPreferenceChanged) {
- MockPrefNotifier notifier(&pref_service_);
- EXPECT_CALL(notifier, FireObservers(kChangedPref)).Times(1);
- notifier.OnPreferenceChanged(kChangedPref);
- }
- TEST_F(PrefNotifierTest, OnInitializationCompleted) {
- MockPrefNotifier notifier(&pref_service_);
- MockPrefInitObserver observer;
- notifier.AddInitObserver(
- base::BindOnce(&MockPrefInitObserver::OnInitializationCompleted,
- base::Unretained(&observer)));
- EXPECT_CALL(observer, OnInitializationCompleted(true));
- notifier.OnInitializationCompleted(true);
- }
- TEST_F(PrefNotifierTest, AddAndRemovePrefObservers) {
- const char pref_name[] = "homepage";
- const char pref_name2[] = "proxy";
- MockPrefNotifier notifier(&pref_service_);
- notifier.AddPrefObserver(pref_name, &obs1_);
- ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs1_));
- ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs1_));
- ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
- ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
- // Re-adding the same observer for the same pref doesn't change anything.
- // Skip this in debug mode, since it hits a DCHECK and death tests aren't
- // thread-safe.
- #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
- notifier.AddPrefObserver(pref_name, &obs1_);
- ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs1_));
- ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs1_));
- ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
- ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
- #endif
- // Ensure that we can add the same observer to a different pref.
- notifier.AddPrefObserver(pref_name2, &obs1_);
- ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs1_));
- ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_));
- ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
- ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
- // Ensure that we can add another observer to the same pref.
- notifier.AddPrefObserver(pref_name, &obs2_);
- ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs1_));
- ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_));
- ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs2_));
- ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
- // Ensure that we can remove all observers, and that removing a non-existent
- // observer is harmless.
- notifier.RemovePrefObserver(pref_name, &obs1_);
- ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs1_));
- ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_));
- ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs2_));
- ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
- notifier.RemovePrefObserver(pref_name, &obs2_);
- ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs1_));
- ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_));
- ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
- ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
- notifier.RemovePrefObserver(pref_name, &obs1_);
- ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs1_));
- ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_));
- ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
- ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
- notifier.RemovePrefObserver(pref_name2, &obs1_);
- ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs1_));
- ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs1_));
- ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
- ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
- }
- TEST_F(PrefNotifierTest, FireObservers) {
- TestingPrefNotifierImpl notifier(&pref_service_);
- notifier.AddPrefObserver(kChangedPref, &obs1_);
- notifier.AddPrefObserver(kUnchangedPref, &obs1_);
- EXPECT_CALL(obs1_, OnPreferenceChanged(&pref_service_, kChangedPref));
- EXPECT_CALL(obs2_, OnPreferenceChanged(_, _)).Times(0);
- notifier.OnPreferenceChanged(kChangedPref);
- Mock::VerifyAndClearExpectations(&obs1_);
- Mock::VerifyAndClearExpectations(&obs2_);
- notifier.AddPrefObserver(kChangedPref, &obs2_);
- notifier.AddPrefObserver(kUnchangedPref, &obs2_);
- EXPECT_CALL(obs1_, OnPreferenceChanged(&pref_service_, kChangedPref));
- EXPECT_CALL(obs2_, OnPreferenceChanged(&pref_service_, kChangedPref));
- notifier.OnPreferenceChanged(kChangedPref);
- Mock::VerifyAndClearExpectations(&obs1_);
- Mock::VerifyAndClearExpectations(&obs2_);
- // Make sure removing an observer from one pref doesn't affect anything else.
- notifier.RemovePrefObserver(kChangedPref, &obs1_);
- EXPECT_CALL(obs1_, OnPreferenceChanged(_, _)).Times(0);
- EXPECT_CALL(obs2_, OnPreferenceChanged(&pref_service_, kChangedPref));
- notifier.OnPreferenceChanged(kChangedPref);
- Mock::VerifyAndClearExpectations(&obs1_);
- Mock::VerifyAndClearExpectations(&obs2_);
- // Make sure removing an observer entirely doesn't affect anything else.
- notifier.RemovePrefObserver(kUnchangedPref, &obs1_);
- EXPECT_CALL(obs1_, OnPreferenceChanged(_, _)).Times(0);
- EXPECT_CALL(obs2_, OnPreferenceChanged(&pref_service_, kChangedPref));
- notifier.OnPreferenceChanged(kChangedPref);
- Mock::VerifyAndClearExpectations(&obs1_);
- Mock::VerifyAndClearExpectations(&obs2_);
- notifier.RemovePrefObserver(kChangedPref, &obs2_);
- notifier.RemovePrefObserver(kUnchangedPref, &obs2_);
- }
- } // namespace
|