1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "mojo/services/public/cpp/view_manager/view.h"
7 #include "base/logging.h"
8 #include "base/strings/stringprintf.h"
9 #include "mojo/services/public/cpp/view_manager/lib/view_private.h"
10 #include "mojo/services/public/cpp/view_manager/util.h"
11 #include "mojo/services/public/cpp/view_manager/view_observer.h"
12 #include "testing/gtest/include/gtest/gtest.h"
16 // View ------------------------------------------------------------------------
18 typedef testing::Test ViewTest;
20 // Subclass with public ctor/dtor.
21 class TestView : public View {
24 ViewPrivate(this).set_id(1);
29 DISALLOW_COPY_AND_ASSIGN(TestView);
32 TEST_F(ViewTest, AddChild) {
36 EXPECT_EQ(1U, v1.children().size());
39 TEST_F(ViewTest, RemoveChild) {
43 EXPECT_EQ(1U, v1.children().size());
45 EXPECT_EQ(0U, v1.children().size());
48 TEST_F(ViewTest, Reparent) {
53 EXPECT_EQ(1U, v1.children().size());
55 EXPECT_EQ(1U, v2.children().size());
56 EXPECT_EQ(0U, v1.children().size());
59 TEST_F(ViewTest, Contains) {
65 EXPECT_TRUE(v1.Contains(&v11));
67 // Indirect descendant.
70 EXPECT_TRUE(v1.Contains(&v111));
73 TEST_F(ViewTest, GetChildById) {
75 ViewPrivate(&v1).set_id(1);
77 ViewPrivate(&v11).set_id(11);
80 ViewPrivate(&v111).set_id(111);
83 // Find direct & indirect descendents.
84 EXPECT_EQ(&v11, v1.GetChildById(v11.id()));
85 EXPECT_EQ(&v111, v1.GetChildById(v111.id()));
88 TEST_F(ViewTest, DrawnAndVisible) {
90 EXPECT_TRUE(v1.visible());
91 EXPECT_FALSE(v1.IsDrawn());
93 ViewPrivate(&v1).set_drawn(true);
97 EXPECT_TRUE(v11.visible());
98 EXPECT_TRUE(v11.IsDrawn());
100 v1.RemoveChild(&v11);
101 EXPECT_TRUE(v11.visible());
102 EXPECT_FALSE(v11.IsDrawn());
105 // ViewObserver --------------------------------------------------------
107 typedef testing::Test ViewObserverTest;
109 bool TreeChangeParamsMatch(const ViewObserver::TreeChangeParams& lhs,
110 const ViewObserver::TreeChangeParams& rhs) {
111 return lhs.target == rhs.target && lhs.old_parent == rhs.old_parent &&
112 lhs.new_parent == rhs.new_parent && lhs.receiver == rhs.receiver;
115 class TreeChangeObserver : public ViewObserver {
117 explicit TreeChangeObserver(View* observee) : observee_(observee) {
118 observee_->AddObserver(this);
120 ~TreeChangeObserver() override { observee_->RemoveObserver(this); }
123 received_params_.clear();
126 const std::vector<TreeChangeParams>& received_params() {
127 return received_params_;
131 // Overridden from ViewObserver:
132 void OnTreeChanging(const TreeChangeParams& params) override {
133 received_params_.push_back(params);
135 void OnTreeChanged(const TreeChangeParams& params) override {
136 received_params_.push_back(params);
140 std::vector<TreeChangeParams> received_params_;
142 DISALLOW_COPY_AND_ASSIGN(TreeChangeObserver);
145 // Adds/Removes v11 to v1.
146 TEST_F(ViewObserverTest, TreeChange_SimpleAddRemove) {
148 TreeChangeObserver o1(&v1);
149 EXPECT_TRUE(o1.received_params().empty());
152 TreeChangeObserver o11(&v11);
153 EXPECT_TRUE(o11.received_params().empty());
159 EXPECT_EQ(2U, o1.received_params().size());
160 ViewObserver::TreeChangeParams p1;
163 p1.old_parent = NULL;
165 EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back()));
167 EXPECT_EQ(2U, o11.received_params().size());
168 ViewObserver::TreeChangeParams p11 = p1;
170 EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front()));
171 EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back()));
175 EXPECT_TRUE(o1.received_params().empty());
176 EXPECT_TRUE(o11.received_params().empty());
180 v1.RemoveChild(&v11);
182 EXPECT_EQ(2U, o1.received_params().size());
186 p1.new_parent = NULL;
187 EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().front()));
189 EXPECT_EQ(2U, o11.received_params().size());
192 EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front()));
193 EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back()));
196 // Creates these two trees:
202 // Then adds/removes v111 from v11.
203 TEST_F(ViewObserverTest, TreeChange_NestedAddRemove) {
204 TestView v1, v11, v111, v1111, v1112;
209 // Tree to be attached.
210 v111.AddChild(&v1111);
211 v111.AddChild(&v1112);
213 TreeChangeObserver o1(&v1), o11(&v11), o111(&v111), o1111(&v1111),
215 ViewObserver::TreeChangeParams p1, p11, p111, p1111, p1112;
221 EXPECT_EQ(2U, o1.received_params().size());
224 p1.old_parent = NULL;
225 p1.new_parent = &v11;
226 EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back()));
228 EXPECT_EQ(2U, o11.received_params().size());
231 EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back()));
233 EXPECT_EQ(2U, o111.received_params().size());
235 p111.receiver = &v111;
236 EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front()));
237 EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back()));
239 EXPECT_EQ(2U, o1111.received_params().size());
241 p1111.receiver = &v1111;
242 EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().front()));
243 EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().back()));
245 EXPECT_EQ(2U, o1112.received_params().size());
247 p1112.receiver = &v1112;
248 EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().front()));
249 EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().back()));
257 EXPECT_TRUE(o1.received_params().empty());
258 EXPECT_TRUE(o11.received_params().empty());
259 EXPECT_TRUE(o111.received_params().empty());
260 EXPECT_TRUE(o1111.received_params().empty());
261 EXPECT_TRUE(o1112.received_params().empty());
263 v11.RemoveChild(&v111);
265 EXPECT_EQ(2U, o1.received_params().size());
268 p1.old_parent = &v11;
269 p1.new_parent = NULL;
270 EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().front()));
272 EXPECT_EQ(2U, o11.received_params().size());
275 EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front()));
277 EXPECT_EQ(2U, o111.received_params().size());
279 p111.receiver = &v111;
280 EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front()));
281 EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back()));
283 EXPECT_EQ(2U, o1111.received_params().size());
285 p1111.receiver = &v1111;
286 EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().front()));
287 EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().back()));
289 EXPECT_EQ(2U, o1112.received_params().size());
291 p1112.receiver = &v1112;
292 EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().front()));
293 EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().back()));
296 TEST_F(ViewObserverTest, TreeChange_Reparent) {
297 TestView v1, v11, v12, v111;
302 TreeChangeObserver o1(&v1), o11(&v11), o12(&v12), o111(&v111);
307 // v1 (root) should see both changing and changed notifications.
308 EXPECT_EQ(4U, o1.received_params().size());
309 ViewObserver::TreeChangeParams p1;
312 p1.old_parent = &v11;
313 p1.new_parent = &v12;
314 EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().front()));
315 EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back()));
317 // v11 should see changing notifications.
318 EXPECT_EQ(2U, o11.received_params().size());
319 ViewObserver::TreeChangeParams p11;
322 EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front()));
324 // v12 should see changed notifications.
325 EXPECT_EQ(2U, o12.received_params().size());
326 ViewObserver::TreeChangeParams p12;
329 EXPECT_TRUE(TreeChangeParamsMatch(p12, o12.received_params().back()));
331 // v111 should see both changing and changed notifications.
332 EXPECT_EQ(2U, o111.received_params().size());
333 ViewObserver::TreeChangeParams p111;
335 p111.receiver = &v111;
336 EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front()));
337 EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back()));
342 class OrderChangeObserver : public ViewObserver {
347 OrderDirection direction;
349 typedef std::vector<Change> Changes;
351 explicit OrderChangeObserver(View* observee) : observee_(observee) {
352 observee_->AddObserver(this);
354 ~OrderChangeObserver() override { observee_->RemoveObserver(this); }
356 Changes GetAndClearChanges() {
358 changes_.swap(changes);
363 // Overridden from ViewObserver:
364 void OnViewReordering(View* view,
366 OrderDirection direction) override {
367 OnViewReordered(view, relative_view, direction);
370 void OnViewReordered(View* view,
372 OrderDirection direction) override {
375 change.relative_view = relative_view;
376 change.direction = direction;
377 changes_.push_back(change);
383 DISALLOW_COPY_AND_ASSIGN(OrderChangeObserver);
388 TEST_F(ViewObserverTest, Order) {
389 TestView v1, v11, v12, v13;
394 // Order: v11, v12, v13
395 EXPECT_EQ(3U, v1.children().size());
396 EXPECT_EQ(&v11, v1.children().front());
397 EXPECT_EQ(&v13, v1.children().back());
400 OrderChangeObserver observer(&v11);
402 // Move v11 to front.
403 // Resulting order: v12, v13, v11
405 EXPECT_EQ(&v12, v1.children().front());
406 EXPECT_EQ(&v11, v1.children().back());
408 OrderChangeObserver::Changes changes = observer.GetAndClearChanges();
409 ASSERT_EQ(2U, changes.size());
410 EXPECT_EQ(&v11, changes[0].view);
411 EXPECT_EQ(&v13, changes[0].relative_view);
412 EXPECT_EQ(ORDER_DIRECTION_ABOVE, changes[0].direction);
414 EXPECT_EQ(&v11, changes[1].view);
415 EXPECT_EQ(&v13, changes[1].relative_view);
416 EXPECT_EQ(ORDER_DIRECTION_ABOVE, changes[1].direction);
420 OrderChangeObserver observer(&v11);
423 // Resulting order: v11, v12, v13
425 EXPECT_EQ(&v11, v1.children().front());
426 EXPECT_EQ(&v13, v1.children().back());
428 OrderChangeObserver::Changes changes = observer.GetAndClearChanges();
429 ASSERT_EQ(2U, changes.size());
430 EXPECT_EQ(&v11, changes[0].view);
431 EXPECT_EQ(&v12, changes[0].relative_view);
432 EXPECT_EQ(ORDER_DIRECTION_BELOW, changes[0].direction);
434 EXPECT_EQ(&v11, changes[1].view);
435 EXPECT_EQ(&v12, changes[1].relative_view);
436 EXPECT_EQ(ORDER_DIRECTION_BELOW, changes[1].direction);
440 OrderChangeObserver observer(&v11);
442 // Move v11 above v12.
443 // Resulting order: v12. v11, v13
444 v11.Reorder(&v12, ORDER_DIRECTION_ABOVE);
445 EXPECT_EQ(&v12, v1.children().front());
446 EXPECT_EQ(&v13, v1.children().back());
448 OrderChangeObserver::Changes changes = observer.GetAndClearChanges();
449 ASSERT_EQ(2U, changes.size());
450 EXPECT_EQ(&v11, changes[0].view);
451 EXPECT_EQ(&v12, changes[0].relative_view);
452 EXPECT_EQ(ORDER_DIRECTION_ABOVE, changes[0].direction);
454 EXPECT_EQ(&v11, changes[1].view);
455 EXPECT_EQ(&v12, changes[1].relative_view);
456 EXPECT_EQ(ORDER_DIRECTION_ABOVE, changes[1].direction);
460 OrderChangeObserver observer(&v11);
462 // Move v11 below v12.
463 // Resulting order: v11, v12, v13
464 v11.Reorder(&v12, ORDER_DIRECTION_BELOW);
465 EXPECT_EQ(&v11, v1.children().front());
466 EXPECT_EQ(&v13, v1.children().back());
468 OrderChangeObserver::Changes changes = observer.GetAndClearChanges();
469 ASSERT_EQ(2U, changes.size());
470 EXPECT_EQ(&v11, changes[0].view);
471 EXPECT_EQ(&v12, changes[0].relative_view);
472 EXPECT_EQ(ORDER_DIRECTION_BELOW, changes[0].direction);
474 EXPECT_EQ(&v11, changes[1].view);
475 EXPECT_EQ(&v12, changes[1].relative_view);
476 EXPECT_EQ(ORDER_DIRECTION_BELOW, changes[1].direction);
482 typedef std::vector<std::string> Changes;
484 std::string ViewIdToString(Id id) {
485 return (id == 0) ? "null" :
486 base::StringPrintf("%d,%d", HiWord(id), LoWord(id));
489 std::string RectToString(const Rect& rect) {
490 return base::StringPrintf("%d,%d %dx%d",
491 rect.x, rect.y, rect.width, rect.height);
494 class BoundsChangeObserver : public ViewObserver {
496 explicit BoundsChangeObserver(View* view) : view_(view) {
497 view_->AddObserver(this);
499 ~BoundsChangeObserver() override { view_->RemoveObserver(this); }
501 Changes GetAndClearChanges() {
503 changes.swap(changes_);
508 // Overridden from ViewObserver:
509 void OnViewBoundsChanging(View* view,
510 const Rect& old_bounds,
511 const Rect& new_bounds) override {
514 "view=%s old_bounds=%s new_bounds=%s phase=changing",
515 ViewIdToString(view->id()).c_str(),
516 RectToString(old_bounds).c_str(),
517 RectToString(new_bounds).c_str()));
519 void OnViewBoundsChanged(View* view,
520 const Rect& old_bounds,
521 const Rect& new_bounds) override {
524 "view=%s old_bounds=%s new_bounds=%s phase=changed",
525 ViewIdToString(view->id()).c_str(),
526 RectToString(old_bounds).c_str(),
527 RectToString(new_bounds).c_str()));
533 DISALLOW_COPY_AND_ASSIGN(BoundsChangeObserver);
538 TEST_F(ViewObserverTest, SetBounds) {
541 BoundsChangeObserver observer(&v1);
543 rect.width = rect.height = 100;
546 Changes changes = observer.GetAndClearChanges();
547 ASSERT_EQ(2U, changes.size());
549 "view=0,1 old_bounds=0,0 0x0 new_bounds=0,0 100x100 phase=changing",
552 "view=0,1 old_bounds=0,0 0x0 new_bounds=0,0 100x100 phase=changed",
559 class VisibilityChangeObserver : public ViewObserver {
561 explicit VisibilityChangeObserver(View* view) : view_(view) {
562 view_->AddObserver(this);
564 ~VisibilityChangeObserver() override { view_->RemoveObserver(this); }
566 Changes GetAndClearChanges() {
568 changes.swap(changes_);
573 // Overridden from ViewObserver:
574 void OnViewVisibilityChanging(View* view) override {
576 base::StringPrintf("view=%s phase=changing visibility=%s",
577 ViewIdToString(view->id()).c_str(),
578 view->visible() ? "true" : "false"));
580 void OnViewVisibilityChanged(View* view) override {
581 changes_.push_back(base::StringPrintf("view=%s phase=changed visibility=%s",
582 ViewIdToString(view->id()).c_str(),
583 view->visible() ? "true" : "false"));
589 DISALLOW_COPY_AND_ASSIGN(VisibilityChangeObserver);
594 TEST_F(ViewObserverTest, SetVisible) {
596 EXPECT_TRUE(v1.visible());
598 // Change visibility from true to false and make sure we get notifications.
599 VisibilityChangeObserver observer(&v1);
600 v1.SetVisible(false);
602 Changes changes = observer.GetAndClearChanges();
603 ASSERT_EQ(2U, changes.size());
604 EXPECT_EQ("view=0,1 phase=changing visibility=true", changes[0]);
605 EXPECT_EQ("view=0,1 phase=changed visibility=false", changes[1]);
608 // Set visible to existing value and verify no notifications.
609 VisibilityChangeObserver observer(&v1);
610 v1.SetVisible(false);
611 EXPECT_TRUE(observer.GetAndClearChanges().empty());
617 class PropertyChangeObserver : public ViewObserver {
619 explicit PropertyChangeObserver(View* view) : view_(view) {
620 view_->AddObserver(this);
622 virtual ~PropertyChangeObserver() { view_->RemoveObserver(this); }
624 Changes GetAndClearChanges() {
626 changes.swap(changes_);
631 // Overridden from ViewObserver:
632 void OnViewPropertyChanged(View* view,
633 const std::string& name,
634 const std::vector<uint8_t>* old_data,
635 const std::vector<uint8_t>* new_data) override {
636 changes_.push_back(base::StringPrintf(
637 "view=%s property changed key=%s old_value=%s new_value=%s",
638 ViewIdToString(view->id()).c_str(),
640 VectorToString(old_data).c_str(),
641 VectorToString(new_data).c_str()));
644 std::string VectorToString(const std::vector<uint8_t>* data) {
656 DISALLOW_COPY_AND_ASSIGN(PropertyChangeObserver);
661 TEST_F(ViewObserverTest, SetProperty) {
663 std::vector<uint8_t> one(1, '1');
666 // Change visibility from true to false and make sure we get notifications.
667 PropertyChangeObserver observer(&v1);
668 v1.SetProperty("one", &one);
669 Changes changes = observer.GetAndClearChanges();
670 ASSERT_EQ(1U, changes.size());
671 EXPECT_EQ("view=0,1 property changed key=one old_value=NULL new_value=1",
673 EXPECT_EQ(1U, v1.properties().size());
676 // Set visible to existing value and verify no notifications.
677 PropertyChangeObserver observer(&v1);
678 v1.SetProperty("one", &one);
679 EXPECT_TRUE(observer.GetAndClearChanges().empty());
680 EXPECT_EQ(1U, v1.properties().size());
683 // Set the value to NULL to delete it.
684 // Change visibility from true to false and make sure we get notifications.
685 PropertyChangeObserver observer(&v1);
686 v1.SetProperty("one", NULL);
687 Changes changes = observer.GetAndClearChanges();
688 ASSERT_EQ(1U, changes.size());
689 EXPECT_EQ("view=0,1 property changed key=one old_value=1 new_value=NULL",
691 EXPECT_EQ(0U, v1.properties().size());
694 // Setting a null property to null shouldn't update us.
695 PropertyChangeObserver observer(&v1);
696 v1.SetProperty("one", NULL);
697 EXPECT_TRUE(observer.GetAndClearChanges().empty());
698 EXPECT_EQ(0U, v1.properties().size());