Commit 59b5ea10 authored by Elly Fong-Jones's avatar Elly Fong-Jones Committed by Commit Bot

views: add color chooser unit tests

This change begins adding test coverage (still quite incomplete) for
//ui/views/color_chooser.

Bug: None
Change-Id: I7ef91fe5b276e90f7e3bd13fcb153b66f90d72c6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2406390
Commit-Queue: Elly Fong-Jones <ellyjones@chromium.org>
Reviewed-by: default avatarPeter Kasting <pkasting@chromium.org>
Cr-Commit-Position: refs/heads/master@{#818002}
parent aa179c6a
...@@ -1342,6 +1342,10 @@ test("views_unittests") { ...@@ -1342,6 +1342,10 @@ test("views_unittests") {
if (use_ozone) { if (use_ozone) {
deps += [ "//ui/ozone" ] deps += [ "//ui/ozone" ]
} }
if (is_linux || is_chromeos) {
sources += [ "color_chooser/color_chooser_unittest.cc" ]
}
} }
# This target is added as a dependency of browser interactive_ui_tests. It must # This target is added as a dependency of browser interactive_ui_tests. It must
......
// Copyright 2020 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.
//
// Very quick HSV primer for those unfamiliar with it:
// It helps to think of HSV like this:
// h is in (0,360) and draws a circle of colors, with r = 0, b = 120, g = 240
// s is in (0,1) and is the distance from the center of that circle - higher
// values are more intense, with s = 0 being white, s = 1 being full color
// and then HSV is the 3d space caused by projecting that circle into a
// cylinder, with v in (0,1) being how far along the cylinder you are; v = 0 is
// black, v = 1 is full color intensity
#include <tuple>
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/test/event_generator.h"
#include "ui/views/background.h"
#include "ui/views/color_chooser/color_chooser_listener.h"
#include "ui/views/color_chooser/color_chooser_view.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/widget/widget_utils.h"
namespace {
class TestChooserListener : public views::ColorChooserListener {
public:
void OnColorChosen(SkColor color) override { color_ = color; }
void OnColorChooserDialogClosed() override { closed_ = true; }
private:
SkColor color_ = SK_ColorTRANSPARENT;
bool closed_ = false;
};
class ColorChooserTest : public views::ViewsTestBase {
public:
~ColorChooserTest() override = default;
void SetUp() override {
ViewsTestBase::SetUp();
chooser_ =
std::make_unique<views::ColorChooserView>(&listener_, SK_ColorGREEN);
chooser_->SetBounds(0, 0, 400, 300);
widget_ = CreateTestWidget(views::Widget::InitParams::TYPE_WINDOW);
widget_->GetContentsView()->AddChildView(chooser());
generator_ = std::make_unique<ui::test::EventGenerator>(
views::GetRootWindow(widget_.get()), widget_->GetNativeWindow());
generator_->set_assume_window_at_origin(false);
}
void TearDown() override {
generator_.reset();
widget_.reset();
ViewsTestBase::TearDown();
}
views::ColorChooserView* chooser() { return chooser_.get(); }
ui::test::EventGenerator* generator() { return generator_.get(); }
void ExpectExactHSV(float h, float s, float v) const {
EXPECT_EQ(h, chooser_->hue());
EXPECT_EQ(s, chooser_->saturation());
EXPECT_EQ(v, chooser_->value());
}
void ExpectApproximateHSV(float h, float s, float v) const {
// At the usual size of the hue chooser it's possible to hit within
// roughly 5 points of hue in either direction.
EXPECT_NEAR(chooser_->hue(), h, 10.0);
EXPECT_NEAR(chooser_->saturation(), s, 0.1);
EXPECT_NEAR(chooser_->value(), v, 0.1);
}
SkColor GetShownColor() const {
return chooser_->selected_color_patch_for_testing()
->background()
->get_color();
}
SkColor GetTextualColor() const {
base::string16 text = chooser_->textfield_for_testing()->GetText();
if (text.empty() || text[0] != '#')
return SK_ColorTRANSPARENT;
uint32_t color;
return base::HexStringToUInt(base::UTF16ToUTF8(text.substr(1)), &color)
? SkColorSetA(color, SK_AlphaOPAQUE)
: SK_ColorTRANSPARENT;
}
void TypeColor(const std::string& color) {
chooser_->textfield_for_testing()->SetText(base::UTF8ToUTF16(color));
// Synthesize ContentsChanged, since Textfield normally doesn't deliver it
// for SetText, only for user-typed text.
chooser_->ContentsChanged(chooser_->textfield_for_testing(),
chooser_->textfield_for_testing()->GetText());
}
void PressMouseAt(views::View* view, const gfx::Point& p) {
#if 0
// TODO(ellyjones): Why doesn't this work?
const gfx::Point po = view->GetBoundsInScreen().origin();
generator_->MoveMouseTo(po + p.OffsetFromOrigin());
generator_->ClickLeftButton();
#endif
ui::MouseEvent press(ui::ET_MOUSE_PRESSED,
gfx::Point(view->x() + p.x(), view->y() + p.y()),
gfx::Point(0, 0), base::TimeTicks::Now(), 0, 0);
view->OnMousePressed(press);
}
private:
TestChooserListener listener_;
std::unique_ptr<views::ColorChooserView> chooser_;
std::unique_ptr<views::Widget> widget_;
std::unique_ptr<ui::test::EventGenerator> generator_;
};
TEST_F(ColorChooserTest, ShowsInitialColor) {
ExpectExactHSV(120, 1, 1);
EXPECT_EQ(GetShownColor(), SK_ColorGREEN);
EXPECT_EQ(GetTextualColor(), SK_ColorGREEN);
}
TEST_F(ColorChooserTest, AdjustingTextAdjustsShown) {
TypeColor("#ff0000");
ExpectExactHSV(0, 1, 1);
EXPECT_EQ(GetShownColor(), SK_ColorRED);
TypeColor("0000ff");
ExpectExactHSV(240, 1, 1);
EXPECT_EQ(GetShownColor(), SK_ColorBLUE);
}
TEST_F(ColorChooserTest, HueSliderChangesHue) {
ExpectExactHSV(120, 1, 1);
views::View* hv = chooser()->hue_view_for_testing();
PressMouseAt(hv, gfx::Point(1, hv->height()));
ExpectApproximateHSV(0, 1, 1);
PressMouseAt(hv, gfx::Point(1, (hv->height() * 3) / 4));
ExpectApproximateHSV(90, 1, 1);
PressMouseAt(hv, gfx::Point(1, hv->height() / 2));
ExpectApproximateHSV(180, 1, 1);
PressMouseAt(hv, gfx::Point(1, hv->height() / 4));
ExpectApproximateHSV(270, 1, 1);
}
// Missing tests, TODO:
// TEST_F(ColorChooserTest, SatValueChooserChangesSatValue)
// TEST_F(ColorChooserTest, UpdateFromWebUpdatesShownValues)
// TEST_F(ColorChooserTest, AdjustingTextAffectsHue)
// TEST_F(ColorChooserTest, AdjustingTextAffectsSatValue)
} // namespace
...@@ -434,17 +434,20 @@ void ColorChooserView::OnSaturationValueChosen(SkScalar saturation, ...@@ -434,17 +434,20 @@ void ColorChooserView::OnSaturationValueChosen(SkScalar saturation,
textfield_->SetText(GetColorText(color)); textfield_->SetText(GetColorText(color));
} }
bool ColorChooserView::CanMinimize() const { View* ColorChooserView::hue_view_for_testing() {
return false; return hue_;
} }
View* ColorChooserView::GetInitiallyFocusedView() { View* ColorChooserView::saturation_value_view_for_testing() {
return saturation_value_;
}
Textfield* ColorChooserView::textfield_for_testing() {
return textfield_; return textfield_;
} }
void ColorChooserView::WindowClosing() { View* ColorChooserView::selected_color_patch_for_testing() {
if (listener_) return selected_color_patch_;
listener_->OnColorChooserDialogClosed();
} }
void ColorChooserView::ContentsChanged(Textfield* sender, void ColorChooserView::ContentsChanged(Textfield* sender,
...@@ -472,4 +475,17 @@ bool ColorChooserView::HandleKeyEvent(Textfield* sender, ...@@ -472,4 +475,17 @@ bool ColorChooserView::HandleKeyEvent(Textfield* sender,
return true; return true;
} }
bool ColorChooserView::CanMinimize() const {
return false;
}
View* ColorChooserView::GetInitiallyFocusedView() {
return textfield_;
}
void ColorChooserView::WindowClosing() {
if (listener_)
listener_->OnColorChooserDialogClosed();
}
} // namespace views } // namespace views
...@@ -42,6 +42,17 @@ class VIEWS_EXPORT ColorChooserView : public WidgetDelegateView, ...@@ -42,6 +42,17 @@ class VIEWS_EXPORT ColorChooserView : public WidgetDelegateView,
float value() const { return hsv_[2]; } float value() const { return hsv_[2]; }
void set_listener(ColorChooserListener* listener) { listener_ = listener; } void set_listener(ColorChooserListener* listener) { listener_ = listener; }
View* hue_view_for_testing();
View* saturation_value_view_for_testing();
Textfield* textfield_for_testing();
View* selected_color_patch_for_testing();
// TextfieldController overrides:
void ContentsChanged(Textfield* sender,
const base::string16& new_contents) override;
bool HandleKeyEvent(Textfield* sender,
const ui::KeyEvent& key_event) override;
private: private:
class HueView; class HueView;
class SaturationValueView; class SaturationValueView;
...@@ -52,12 +63,6 @@ class VIEWS_EXPORT ColorChooserView : public WidgetDelegateView, ...@@ -52,12 +63,6 @@ class VIEWS_EXPORT ColorChooserView : public WidgetDelegateView,
View* GetInitiallyFocusedView() override; View* GetInitiallyFocusedView() override;
void WindowClosing() override; void WindowClosing() override;
// TextfieldController overrides:
void ContentsChanged(Textfield* sender,
const base::string16& new_contents) override;
bool HandleKeyEvent(Textfield* sender,
const ui::KeyEvent& key_event) override;
// The current color in HSV coordinate. // The current color in HSV coordinate.
SkScalar hsv_[3]; SkScalar hsv_[3];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment