blob: fba89e185d661e250d86b54c8437da33f88f76f4 [file] [log] [blame]
// Copyright 2011 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/views/controls/progress_bar.h"
#include <string>
#include "base/memory/raw_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/color/color_id.h"
#include "ui/events/test/event_generator.h"
#include "ui/gfx/color_utils.h"
#include "ui/native_theme/native_theme.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/layout/flex_layout.h"
#include "ui/views/test/ax_event_counter.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/test/views_test_utils.h"
namespace views {
class ProgressBarTest : public ViewsTestBase {
protected:
// ViewsTestBase:
void SetUp() override {
ViewsTestBase::SetUp();
widget_ = CreateTestWidget(Widget::InitParams::CLIENT_OWNS_WIDGET);
container_view_ = widget_->SetContentsView(std::make_unique<View>());
auto* layout =
container_view_->SetLayoutManager(std::make_unique<FlexLayout>());
layout->SetOrientation(views::LayoutOrientation::kVertical);
bar_ = container_view_->AddChildView(std::make_unique<ProgressBar>());
views::test::RunScheduledLayout(container_view_);
widget_->Show();
}
void TearDown() override {
container_view_ = nullptr;
bar_ = nullptr;
widget_.reset();
ViewsTestBase::TearDown();
}
ProgressBar* bar() { return bar_.get(); }
std::unique_ptr<Widget> widget_;
raw_ptr<views::View> container_view_;
raw_ptr<ProgressBar> bar_;
};
TEST_F(ProgressBarTest, AccessibleNodeData) {
bar()->SetValue(0.626);
ui::AXNodeData node_data;
bar()->GetViewAccessibility().GetAccessibleNodeData(&node_data);
EXPECT_EQ(ax::mojom::Role::kProgressIndicator, node_data.role);
EXPECT_EQ(std::u16string(),
node_data.GetString16Attribute(ax::mojom::StringAttribute::kName));
EXPECT_EQ(std::string("62%"),
node_data.GetStringAttribute(ax::mojom::StringAttribute::kValue));
EXPECT_FALSE(
node_data.HasIntAttribute(ax::mojom::IntAttribute::kRestriction));
}
// Verifies the correct a11y events are raised for an accessible progress bar.
TEST_F(ProgressBarTest, AccessibilityEvents) {
test::AXEventCounter ax_counter(views::AXUpdateNotifier::Get());
EXPECT_EQ(0, ax_counter.GetCount(ax::mojom::Event::kValueChanged));
bar()->SetValue(0.50);
EXPECT_EQ(1, ax_counter.GetCount(ax::mojom::Event::kValueChanged));
bar()->SetValue(0.63);
EXPECT_EQ(2, ax_counter.GetCount(ax::mojom::Event::kValueChanged));
bar()->SetValue(0.636);
EXPECT_EQ(2, ax_counter.GetCount(ax::mojom::Event::kValueChanged));
bar()->SetValue(0.642);
EXPECT_EQ(3, ax_counter.GetCount(ax::mojom::Event::kValueChanged));
widget_->Hide();
widget_->Show();
EXPECT_EQ(3, ax_counter.GetCount(ax::mojom::Event::kValueChanged));
widget_->Hide();
bar()->SetValue(0.8);
EXPECT_EQ(3, ax_counter.GetCount(ax::mojom::Event::kValueChanged));
widget_->Show();
EXPECT_EQ(4, ax_counter.GetCount(ax::mojom::Event::kValueChanged));
}
// Test that default colors can be overridden. Used by Chromecast.
TEST_F(ProgressBarTest, OverrideDefaultColors) {
EXPECT_NE(SK_ColorRED, bar()->GetForegroundColor());
EXPECT_NE(SK_ColorGREEN, bar()->GetBackgroundColor());
EXPECT_NE(bar()->GetForegroundColor(), bar()->GetBackgroundColor());
bar()->SetForegroundColor(SK_ColorRED);
bar()->SetBackgroundColor(SK_ColorGREEN);
EXPECT_EQ(SK_ColorRED, bar()->GetForegroundColor());
EXPECT_EQ(SK_ColorGREEN, bar()->GetBackgroundColor());
// Override colors with color ID. It will also override the colors set with
// SkColor.
bar()->SetForegroundColorId(ui::kColorSysPrimary);
bar()->SetBackgroundColorId(ui::kColorSysPrimaryContainer);
const auto* color_provider = bar()->GetColorProvider();
EXPECT_EQ(color_provider->GetColor(ui::kColorSysPrimary),
bar()->GetForegroundColor());
EXPECT_EQ(color_provider->GetColor(ui::kColorSysPrimaryContainer),
bar()->GetBackgroundColor());
EXPECT_EQ(ui::kColorSysPrimary, bar()->GetForegroundColorId().value());
EXPECT_EQ(ui::kColorSysPrimaryContainer,
bar()->GetBackgroundColorId().value());
// Override the colors set with color ID by SkColor.
bar()->SetForegroundColor(SK_ColorRED);
bar()->SetBackgroundColor(SK_ColorGREEN);
EXPECT_EQ(SK_ColorRED, bar()->GetForegroundColor());
EXPECT_EQ(SK_ColorGREEN, bar()->GetBackgroundColor());
EXPECT_EQ(std::nullopt, bar()->GetForegroundColorId());
EXPECT_EQ(std::nullopt, bar()->GetBackgroundColorId());
}
// Test that if no `preferred_corner_radii` are provided the default radius is
// 3, and a value of `std::nullopt` will not round the corners.
TEST_F(ProgressBarTest, RoundCornerDefault) {
// The default bar should have a rounded corner radius of 3.
EXPECT_EQ(gfx::RoundedCornersF(3), bar()->GetPreferredCornerRadii());
// Setting `std::nullopt` for the corner radius should make the bar have no
// rounded corners.
bar()->SetPreferredHeight(12);
bar()->SetPreferredCornerRadii(std::nullopt);
views::test::RunScheduledLayout(container_view_);
EXPECT_EQ(gfx::RoundedCornersF(0), bar()->GetPreferredCornerRadii());
EXPECT_TRUE(bar()->GetPreferredCornerRadii().IsEmpty());
}
// Test that a value set for `preferred_corner_radii` is saved and can be
// retrieved from `GetPreferredCornerRadii()`.
TEST_F(ProgressBarTest, RoundCornerRetrieval) {
// Setting custom corners should result in them being saved.
bar()->SetPreferredHeight(12);
bar()->SetPreferredCornerRadii(gfx::RoundedCornersF(6));
views::test::RunScheduledLayout(container_view_);
EXPECT_EQ(gfx::RoundedCornersF(6), bar()->GetPreferredCornerRadii());
}
// Test that `GetPreferredCornerRadii()` will return no corner with a radius
// greater than the height of the bar.
TEST_F(ProgressBarTest, RoundCornerMax) {
// The max corner radius for a bar with a height of 12 should be 12.
bar()->SetPreferredHeight(12);
bar()->SetPreferredCornerRadii(gfx::RoundedCornersF(13, 14, 15, 16));
views::test::RunScheduledLayout(container_view_);
EXPECT_EQ(gfx::RoundedCornersF(12, 12, 12, 12),
bar()->GetPreferredCornerRadii());
}
// Test that if value is set negative, which means progress bar is
// indeterminate, the string attribute value should be empty.
TEST_F(ProgressBarTest, RemoveValue) {
// setting negative progress bar value
bar()->SetValue(-0.626);
ui::AXNodeData node_data;
bar()->GetViewAccessibility().GetAccessibleNodeData(&node_data);
EXPECT_EQ(std::string(""),
node_data.GetStringAttribute(ax::mojom::StringAttribute::kValue));
}
} // namespace views