Commit bc2b383e authored by Leonard Grey's avatar Leonard Grey Committed by Commit Bot

UIDevTools: Extract CSS tests

Currently, UIDevToolsTest tests the whole system together
in a single test file. This file uses WindowElement in most
tests, which makes it difficult to port for the forthcoming
Mac implementation, which does not have WindowElement due
to not being an Aura platform.

This  is the first of a series of changes that will
break most of UIDevToolsTest up into more granular tests,
which will make it easier to isolate WindowElement use
to Aura.

This change takes the functionality that was previously
being tested in the style tests in UIDevToolsTest, and
breaks it into:
- css_agent_unittest.cc, which tests interaction between
elements and CSSAgent
- Separate files for individual element subclasses, to
ensure the mapping between the elements and their underlying
objects.

Additionally, it fixes a few bugs smoked out by the new
tests in CSSAgent and WidgetElement.

Bug: 769352
Change-Id: Ie24f2166a2dbe7fef31db2800c8bf88a1f470057
Reviewed-on: https://chromium-review.googlesource.com/1231033
Commit-Queue: Leonard Grey <lgrey@chromium.org>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Cr-Commit-Position: refs/heads/master@{#592401}
parent f36de8b1
......@@ -97,3 +97,35 @@ component("ui_devtools") {
"//services/network/public/mojom",
]
}
static_library("test_support") {
testonly = true
sources = [
"ui_devtools_unittest_utils.cc",
"ui_devtools_unittest_utils.h",
]
public_deps = [
":ui_devtools",
"//testing/gmock",
]
}
source_set("unit_tests") {
testonly = true
cflags = []
if (is_win) {
cflags += [ "/wd4800" ] # Value forced to bool.
}
sources = [
"css_agent_unittest.cc",
]
deps = [
":test_support",
"//testing/gtest",
]
configs += [ "//build/config:precompiled_headers" ]
}
......@@ -167,10 +167,10 @@ Response CSSAgent::setStyleTexts(
if (!response.isSuccess())
return response;
updated_styles->addItem(BuildCSSStyle(ui_element));
if (!SetPropertiesForUIElement(ui_element, updated_bounds, visible))
return NodeNotFoundError(node_id);
updated_styles->addItem(BuildCSSStyle(ui_element));
}
*result = std::move(updated_styles);
return Response::OK();
......
// Copyright 2018 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 "components/ui_devtools/css_agent.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "components/ui_devtools/dom_agent.h"
#include "components/ui_devtools/ui_devtools_unittest_utils.h"
#include "components/ui_devtools/ui_element.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace ui_devtools {
class FakeUIElement : public UIElement {
public:
FakeUIElement(UIElementDelegate* ui_element_delegate)
: UIElement(UIElementType::ROOT, ui_element_delegate, nullptr) {}
~FakeUIElement() override {}
// Return a vector of pairs of properties' names and values.
std::vector<std::pair<std::string, std::string>> GetCustomProperties()
const override {
return {};
}
void GetBounds(gfx::Rect* bounds) const override { *bounds = bounds_; }
void SetBounds(const gfx::Rect& bounds) override { bounds_ = bounds; }
void GetVisible(bool* visible) const override { *visible = visible_; }
void SetVisible(bool visible) override { visible_ = visible; }
bool visible() const { return visible_; }
gfx::Rect bounds() const { return bounds_; }
std::pair<gfx::NativeWindow, gfx::Rect> GetNodeWindowAndBounds()
const override {
return {nullptr, gfx::Rect()};
}
std::unique_ptr<protocol::Array<std::string>> GetAttributes() const override {
return protocol::Array<std::string>::create();
}
private:
gfx::Rect bounds_;
bool visible_;
};
class FakeDOMAgent : public DOMAgent {
public:
void OnUIElementAdded(UIElement* parent, UIElement* child) override {
// nullptr root short circuits everything but adding |child|
// to the node ID map, which is all we need here.
DOMAgent::OnUIElementAdded(nullptr, child);
}
std::unique_ptr<protocol::DOM::Node> BuildTreeForUIElement(
UIElement* root) override {
return BuildDomNodeFromUIElement(root);
}
std::vector<UIElement*> CreateChildrenForRoot() override { return {}; }
};
class CSSAgentTest : public testing::Test {
public:
void SetUp() override {
testing::Test::SetUp();
frontend_channel_ = std::make_unique<FakeFrontendChannel>();
uber_dispatcher_ =
std::make_unique<protocol::UberDispatcher>(frontend_channel_.get());
dom_agent_ = std::make_unique<FakeDOMAgent>();
dom_agent_->Init(uber_dispatcher_.get());
css_agent_ = std::make_unique<CSSAgent>(dom_agent_.get());
css_agent_->Init(uber_dispatcher_.get());
css_agent_->enable();
element_ = std::make_unique<FakeUIElement>(dom_agent_.get());
dom_agent_->OnUIElementAdded(nullptr, element_.get());
}
protected:
using StyleArray = protocol::Array<protocol::CSS::CSSStyle>;
std::pair<bool, std::unique_ptr<StyleArray>> SetStyle(
const std::string& style_text,
int node_id) {
auto edits = protocol::Array<protocol::CSS::StyleDeclarationEdit>::create();
auto edit = protocol::CSS::StyleDeclarationEdit::create()
.setStyleSheetId(base::IntToString(node_id))
.setText(style_text)
.build();
edits->addItem(std::move(edit));
std::unique_ptr<StyleArray> output;
auto response = css_agent_->setStyleTexts(std::move(edits), &output);
return {response.isSuccess(), std::move(output)};
}
std::string GetValueForProperty(protocol::CSS::CSSStyle* style,
const std::string& property_name) {
auto* properties = style->getCssProperties();
for (size_t i = 0; i < properties->length(); ++i) {
auto* property = properties->get(i);
if (property->getName() == property_name) {
return property->getValue();
}
}
return std::string();
}
int GetStyleSheetChangedCount(int node_id) {
return frontend_channel_->CountProtocolNotificationMessage(
base::StringPrintf("{\"method\":\"CSS.styleSheetChanged\",\"params\":{"
"\"styleSheetId\":\"%d\"}}",
node_id));
}
CSSAgent* css_agent() { return css_agent_.get(); }
DOMAgent* dom_agent() { return dom_agent_.get(); }
FakeUIElement* element() { return element_.get(); }
private:
std::unique_ptr<CSSAgent> css_agent_;
std::unique_ptr<DOMAgent> dom_agent_;
std::unique_ptr<FakeFrontendChannel> frontend_channel_;
std::unique_ptr<protocol::UberDispatcher> uber_dispatcher_;
std::unique_ptr<FakeUIElement> element_;
};
TEST_F(CSSAgentTest, UnrecognizedNodeFails) {
EXPECT_FALSE(SetStyle("x : 25", 42).first);
}
TEST_F(CSSAgentTest, UnrecognizedKeyFails) {
element()->SetVisible(true);
element()->SetBounds(gfx::Rect(1, 2, 3, 4));
auto result = SetStyle("nonsense : 3.14", element()->node_id());
EXPECT_FALSE(result.first);
EXPECT_FALSE(result.second);
// Ensure element didn't change.
EXPECT_TRUE(element()->visible());
EXPECT_EQ(element()->bounds(), gfx::Rect(1, 2, 3, 4));
}
TEST_F(CSSAgentTest, UnrecognizedValueFails) {
element()->SetVisible(true);
element()->SetBounds(gfx::Rect(1, 2, 3, 4));
auto result = SetStyle("visibility : banana", element()->node_id());
EXPECT_FALSE(result.first);
EXPECT_FALSE(result.second);
// Ensure element didn't change.
EXPECT_TRUE(element()->visible());
EXPECT_EQ(element()->bounds(), gfx::Rect(1, 2, 3, 4));
}
TEST_F(CSSAgentTest, SettingVisibility) {
element()->SetVisible(false);
DCHECK(!element()->visible());
auto result = SetStyle("visibility: 1", element()->node_id());
EXPECT_TRUE(result.first);
EXPECT_TRUE(element()->visible());
EXPECT_EQ(result.second->length(), 1U);
protocol::CSS::CSSStyle* style = result.second->get(0);
EXPECT_EQ(style->getStyleSheetId("default"),
base::IntToString(element()->node_id()));
EXPECT_EQ(GetValueForProperty(style, "visibility"), "1");
}
TEST_F(CSSAgentTest, SettingX) {
DCHECK_EQ(element()->bounds().x(), 0);
auto result = SetStyle("x: 500", element()->node_id());
EXPECT_TRUE(result.first);
EXPECT_EQ(element()->bounds().x(), 500);
EXPECT_EQ(result.second->length(), 1U);
protocol::CSS::CSSStyle* style = result.second->get(0);
EXPECT_EQ(style->getStyleSheetId("default"),
base::IntToString(element()->node_id()));
EXPECT_EQ(GetValueForProperty(style, "x"), "500");
}
TEST_F(CSSAgentTest, SettingY) {
DCHECK_EQ(element()->bounds().y(), 0);
auto result = SetStyle("y: 100", element()->node_id());
EXPECT_TRUE(result.first);
EXPECT_EQ(element()->bounds().y(), 100);
EXPECT_EQ(result.second->length(), 1U);
protocol::CSS::CSSStyle* style = result.second->get(0);
EXPECT_EQ(style->getStyleSheetId("default"),
base::IntToString(element()->node_id()));
EXPECT_EQ(GetValueForProperty(style, "y"), "100");
}
TEST_F(CSSAgentTest, SettingWidth) {
DCHECK_EQ(element()->bounds().width(), 0);
auto result = SetStyle("width: 20", element()->node_id());
EXPECT_TRUE(result.first);
EXPECT_EQ(element()->bounds().width(), 20);
EXPECT_EQ(result.second->length(), 1U);
protocol::CSS::CSSStyle* style = result.second->get(0);
EXPECT_EQ(style->getStyleSheetId("default"),
base::IntToString(element()->node_id()));
EXPECT_EQ(GetValueForProperty(style, "width"), "20");
}
TEST_F(CSSAgentTest, SettingHeight) {
DCHECK_EQ(element()->bounds().height(), 0);
auto result = SetStyle("height: 30", element()->node_id());
EXPECT_TRUE(result.first);
EXPECT_EQ(element()->bounds().height(), 30);
EXPECT_EQ(result.second->length(), 1U);
protocol::CSS::CSSStyle* style = result.second->get(0);
EXPECT_EQ(style->getStyleSheetId("default"),
base::IntToString(element()->node_id()));
EXPECT_EQ(GetValueForProperty(style, "height"), "30");
}
TEST_F(CSSAgentTest, SettingAll) {
DCHECK(element()->bounds() == gfx::Rect());
DCHECK(element()->visible());
// Throw in odd whitespace while we're at it.
std::string new_text(
"\ny: 25; width: 50; visibility:0; height: 30;\nx: 9000;\n\n");
auto result = SetStyle(new_text, element()->node_id());
EXPECT_TRUE(result.first);
EXPECT_EQ(element()->bounds(), gfx::Rect(9000, 25, 50, 30));
EXPECT_FALSE(element()->visible());
EXPECT_EQ(result.second->length(), 1U);
protocol::CSS::CSSStyle* style = result.second->get(0);
EXPECT_EQ(style->getStyleSheetId("default"),
base::IntToString(element()->node_id()));
EXPECT_EQ(GetValueForProperty(style, "x"), "9000");
EXPECT_EQ(GetValueForProperty(style, "y"), "25");
EXPECT_EQ(GetValueForProperty(style, "width"), "50");
EXPECT_EQ(GetValueForProperty(style, "height"), "30");
EXPECT_EQ(GetValueForProperty(style, "visibility"), "0");
}
TEST_F(CSSAgentTest, UpdateOnBoundsChange) {
FakeUIElement another_element(dom_agent());
EXPECT_EQ(0, GetStyleSheetChangedCount(element()->node_id()));
EXPECT_EQ(0, GetStyleSheetChangedCount(another_element.node_id()));
css_agent()->OnElementBoundsChanged(element());
EXPECT_EQ(1, GetStyleSheetChangedCount(element()->node_id()));
EXPECT_EQ(0, GetStyleSheetChangedCount(another_element.node_id()));
css_agent()->OnElementBoundsChanged(&another_element);
EXPECT_EQ(1, GetStyleSheetChangedCount(element()->node_id()));
EXPECT_EQ(1, GetStyleSheetChangedCount(another_element.node_id()));
css_agent()->OnElementBoundsChanged(&another_element);
EXPECT_EQ(1, GetStyleSheetChangedCount(element()->node_id()));
EXPECT_EQ(2, GetStyleSheetChangedCount(another_element.node_id()));
}
} // namespace ui_devtools
// Copyright 2018 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 "components/ui_devtools/ui_devtools_unittest_utils.h"
#include "base/strings/string_util.h"
namespace ui_devtools {
MockUIElementDelegate::MockUIElementDelegate() {}
MockUIElementDelegate::~MockUIElementDelegate() {}
FakeFrontendChannel::FakeFrontendChannel() {}
FakeFrontendChannel::~FakeFrontendChannel() {}
int FakeFrontendChannel::CountProtocolNotificationMessageStartsWith(
const std::string& message) {
int count = 0;
for (const std::string& s : protocol_notification_messages_) {
if (base::StartsWith(s, message, base::CompareCase::SENSITIVE))
count++;
}
return count;
}
int FakeFrontendChannel::CountProtocolNotificationMessage(
const std::string& message) {
return std::count(protocol_notification_messages_.begin(),
protocol_notification_messages_.end(), message);
}
void FakeFrontendChannel::sendProtocolNotification(
std::unique_ptr<protocol::Serializable> message) {
protocol_notification_messages_.push_back(message->serialize());
}
} // namespace ui_devtools
// Copyright 2018 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.
#ifndef COMPONENTS_UI_DEVTOOLS_UI_DEVTOOLS_UNITTEST_UTILS_H_
#define COMPONENTS_UI_DEVTOOLS_UI_DEVTOOLS_UNITTEST_UTILS_H_
#include "components/ui_devtools/Protocol.h"
#include "components/ui_devtools/ui_element_delegate.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace ui_devtools {
class FakeFrontendChannel : public protocol::FrontendChannel {
public:
FakeFrontendChannel();
~FakeFrontendChannel() override;
int CountProtocolNotificationMessageStartsWith(const std::string& message);
int CountProtocolNotificationMessage(const std::string& message);
// FrontendChannel:
void sendProtocolResponse(
int callId,
std::unique_ptr<protocol::Serializable> message) override {}
void flushProtocolNotifications() override {}
void fallThrough(int call_id,
const std::string& method,
const std::string& message) override {}
void sendProtocolNotification(
std::unique_ptr<protocol::Serializable> message) override;
private:
std::vector<std::string> protocol_notification_messages_;
DISALLOW_COPY_AND_ASSIGN(FakeFrontendChannel);
};
class MockUIElementDelegate : public UIElementDelegate {
public:
MockUIElementDelegate();
~MockUIElementDelegate() override;
MOCK_METHOD2(OnUIElementAdded, void(UIElement*, UIElement*));
MOCK_METHOD2(OnUIElementReordered, void(UIElement*, UIElement*));
MOCK_METHOD1(OnUIElementRemoved, void(UIElement*));
MOCK_METHOD1(OnUIElementBoundsChanged, void(UIElement*));
};
} // namespace ui_devtools
#endif // COMPONENTS_UI_DEVTOOLS_UI_DEVTOOLS_UNITTEST_UTILS_H_
......@@ -42,11 +42,15 @@ source_set("unit_tests") {
sources = [
"ui_devtools_unittest.cc",
"view_element_unittest.cc",
"widget_element_unittest.cc",
"window_element_unittest.cc",
]
deps = [
":views",
"//components/ui_devtools",
"//components/ui_devtools:test_support",
"//skia",
"//testing/gtest",
"//ui/aura",
......
// Copyright 2018 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 "components/ui_devtools/views/view_element.h"
#include "base/strings/utf_string_conversions.h"
#include "components/ui_devtools/Protocol.h"
#include "components/ui_devtools/ui_devtools_unittest_utils.h"
#include "ui/views/test/views_test_base.h"
namespace ui_devtools {
using ::testing::_;
class NamedTestView : public views::View {
public:
static const char kViewClassName[];
const char* GetClassName() const override { return kViewClassName; }
// For custom properties test.
bool GetTooltipText(const gfx::Point& p,
base::string16* tooltip) const override {
*tooltip = base::ASCIIToUTF16("This is the tooltip");
return true;
}
};
const char NamedTestView::kViewClassName[] = "NamedTestView";
class ViewElementTest : public views::ViewsTestBase {
public:
ViewElementTest() {}
~ViewElementTest() override {}
protected:
void SetUp() override {
views::ViewsTestBase::SetUp();
view_.reset(new NamedTestView);
delegate_.reset(new testing::NiceMock<MockUIElementDelegate>);
// |OnUIElementAdded| is called on element creation.
EXPECT_CALL(*delegate_, OnUIElementAdded(_, _)).Times(1);
element_.reset(new ViewElement(view_.get(), delegate_.get(), nullptr));
}
NamedTestView* view() { return view_.get(); }
ViewElement* element() { return element_.get(); }
MockUIElementDelegate* delegate() { return delegate_.get(); }
private:
std::unique_ptr<NamedTestView> view_;
std::unique_ptr<ViewElement> element_;
std::unique_ptr<MockUIElementDelegate> delegate_;
DISALLOW_COPY_AND_ASSIGN(ViewElementTest);
};
TEST_F(ViewElementTest, SettingsBoundsOnViewCallsDelegate) {
EXPECT_CALL(*delegate(), OnUIElementBoundsChanged(element())).Times(1);
view()->SetBounds(1, 2, 3, 4);
}
TEST_F(ViewElementTest, AddingChildView) {
// The first call is from the element being created, before it
// gets parented to |element_|.
EXPECT_CALL(*delegate(), OnUIElementAdded(nullptr, _)).Times(1);
EXPECT_CALL(*delegate(), OnUIElementAdded(element(), _)).Times(1);
views::View child_view;
view()->AddChildView(&child_view);
DCHECK_EQ(element()->children().size(), 1U);
UIElement* child_element = element()->children()[0];
EXPECT_CALL(*delegate(), OnUIElementRemoved(child_element)).Times(1);
view()->RemoveChildView(&child_view);
}
TEST_F(ViewElementTest, SettingsBoundsOnElementSetsOnView) {
DCHECK(view()->bounds() == gfx::Rect());
element()->SetBounds(gfx::Rect(1, 2, 3, 4));
EXPECT_EQ(view()->bounds(), gfx::Rect(1, 2, 3, 4));
}
TEST_F(ViewElementTest, SettingVisibleOnElementSetsOnView) {
DCHECK(view()->visible());
element()->SetVisible(false);
EXPECT_FALSE(view()->visible());
element()->SetVisible(true);
EXPECT_TRUE(view()->visible());
}
TEST_F(ViewElementTest, GetVisible) {
bool visible;
view()->SetVisible(false);
element()->GetVisible(&visible);
EXPECT_FALSE(visible);
view()->SetVisible(true);
element()->GetVisible(&visible);
EXPECT_TRUE(visible);
}
TEST_F(ViewElementTest, GetBounds) {
gfx::Rect bounds;
view()->SetBounds(10, 20, 30, 40);
element()->GetBounds(&bounds);
EXPECT_EQ(bounds, gfx::Rect(10, 20, 30, 40));
}
TEST_F(ViewElementTest, GetAttributes) {
std::unique_ptr<protocol::Array<std::string>> attrs =
element()->GetAttributes();
DCHECK_EQ(attrs->length(), 2U);
EXPECT_EQ(attrs->get(0), "name");
EXPECT_EQ(attrs->get(1), NamedTestView::kViewClassName);
}
TEST_F(ViewElementTest, GetCustomProperties) {
auto props = element()->GetCustomProperties();
DCHECK_EQ(props.size(), 1U);
EXPECT_EQ(props[0].first, "tooltip");
EXPECT_EQ(props[0].second, "This is the tooltip");
}
} // namespace ui_devtools
......@@ -15,10 +15,14 @@ WidgetElement::WidgetElement(views::Widget* widget,
: UIElement(UIElementType::WIDGET, ui_element_delegate, parent),
widget_(widget) {
widget_->AddRemovalsObserver(this);
widget_->AddObserver(this);
}
WidgetElement::~WidgetElement() {
widget_->RemoveRemovalsObserver(this);
if (widget_) {
widget_->RemoveRemovalsObserver(this);
widget_->RemoveObserver(this);
}
}
void WidgetElement::OnWillRemoveView(views::Widget* widget, views::View* view) {
......@@ -36,6 +40,12 @@ void WidgetElement::OnWidgetBoundsChanged(views::Widget* widget,
delegate()->OnUIElementBoundsChanged(this);
}
void WidgetElement::OnWidgetDestroyed(views::Widget* widget) {
DCHECK_EQ(widget, widget_);
delegate()->OnUIElementRemoved(this);
widget_ = nullptr;
}
std::vector<std::pair<std::string, std::string>>
WidgetElement::GetCustomProperties() const {
return {};
......
......@@ -33,6 +33,7 @@ class WidgetElement : public views::WidgetRemovalsObserver,
// views::WidgetObserver:
void OnWidgetBoundsChanged(views::Widget* widget,
const gfx::Rect& new_bounds) override;
void OnWidgetDestroyed(views::Widget* widget) override;
// UIElement:
std::vector<std::pair<std::string, std::string>> GetCustomProperties()
......
// Copyright 2018 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 "components/ui_devtools/views/widget_element.h"
#include "components/ui_devtools/Protocol.h"
#include "components/ui_devtools/ui_devtools_unittest_utils.h"
#include "components/ui_devtools/views/view_element.h"
#include "ui/views/test/views_test_base.h"
namespace ui_devtools {
using ::testing::_;
namespace {
const std::string kWidgetName = "A test widget";
}
class WidgetElementTest : public views::ViewsTestBase {
public:
WidgetElementTest() {}
~WidgetElementTest() override {}
void SetUp() override {
views::ViewsTestBase::SetUp();
widget_ = new views::Widget;
views::Widget::InitParams params =
CreateParams(views::Widget::InitParams::TYPE_WINDOW);
params.name = kWidgetName;
widget_->Init(params);
delegate_.reset(new testing::NiceMock<MockUIElementDelegate>);
element_.reset(new WidgetElement(widget_, delegate_.get(), nullptr));
// The widget element will delete the ViewElement in |OnWillRemoveView|
// TODO(lgrey): I think probably WidgetElement should do this itself
// rather than making the DOMAgent (or test) put the tree together.
element()->AddChild(
new ViewElement(widget_->GetRootView(), delegate_.get(), element()));
}
void TearDown() override {
widget_->CloseNow();
views::ViewsTestBase::TearDown();
}
protected:
views::Widget* widget() { return widget_; };
WidgetElement* element() { return element_.get(); }
MockUIElementDelegate* delegate() { return delegate_.get(); }
private:
views::Widget* widget_ = nullptr;
std::unique_ptr<WidgetElement> element_;
std::unique_ptr<MockUIElementDelegate> delegate_;
DISALLOW_COPY_AND_ASSIGN(WidgetElementTest);
};
TEST_F(WidgetElementTest, SettingsBoundsOnWidgetCallsDelegate) {
// Once for the root view, and once for the widget.
EXPECT_CALL(*delegate(), OnUIElementBoundsChanged(_))
.Times(::testing::AtLeast(1));
EXPECT_CALL(*delegate(), OnUIElementBoundsChanged(element()))
.Times(::testing::AtLeast(1));
widget()->SetBounds(gfx::Rect(10, 20, 300, 400));
}
TEST_F(WidgetElementTest, SettingsBoundsOnElementSetsOnWidget) {
gfx::Rect old_bounds = widget()->GetRestoredBounds();
gfx::Rect new_bounds = gfx::Rect(10, 20, 300, 400);
DCHECK(old_bounds != new_bounds);
element()->SetBounds(new_bounds);
EXPECT_EQ(widget()->GetRestoredBounds(), new_bounds);
}
TEST_F(WidgetElementTest, SettingVisibleOnElementSetsOnWidget) {
DCHECK(!widget()->IsVisible());
element()->SetVisible(true);
EXPECT_TRUE(widget()->IsVisible());
element()->SetVisible(false);
EXPECT_FALSE(widget()->IsVisible());
}
TEST_F(WidgetElementTest, GetBounds) {
gfx::Rect actual_bounds;
gfx::Rect new_bounds = gfx::Rect(10, 20, 300, 400);
widget()->SetBounds(new_bounds);
element()->GetBounds(&actual_bounds);
EXPECT_EQ(actual_bounds, new_bounds);
}
TEST_F(WidgetElementTest, GetVisible) {
DCHECK(!widget()->IsVisible());
bool visible;
element()->GetVisible(&visible);
EXPECT_FALSE(visible);
widget()->Show();
element()->GetVisible(&visible);
EXPECT_TRUE(visible);
widget()->Hide();
element()->GetVisible(&visible);
EXPECT_FALSE(visible);
}
TEST_F(WidgetElementTest, GetAttributes) {
std::unique_ptr<protocol::Array<std::string>> attrs =
element()->GetAttributes();
DCHECK_EQ(attrs->length(), 4U);
EXPECT_EQ(attrs->get(0), "name");
EXPECT_EQ(attrs->get(1), kWidgetName);
DCHECK(!widget()->IsActive());
EXPECT_EQ(attrs->get(2), "active");
EXPECT_EQ(attrs->get(3), "false");
widget()->Activate();
attrs = element()->GetAttributes();
DCHECK_EQ(attrs->length(), 4U);
EXPECT_EQ(attrs->get(2), "active");
EXPECT_EQ(attrs->get(3), "true");
}
} // namespace ui_devtools
// Copyright 2018 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 "components/ui_devtools/views/window_element.h"
#include "components/ui_devtools/Protocol.h"
#include "components/ui_devtools/ui_devtools_unittest_utils.h"
#include "ui/aura/window.h"
#include "ui/views/test/views_test_base.h"
#include "ui/wm/core/window_util.h"
namespace ui_devtools {
using ::testing::_;
class WindowElementTest : public views::ViewsTestBase {
public:
WindowElementTest() {}
~WindowElementTest() override {}
void SetUp() override {
views::ViewsTestBase::SetUp();
window_.reset(new aura::Window(nullptr, aura::client::WINDOW_TYPE_NORMAL));
window_->Init(ui::LAYER_NOT_DRAWN);
aura::Window* root_window = GetContext();
DCHECK(root_window);
root_window->AddChild(window_.get());
delegate_.reset(new testing::NiceMock<MockUIElementDelegate>);
// |OnUIElementAdded| is called on element creation.
EXPECT_CALL(*delegate_, OnUIElementAdded(_, _)).Times(1);
element_.reset(new WindowElement(window_.get(), delegate_.get(), nullptr));
}
void TearDown() override {
// The root window needs to be empty by teardown.
element_.reset();
delegate_.reset();
window_.reset();
views::ViewsTestBase::TearDown();
}
protected:
aura::Window* window() { return window_.get(); }
WindowElement* element() { return element_.get(); }
MockUIElementDelegate* delegate() { return delegate_.get(); }
private:
std::unique_ptr<aura::Window> window_;
std::unique_ptr<WindowElement> element_;
std::unique_ptr<MockUIElementDelegate> delegate_;
DISALLOW_COPY_AND_ASSIGN(WindowElementTest);
};
TEST_F(WindowElementTest, SettingsBoundsOnWindowCallsDelegate) {
EXPECT_CALL(*delegate(), OnUIElementBoundsChanged(element())).Times(1);
window()->SetBounds(gfx::Rect(10, 20, 300, 400));
}
TEST_F(WindowElementTest, SettingsBoundsOnElementSetsOnWindow) {
gfx::Rect old_bounds = window()->bounds();
gfx::Rect new_bounds = gfx::Rect(10, 20, 300, 400);
DCHECK(old_bounds != new_bounds);
element()->SetBounds(new_bounds);
EXPECT_EQ(window()->bounds(), new_bounds);
}
TEST_F(WindowElementTest, SettingVisibleOnElementSetsOnWindow) {
DCHECK(!window()->IsVisible());
element()->SetVisible(true);
EXPECT_TRUE(window()->IsVisible());
element()->SetVisible(false);
EXPECT_FALSE(window()->IsVisible());
}
TEST_F(WindowElementTest, GetVisible) {
bool visible;
window()->Hide();
element()->GetVisible(&visible);
EXPECT_FALSE(visible);
window()->Show();
element()->GetVisible(&visible);
EXPECT_TRUE(visible);
}
TEST_F(WindowElementTest, GetBounds) {
gfx::Rect actual_bounds;
gfx::Rect new_bounds = gfx::Rect(10, 20, 300, 400);
window()->SetBounds(new_bounds);
element()->GetBounds(&actual_bounds);
EXPECT_EQ(actual_bounds, new_bounds);
}
TEST_F(WindowElementTest, GetAttributes) {
std::string window_name("A window name");
window()->SetName(window_name);
std::unique_ptr<protocol::Array<std::string>> attrs =
element()->GetAttributes();
DCHECK_EQ(attrs->length(), 4U);
EXPECT_EQ(attrs->get(0), "name");
EXPECT_EQ(attrs->get(1), window_name);
DCHECK(!wm::IsActiveWindow(window()));
EXPECT_EQ(attrs->get(2), "active");
EXPECT_EQ(attrs->get(3), "false");
wm::ActivateWindow(window());
attrs = element()->GetAttributes();
DCHECK_EQ(attrs->length(), 4U);
EXPECT_EQ(attrs->get(2), "active");
EXPECT_EQ(attrs->get(3), "true");
}
} // namespace ui_devtools
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