blob: aeeea160eaf2adb3782ab2599100eab46c0084df [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/color/color_provider_manager.h"
#include <vector>
#include "base/functional/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/color/color_mixer.h"
#include "ui/color/color_provider.h"
#include "ui/color/color_recipe.h"
#include "ui/color/color_test_ids.h"
#include "ui/gfx/color_palette.h"
namespace ui {
namespace {
class ColorProviderManagerTest : public testing::Test {
public:
ColorProviderManagerTest() { ColorProviderManager::ResetForTesting(); }
ColorProviderManagerTest(const ColorProviderManagerTest&) = delete;
ColorProviderManagerTest& operator=(const ColorProviderManagerTest&) = delete;
~ColorProviderManagerTest() override {
ColorProviderManager::ResetForTesting();
}
};
ColorProvider* GetLightNormalColorProvider() {
return ColorProviderManager::GetForTesting().GetColorProviderFor(
{ColorProviderManager::ColorMode::kLight,
ColorProviderManager::ContrastMode::kNormal, ui::SystemTheme::kDefault,
ColorProviderManager::FrameType::kChromium, absl::nullopt, nullptr});
}
class TestInitializerSupplier
: public ColorProviderManager::InitializerSupplier {
void AddColorMixers(ColorProvider* provider,
const ColorProviderManager::Key& key) const override {}
};
} // namespace
// Verifies that color providers endure for each call to GetColorProviderFor().
TEST_F(ColorProviderManagerTest, Persistence) {
base::HistogramTester histogram_tester;
ColorProvider* provider = GetLightNormalColorProvider();
ASSERT_NE(nullptr, provider);
EXPECT_EQ(provider, GetLightNormalColorProvider());
histogram_tester.ExpectTotalCount(
"Views.Browser.TimeSpentInitializingColorProvider", 1);
}
// Verifies that the initializer is called for each newly created color
// provider.
TEST_F(ColorProviderManagerTest, SetInitializer) {
ColorProviderManager::GetForTesting().AppendColorProviderInitializer(
base::BindRepeating(
[](ColorProvider* provider, const ColorProviderManager::Key&) {
provider->AddMixer()[kColorTest0] = {SK_ColorBLUE};
}));
base::HistogramTester histogram_tester;
ColorProvider* provider = GetLightNormalColorProvider();
ASSERT_NE(nullptr, provider);
EXPECT_EQ(SK_ColorBLUE, provider->GetColor(kColorTest0));
histogram_tester.ExpectTotalCount(
"Views.Browser.TimeSpentInitializingColorProvider", 1);
}
// Verifies resetting the manager clears the provider. This is useful to keep
// unit tests isolated from each other.
TEST_F(ColorProviderManagerTest, Reset) {
ColorProviderManager::GetForTesting().AppendColorProviderInitializer(
base::BindRepeating(
[](ColorProvider* provider, const ColorProviderManager::Key&) {
provider->AddMixer()[kColorTest0] = {SK_ColorBLUE};
}));
base::HistogramTester histogram_tester;
ColorProvider* provider = GetLightNormalColorProvider();
ASSERT_NE(nullptr, provider);
EXPECT_EQ(SK_ColorBLUE, provider->GetColor(kColorTest0));
ColorProviderManager::ResetForTesting();
EXPECT_EQ(gfx::kPlaceholderColor,
GetLightNormalColorProvider()->GetColor(kColorTest0));
histogram_tester.ExpectTotalCount(
"Views.Browser.TimeSpentInitializingColorProvider", 2);
}
TEST_F(ColorProviderManagerTest, LookupWithDeletedMember) {
ColorProviderManager& manager = ColorProviderManager::GetForTesting();
ColorProviderManager::Key key;
{
TestInitializerSupplier supplier;
key.app_controller = &supplier;
EXPECT_TRUE(manager.GetColorProviderFor(key));
key.app_controller = &supplier;
}
// key.app_controller is now invalid but shouldn't be dereferenced so the key
// is still safe to use.
EXPECT_TRUE(manager.GetColorProviderFor(key));
}
TEST_F(ColorProviderManagerTest, KeyOrderIsStable) {
ColorProviderManager::Key keys[2];
// Allocate two suppliers.
std::vector<TestInitializerSupplier> supplier(2);
keys[0].app_controller = &supplier[0];
keys[1].app_controller = &supplier[1];
// Validate order.
ASSERT_LT(keys[0], keys[1]);
// Delete the higher of the two suppliers.
supplier.pop_back();
// Verify that the order hasn't changed.
EXPECT_LT(keys[0], keys[1]);
}
} // namespace ui