blob: 4daacc1a21aaa4db302fa323b9f1a5cdf2e934c0 [file] [log] [blame]
// Copyright (c) 2016 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 "ui/views/controls/button/toggle_button.h"
#include <memory>
#include <utility>
#include "base/macros.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/event_utils.h"
#include "ui/events/test/event_generator.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/widget/widget_utils.h"
namespace views {
class TestToggleButton : public ToggleButton {
public:
explicit TestToggleButton(int* counter) : counter_(counter) {}
~TestToggleButton() override {
// Calling SetInkDropMode() in this subclass allows this class's
// implementation of RemoveInkDropLayer() to be called. The same
// call is made in ~ToggleButton() so this is testing the general technique.
SetInkDropMode(InkDropMode::OFF);
}
using View::Focus;
protected:
// ToggleButton:
void AddInkDropLayer(ui::Layer* ink_drop_layer) override {
++(*counter_);
ToggleButton::AddInkDropLayer(ink_drop_layer);
}
void RemoveInkDropLayer(ui::Layer* ink_drop_layer) override {
ToggleButton::RemoveInkDropLayer(ink_drop_layer);
--(*counter_);
}
private:
int* counter_;
DISALLOW_COPY_AND_ASSIGN(TestToggleButton);
};
class ToggleButtonTest : public ViewsTestBase {
public:
ToggleButtonTest() = default;
~ToggleButtonTest() override = default;
void SetUp() override {
ViewsTestBase::SetUp();
// Create a widget so that the ToggleButton can query the hover state
// correctly.
widget_ = std::make_unique<Widget>();
Widget::InitParams params =
CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.bounds = gfx::Rect(0, 0, 650, 650);
widget_->Init(std::move(params));
widget_->Show();
button_ =
widget_->SetContentsView(std::make_unique<TestToggleButton>(&counter_));
}
void TearDown() override {
widget_.reset();
ViewsTestBase::TearDown();
}
protected:
int counter() const { return counter_; }
Widget* widget() { return widget_.get(); }
TestToggleButton* button() { return button_; }
private:
std::unique_ptr<Widget> widget_;
TestToggleButton* button_ = nullptr;
int counter_ = 0;
DISALLOW_COPY_AND_ASSIGN(ToggleButtonTest);
};
// Starts ink drop animation on a ToggleButton and destroys the button.
// The test verifies that the ink drop layer is removed properly when the
// ToggleButton gets destroyed.
TEST_F(ToggleButtonTest, ToggleButtonDestroyed) {
EXPECT_EQ(0, counter());
gfx::Point center(10, 10);
button()->OnMousePressed(ui::MouseEvent(
ui::ET_MOUSE_PRESSED, center, center, ui::EventTimeForNow(),
ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON));
EXPECT_EQ(1, counter());
delete button();
EXPECT_EQ(0, counter());
}
// Make sure nothing bad happens when the widget is destroyed while the
// ToggleButton has focus (and is showing a ripple).
TEST_F(ToggleButtonTest, ShutdownWithFocus) {
button()->RequestFocus();
EXPECT_EQ(1, counter());
}
// Verify that ToggleButton::accepts_events_ works as expected.
TEST_F(ToggleButtonTest, AcceptEvents) {
EXPECT_FALSE(button()->GetIsOn());
ui::test::EventGenerator generator(GetRootWindow(widget()));
// Clicking toggles.
generator.ClickLeftButton();
EXPECT_TRUE(button()->GetIsOn());
generator.ClickLeftButton();
EXPECT_FALSE(button()->GetIsOn());
// Spacebar toggles.
button()->RequestFocus();
generator.PressKey(ui::VKEY_SPACE, ui::EF_NONE);
generator.ReleaseKey(ui::VKEY_SPACE, ui::EF_NONE);
EXPECT_TRUE(button()->GetIsOn());
generator.PressKey(ui::VKEY_SPACE, ui::EF_NONE);
generator.ReleaseKey(ui::VKEY_SPACE, ui::EF_NONE);
EXPECT_FALSE(button()->GetIsOn());
// Spacebar and clicking do nothing when not accepting events, but focus is
// not affected.
button()->SetAcceptsEvents(false);
EXPECT_TRUE(button()->HasFocus());
generator.PressKey(ui::VKEY_SPACE, ui::EF_NONE);
generator.ReleaseKey(ui::VKEY_SPACE, ui::EF_NONE);
EXPECT_FALSE(button()->GetIsOn());
generator.ClickLeftButton();
EXPECT_FALSE(button()->GetIsOn());
// Re-enable events and clicking and spacebar resume working.
button()->SetAcceptsEvents(true);
generator.PressKey(ui::VKEY_SPACE, ui::EF_NONE);
generator.ReleaseKey(ui::VKEY_SPACE, ui::EF_NONE);
EXPECT_TRUE(button()->GetIsOn());
generator.ClickLeftButton();
EXPECT_FALSE(button()->GetIsOn());
}
} // namespace views