summaryrefslogtreecommitdiffstats
path: root/components/mus/public/cpp/tests
diff options
context:
space:
mode:
Diffstat (limited to 'components/mus/public/cpp/tests')
-rw-r--r--components/mus/public/cpp/tests/BUILD.gn10
-rw-r--r--components/mus/public/cpp/tests/run_all_unittests.cc6
-rw-r--r--components/mus/public/cpp/tests/view_manager_test_suite.h27
-rw-r--r--components/mus/public/cpp/tests/view_unittest.cc874
-rw-r--r--components/mus/public/cpp/tests/window_server_test_base.cc (renamed from components/mus/public/cpp/tests/view_manager_test_base.cc)40
-rw-r--r--components/mus/public/cpp/tests/window_server_test_base.h (renamed from components/mus/public/cpp/tests/view_manager_test_base.h)46
-rw-r--r--components/mus/public/cpp/tests/window_server_test_suite.cc (renamed from components/mus/public/cpp/tests/view_manager_test_suite.cc)8
-rw-r--r--components/mus/public/cpp/tests/window_server_test_suite.h27
-rw-r--r--components/mus/public/cpp/tests/window_unittest.cc875
9 files changed, 957 insertions, 956 deletions
diff --git a/components/mus/public/cpp/tests/BUILD.gn b/components/mus/public/cpp/tests/BUILD.gn
index c582994..b9ba5d0 100644
--- a/components/mus/public/cpp/tests/BUILD.gn
+++ b/components/mus/public/cpp/tests/BUILD.gn
@@ -9,8 +9,8 @@ source_set("test_support") {
testonly = true
sources = [
- "view_manager_test_base.cc",
- "view_manager_test_base.h",
+ "window_server_test_base.cc",
+ "window_server_test_base.h",
]
deps = [
@@ -26,9 +26,9 @@ source_set("test_support") {
test("mojo_view_manager_lib_unittests") {
sources = [
"run_all_unittests.cc",
- "view_manager_test_suite.cc",
- "view_manager_test_suite.h",
- "view_unittest.cc",
+ "window_server_test_suite.cc",
+ "window_server_test_suite.h",
+ "window_unittest.cc",
]
deps = [
diff --git a/components/mus/public/cpp/tests/run_all_unittests.cc b/components/mus/public/cpp/tests/run_all_unittests.cc
index ee82a07..1af6dbd 100644
--- a/components/mus/public/cpp/tests/run_all_unittests.cc
+++ b/components/mus/public/cpp/tests/run_all_unittests.cc
@@ -4,12 +4,12 @@
#include "base/bind.h"
#include "base/test/launcher/unit_test_launcher.h"
-#include "components/mus/public/cpp/tests/view_manager_test_suite.h"
+#include "components/mus/public/cpp/tests/window_server_test_suite.h"
int main(int argc, char** argv) {
- mus::ViewManagerTestSuite test_suite(argc, argv);
+ mus::WindowServerTestSuite test_suite(argc, argv);
return base::LaunchUnitTests(argc, argv,
- base::Bind(&mus::ViewManagerTestSuite::Run,
+ base::Bind(&mus::WindowServerTestSuite::Run,
base::Unretained(&test_suite)));
}
diff --git a/components/mus/public/cpp/tests/view_manager_test_suite.h b/components/mus/public/cpp/tests/view_manager_test_suite.h
deleted file mode 100644
index b68bb2f..0000000
--- a/components/mus/public/cpp/tests/view_manager_test_suite.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2014 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_MUS_PUBLIC_CPP_TESTS_VIEW_MANAGER_TEST_SUITE_H_
-#define COMPONENTS_MUS_PUBLIC_CPP_TESTS_VIEW_MANAGER_TEST_SUITE_H_
-
-#include "base/test/test_suite.h"
-#include "third_party/mojo/src/mojo/public/cpp/system/macros.h"
-
-namespace mus {
-
-class ViewManagerTestSuite : public base::TestSuite {
- public:
- ViewManagerTestSuite(int argc, char** argv);
- ~ViewManagerTestSuite() override;
-
- protected:
- void Initialize() override;
-
- private:
- MOJO_DISALLOW_COPY_AND_ASSIGN(ViewManagerTestSuite);
-};
-
-} // namespace mus
-
-#endif // COMPONENTS_MUS_PUBLIC_CPP_TESTS_VIEW_MANAGER_TEST_SUITE_H_
diff --git a/components/mus/public/cpp/tests/view_unittest.cc b/components/mus/public/cpp/tests/view_unittest.cc
deleted file mode 100644
index c991ca3..0000000
--- a/components/mus/public/cpp/tests/view_unittest.cc
+++ /dev/null
@@ -1,874 +0,0 @@
-// Copyright 2014 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/mus/public/cpp/view.h"
-
-#include "base/logging.h"
-#include "base/strings/stringprintf.h"
-#include "components/mus/public/cpp/lib/view_private.h"
-#include "components/mus/public/cpp/util.h"
-#include "components/mus/public/cpp/view_observer.h"
-#include "components/mus/public/cpp/view_property.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace mus {
-
-// View ------------------------------------------------------------------------
-
-typedef testing::Test ViewTest;
-
-// Subclass with public ctor/dtor.
-class TestView : public View {
- public:
- TestView() { ViewPrivate(this).set_id(1); }
- ~TestView() {}
-
- private:
- MOJO_DISALLOW_COPY_AND_ASSIGN(TestView);
-};
-
-TEST_F(ViewTest, AddChild) {
- TestView v1;
- TestView v11;
- v1.AddChild(&v11);
- EXPECT_EQ(1U, v1.children().size());
-}
-
-TEST_F(ViewTest, RemoveChild) {
- TestView v1;
- TestView v11;
- v1.AddChild(&v11);
- EXPECT_EQ(1U, v1.children().size());
- v1.RemoveChild(&v11);
- EXPECT_EQ(0U, v1.children().size());
-}
-
-TEST_F(ViewTest, Reparent) {
- TestView v1;
- TestView v2;
- TestView v11;
- v1.AddChild(&v11);
- EXPECT_EQ(1U, v1.children().size());
- v2.AddChild(&v11);
- EXPECT_EQ(1U, v2.children().size());
- EXPECT_EQ(0U, v1.children().size());
-}
-
-TEST_F(ViewTest, Contains) {
- TestView v1;
-
- // Direct descendant.
- TestView v11;
- v1.AddChild(&v11);
- EXPECT_TRUE(v1.Contains(&v11));
-
- // Indirect descendant.
- TestView v111;
- v11.AddChild(&v111);
- EXPECT_TRUE(v1.Contains(&v111));
-}
-
-TEST_F(ViewTest, GetChildById) {
- TestView v1;
- ViewPrivate(&v1).set_id(1);
- TestView v11;
- ViewPrivate(&v11).set_id(11);
- v1.AddChild(&v11);
- TestView v111;
- ViewPrivate(&v111).set_id(111);
- v11.AddChild(&v111);
-
- // Find direct & indirect descendents.
- EXPECT_EQ(&v11, v1.GetChildById(v11.id()));
- EXPECT_EQ(&v111, v1.GetChildById(v111.id()));
-}
-
-TEST_F(ViewTest, DrawnAndVisible) {
- TestView v1;
- EXPECT_TRUE(v1.visible());
- EXPECT_FALSE(v1.IsDrawn());
-
- ViewPrivate(&v1).set_drawn(true);
-
- TestView v11;
- v1.AddChild(&v11);
- EXPECT_TRUE(v11.visible());
- EXPECT_TRUE(v11.IsDrawn());
-
- v1.RemoveChild(&v11);
- EXPECT_TRUE(v11.visible());
- EXPECT_FALSE(v11.IsDrawn());
-}
-
-namespace {
-DEFINE_VIEW_PROPERTY_KEY(int, kIntKey, -2);
-DEFINE_VIEW_PROPERTY_KEY(const char*, kStringKey, "squeamish");
-}
-
-TEST_F(ViewTest, Property) {
- TestView v;
-
- // Non-existent properties should return the default values.
- EXPECT_EQ(-2, v.GetLocalProperty(kIntKey));
- EXPECT_EQ(std::string("squeamish"), v.GetLocalProperty(kStringKey));
-
- // A set property value should be returned again (even if it's the default
- // value).
- v.SetLocalProperty(kIntKey, INT_MAX);
- EXPECT_EQ(INT_MAX, v.GetLocalProperty(kIntKey));
- v.SetLocalProperty(kIntKey, -2);
- EXPECT_EQ(-2, v.GetLocalProperty(kIntKey));
- v.SetLocalProperty(kIntKey, INT_MIN);
- EXPECT_EQ(INT_MIN, v.GetLocalProperty(kIntKey));
-
- v.SetLocalProperty(kStringKey, static_cast<const char*>(NULL));
- EXPECT_EQ(NULL, v.GetLocalProperty(kStringKey));
- v.SetLocalProperty(kStringKey, "squeamish");
- EXPECT_EQ(std::string("squeamish"), v.GetLocalProperty(kStringKey));
- v.SetLocalProperty(kStringKey, "ossifrage");
- EXPECT_EQ(std::string("ossifrage"), v.GetLocalProperty(kStringKey));
-
- // ClearProperty should restore the default value.
- v.ClearLocalProperty(kIntKey);
- EXPECT_EQ(-2, v.GetLocalProperty(kIntKey));
- v.ClearLocalProperty(kStringKey);
- EXPECT_EQ(std::string("squeamish"), v.GetLocalProperty(kStringKey));
-}
-
-namespace {
-
-class TestProperty {
- public:
- TestProperty() {}
- virtual ~TestProperty() { last_deleted_ = this; }
- static TestProperty* last_deleted() { return last_deleted_; }
-
- private:
- static TestProperty* last_deleted_;
- MOJO_DISALLOW_COPY_AND_ASSIGN(TestProperty);
-};
-
-TestProperty* TestProperty::last_deleted_ = NULL;
-
-DEFINE_OWNED_VIEW_PROPERTY_KEY(TestProperty, kOwnedKey, NULL);
-
-} // namespace
-
-TEST_F(ViewTest, OwnedProperty) {
- TestProperty* p3 = NULL;
- {
- TestView v;
- EXPECT_EQ(NULL, v.GetLocalProperty(kOwnedKey));
- TestProperty* p1 = new TestProperty();
- v.SetLocalProperty(kOwnedKey, p1);
- EXPECT_EQ(p1, v.GetLocalProperty(kOwnedKey));
- EXPECT_EQ(NULL, TestProperty::last_deleted());
-
- TestProperty* p2 = new TestProperty();
- v.SetLocalProperty(kOwnedKey, p2);
- EXPECT_EQ(p2, v.GetLocalProperty(kOwnedKey));
- EXPECT_EQ(p1, TestProperty::last_deleted());
-
- v.ClearLocalProperty(kOwnedKey);
- EXPECT_EQ(NULL, v.GetLocalProperty(kOwnedKey));
- EXPECT_EQ(p2, TestProperty::last_deleted());
-
- p3 = new TestProperty();
- v.SetLocalProperty(kOwnedKey, p3);
- EXPECT_EQ(p3, v.GetLocalProperty(kOwnedKey));
- EXPECT_EQ(p2, TestProperty::last_deleted());
- }
-
- EXPECT_EQ(p3, TestProperty::last_deleted());
-}
-
-// ViewObserver --------------------------------------------------------
-
-typedef testing::Test ViewObserverTest;
-
-bool TreeChangeParamsMatch(const ViewObserver::TreeChangeParams& lhs,
- const ViewObserver::TreeChangeParams& rhs) {
- return lhs.target == rhs.target && lhs.old_parent == rhs.old_parent &&
- lhs.new_parent == rhs.new_parent && lhs.receiver == rhs.receiver;
-}
-
-class TreeChangeObserver : public ViewObserver {
- public:
- explicit TreeChangeObserver(View* observee) : observee_(observee) {
- observee_->AddObserver(this);
- }
- ~TreeChangeObserver() override { observee_->RemoveObserver(this); }
-
- void Reset() { received_params_.clear(); }
-
- const std::vector<TreeChangeParams>& received_params() {
- return received_params_;
- }
-
- private:
- // Overridden from ViewObserver:
- void OnTreeChanging(const TreeChangeParams& params) override {
- received_params_.push_back(params);
- }
- void OnTreeChanged(const TreeChangeParams& params) override {
- received_params_.push_back(params);
- }
-
- View* observee_;
- std::vector<TreeChangeParams> received_params_;
-
- MOJO_DISALLOW_COPY_AND_ASSIGN(TreeChangeObserver);
-};
-
-// Adds/Removes v11 to v1.
-TEST_F(ViewObserverTest, TreeChange_SimpleAddRemove) {
- TestView v1;
- TreeChangeObserver o1(&v1);
- EXPECT_TRUE(o1.received_params().empty());
-
- TestView v11;
- TreeChangeObserver o11(&v11);
- EXPECT_TRUE(o11.received_params().empty());
-
- // Add.
-
- v1.AddChild(&v11);
-
- EXPECT_EQ(2U, o1.received_params().size());
- ViewObserver::TreeChangeParams p1;
- p1.target = &v11;
- p1.receiver = &v1;
- p1.old_parent = NULL;
- p1.new_parent = &v1;
- EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back()));
-
- EXPECT_EQ(2U, o11.received_params().size());
- ViewObserver::TreeChangeParams p11 = p1;
- p11.receiver = &v11;
- EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front()));
- EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back()));
-
- o1.Reset();
- o11.Reset();
- EXPECT_TRUE(o1.received_params().empty());
- EXPECT_TRUE(o11.received_params().empty());
-
- // Remove.
-
- v1.RemoveChild(&v11);
-
- EXPECT_EQ(2U, o1.received_params().size());
- p1.target = &v11;
- p1.receiver = &v1;
- p1.old_parent = &v1;
- p1.new_parent = NULL;
- EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().front()));
-
- EXPECT_EQ(2U, o11.received_params().size());
- p11 = p1;
- p11.receiver = &v11;
- EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front()));
- EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back()));
-}
-
-// Creates these two trees:
-// v1
-// +- v11
-// v111
-// +- v1111
-// +- v1112
-// Then adds/removes v111 from v11.
-TEST_F(ViewObserverTest, TreeChange_NestedAddRemove) {
- TestView v1, v11, v111, v1111, v1112;
-
- // Root tree.
- v1.AddChild(&v11);
-
- // Tree to be attached.
- v111.AddChild(&v1111);
- v111.AddChild(&v1112);
-
- TreeChangeObserver o1(&v1), o11(&v11), o111(&v111), o1111(&v1111),
- o1112(&v1112);
- ViewObserver::TreeChangeParams p1, p11, p111, p1111, p1112;
-
- // Add.
-
- v11.AddChild(&v111);
-
- EXPECT_EQ(2U, o1.received_params().size());
- p1.target = &v111;
- p1.receiver = &v1;
- p1.old_parent = NULL;
- p1.new_parent = &v11;
- EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back()));
-
- EXPECT_EQ(2U, o11.received_params().size());
- p11 = p1;
- p11.receiver = &v11;
- EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back()));
-
- EXPECT_EQ(2U, o111.received_params().size());
- p111 = p11;
- p111.receiver = &v111;
- EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front()));
- EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back()));
-
- EXPECT_EQ(2U, o1111.received_params().size());
- p1111 = p111;
- p1111.receiver = &v1111;
- EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().front()));
- EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().back()));
-
- EXPECT_EQ(2U, o1112.received_params().size());
- p1112 = p111;
- p1112.receiver = &v1112;
- EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().front()));
- EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().back()));
-
- // Remove.
- o1.Reset();
- o11.Reset();
- o111.Reset();
- o1111.Reset();
- o1112.Reset();
- EXPECT_TRUE(o1.received_params().empty());
- EXPECT_TRUE(o11.received_params().empty());
- EXPECT_TRUE(o111.received_params().empty());
- EXPECT_TRUE(o1111.received_params().empty());
- EXPECT_TRUE(o1112.received_params().empty());
-
- v11.RemoveChild(&v111);
-
- EXPECT_EQ(2U, o1.received_params().size());
- p1.target = &v111;
- p1.receiver = &v1;
- p1.old_parent = &v11;
- p1.new_parent = NULL;
- EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().front()));
-
- EXPECT_EQ(2U, o11.received_params().size());
- p11 = p1;
- p11.receiver = &v11;
- EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front()));
-
- EXPECT_EQ(2U, o111.received_params().size());
- p111 = p11;
- p111.receiver = &v111;
- EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front()));
- EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back()));
-
- EXPECT_EQ(2U, o1111.received_params().size());
- p1111 = p111;
- p1111.receiver = &v1111;
- EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().front()));
- EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().back()));
-
- EXPECT_EQ(2U, o1112.received_params().size());
- p1112 = p111;
- p1112.receiver = &v1112;
- EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().front()));
- EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().back()));
-}
-
-TEST_F(ViewObserverTest, TreeChange_Reparent) {
- TestView v1, v11, v12, v111;
- v1.AddChild(&v11);
- v1.AddChild(&v12);
- v11.AddChild(&v111);
-
- TreeChangeObserver o1(&v1), o11(&v11), o12(&v12), o111(&v111);
-
- // Reparent.
- v12.AddChild(&v111);
-
- // v1 (root) should see both changing and changed notifications.
- EXPECT_EQ(4U, o1.received_params().size());
- ViewObserver::TreeChangeParams p1;
- p1.target = &v111;
- p1.receiver = &v1;
- p1.old_parent = &v11;
- p1.new_parent = &v12;
- EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().front()));
- EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back()));
-
- // v11 should see changing notifications.
- EXPECT_EQ(2U, o11.received_params().size());
- ViewObserver::TreeChangeParams p11;
- p11 = p1;
- p11.receiver = &v11;
- EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front()));
-
- // v12 should see changed notifications.
- EXPECT_EQ(2U, o12.received_params().size());
- ViewObserver::TreeChangeParams p12;
- p12 = p1;
- p12.receiver = &v12;
- EXPECT_TRUE(TreeChangeParamsMatch(p12, o12.received_params().back()));
-
- // v111 should see both changing and changed notifications.
- EXPECT_EQ(2U, o111.received_params().size());
- ViewObserver::TreeChangeParams p111;
- p111 = p1;
- p111.receiver = &v111;
- EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front()));
- EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back()));
-}
-
-namespace {
-
-class OrderChangeObserver : public ViewObserver {
- public:
- struct Change {
- View* view;
- View* relative_view;
- mojo::OrderDirection direction;
- };
- typedef std::vector<Change> Changes;
-
- explicit OrderChangeObserver(View* observee) : observee_(observee) {
- observee_->AddObserver(this);
- }
- ~OrderChangeObserver() override { observee_->RemoveObserver(this); }
-
- Changes GetAndClearChanges() {
- Changes changes;
- changes_.swap(changes);
- return changes;
- }
-
- private:
- // Overridden from ViewObserver:
- void OnViewReordering(View* view,
- View* relative_view,
- mojo::OrderDirection direction) override {
- OnViewReordered(view, relative_view, direction);
- }
-
- void OnViewReordered(View* view,
- View* relative_view,
- mojo::OrderDirection direction) override {
- Change change;
- change.view = view;
- change.relative_view = relative_view;
- change.direction = direction;
- changes_.push_back(change);
- }
-
- View* observee_;
- Changes changes_;
-
- MOJO_DISALLOW_COPY_AND_ASSIGN(OrderChangeObserver);
-};
-
-} // namespace
-
-TEST_F(ViewObserverTest, Order) {
- TestView v1, v11, v12, v13;
- v1.AddChild(&v11);
- v1.AddChild(&v12);
- v1.AddChild(&v13);
-
- // Order: v11, v12, v13
- EXPECT_EQ(3U, v1.children().size());
- EXPECT_EQ(&v11, v1.children().front());
- EXPECT_EQ(&v13, v1.children().back());
-
- {
- OrderChangeObserver observer(&v11);
-
- // Move v11 to front.
- // Resulting order: v12, v13, v11
- v11.MoveToFront();
- EXPECT_EQ(&v12, v1.children().front());
- EXPECT_EQ(&v11, v1.children().back());
-
- OrderChangeObserver::Changes changes = observer.GetAndClearChanges();
- ASSERT_EQ(2U, changes.size());
- EXPECT_EQ(&v11, changes[0].view);
- EXPECT_EQ(&v13, changes[0].relative_view);
- EXPECT_EQ(mojo::ORDER_DIRECTION_ABOVE, changes[0].direction);
-
- EXPECT_EQ(&v11, changes[1].view);
- EXPECT_EQ(&v13, changes[1].relative_view);
- EXPECT_EQ(mojo::ORDER_DIRECTION_ABOVE, changes[1].direction);
- }
-
- {
- OrderChangeObserver observer(&v11);
-
- // Move v11 to back.
- // Resulting order: v11, v12, v13
- v11.MoveToBack();
- EXPECT_EQ(&v11, v1.children().front());
- EXPECT_EQ(&v13, v1.children().back());
-
- OrderChangeObserver::Changes changes = observer.GetAndClearChanges();
- ASSERT_EQ(2U, changes.size());
- EXPECT_EQ(&v11, changes[0].view);
- EXPECT_EQ(&v12, changes[0].relative_view);
- EXPECT_EQ(mojo::ORDER_DIRECTION_BELOW, changes[0].direction);
-
- EXPECT_EQ(&v11, changes[1].view);
- EXPECT_EQ(&v12, changes[1].relative_view);
- EXPECT_EQ(mojo::ORDER_DIRECTION_BELOW, changes[1].direction);
- }
-
- {
- OrderChangeObserver observer(&v11);
-
- // Move v11 above v12.
- // Resulting order: v12. v11, v13
- v11.Reorder(&v12, mojo::ORDER_DIRECTION_ABOVE);
- EXPECT_EQ(&v12, v1.children().front());
- EXPECT_EQ(&v13, v1.children().back());
-
- OrderChangeObserver::Changes changes = observer.GetAndClearChanges();
- ASSERT_EQ(2U, changes.size());
- EXPECT_EQ(&v11, changes[0].view);
- EXPECT_EQ(&v12, changes[0].relative_view);
- EXPECT_EQ(mojo::ORDER_DIRECTION_ABOVE, changes[0].direction);
-
- EXPECT_EQ(&v11, changes[1].view);
- EXPECT_EQ(&v12, changes[1].relative_view);
- EXPECT_EQ(mojo::ORDER_DIRECTION_ABOVE, changes[1].direction);
- }
-
- {
- OrderChangeObserver observer(&v11);
-
- // Move v11 below v12.
- // Resulting order: v11, v12, v13
- v11.Reorder(&v12, mojo::ORDER_DIRECTION_BELOW);
- EXPECT_EQ(&v11, v1.children().front());
- EXPECT_EQ(&v13, v1.children().back());
-
- OrderChangeObserver::Changes changes = observer.GetAndClearChanges();
- ASSERT_EQ(2U, changes.size());
- EXPECT_EQ(&v11, changes[0].view);
- EXPECT_EQ(&v12, changes[0].relative_view);
- EXPECT_EQ(mojo::ORDER_DIRECTION_BELOW, changes[0].direction);
-
- EXPECT_EQ(&v11, changes[1].view);
- EXPECT_EQ(&v12, changes[1].relative_view);
- EXPECT_EQ(mojo::ORDER_DIRECTION_BELOW, changes[1].direction);
- }
-}
-
-namespace {
-
-typedef std::vector<std::string> Changes;
-
-std::string ViewIdToString(Id id) {
- return (id == 0) ? "null"
- : base::StringPrintf("%d,%d", HiWord(id), LoWord(id));
-}
-
-std::string RectToString(const mojo::Rect& rect) {
- return base::StringPrintf("%d,%d %dx%d", rect.x, rect.y, rect.width,
- rect.height);
-}
-
-class BoundsChangeObserver : public ViewObserver {
- public:
- explicit BoundsChangeObserver(View* view) : view_(view) {
- view_->AddObserver(this);
- }
- ~BoundsChangeObserver() override { view_->RemoveObserver(this); }
-
- Changes GetAndClearChanges() {
- Changes changes;
- changes.swap(changes_);
- return changes;
- }
-
- private:
- // Overridden from ViewObserver:
- void OnViewBoundsChanging(View* view,
- const mojo::Rect& old_bounds,
- const mojo::Rect& new_bounds) override {
- changes_.push_back(base::StringPrintf(
- "view=%s old_bounds=%s new_bounds=%s phase=changing",
- ViewIdToString(view->id()).c_str(), RectToString(old_bounds).c_str(),
- RectToString(new_bounds).c_str()));
- }
- void OnViewBoundsChanged(View* view,
- const mojo::Rect& old_bounds,
- const mojo::Rect& new_bounds) override {
- changes_.push_back(base::StringPrintf(
- "view=%s old_bounds=%s new_bounds=%s phase=changed",
- ViewIdToString(view->id()).c_str(), RectToString(old_bounds).c_str(),
- RectToString(new_bounds).c_str()));
- }
-
- View* view_;
- Changes changes_;
-
- MOJO_DISALLOW_COPY_AND_ASSIGN(BoundsChangeObserver);
-};
-
-} // namespace
-
-TEST_F(ViewObserverTest, SetBounds) {
- TestView v1;
- {
- BoundsChangeObserver observer(&v1);
- mojo::Rect rect;
- rect.width = rect.height = 100;
- v1.SetBounds(rect);
-
- Changes changes = observer.GetAndClearChanges();
- ASSERT_EQ(2U, changes.size());
- EXPECT_EQ(
- "view=0,1 old_bounds=0,0 0x0 new_bounds=0,0 100x100 phase=changing",
- changes[0]);
- EXPECT_EQ(
- "view=0,1 old_bounds=0,0 0x0 new_bounds=0,0 100x100 phase=changed",
- changes[1]);
- }
-}
-
-namespace {
-
-class VisibilityChangeObserver : public ViewObserver {
- public:
- explicit VisibilityChangeObserver(View* view) : view_(view) {
- view_->AddObserver(this);
- }
- ~VisibilityChangeObserver() override { view_->RemoveObserver(this); }
-
- Changes GetAndClearChanges() {
- Changes changes;
- changes.swap(changes_);
- return changes;
- }
-
- private:
- // Overridden from ViewObserver:
- void OnViewVisibilityChanging(View* view) override {
- changes_.push_back(
- base::StringPrintf("view=%s phase=changing visibility=%s",
- ViewIdToString(view->id()).c_str(),
- view->visible() ? "true" : "false"));
- }
- void OnViewVisibilityChanged(View* view) override {
- changes_.push_back(base::StringPrintf("view=%s phase=changed visibility=%s",
- ViewIdToString(view->id()).c_str(),
- view->visible() ? "true" : "false"));
- }
-
- View* view_;
- Changes changes_;
-
- MOJO_DISALLOW_COPY_AND_ASSIGN(VisibilityChangeObserver);
-};
-
-} // namespace
-
-TEST_F(ViewObserverTest, SetVisible) {
- TestView v1;
- EXPECT_TRUE(v1.visible());
- {
- // Change visibility from true to false and make sure we get notifications.
- VisibilityChangeObserver observer(&v1);
- v1.SetVisible(false);
-
- Changes changes = observer.GetAndClearChanges();
- ASSERT_EQ(2U, changes.size());
- EXPECT_EQ("view=0,1 phase=changing visibility=true", changes[0]);
- EXPECT_EQ("view=0,1 phase=changed visibility=false", changes[1]);
- }
- {
- // Set visible to existing value and verify no notifications.
- VisibilityChangeObserver observer(&v1);
- v1.SetVisible(false);
- EXPECT_TRUE(observer.GetAndClearChanges().empty());
- }
-}
-
-TEST_F(ViewObserverTest, SetVisibleParent) {
- TestView parent;
- ViewPrivate(&parent).set_id(1);
- TestView child;
- ViewPrivate(&child).set_id(2);
- parent.AddChild(&child);
- EXPECT_TRUE(parent.visible());
- EXPECT_TRUE(child.visible());
- {
- // Change visibility from true to false and make sure we get notifications
- // on the parent.
- VisibilityChangeObserver observer(&parent);
- child.SetVisible(false);
-
- Changes changes = observer.GetAndClearChanges();
- ASSERT_EQ(1U, changes.size());
- EXPECT_EQ("view=0,2 phase=changed visibility=false", changes[0]);
- }
-}
-
-TEST_F(ViewObserverTest, SetVisibleChild) {
- TestView parent;
- ViewPrivate(&parent).set_id(1);
- TestView child;
- ViewPrivate(&child).set_id(2);
- parent.AddChild(&child);
- EXPECT_TRUE(parent.visible());
- EXPECT_TRUE(child.visible());
- {
- // Change visibility from true to false and make sure we get notifications
- // on the child.
- VisibilityChangeObserver observer(&child);
- parent.SetVisible(false);
-
- Changes changes = observer.GetAndClearChanges();
- ASSERT_EQ(1U, changes.size());
- EXPECT_EQ("view=0,1 phase=changed visibility=false", changes[0]);
- }
-}
-
-namespace {
-
-class SharedPropertyChangeObserver : public ViewObserver {
- public:
- explicit SharedPropertyChangeObserver(View* view) : view_(view) {
- view_->AddObserver(this);
- }
- ~SharedPropertyChangeObserver() override { view_->RemoveObserver(this); }
-
- Changes GetAndClearChanges() {
- Changes changes;
- changes.swap(changes_);
- return changes;
- }
-
- private:
- // Overridden from ViewObserver:
- void OnViewSharedPropertyChanged(
- View* view,
- const std::string& name,
- const std::vector<uint8_t>* old_data,
- const std::vector<uint8_t>* new_data) override {
- changes_.push_back(base::StringPrintf(
- "view=%s shared property changed key=%s old_value=%s new_value=%s",
- ViewIdToString(view->id()).c_str(), name.c_str(),
- VectorToString(old_data).c_str(), VectorToString(new_data).c_str()));
- }
-
- std::string VectorToString(const std::vector<uint8_t>* data) {
- if (!data)
- return "NULL";
- std::string s;
- for (char c : *data)
- s += c;
- return s;
- }
-
- View* view_;
- Changes changes_;
-
- MOJO_DISALLOW_COPY_AND_ASSIGN(SharedPropertyChangeObserver);
-};
-
-} // namespace
-
-TEST_F(ViewObserverTest, SetLocalProperty) {
- TestView v1;
- std::vector<uint8_t> one(1, '1');
-
- {
- // Change visibility from true to false and make sure we get notifications.
- SharedPropertyChangeObserver observer(&v1);
- v1.SetSharedProperty("one", &one);
- Changes changes = observer.GetAndClearChanges();
- ASSERT_EQ(1U, changes.size());
- EXPECT_EQ(
- "view=0,1 shared property changed key=one old_value=NULL new_value=1",
- changes[0]);
- EXPECT_EQ(1U, v1.shared_properties().size());
- }
- {
- // Set visible to existing value and verify no notifications.
- SharedPropertyChangeObserver observer(&v1);
- v1.SetSharedProperty("one", &one);
- EXPECT_TRUE(observer.GetAndClearChanges().empty());
- EXPECT_EQ(1U, v1.shared_properties().size());
- }
- {
- // Set the value to NULL to delete it.
- // Change visibility from true to false and make sure we get notifications.
- SharedPropertyChangeObserver observer(&v1);
- v1.SetSharedProperty("one", NULL);
- Changes changes = observer.GetAndClearChanges();
- ASSERT_EQ(1U, changes.size());
- EXPECT_EQ(
- "view=0,1 shared property changed key=one old_value=1 new_value=NULL",
- changes[0]);
- EXPECT_EQ(0U, v1.shared_properties().size());
- }
- {
- // Setting a null property to null shouldn't update us.
- SharedPropertyChangeObserver observer(&v1);
- v1.SetSharedProperty("one", NULL);
- EXPECT_TRUE(observer.GetAndClearChanges().empty());
- EXPECT_EQ(0U, v1.shared_properties().size());
- }
-}
-
-namespace {
-
-typedef std::pair<const void*, intptr_t> PropertyChangeInfo;
-
-class LocalPropertyChangeObserver : public ViewObserver {
- public:
- explicit LocalPropertyChangeObserver(View* view)
- : view_(view), property_key_(nullptr), old_property_value_(-1) {
- view_->AddObserver(this);
- }
- ~LocalPropertyChangeObserver() override { view_->RemoveObserver(this); }
-
- PropertyChangeInfo PropertyChangeInfoAndClear() {
- PropertyChangeInfo result(property_key_, old_property_value_);
- property_key_ = NULL;
- old_property_value_ = -3;
- return result;
- }
-
- private:
- void OnViewLocalPropertyChanged(View* window,
- const void* key,
- intptr_t old) override {
- property_key_ = key;
- old_property_value_ = old;
- }
-
- View* view_;
- const void* property_key_;
- intptr_t old_property_value_;
-
- MOJO_DISALLOW_COPY_AND_ASSIGN(LocalPropertyChangeObserver);
-};
-
-} // namespace
-
-TEST_F(ViewObserverTest, LocalPropertyChanged) {
- TestView v1;
- LocalPropertyChangeObserver o(&v1);
-
- static const ViewProperty<int> prop = {-2};
-
- v1.SetLocalProperty(&prop, 1);
- EXPECT_EQ(PropertyChangeInfo(&prop, -2), o.PropertyChangeInfoAndClear());
- v1.SetLocalProperty(&prop, -2);
- EXPECT_EQ(PropertyChangeInfo(&prop, 1), o.PropertyChangeInfoAndClear());
- v1.SetLocalProperty(&prop, 3);
- EXPECT_EQ(PropertyChangeInfo(&prop, -2), o.PropertyChangeInfoAndClear());
- v1.ClearLocalProperty(&prop);
- EXPECT_EQ(PropertyChangeInfo(&prop, 3), o.PropertyChangeInfoAndClear());
-
- // Sanity check to see if |PropertyChangeInfoAndClear| really clears.
- EXPECT_EQ(PropertyChangeInfo(reinterpret_cast<const void*>(NULL), -3),
- o.PropertyChangeInfoAndClear());
-}
-
-} // namespace mus
diff --git a/components/mus/public/cpp/tests/view_manager_test_base.cc b/components/mus/public/cpp/tests/window_server_test_base.cc
index e4bf2ba..649fc24 100644
--- a/components/mus/public/cpp/tests/view_manager_test_base.cc
+++ b/components/mus/public/cpp/tests/window_server_test_base.cc
@@ -2,15 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/mus/public/cpp/tests/view_manager_test_base.h"
+#include "components/mus/public/cpp/tests/window_server_test_base.h"
#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/test/test_timeouts.h"
-#include "components/mus/public/cpp/view.h"
-#include "components/mus/public/cpp/view_tree_connection.h"
-#include "components/mus/public/cpp/view_tree_host_factory.h"
+#include "components/mus/public/cpp/window.h"
+#include "components/mus/public/cpp/window_tree_connection.h"
+#include "components/mus/public/cpp/window_tree_host_factory.h"
#include "mojo/application/public/cpp/application_impl.h"
namespace mus {
@@ -26,15 +26,15 @@ void TimeoutRunLoop(const base::Closure& timeout_task, bool* timeout) {
} // namespace
-ViewManagerTestBase::ViewManagerTestBase()
+WindowServerTestBase::WindowServerTestBase()
: most_recent_connection_(nullptr),
window_manager_(nullptr),
- view_tree_connection_destroyed_(false) {}
+ window_tree_connection_destroyed_(false) {}
-ViewManagerTestBase::~ViewManagerTestBase() {}
+WindowServerTestBase::~WindowServerTestBase() {}
// static
-bool ViewManagerTestBase::DoRunLoopWithTimeout() {
+bool WindowServerTestBase::DoRunLoopWithTimeout() {
if (current_run_loop != nullptr)
return false;
@@ -51,7 +51,7 @@ bool ViewManagerTestBase::DoRunLoopWithTimeout() {
}
// static
-bool ViewManagerTestBase::QuitRunLoop() {
+bool WindowServerTestBase::QuitRunLoop() {
if (!current_run_loop)
return false;
@@ -60,44 +60,44 @@ bool ViewManagerTestBase::QuitRunLoop() {
return true;
}
-void ViewManagerTestBase::SetUp() {
+void WindowServerTestBase::SetUp() {
ApplicationTestBase::SetUp();
- CreateSingleViewTreeHost(application_impl(), this, &host_);
+ CreateSingleWindowTreeHost(application_impl(), this, &host_);
ASSERT_TRUE(DoRunLoopWithTimeout()); // RunLoop should be quit by OnEmbed().
std::swap(window_manager_, most_recent_connection_);
}
-void ViewManagerTestBase::TearDown() {
+void WindowServerTestBase::TearDown() {
ApplicationTestBase::TearDown();
}
-mojo::ApplicationDelegate* ViewManagerTestBase::GetApplicationDelegate() {
+mojo::ApplicationDelegate* WindowServerTestBase::GetApplicationDelegate() {
return this;
}
-bool ViewManagerTestBase::ConfigureIncomingConnection(
+bool WindowServerTestBase::ConfigureIncomingConnection(
mojo::ApplicationConnection* connection) {
connection->AddService<mojo::ViewTreeClient>(this);
return true;
}
-void ViewManagerTestBase::OnEmbed(View* root) {
+void WindowServerTestBase::OnEmbed(Window* root) {
most_recent_connection_ = root->connection();
EXPECT_TRUE(QuitRunLoop());
}
-void ViewManagerTestBase::OnConnectionLost(ViewTreeConnection* connection) {
- view_tree_connection_destroyed_ = true;
+void WindowServerTestBase::OnConnectionLost(WindowTreeConnection* connection) {
+ window_tree_connection_destroyed_ = true;
}
-void ViewManagerTestBase::Create(
+void WindowServerTestBase::Create(
mojo::ApplicationConnection* connection,
mojo::InterfaceRequest<mojo::ViewTreeClient> request) {
- ViewTreeConnection::Create(
+ WindowTreeConnection::Create(
this, request.Pass(),
- ViewTreeConnection::CreateType::DONT_WAIT_FOR_EMBED);
+ WindowTreeConnection::CreateType::DONT_WAIT_FOR_EMBED);
}
} // namespace mus
diff --git a/components/mus/public/cpp/tests/view_manager_test_base.h b/components/mus/public/cpp/tests/window_server_test_base.h
index a1529f3..b46c871 100644
--- a/components/mus/public/cpp/tests/view_manager_test_base.h
+++ b/components/mus/public/cpp/tests/window_server_test_base.h
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_MUS_PUBLIC_CPP_TESTS_VIEW_MANAGER_TEST_BASE_H_
-#define COMPONENTS_MUS_PUBLIC_CPP_TESTS_VIEW_MANAGER_TEST_BASE_H_
+#ifndef COMPONENTS_MUS_PUBLIC_CPP_TESTS_WINDOW_SERVER_TEST_BASE_H_
+#define COMPONENTS_MUS_PUBLIC_CPP_TESTS_WINDOW_SERVER_TEST_BASE_H_
#include "base/memory/scoped_ptr.h"
-#include "components/mus/public/cpp/view_tree_delegate.h"
+#include "components/mus/public/cpp/window_tree_delegate.h"
#include "components/mus/public/interfaces/view_tree.mojom.h"
#include "components/mus/public/interfaces/view_tree_host.mojom.h"
#include "mojo/application/public/cpp/application_delegate.h"
@@ -15,22 +15,22 @@
namespace mus {
-// ViewManagerTestBase is a base class for use with app tests that use
-// ViewManager. SetUp() connects to the ViewManager and blocks until OnEmbed()
-// has been invoked. window_manager() can be used to access the ViewManager
+// WindowServerTestBase is a base class for use with app tests that use
+// WindowServer. SetUp() connects to the WindowServer and blocks until OnEmbed()
+// has been invoked. window_manager() can be used to access the WindowServer
// established as part of SetUp().
-class ViewManagerTestBase
+class WindowServerTestBase
: public mojo::test::ApplicationTestBase,
public mojo::ApplicationDelegate,
- public ViewTreeDelegate,
+ public WindowTreeDelegate,
public mojo::InterfaceFactory<mojo::ViewTreeClient> {
public:
- ViewManagerTestBase();
- ~ViewManagerTestBase() override;
+ WindowServerTestBase();
+ ~WindowServerTestBase() override;
- // True if ViewTreeDelegate::OnConnectionLost() was called.
- bool view_tree_connection_destroyed() const {
- return view_tree_connection_destroyed_;
+ // True if WindowTreeDelegate::OnConnectionLost() was called.
+ bool window_tree_connection_destroyed() const {
+ return window_tree_connection_destroyed_;
}
// Runs the MessageLoop until QuitRunLoop() is called, or a timeout occurs.
@@ -42,10 +42,10 @@ class ViewManagerTestBase
// success, false if a RunLoop isn't running.
static bool QuitRunLoop() WARN_UNUSED_RESULT;
- ViewTreeConnection* window_manager() { return window_manager_; }
+ WindowTreeConnection* window_manager() { return window_manager_; }
protected:
- ViewTreeConnection* most_recent_connection() {
+ WindowTreeConnection* most_recent_connection() {
return most_recent_connection_;
}
@@ -60,9 +60,9 @@ class ViewManagerTestBase
bool ConfigureIncomingConnection(
mojo::ApplicationConnection* connection) override;
- // ViewTreeDelegate:
- void OnEmbed(View* root) override;
- void OnConnectionLost(ViewTreeConnection* connection) override;
+ // WindowTreeDelegate:
+ void OnEmbed(Window* root) override;
+ void OnConnectionLost(WindowTreeConnection* connection) override;
// InterfaceFactory<ViewTreeClient>:
void Create(mojo::ApplicationConnection* connection,
@@ -70,20 +70,20 @@ class ViewManagerTestBase
// Used to receive the most recent view tree connection loaded by an embed
// action.
- ViewTreeConnection* most_recent_connection_;
+ WindowTreeConnection* most_recent_connection_;
private:
mojo::ViewTreeHostPtr host_;
// The View Manager connection held by the window manager (app running at the
// root view).
- ViewTreeConnection* window_manager_;
+ WindowTreeConnection* window_manager_;
- bool view_tree_connection_destroyed_;
+ bool window_tree_connection_destroyed_;
- MOJO_DISALLOW_COPY_AND_ASSIGN(ViewManagerTestBase);
+ MOJO_DISALLOW_COPY_AND_ASSIGN(WindowServerTestBase);
};
} // namespace mus
-#endif // COMPONENTS_MUS_PUBLIC_CPP_TESTS_VIEW_MANAGER_TEST_BASE_H_
+#endif // COMPONENTS_MUS_PUBLIC_CPP_TESTS_WINDOW_SERVER_TEST_BASE_H_
diff --git a/components/mus/public/cpp/tests/view_manager_test_suite.cc b/components/mus/public/cpp/tests/window_server_test_suite.cc
index a1e0c98..ea1a04c 100644
--- a/components/mus/public/cpp/tests/view_manager_test_suite.cc
+++ b/components/mus/public/cpp/tests/window_server_test_suite.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/mus/public/cpp/tests/view_manager_test_suite.h"
+#include "components/mus/public/cpp/tests/window_server_test_suite.h"
#include "base/i18n/icu_util.h"
@@ -12,12 +12,12 @@
namespace mus {
-ViewManagerTestSuite::ViewManagerTestSuite(int argc, char** argv)
+WindowServerTestSuite::WindowServerTestSuite(int argc, char** argv)
: TestSuite(argc, argv) {}
-ViewManagerTestSuite::~ViewManagerTestSuite() {}
+WindowServerTestSuite::~WindowServerTestSuite() {}
-void ViewManagerTestSuite::Initialize() {
+void WindowServerTestSuite::Initialize() {
#if defined(USE_X11)
// Each test ends up creating a new thread for the native viewport service.
// In other words we'll use X on different threads, so tell it that.
diff --git a/components/mus/public/cpp/tests/window_server_test_suite.h b/components/mus/public/cpp/tests/window_server_test_suite.h
new file mode 100644
index 0000000..cbc2eb7
--- /dev/null
+++ b/components/mus/public/cpp/tests/window_server_test_suite.h
@@ -0,0 +1,27 @@
+// Copyright 2014 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_MUS_PUBLIC_CPP_TESTS_WINDOW_SERVER_TEST_SUITE_H_
+#define COMPONENTS_MUS_PUBLIC_CPP_TESTS_WINDOW_SERVER_TEST_SUITE_H_
+
+#include "base/test/test_suite.h"
+#include "third_party/mojo/src/mojo/public/cpp/system/macros.h"
+
+namespace mus {
+
+class WindowServerTestSuite : public base::TestSuite {
+ public:
+ WindowServerTestSuite(int argc, char** argv);
+ ~WindowServerTestSuite() override;
+
+ protected:
+ void Initialize() override;
+
+ private:
+ MOJO_DISALLOW_COPY_AND_ASSIGN(WindowServerTestSuite);
+};
+
+} // namespace mus
+
+#endif // COMPONENTS_MUS_PUBLIC_CPP_TESTS_WINDOW_SERVER_TEST_SUITE_H_
diff --git a/components/mus/public/cpp/tests/window_unittest.cc b/components/mus/public/cpp/tests/window_unittest.cc
new file mode 100644
index 0000000..870a026
--- /dev/null
+++ b/components/mus/public/cpp/tests/window_unittest.cc
@@ -0,0 +1,875 @@
+// Copyright 2014 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/mus/public/cpp/window.h"
+
+#include "base/logging.h"
+#include "base/strings/stringprintf.h"
+#include "components/mus/public/cpp/lib/window_private.h"
+#include "components/mus/public/cpp/util.h"
+#include "components/mus/public/cpp/window_observer.h"
+#include "components/mus/public/cpp/window_property.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mus {
+
+// Window ---------------------------------------------------------------------
+
+typedef testing::Test WindowTest;
+
+// Subclass with public ctor/dtor.
+class TestWindow : public Window {
+ public:
+ TestWindow() { WindowPrivate(this).set_id(1); }
+ ~TestWindow() {}
+
+ private:
+ MOJO_DISALLOW_COPY_AND_ASSIGN(TestWindow);
+};
+
+TEST_F(WindowTest, AddChild) {
+ TestWindow w1;
+ TestWindow w11;
+ w1.AddChild(&w11);
+ EXPECT_EQ(1U, w1.children().size());
+}
+
+TEST_F(WindowTest, RemoveChild) {
+ TestWindow w1;
+ TestWindow w11;
+ w1.AddChild(&w11);
+ EXPECT_EQ(1U, w1.children().size());
+ w1.RemoveChild(&w11);
+ EXPECT_EQ(0U, w1.children().size());
+}
+
+TEST_F(WindowTest, Reparent) {
+ TestWindow w1;
+ TestWindow w2;
+ TestWindow w11;
+ w1.AddChild(&w11);
+ EXPECT_EQ(1U, w1.children().size());
+ w2.AddChild(&w11);
+ EXPECT_EQ(1U, w2.children().size());
+ EXPECT_EQ(0U, w1.children().size());
+}
+
+TEST_F(WindowTest, Contains) {
+ TestWindow w1;
+
+ // Direct descendant.
+ TestWindow w11;
+ w1.AddChild(&w11);
+ EXPECT_TRUE(w1.Contains(&w11));
+
+ // Indirect descendant.
+ TestWindow w111;
+ w11.AddChild(&w111);
+ EXPECT_TRUE(w1.Contains(&w111));
+}
+
+TEST_F(WindowTest, GetChildById) {
+ TestWindow w1;
+ WindowPrivate(&w1).set_id(1);
+ TestWindow w11;
+ WindowPrivate(&w11).set_id(11);
+ w1.AddChild(&w11);
+ TestWindow w111;
+ WindowPrivate(&w111).set_id(111);
+ w11.AddChild(&w111);
+
+ // Find direct & indirect descendents.
+ EXPECT_EQ(&w11, w1.GetChildById(w11.id()));
+ EXPECT_EQ(&w111, w1.GetChildById(w111.id()));
+}
+
+TEST_F(WindowTest, DrawnAndVisible) {
+ TestWindow w1;
+ EXPECT_TRUE(w1.visible());
+ EXPECT_FALSE(w1.IsDrawn());
+
+ WindowPrivate(&w1).set_drawn(true);
+
+ TestWindow w11;
+ w1.AddChild(&w11);
+ EXPECT_TRUE(w11.visible());
+ EXPECT_TRUE(w11.IsDrawn());
+
+ w1.RemoveChild(&w11);
+ EXPECT_TRUE(w11.visible());
+ EXPECT_FALSE(w11.IsDrawn());
+}
+
+namespace {
+DEFINE_WINDOW_PROPERTY_KEY(int, kIntKey, -2);
+DEFINE_WINDOW_PROPERTY_KEY(const char*, kStringKey, "squeamish");
+}
+
+TEST_F(WindowTest, Property) {
+ TestWindow w;
+
+ // Non-existent properties should return the default walues.
+ EXPECT_EQ(-2, w.GetLocalProperty(kIntKey));
+ EXPECT_EQ(std::string("squeamish"), w.GetLocalProperty(kStringKey));
+
+ // A set property walue should be returned again (even if it's the default
+ // walue).
+ w.SetLocalProperty(kIntKey, INT_MAX);
+ EXPECT_EQ(INT_MAX, w.GetLocalProperty(kIntKey));
+ w.SetLocalProperty(kIntKey, -2);
+ EXPECT_EQ(-2, w.GetLocalProperty(kIntKey));
+ w.SetLocalProperty(kIntKey, INT_MIN);
+ EXPECT_EQ(INT_MIN, w.GetLocalProperty(kIntKey));
+
+ w.SetLocalProperty(kStringKey, static_cast<const char*>(NULL));
+ EXPECT_EQ(NULL, w.GetLocalProperty(kStringKey));
+ w.SetLocalProperty(kStringKey, "squeamish");
+ EXPECT_EQ(std::string("squeamish"), w.GetLocalProperty(kStringKey));
+ w.SetLocalProperty(kStringKey, "ossifrage");
+ EXPECT_EQ(std::string("ossifrage"), w.GetLocalProperty(kStringKey));
+
+ // ClearProperty should restore the default walue.
+ w.ClearLocalProperty(kIntKey);
+ EXPECT_EQ(-2, w.GetLocalProperty(kIntKey));
+ w.ClearLocalProperty(kStringKey);
+ EXPECT_EQ(std::string("squeamish"), w.GetLocalProperty(kStringKey));
+}
+
+namespace {
+
+class TestProperty {
+ public:
+ TestProperty() {}
+ virtual ~TestProperty() { last_deleted_ = this; }
+ static TestProperty* last_deleted() { return last_deleted_; }
+
+ private:
+ static TestProperty* last_deleted_;
+ MOJO_DISALLOW_COPY_AND_ASSIGN(TestProperty);
+};
+
+TestProperty* TestProperty::last_deleted_ = NULL;
+
+DEFINE_OWNED_WINDOW_PROPERTY_KEY(TestProperty, kOwnedKey, NULL);
+
+} // namespace
+
+TEST_F(WindowTest, OwnedProperty) {
+ TestProperty* p3 = NULL;
+ {
+ TestWindow w;
+ EXPECT_EQ(NULL, w.GetLocalProperty(kOwnedKey));
+ TestProperty* p1 = new TestProperty();
+ w.SetLocalProperty(kOwnedKey, p1);
+ EXPECT_EQ(p1, w.GetLocalProperty(kOwnedKey));
+ EXPECT_EQ(NULL, TestProperty::last_deleted());
+
+ TestProperty* p2 = new TestProperty();
+ w.SetLocalProperty(kOwnedKey, p2);
+ EXPECT_EQ(p2, w.GetLocalProperty(kOwnedKey));
+ EXPECT_EQ(p1, TestProperty::last_deleted());
+
+ w.ClearLocalProperty(kOwnedKey);
+ EXPECT_EQ(NULL, w.GetLocalProperty(kOwnedKey));
+ EXPECT_EQ(p2, TestProperty::last_deleted());
+
+ p3 = new TestProperty();
+ w.SetLocalProperty(kOwnedKey, p3);
+ EXPECT_EQ(p3, w.GetLocalProperty(kOwnedKey));
+ EXPECT_EQ(p2, TestProperty::last_deleted());
+ }
+
+ EXPECT_EQ(p3, TestProperty::last_deleted());
+}
+
+// WindowObserver --------------------------------------------------------
+
+typedef testing::Test WindowObserverTest;
+
+bool TreeChangeParamsMatch(const WindowObserver::TreeChangeParams& lhs,
+ const WindowObserver::TreeChangeParams& rhs) {
+ return lhs.target == rhs.target && lhs.old_parent == rhs.old_parent &&
+ lhs.new_parent == rhs.new_parent && lhs.receiver == rhs.receiver;
+}
+
+class TreeChangeObserver : public WindowObserver {
+ public:
+ explicit TreeChangeObserver(Window* observee) : observee_(observee) {
+ observee_->AddObserver(this);
+ }
+ ~TreeChangeObserver() override { observee_->RemoveObserver(this); }
+
+ void Reset() { received_params_.clear(); }
+
+ const std::vector<TreeChangeParams>& received_params() {
+ return received_params_;
+ }
+
+ private:
+ // Overridden from WindowObserver:
+ void OnTreeChanging(const TreeChangeParams& params) override {
+ received_params_.push_back(params);
+ }
+ void OnTreeChanged(const TreeChangeParams& params) override {
+ received_params_.push_back(params);
+ }
+
+ Window* observee_;
+ std::vector<TreeChangeParams> received_params_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(TreeChangeObserver);
+};
+
+// Adds/Removes w11 to w1.
+TEST_F(WindowObserverTest, TreeChange_SimpleAddRemove) {
+ TestWindow w1;
+ TreeChangeObserver o1(&w1);
+ EXPECT_TRUE(o1.received_params().empty());
+
+ TestWindow w11;
+ TreeChangeObserver o11(&w11);
+ EXPECT_TRUE(o11.received_params().empty());
+
+ // Add.
+
+ w1.AddChild(&w11);
+
+ EXPECT_EQ(2U, o1.received_params().size());
+ WindowObserver::TreeChangeParams p1;
+ p1.target = &w11;
+ p1.receiver = &w1;
+ p1.old_parent = NULL;
+ p1.new_parent = &w1;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back()));
+
+ EXPECT_EQ(2U, o11.received_params().size());
+ WindowObserver::TreeChangeParams p11 = p1;
+ p11.receiver = &w11;
+ EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front()));
+ EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back()));
+
+ o1.Reset();
+ o11.Reset();
+ EXPECT_TRUE(o1.received_params().empty());
+ EXPECT_TRUE(o11.received_params().empty());
+
+ // Remove.
+
+ w1.RemoveChild(&w11);
+
+ EXPECT_EQ(2U, o1.received_params().size());
+ p1.target = &w11;
+ p1.receiver = &w1;
+ p1.old_parent = &w1;
+ p1.new_parent = NULL;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().front()));
+
+ EXPECT_EQ(2U, o11.received_params().size());
+ p11 = p1;
+ p11.receiver = &w11;
+ EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front()));
+ EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back()));
+}
+
+// Creates these two trees:
+// w1
+// +- w11
+// w111
+// +- w1111
+// +- w1112
+// Then adds/removes w111 from w11.
+TEST_F(WindowObserverTest, TreeChange_NestedAddRemove) {
+ TestWindow w1, w11, w111, w1111, w1112;
+
+ // Root tree.
+ w1.AddChild(&w11);
+
+ // Tree to be attached.
+ w111.AddChild(&w1111);
+ w111.AddChild(&w1112);
+
+ TreeChangeObserver o1(&w1), o11(&w11), o111(&w111), o1111(&w1111),
+ o1112(&w1112);
+ WindowObserver::TreeChangeParams p1, p11, p111, p1111, p1112;
+
+ // Add.
+
+ w11.AddChild(&w111);
+
+ EXPECT_EQ(2U, o1.received_params().size());
+ p1.target = &w111;
+ p1.receiver = &w1;
+ p1.old_parent = NULL;
+ p1.new_parent = &w11;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back()));
+
+ EXPECT_EQ(2U, o11.received_params().size());
+ p11 = p1;
+ p11.receiver = &w11;
+ EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back()));
+
+ EXPECT_EQ(2U, o111.received_params().size());
+ p111 = p11;
+ p111.receiver = &w111;
+ EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front()));
+ EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back()));
+
+ EXPECT_EQ(2U, o1111.received_params().size());
+ p1111 = p111;
+ p1111.receiver = &w1111;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().front()));
+ EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().back()));
+
+ EXPECT_EQ(2U, o1112.received_params().size());
+ p1112 = p111;
+ p1112.receiver = &w1112;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().front()));
+ EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().back()));
+
+ // Remove.
+ o1.Reset();
+ o11.Reset();
+ o111.Reset();
+ o1111.Reset();
+ o1112.Reset();
+ EXPECT_TRUE(o1.received_params().empty());
+ EXPECT_TRUE(o11.received_params().empty());
+ EXPECT_TRUE(o111.received_params().empty());
+ EXPECT_TRUE(o1111.received_params().empty());
+ EXPECT_TRUE(o1112.received_params().empty());
+
+ w11.RemoveChild(&w111);
+
+ EXPECT_EQ(2U, o1.received_params().size());
+ p1.target = &w111;
+ p1.receiver = &w1;
+ p1.old_parent = &w11;
+ p1.new_parent = NULL;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().front()));
+
+ EXPECT_EQ(2U, o11.received_params().size());
+ p11 = p1;
+ p11.receiver = &w11;
+ EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front()));
+
+ EXPECT_EQ(2U, o111.received_params().size());
+ p111 = p11;
+ p111.receiver = &w111;
+ EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front()));
+ EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back()));
+
+ EXPECT_EQ(2U, o1111.received_params().size());
+ p1111 = p111;
+ p1111.receiver = &w1111;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().front()));
+ EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().back()));
+
+ EXPECT_EQ(2U, o1112.received_params().size());
+ p1112 = p111;
+ p1112.receiver = &w1112;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().front()));
+ EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().back()));
+}
+
+TEST_F(WindowObserverTest, TreeChange_Reparent) {
+ TestWindow w1, w11, w12, w111;
+ w1.AddChild(&w11);
+ w1.AddChild(&w12);
+ w11.AddChild(&w111);
+
+ TreeChangeObserver o1(&w1), o11(&w11), o12(&w12), o111(&w111);
+
+ // Reparent.
+ w12.AddChild(&w111);
+
+ // w1 (root) should see both changing and changed notifications.
+ EXPECT_EQ(4U, o1.received_params().size());
+ WindowObserver::TreeChangeParams p1;
+ p1.target = &w111;
+ p1.receiver = &w1;
+ p1.old_parent = &w11;
+ p1.new_parent = &w12;
+ EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().front()));
+ EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back()));
+
+ // w11 should see changing notifications.
+ EXPECT_EQ(2U, o11.received_params().size());
+ WindowObserver::TreeChangeParams p11;
+ p11 = p1;
+ p11.receiver = &w11;
+ EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front()));
+
+ // w12 should see changed notifications.
+ EXPECT_EQ(2U, o12.received_params().size());
+ WindowObserver::TreeChangeParams p12;
+ p12 = p1;
+ p12.receiver = &w12;
+ EXPECT_TRUE(TreeChangeParamsMatch(p12, o12.received_params().back()));
+
+ // w111 should see both changing and changed notifications.
+ EXPECT_EQ(2U, o111.received_params().size());
+ WindowObserver::TreeChangeParams p111;
+ p111 = p1;
+ p111.receiver = &w111;
+ EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front()));
+ EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back()));
+}
+
+namespace {
+
+class OrderChangeObserver : public WindowObserver {
+ public:
+ struct Change {
+ Window* window;
+ Window* relative_window;
+ mojo::OrderDirection direction;
+ };
+ typedef std::vector<Change> Changes;
+
+ explicit OrderChangeObserver(Window* observee) : observee_(observee) {
+ observee_->AddObserver(this);
+ }
+ ~OrderChangeObserver() override { observee_->RemoveObserver(this); }
+
+ Changes GetAndClearChanges() {
+ Changes changes;
+ changes_.swap(changes);
+ return changes;
+ }
+
+ private:
+ // Overridden from WindowObserver:
+ void OnWindowReordering(Window* window,
+ Window* relative_window,
+ mojo::OrderDirection direction) override {
+ OnWindowReordered(window, relative_window, direction);
+ }
+
+ void OnWindowReordered(Window* window,
+ Window* relative_window,
+ mojo::OrderDirection direction) override {
+ Change change;
+ change.window = window;
+ change.relative_window = relative_window;
+ change.direction = direction;
+ changes_.push_back(change);
+ }
+
+ Window* observee_;
+ Changes changes_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(OrderChangeObserver);
+};
+
+} // namespace
+
+TEST_F(WindowObserverTest, Order) {
+ TestWindow w1, w11, w12, w13;
+ w1.AddChild(&w11);
+ w1.AddChild(&w12);
+ w1.AddChild(&w13);
+
+ // Order: w11, w12, w13
+ EXPECT_EQ(3U, w1.children().size());
+ EXPECT_EQ(&w11, w1.children().front());
+ EXPECT_EQ(&w13, w1.children().back());
+
+ {
+ OrderChangeObserver observer(&w11);
+
+ // Move w11 to front.
+ // Resulting order: w12, w13, w11
+ w11.MoveToFront();
+ EXPECT_EQ(&w12, w1.children().front());
+ EXPECT_EQ(&w11, w1.children().back());
+
+ OrderChangeObserver::Changes changes = observer.GetAndClearChanges();
+ ASSERT_EQ(2U, changes.size());
+ EXPECT_EQ(&w11, changes[0].window);
+ EXPECT_EQ(&w13, changes[0].relative_window);
+ EXPECT_EQ(mojo::ORDER_DIRECTION_ABOVE, changes[0].direction);
+
+ EXPECT_EQ(&w11, changes[1].window);
+ EXPECT_EQ(&w13, changes[1].relative_window);
+ EXPECT_EQ(mojo::ORDER_DIRECTION_ABOVE, changes[1].direction);
+ }
+
+ {
+ OrderChangeObserver observer(&w11);
+
+ // Move w11 to back.
+ // Resulting order: w11, w12, w13
+ w11.MoveToBack();
+ EXPECT_EQ(&w11, w1.children().front());
+ EXPECT_EQ(&w13, w1.children().back());
+
+ OrderChangeObserver::Changes changes = observer.GetAndClearChanges();
+ ASSERT_EQ(2U, changes.size());
+ EXPECT_EQ(&w11, changes[0].window);
+ EXPECT_EQ(&w12, changes[0].relative_window);
+ EXPECT_EQ(mojo::ORDER_DIRECTION_BELOW, changes[0].direction);
+
+ EXPECT_EQ(&w11, changes[1].window);
+ EXPECT_EQ(&w12, changes[1].relative_window);
+ EXPECT_EQ(mojo::ORDER_DIRECTION_BELOW, changes[1].direction);
+ }
+
+ {
+ OrderChangeObserver observer(&w11);
+
+ // Move w11 above w12.
+ // Resulting order: w12. w11, w13
+ w11.Reorder(&w12, mojo::ORDER_DIRECTION_ABOVE);
+ EXPECT_EQ(&w12, w1.children().front());
+ EXPECT_EQ(&w13, w1.children().back());
+
+ OrderChangeObserver::Changes changes = observer.GetAndClearChanges();
+ ASSERT_EQ(2U, changes.size());
+ EXPECT_EQ(&w11, changes[0].window);
+ EXPECT_EQ(&w12, changes[0].relative_window);
+ EXPECT_EQ(mojo::ORDER_DIRECTION_ABOVE, changes[0].direction);
+
+ EXPECT_EQ(&w11, changes[1].window);
+ EXPECT_EQ(&w12, changes[1].relative_window);
+ EXPECT_EQ(mojo::ORDER_DIRECTION_ABOVE, changes[1].direction);
+ }
+
+ {
+ OrderChangeObserver observer(&w11);
+
+ // Move w11 below w12.
+ // Resulting order: w11, w12, w13
+ w11.Reorder(&w12, mojo::ORDER_DIRECTION_BELOW);
+ EXPECT_EQ(&w11, w1.children().front());
+ EXPECT_EQ(&w13, w1.children().back());
+
+ OrderChangeObserver::Changes changes = observer.GetAndClearChanges();
+ ASSERT_EQ(2U, changes.size());
+ EXPECT_EQ(&w11, changes[0].window);
+ EXPECT_EQ(&w12, changes[0].relative_window);
+ EXPECT_EQ(mojo::ORDER_DIRECTION_BELOW, changes[0].direction);
+
+ EXPECT_EQ(&w11, changes[1].window);
+ EXPECT_EQ(&w12, changes[1].relative_window);
+ EXPECT_EQ(mojo::ORDER_DIRECTION_BELOW, changes[1].direction);
+ }
+}
+
+namespace {
+
+typedef std::vector<std::string> Changes;
+
+std::string WindowIdToString(Id id) {
+ return (id == 0) ? "null"
+ : base::StringPrintf("%d,%d", HiWord(id), LoWord(id));
+}
+
+std::string RectToString(const mojo::Rect& rect) {
+ return base::StringPrintf("%d,%d %dx%d", rect.x, rect.y, rect.width,
+ rect.height);
+}
+
+class BoundsChangeObserver : public WindowObserver {
+ public:
+ explicit BoundsChangeObserver(Window* window) : window_(window) {
+ window_->AddObserver(this);
+ }
+ ~BoundsChangeObserver() override { window_->RemoveObserver(this); }
+
+ Changes GetAndClearChanges() {
+ Changes changes;
+ changes.swap(changes_);
+ return changes;
+ }
+
+ private:
+ // Overridden from WindowObserver:
+ void OnWindowBoundsChanging(Window* window,
+ const mojo::Rect& old_bounds,
+ const mojo::Rect& new_bounds) override {
+ changes_.push_back(base::StringPrintf(
+ "window=%s old_bounds=%s new_bounds=%s phase=changing",
+ WindowIdToString(window->id()).c_str(),
+ RectToString(old_bounds).c_str(), RectToString(new_bounds).c_str()));
+ }
+ void OnWindowBoundsChanged(Window* window,
+ const mojo::Rect& old_bounds,
+ const mojo::Rect& new_bounds) override {
+ changes_.push_back(base::StringPrintf(
+ "window=%s old_bounds=%s new_bounds=%s phase=changed",
+ WindowIdToString(window->id()).c_str(),
+ RectToString(old_bounds).c_str(), RectToString(new_bounds).c_str()));
+ }
+
+ Window* window_;
+ Changes changes_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(BoundsChangeObserver);
+};
+
+} // namespace
+
+TEST_F(WindowObserverTest, SetBounds) {
+ TestWindow w1;
+ {
+ BoundsChangeObserver observer(&w1);
+ mojo::Rect rect;
+ rect.width = rect.height = 100;
+ w1.SetBounds(rect);
+
+ Changes changes = observer.GetAndClearChanges();
+ ASSERT_EQ(2U, changes.size());
+ EXPECT_EQ(
+ "window=0,1 old_bounds=0,0 0x0 new_bounds=0,0 100x100 phase=changing",
+ changes[0]);
+ EXPECT_EQ(
+ "window=0,1 old_bounds=0,0 0x0 new_bounds=0,0 100x100 phase=changed",
+ changes[1]);
+ }
+}
+
+namespace {
+
+class VisibilityChangeObserver : public WindowObserver {
+ public:
+ explicit VisibilityChangeObserver(Window* window) : window_(window) {
+ window_->AddObserver(this);
+ }
+ ~VisibilityChangeObserver() override { window_->RemoveObserver(this); }
+
+ Changes GetAndClearChanges() {
+ Changes changes;
+ changes.swap(changes_);
+ return changes;
+ }
+
+ private:
+ // Overridden from WindowObserver:
+ void OnWindowVisibilityChanging(Window* window) override {
+ changes_.push_back(
+ base::StringPrintf("window=%s phase=changing wisibility=%s",
+ WindowIdToString(window->id()).c_str(),
+ window->visible() ? "true" : "false"));
+ }
+ void OnWindowVisibilityChanged(Window* window) override {
+ changes_.push_back(
+ base::StringPrintf("window=%s phase=changed wisibility=%s",
+ WindowIdToString(window->id()).c_str(),
+ window->visible() ? "true" : "false"));
+ }
+
+ Window* window_;
+ Changes changes_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(VisibilityChangeObserver);
+};
+
+} // namespace
+
+TEST_F(WindowObserverTest, SetVisible) {
+ TestWindow w1;
+ EXPECT_TRUE(w1.visible());
+ {
+ // Change wisibility from true to false and make sure we get notifications.
+ VisibilityChangeObserver observer(&w1);
+ w1.SetVisible(false);
+
+ Changes changes = observer.GetAndClearChanges();
+ ASSERT_EQ(2U, changes.size());
+ EXPECT_EQ("window=0,1 phase=changing wisibility=true", changes[0]);
+ EXPECT_EQ("window=0,1 phase=changed wisibility=false", changes[1]);
+ }
+ {
+ // Set visible to existing walue and werify no notifications.
+ VisibilityChangeObserver observer(&w1);
+ w1.SetVisible(false);
+ EXPECT_TRUE(observer.GetAndClearChanges().empty());
+ }
+}
+
+TEST_F(WindowObserverTest, SetVisibleParent) {
+ TestWindow parent;
+ WindowPrivate(&parent).set_id(1);
+ TestWindow child;
+ WindowPrivate(&child).set_id(2);
+ parent.AddChild(&child);
+ EXPECT_TRUE(parent.visible());
+ EXPECT_TRUE(child.visible());
+ {
+ // Change wisibility from true to false and make sure we get notifications
+ // on the parent.
+ VisibilityChangeObserver observer(&parent);
+ child.SetVisible(false);
+
+ Changes changes = observer.GetAndClearChanges();
+ ASSERT_EQ(1U, changes.size());
+ EXPECT_EQ("window=0,2 phase=changed wisibility=false", changes[0]);
+ }
+}
+
+TEST_F(WindowObserverTest, SetVisibleChild) {
+ TestWindow parent;
+ WindowPrivate(&parent).set_id(1);
+ TestWindow child;
+ WindowPrivate(&child).set_id(2);
+ parent.AddChild(&child);
+ EXPECT_TRUE(parent.visible());
+ EXPECT_TRUE(child.visible());
+ {
+ // Change wisibility from true to false and make sure we get notifications
+ // on the child.
+ VisibilityChangeObserver observer(&child);
+ parent.SetVisible(false);
+
+ Changes changes = observer.GetAndClearChanges();
+ ASSERT_EQ(1U, changes.size());
+ EXPECT_EQ("window=0,1 phase=changed wisibility=false", changes[0]);
+ }
+}
+
+namespace {
+
+class SharedPropertyChangeObserver : public WindowObserver {
+ public:
+ explicit SharedPropertyChangeObserver(Window* window) : window_(window) {
+ window_->AddObserver(this);
+ }
+ ~SharedPropertyChangeObserver() override { window_->RemoveObserver(this); }
+
+ Changes GetAndClearChanges() {
+ Changes changes;
+ changes.swap(changes_);
+ return changes;
+ }
+
+ private:
+ // Overridden from WindowObserver:
+ void OnWindowSharedPropertyChanged(
+ Window* window,
+ const std::string& name,
+ const std::vector<uint8_t>* old_data,
+ const std::vector<uint8_t>* new_data) override {
+ changes_.push_back(base::StringPrintf(
+ "window=%s shared property changed key=%s old_value=%s new_value=%s",
+ WindowIdToString(window->id()).c_str(), name.c_str(),
+ VectorToString(old_data).c_str(), VectorToString(new_data).c_str()));
+ }
+
+ std::string VectorToString(const std::vector<uint8_t>* data) {
+ if (!data)
+ return "NULL";
+ std::string s;
+ for (char c : *data)
+ s += c;
+ return s;
+ }
+
+ Window* window_;
+ Changes changes_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(SharedPropertyChangeObserver);
+};
+
+} // namespace
+
+TEST_F(WindowObserverTest, SetLocalProperty) {
+ TestWindow w1;
+ std::vector<uint8_t> one(1, '1');
+
+ {
+ // Change wisibility from true to false and make sure we get notifications.
+ SharedPropertyChangeObserver observer(&w1);
+ w1.SetSharedProperty("one", &one);
+ Changes changes = observer.GetAndClearChanges();
+ ASSERT_EQ(1U, changes.size());
+ EXPECT_EQ(
+ "window=0,1 shared property changed key=one old_value=NULL new_value=1",
+ changes[0]);
+ EXPECT_EQ(1U, w1.shared_properties().size());
+ }
+ {
+ // Set visible to existing walue and werify no notifications.
+ SharedPropertyChangeObserver observer(&w1);
+ w1.SetSharedProperty("one", &one);
+ EXPECT_TRUE(observer.GetAndClearChanges().empty());
+ EXPECT_EQ(1U, w1.shared_properties().size());
+ }
+ {
+ // Set the walue to NULL to delete it.
+ // Change wisibility from true to false and make sure we get notifications.
+ SharedPropertyChangeObserver observer(&w1);
+ w1.SetSharedProperty("one", NULL);
+ Changes changes = observer.GetAndClearChanges();
+ ASSERT_EQ(1U, changes.size());
+ EXPECT_EQ(
+ "window=0,1 shared property changed key=one old_value=1 new_value=NULL",
+ changes[0]);
+ EXPECT_EQ(0U, w1.shared_properties().size());
+ }
+ {
+ // Setting a null property to null shouldn't update us.
+ SharedPropertyChangeObserver observer(&w1);
+ w1.SetSharedProperty("one", NULL);
+ EXPECT_TRUE(observer.GetAndClearChanges().empty());
+ EXPECT_EQ(0U, w1.shared_properties().size());
+ }
+}
+
+namespace {
+
+typedef std::pair<const void*, intptr_t> PropertyChangeInfo;
+
+class LocalPropertyChangeObserver : public WindowObserver {
+ public:
+ explicit LocalPropertyChangeObserver(Window* window)
+ : window_(window), property_key_(nullptr), old_property_value_(-1) {
+ window_->AddObserver(this);
+ }
+ ~LocalPropertyChangeObserver() override { window_->RemoveObserver(this); }
+
+ PropertyChangeInfo PropertyChangeInfoAndClear() {
+ PropertyChangeInfo result(property_key_, old_property_value_);
+ property_key_ = NULL;
+ old_property_value_ = -3;
+ return result;
+ }
+
+ private:
+ void OnWindowLocalPropertyChanged(Window* window,
+ const void* key,
+ intptr_t old) override {
+ property_key_ = key;
+ old_property_value_ = old;
+ }
+
+ Window* window_;
+ const void* property_key_;
+ intptr_t old_property_value_;
+
+ MOJO_DISALLOW_COPY_AND_ASSIGN(LocalPropertyChangeObserver);
+};
+
+} // namespace
+
+TEST_F(WindowObserverTest, LocalPropertyChanged) {
+ TestWindow w1;
+ LocalPropertyChangeObserver o(&w1);
+
+ static const WindowProperty<int> prop = {-2};
+
+ w1.SetLocalProperty(&prop, 1);
+ EXPECT_EQ(PropertyChangeInfo(&prop, -2), o.PropertyChangeInfoAndClear());
+ w1.SetLocalProperty(&prop, -2);
+ EXPECT_EQ(PropertyChangeInfo(&prop, 1), o.PropertyChangeInfoAndClear());
+ w1.SetLocalProperty(&prop, 3);
+ EXPECT_EQ(PropertyChangeInfo(&prop, -2), o.PropertyChangeInfoAndClear());
+ w1.ClearLocalProperty(&prop);
+ EXPECT_EQ(PropertyChangeInfo(&prop, 3), o.PropertyChangeInfoAndClear());
+
+ // Sanity check to see if |PropertyChangeInfoAndClear| really clears.
+ EXPECT_EQ(PropertyChangeInfo(reinterpret_cast<const void*>(NULL), -3),
+ o.PropertyChangeInfoAndClear());
+}
+
+} // namespace mus