Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: components/mus/public/cpp/tests/window_unittest.cc

Issue 2119963002: Move mus to //services/ui (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "components/mus/public/cpp/window.h"
6
7 #include <limits.h>
8 #include <stdint.h>
9
10 #include "base/logging.h"
11 #include "base/macros.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/stringprintf.h"
14 #include "components/mus/common/util.h"
15 #include "components/mus/public/cpp/lib/window_private.h"
16 #include "components/mus/public/cpp/property_type_converters.h"
17 #include "components/mus/public/cpp/tests/test_window.h"
18 #include "components/mus/public/cpp/window_observer.h"
19 #include "components/mus/public/cpp/window_property.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "ui/gfx/geometry/rect.h"
22
23 namespace mus {
24
25 namespace {
26
27 TestWindow* CreateTestWindow(TestWindow* parent) {
28 TestWindow* window = new TestWindow;
29 if (parent)
30 parent->AddChild(window);
31 return window;
32 }
33
34 TestWindow* CreateTestWindow(int id, TestWindow* parent) {
35 TestWindow* window = new TestWindow(0);
36 window->set_local_id(id);
37 if (parent)
38 parent->AddChild(window);
39 return window;
40 }
41
42 std::string ChildWindowIDsAsString(TestWindow* parent) {
43 std::string result;
44 for (Window* child : parent->children()) {
45 if (!result.empty())
46 result += " ";
47 result += base::IntToString(child->local_id());
48 }
49 return result;
50 }
51
52 } // namespace
53 // Window ---------------------------------------------------------------------
54
55 using WindowTest = testing::Test;
56
57 TEST_F(WindowTest, AddChild) {
58 TestWindow w1;
59 TestWindow w11;
60 w1.AddChild(&w11);
61 EXPECT_EQ(1U, w1.children().size());
62 }
63
64 TEST_F(WindowTest, RemoveChild) {
65 TestWindow w1;
66 TestWindow w11;
67 w1.AddChild(&w11);
68 EXPECT_EQ(1U, w1.children().size());
69 w1.RemoveChild(&w11);
70 EXPECT_EQ(0U, w1.children().size());
71 }
72
73 TEST_F(WindowTest, Reparent) {
74 TestWindow w1;
75 TestWindow w2;
76 TestWindow w11;
77 w1.AddChild(&w11);
78 EXPECT_EQ(1U, w1.children().size());
79 w2.AddChild(&w11);
80 EXPECT_EQ(1U, w2.children().size());
81 EXPECT_EQ(0U, w1.children().size());
82 }
83
84 TEST_F(WindowTest, Contains) {
85 TestWindow w1;
86
87 // Direct descendant.
88 TestWindow w11;
89 w1.AddChild(&w11);
90 EXPECT_TRUE(w1.Contains(&w11));
91
92 // Indirect descendant.
93 TestWindow w111;
94 w11.AddChild(&w111);
95 EXPECT_TRUE(w1.Contains(&w111));
96 }
97 TEST_F(WindowTest, GetChildByLocalId) {
98 TestWindow w1;
99 w1.set_local_id(0);
100 EXPECT_EQ(&w1, w1.GetChildByLocalId(0));
101
102 TestWindow w11;
103 w11.set_local_id(11);
104 w1.AddChild(&w11);
105
106 TestWindow w12;
107 w12.set_local_id(w1.local_id());
108 w1.AddChild(&w12);
109
110 TestWindow w111;
111 w111.set_local_id(111);
112 w11.AddChild(&w111);
113
114 // Find direct & indirect descendents.
115 EXPECT_EQ(&w11, w1.GetChildByLocalId(w11.local_id()));
116 EXPECT_EQ(&w111, w1.GetChildByLocalId(w111.local_id()));
117 // Verifies parent returned by child with same id.
118 EXPECT_EQ(&w1, w1.GetChildByLocalId(w1.local_id()));
119 }
120
121 TEST_F(WindowTest, DrawnAndVisible) {
122 TestWindow w1;
123 EXPECT_FALSE(w1.visible());
124 w1.SetVisible(true);
125 EXPECT_TRUE(w1.visible());
126 EXPECT_FALSE(w1.IsDrawn());
127
128 WindowPrivate(&w1).set_parent_drawn(true);
129
130 TestWindow w11;
131 w11.SetVisible(true);
132 w1.AddChild(&w11);
133 EXPECT_TRUE(w11.visible());
134 EXPECT_TRUE(w11.IsDrawn());
135
136 w1.RemoveChild(&w11);
137 EXPECT_TRUE(w11.visible());
138 EXPECT_FALSE(w11.IsDrawn());
139 }
140
141 namespace {
142 MUS_DEFINE_WINDOW_PROPERTY_KEY(int, kIntKey, -2);
143 MUS_DEFINE_WINDOW_PROPERTY_KEY(const char*, kStringKey, "squeamish");
144 }
145
146 TEST_F(WindowTest, Property) {
147 TestWindow w;
148
149 // Non-existent properties should return the default walues.
150 EXPECT_EQ(-2, w.GetLocalProperty(kIntKey));
151 EXPECT_EQ(std::string("squeamish"), w.GetLocalProperty(kStringKey));
152
153 // A set property walue should be returned again (even if it's the default
154 // walue).
155 w.SetLocalProperty(kIntKey, INT_MAX);
156 EXPECT_EQ(INT_MAX, w.GetLocalProperty(kIntKey));
157 w.SetLocalProperty(kIntKey, -2);
158 EXPECT_EQ(-2, w.GetLocalProperty(kIntKey));
159 w.SetLocalProperty(kIntKey, INT_MIN);
160 EXPECT_EQ(INT_MIN, w.GetLocalProperty(kIntKey));
161
162 w.SetLocalProperty(kStringKey, static_cast<const char*>(NULL));
163 EXPECT_EQ(NULL, w.GetLocalProperty(kStringKey));
164 w.SetLocalProperty(kStringKey, "squeamish");
165 EXPECT_EQ(std::string("squeamish"), w.GetLocalProperty(kStringKey));
166 w.SetLocalProperty(kStringKey, "ossifrage");
167 EXPECT_EQ(std::string("ossifrage"), w.GetLocalProperty(kStringKey));
168
169 // ClearProperty should restore the default walue.
170 w.ClearLocalProperty(kIntKey);
171 EXPECT_EQ(-2, w.GetLocalProperty(kIntKey));
172 w.ClearLocalProperty(kStringKey);
173 EXPECT_EQ(std::string("squeamish"), w.GetLocalProperty(kStringKey));
174 }
175
176 namespace {
177
178 class TestProperty {
179 public:
180 TestProperty() {}
181 virtual ~TestProperty() { last_deleted_ = this; }
182 static TestProperty* last_deleted() { return last_deleted_; }
183
184 private:
185 static TestProperty* last_deleted_;
186 DISALLOW_COPY_AND_ASSIGN(TestProperty);
187 };
188
189 TestProperty* TestProperty::last_deleted_ = NULL;
190
191 MUS_DEFINE_OWNED_WINDOW_PROPERTY_KEY(TestProperty, kOwnedKey, NULL);
192
193 } // namespace
194
195 TEST_F(WindowTest, OwnedProperty) {
196 TestProperty* p3 = NULL;
197 {
198 TestWindow w;
199 EXPECT_EQ(NULL, w.GetLocalProperty(kOwnedKey));
200 TestProperty* p1 = new TestProperty();
201 w.SetLocalProperty(kOwnedKey, p1);
202 EXPECT_EQ(p1, w.GetLocalProperty(kOwnedKey));
203 EXPECT_EQ(NULL, TestProperty::last_deleted());
204
205 TestProperty* p2 = new TestProperty();
206 w.SetLocalProperty(kOwnedKey, p2);
207 EXPECT_EQ(p2, w.GetLocalProperty(kOwnedKey));
208 EXPECT_EQ(p1, TestProperty::last_deleted());
209
210 w.ClearLocalProperty(kOwnedKey);
211 EXPECT_EQ(NULL, w.GetLocalProperty(kOwnedKey));
212 EXPECT_EQ(p2, TestProperty::last_deleted());
213
214 p3 = new TestProperty();
215 w.SetLocalProperty(kOwnedKey, p3);
216 EXPECT_EQ(p3, w.GetLocalProperty(kOwnedKey));
217 EXPECT_EQ(p2, TestProperty::last_deleted());
218 }
219
220 EXPECT_EQ(p3, TestProperty::last_deleted());
221 }
222
223 // WindowObserver --------------------------------------------------------
224
225 typedef testing::Test WindowObserverTest;
226
227 bool TreeChangeParamsMatch(const WindowObserver::TreeChangeParams& lhs,
228 const WindowObserver::TreeChangeParams& rhs) {
229 return lhs.target == rhs.target && lhs.old_parent == rhs.old_parent &&
230 lhs.new_parent == rhs.new_parent && lhs.receiver == rhs.receiver;
231 }
232
233 class TreeChangeObserver : public WindowObserver {
234 public:
235 explicit TreeChangeObserver(Window* observee) : observee_(observee) {
236 observee_->AddObserver(this);
237 }
238 ~TreeChangeObserver() override { observee_->RemoveObserver(this); }
239
240 void Reset() { received_params_.clear(); }
241
242 const std::vector<TreeChangeParams>& received_params() {
243 return received_params_;
244 }
245
246 private:
247 // Overridden from WindowObserver:
248 void OnTreeChanging(const TreeChangeParams& params) override {
249 received_params_.push_back(params);
250 }
251 void OnTreeChanged(const TreeChangeParams& params) override {
252 received_params_.push_back(params);
253 }
254
255 Window* observee_;
256 std::vector<TreeChangeParams> received_params_;
257
258 DISALLOW_COPY_AND_ASSIGN(TreeChangeObserver);
259 };
260
261 // Adds/Removes w11 to w1.
262 TEST_F(WindowObserverTest, TreeChange_SimpleAddRemove) {
263 TestWindow w1;
264 w1.set_local_id(1);
265 TreeChangeObserver o1(&w1);
266 EXPECT_TRUE(o1.received_params().empty());
267
268 TestWindow w11;
269 w11.set_local_id(11);
270 TreeChangeObserver o11(&w11);
271 EXPECT_TRUE(o11.received_params().empty());
272
273 // Add.
274
275 w1.AddChild(&w11);
276
277 EXPECT_EQ(2U, o1.received_params().size());
278 WindowObserver::TreeChangeParams p1;
279 p1.target = &w11;
280 p1.receiver = &w1;
281 p1.old_parent = NULL;
282 p1.new_parent = &w1;
283 EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back()));
284
285 EXPECT_EQ(2U, o11.received_params().size());
286 WindowObserver::TreeChangeParams p11 = p1;
287 p11.receiver = &w11;
288 EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front()));
289 EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back()));
290
291 o1.Reset();
292 o11.Reset();
293 EXPECT_TRUE(o1.received_params().empty());
294 EXPECT_TRUE(o11.received_params().empty());
295
296 // Remove.
297
298 w1.RemoveChild(&w11);
299
300 EXPECT_EQ(2U, o1.received_params().size());
301 p1.target = &w11;
302 p1.receiver = &w1;
303 p1.old_parent = &w1;
304 p1.new_parent = NULL;
305 EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().front()));
306
307 EXPECT_EQ(2U, o11.received_params().size());
308 p11 = p1;
309 p11.receiver = &w11;
310 EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front()));
311 EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back()));
312 }
313
314 // Creates these two trees:
315 // w1
316 // +- w11
317 // w111
318 // +- w1111
319 // +- w1112
320 // Then adds/removes w111 from w11.
321 TEST_F(WindowObserverTest, TreeChange_NestedAddRemove) {
322 TestWindow w1, w11, w111, w1111, w1112;
323
324 // Root tree.
325 w1.AddChild(&w11);
326
327 // Tree to be attached.
328 w111.AddChild(&w1111);
329 w111.AddChild(&w1112);
330
331 TreeChangeObserver o1(&w1), o11(&w11), o111(&w111), o1111(&w1111),
332 o1112(&w1112);
333 WindowObserver::TreeChangeParams p1, p11, p111, p1111, p1112;
334
335 // Add.
336
337 w11.AddChild(&w111);
338
339 EXPECT_EQ(2U, o1.received_params().size());
340 p1.target = &w111;
341 p1.receiver = &w1;
342 p1.old_parent = NULL;
343 p1.new_parent = &w11;
344 EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back()));
345
346 EXPECT_EQ(2U, o11.received_params().size());
347 p11 = p1;
348 p11.receiver = &w11;
349 EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back()));
350
351 EXPECT_EQ(2U, o111.received_params().size());
352 p111 = p11;
353 p111.receiver = &w111;
354 EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front()));
355 EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back()));
356
357 EXPECT_EQ(2U, o1111.received_params().size());
358 p1111 = p111;
359 p1111.receiver = &w1111;
360 EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().front()));
361 EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().back()));
362
363 EXPECT_EQ(2U, o1112.received_params().size());
364 p1112 = p111;
365 p1112.receiver = &w1112;
366 EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().front()));
367 EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().back()));
368
369 // Remove.
370 o1.Reset();
371 o11.Reset();
372 o111.Reset();
373 o1111.Reset();
374 o1112.Reset();
375 EXPECT_TRUE(o1.received_params().empty());
376 EXPECT_TRUE(o11.received_params().empty());
377 EXPECT_TRUE(o111.received_params().empty());
378 EXPECT_TRUE(o1111.received_params().empty());
379 EXPECT_TRUE(o1112.received_params().empty());
380
381 w11.RemoveChild(&w111);
382
383 EXPECT_EQ(2U, o1.received_params().size());
384 p1.target = &w111;
385 p1.receiver = &w1;
386 p1.old_parent = &w11;
387 p1.new_parent = NULL;
388 EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().front()));
389
390 EXPECT_EQ(2U, o11.received_params().size());
391 p11 = p1;
392 p11.receiver = &w11;
393 EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front()));
394
395 EXPECT_EQ(2U, o111.received_params().size());
396 p111 = p11;
397 p111.receiver = &w111;
398 EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front()));
399 EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back()));
400
401 EXPECT_EQ(2U, o1111.received_params().size());
402 p1111 = p111;
403 p1111.receiver = &w1111;
404 EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().front()));
405 EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().back()));
406
407 EXPECT_EQ(2U, o1112.received_params().size());
408 p1112 = p111;
409 p1112.receiver = &w1112;
410 EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().front()));
411 EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().back()));
412 }
413
414 TEST_F(WindowObserverTest, TreeChange_Reparent) {
415 TestWindow w1, w11, w12, w111;
416 w1.AddChild(&w11);
417 w1.AddChild(&w12);
418 w11.AddChild(&w111);
419
420 TreeChangeObserver o1(&w1), o11(&w11), o12(&w12), o111(&w111);
421
422 // Reparent.
423 w12.AddChild(&w111);
424
425 // w1 (root) should see both changing and changed notifications.
426 EXPECT_EQ(4U, o1.received_params().size());
427 WindowObserver::TreeChangeParams p1;
428 p1.target = &w111;
429 p1.receiver = &w1;
430 p1.old_parent = &w11;
431 p1.new_parent = &w12;
432 EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().front()));
433 EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back()));
434
435 // w11 should see changing notifications.
436 EXPECT_EQ(2U, o11.received_params().size());
437 WindowObserver::TreeChangeParams p11;
438 p11 = p1;
439 p11.receiver = &w11;
440 EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front()));
441
442 // w12 should see changed notifications.
443 EXPECT_EQ(2U, o12.received_params().size());
444 WindowObserver::TreeChangeParams p12;
445 p12 = p1;
446 p12.receiver = &w12;
447 EXPECT_TRUE(TreeChangeParamsMatch(p12, o12.received_params().back()));
448
449 // w111 should see both changing and changed notifications.
450 EXPECT_EQ(2U, o111.received_params().size());
451 WindowObserver::TreeChangeParams p111;
452 p111 = p1;
453 p111.receiver = &w111;
454 EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front()));
455 EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back()));
456 }
457
458 namespace {
459
460 class OrderChangeObserver : public WindowObserver {
461 public:
462 struct Change {
463 Window* window;
464 Window* relative_window;
465 mojom::OrderDirection direction;
466 };
467 typedef std::vector<Change> Changes;
468
469 explicit OrderChangeObserver(Window* observee) : observee_(observee) {
470 observee_->AddObserver(this);
471 }
472 ~OrderChangeObserver() override { observee_->RemoveObserver(this); }
473
474 Changes GetAndClearChanges() {
475 Changes changes;
476 changes_.swap(changes);
477 return changes;
478 }
479
480 private:
481 // Overridden from WindowObserver:
482 void OnWindowReordering(Window* window,
483 Window* relative_window,
484 mojom::OrderDirection direction) override {
485 OnWindowReordered(window, relative_window, direction);
486 }
487
488 void OnWindowReordered(Window* window,
489 Window* relative_window,
490 mojom::OrderDirection direction) override {
491 Change change;
492 change.window = window;
493 change.relative_window = relative_window;
494 change.direction = direction;
495 changes_.push_back(change);
496 }
497
498 Window* observee_;
499 Changes changes_;
500
501 DISALLOW_COPY_AND_ASSIGN(OrderChangeObserver);
502 };
503
504 } // namespace
505
506 TEST_F(WindowObserverTest, Order) {
507 TestWindow w1, w11, w12, w13;
508 w1.AddChild(&w11);
509 w1.AddChild(&w12);
510 w1.AddChild(&w13);
511
512 // Order: w11, w12, w13
513 EXPECT_EQ(3U, w1.children().size());
514 EXPECT_EQ(&w11, w1.children().front());
515 EXPECT_EQ(&w13, w1.children().back());
516
517 {
518 OrderChangeObserver observer(&w11);
519
520 // Move w11 to front.
521 // Resulting order: w12, w13, w11
522 w11.MoveToFront();
523 EXPECT_EQ(&w12, w1.children().front());
524 EXPECT_EQ(&w11, w1.children().back());
525
526 OrderChangeObserver::Changes changes = observer.GetAndClearChanges();
527 ASSERT_EQ(2U, changes.size());
528 EXPECT_EQ(&w11, changes[0].window);
529 EXPECT_EQ(&w13, changes[0].relative_window);
530 EXPECT_EQ(mojom::OrderDirection::ABOVE, changes[0].direction);
531
532 EXPECT_EQ(&w11, changes[1].window);
533 EXPECT_EQ(&w13, changes[1].relative_window);
534 EXPECT_EQ(mojom::OrderDirection::ABOVE, changes[1].direction);
535 }
536
537 {
538 OrderChangeObserver observer(&w11);
539
540 // Move w11 to back.
541 // Resulting order: w11, w12, w13
542 w11.MoveToBack();
543 EXPECT_EQ(&w11, w1.children().front());
544 EXPECT_EQ(&w13, w1.children().back());
545
546 OrderChangeObserver::Changes changes = observer.GetAndClearChanges();
547 ASSERT_EQ(2U, changes.size());
548 EXPECT_EQ(&w11, changes[0].window);
549 EXPECT_EQ(&w12, changes[0].relative_window);
550 EXPECT_EQ(mojom::OrderDirection::BELOW, changes[0].direction);
551
552 EXPECT_EQ(&w11, changes[1].window);
553 EXPECT_EQ(&w12, changes[1].relative_window);
554 EXPECT_EQ(mojom::OrderDirection::BELOW, changes[1].direction);
555 }
556
557 {
558 OrderChangeObserver observer(&w11);
559
560 // Move w11 above w12.
561 // Resulting order: w12. w11, w13
562 w11.Reorder(&w12, mojom::OrderDirection::ABOVE);
563 EXPECT_EQ(&w12, w1.children().front());
564 EXPECT_EQ(&w13, w1.children().back());
565
566 OrderChangeObserver::Changes changes = observer.GetAndClearChanges();
567 ASSERT_EQ(2U, changes.size());
568 EXPECT_EQ(&w11, changes[0].window);
569 EXPECT_EQ(&w12, changes[0].relative_window);
570 EXPECT_EQ(mojom::OrderDirection::ABOVE, changes[0].direction);
571
572 EXPECT_EQ(&w11, changes[1].window);
573 EXPECT_EQ(&w12, changes[1].relative_window);
574 EXPECT_EQ(mojom::OrderDirection::ABOVE, changes[1].direction);
575 }
576
577 {
578 OrderChangeObserver observer(&w11);
579
580 // Move w11 below w12.
581 // Resulting order: w11, w12, w13
582 w11.Reorder(&w12, mojom::OrderDirection::BELOW);
583 EXPECT_EQ(&w11, w1.children().front());
584 EXPECT_EQ(&w13, w1.children().back());
585
586 OrderChangeObserver::Changes changes = observer.GetAndClearChanges();
587 ASSERT_EQ(2U, changes.size());
588 EXPECT_EQ(&w11, changes[0].window);
589 EXPECT_EQ(&w12, changes[0].relative_window);
590 EXPECT_EQ(mojom::OrderDirection::BELOW, changes[0].direction);
591
592 EXPECT_EQ(&w11, changes[1].window);
593 EXPECT_EQ(&w12, changes[1].relative_window);
594 EXPECT_EQ(mojom::OrderDirection::BELOW, changes[1].direction);
595 }
596 }
597
598 namespace {
599
600 typedef std::vector<std::string> Changes;
601
602 std::string RectToString(const gfx::Rect& rect) {
603 return base::StringPrintf("%d,%d %dx%d", rect.x(), rect.y(), rect.width(),
604 rect.height());
605 }
606
607 class BoundsChangeObserver : public WindowObserver {
608 public:
609 explicit BoundsChangeObserver(Window* window) : window_(window) {
610 window_->AddObserver(this);
611 }
612 ~BoundsChangeObserver() override { window_->RemoveObserver(this); }
613
614 Changes GetAndClearChanges() {
615 Changes changes;
616 changes.swap(changes_);
617 return changes;
618 }
619
620 private:
621 // Overridden from WindowObserver:
622 void OnWindowBoundsChanging(Window* window,
623 const gfx::Rect& old_bounds,
624 const gfx::Rect& new_bounds) override {
625 changes_.push_back(base::StringPrintf(
626 "window=%d old_bounds=%s new_bounds=%s phase=changing",
627 window->local_id(), RectToString(old_bounds).c_str(),
628 RectToString(new_bounds).c_str()));
629 }
630 void OnWindowBoundsChanged(Window* window,
631 const gfx::Rect& old_bounds,
632 const gfx::Rect& new_bounds) override {
633 changes_.push_back(base::StringPrintf(
634 "window=%d old_bounds=%s new_bounds=%s phase=changed",
635 window->local_id(), RectToString(old_bounds).c_str(),
636 RectToString(new_bounds).c_str()));
637 }
638
639 Window* window_;
640 Changes changes_;
641
642 DISALLOW_COPY_AND_ASSIGN(BoundsChangeObserver);
643 };
644
645 } // namespace
646
647 TEST_F(WindowObserverTest, SetBounds) {
648 TestWindow w1;
649 w1.set_local_id(1);
650 {
651 BoundsChangeObserver observer(&w1);
652 w1.SetBounds(gfx::Rect(0, 0, 100, 100));
653
654 Changes changes = observer.GetAndClearChanges();
655 ASSERT_EQ(2U, changes.size());
656 EXPECT_EQ(
657 "window=1 old_bounds=0,0 0x0 new_bounds=0,0 100x100 phase=changing",
658 changes[0]);
659 EXPECT_EQ(
660 "window=1 old_bounds=0,0 0x0 new_bounds=0,0 100x100 phase=changed",
661 changes[1]);
662 }
663 }
664
665 namespace {
666
667 class VisibilityChangeObserver : public WindowObserver {
668 public:
669 explicit VisibilityChangeObserver(Window* window) : window_(window) {
670 window_->AddObserver(this);
671 }
672 ~VisibilityChangeObserver() override { window_->RemoveObserver(this); }
673
674 Changes GetAndClearChanges() {
675 Changes changes;
676 changes.swap(changes_);
677 return changes;
678 }
679
680 private:
681 // Overridden from WindowObserver:
682 void OnWindowVisibilityChanging(Window* window) override {
683 changes_.push_back(base::StringPrintf(
684 "window=%d phase=changing wisibility=%s", window->local_id(),
685 window->visible() ? "true" : "false"));
686 }
687 void OnWindowVisibilityChanged(Window* window) override {
688 changes_.push_back(base::StringPrintf(
689 "window=%d phase=changed wisibility=%s", window->local_id(),
690 window->visible() ? "true" : "false"));
691 }
692
693 Window* window_;
694 Changes changes_;
695
696 DISALLOW_COPY_AND_ASSIGN(VisibilityChangeObserver);
697 };
698
699 } // namespace
700
701 TEST_F(WindowObserverTest, SetVisible) {
702 TestWindow w1;
703 EXPECT_FALSE(w1.visible());
704 w1.set_local_id(1);
705 w1.SetVisible(true);
706 EXPECT_TRUE(w1.visible());
707 {
708 // Change wisibility from true to false and make sure we get notifications.
709 VisibilityChangeObserver observer(&w1);
710 w1.SetVisible(false);
711
712 Changes changes = observer.GetAndClearChanges();
713 ASSERT_EQ(2U, changes.size());
714 EXPECT_EQ("window=1 phase=changing wisibility=true", changes[0]);
715 EXPECT_EQ("window=1 phase=changed wisibility=false", changes[1]);
716 }
717 {
718 // Set visible to existing walue and werify no notifications.
719 VisibilityChangeObserver observer(&w1);
720 w1.SetVisible(false);
721 EXPECT_TRUE(observer.GetAndClearChanges().empty());
722 }
723 }
724
725 TEST_F(WindowObserverTest, SetVisibleParent) {
726 TestWindow parent;
727 parent.SetVisible(true);
728 parent.set_local_id(1);
729 TestWindow child;
730 child.SetVisible(true);
731 child.set_local_id(2);
732 parent.AddChild(&child);
733 EXPECT_TRUE(parent.visible());
734 EXPECT_TRUE(child.visible());
735 {
736 // Change wisibility from true to false and make sure we get notifications
737 // on the parent.
738 VisibilityChangeObserver observer(&parent);
739 child.SetVisible(false);
740
741 Changes changes = observer.GetAndClearChanges();
742 ASSERT_EQ(1U, changes.size());
743 EXPECT_EQ("window=2 phase=changed wisibility=false", changes[0]);
744 }
745 }
746
747 TEST_F(WindowObserverTest, SetVisibleChild) {
748 TestWindow parent;
749 parent.SetVisible(true);
750 parent.set_local_id(1);
751 TestWindow child;
752 child.SetVisible(true);
753 child.set_local_id(2);
754 parent.AddChild(&child);
755 EXPECT_TRUE(parent.visible());
756 EXPECT_TRUE(child.visible());
757 {
758 // Change wisibility from true to false and make sure we get notifications
759 // on the child.
760 VisibilityChangeObserver observer(&child);
761 parent.SetVisible(false);
762
763 Changes changes = observer.GetAndClearChanges();
764 ASSERT_EQ(1U, changes.size());
765 EXPECT_EQ("window=1 phase=changed wisibility=false", changes[0]);
766 }
767 }
768
769 namespace {
770
771 class OpacityChangeObserver : public WindowObserver {
772 public:
773 explicit OpacityChangeObserver(Window* window) : window_(window) {
774 window_->AddObserver(this);
775 }
776 ~OpacityChangeObserver() override { window_->RemoveObserver(this); }
777
778 Changes GetAndClearChanges() {
779 Changes changes;
780 changes.swap(changes_);
781 return changes;
782 }
783
784 private:
785 // WindowObserver:
786 void OnWindowOpacityChanged(Window* window,
787 float old_opacity,
788 float new_opacity) override {
789 changes_.push_back(
790 base::StringPrintf("window=%d old_opacity=%.2f new_opacity=%.2f",
791 window->local_id(), old_opacity, new_opacity));
792 }
793
794 Window* window_;
795 Changes changes_;
796
797 DISALLOW_COPY_AND_ASSIGN(OpacityChangeObserver);
798 };
799
800 } // namespace
801
802 // Tests that WindowObserver is only notified when opacity changes.
803 TEST_F(WindowObserverTest, SetOpacity) {
804 TestWindow w1;
805 w1.set_local_id(1);
806 EXPECT_FLOAT_EQ(1.0f, w1.opacity());
807
808 // Changing the opacity should trigger a notification.
809 OpacityChangeObserver observer(&w1);
810 w1.SetOpacity(0.5f);
811 EXPECT_FLOAT_EQ(0.5f, w1.opacity());
812 Changes changes = observer.GetAndClearChanges();
813 ASSERT_EQ(1u, changes.size());
814 EXPECT_EQ("window=1 old_opacity=1.00 new_opacity=0.50", changes[0]);
815
816 // Setting to the same opacity should be rejected, no notification.
817 w1.SetOpacity(0.5f);
818 EXPECT_FLOAT_EQ(0.5f, w1.opacity());
819 changes = observer.GetAndClearChanges();
820 EXPECT_TRUE(changes.empty());
821
822 // Alternate sources of opacity changes should trigger a notification.
823 WindowPrivate(&w1).LocalSetOpacity(1.0f);
824 EXPECT_FLOAT_EQ(1.0f, w1.opacity());
825 changes = observer.GetAndClearChanges();
826 ASSERT_EQ(1u, changes.size());
827 EXPECT_EQ("window=1 old_opacity=0.50 new_opacity=1.00", changes[0]);
828 }
829
830 namespace {
831
832 class SharedPropertyChangeObserver : public WindowObserver {
833 public:
834 explicit SharedPropertyChangeObserver(Window* window) : window_(window) {
835 window_->AddObserver(this);
836 }
837 ~SharedPropertyChangeObserver() override { window_->RemoveObserver(this); }
838
839 Changes GetAndClearChanges() {
840 Changes changes;
841 changes.swap(changes_);
842 return changes;
843 }
844
845 private:
846 // Overridden from WindowObserver:
847 void OnWindowSharedPropertyChanged(
848 Window* window,
849 const std::string& name,
850 const std::vector<uint8_t>* old_data,
851 const std::vector<uint8_t>* new_data) override {
852 changes_.push_back(base::StringPrintf(
853 "window=%d shared property changed key=%s old_value=%s new_value=%s",
854 window->local_id(), name.c_str(), VectorToString(old_data).c_str(),
855 VectorToString(new_data).c_str()));
856 }
857
858 std::string VectorToString(const std::vector<uint8_t>* data) {
859 if (!data)
860 return "NULL";
861 gfx::Size size = mojo::ConvertTo<gfx::Size>(*data);
862 return base::StringPrintf("%d,%d", size.width(), size.height());
863 }
864
865 Window* window_;
866 Changes changes_;
867
868 DISALLOW_COPY_AND_ASSIGN(SharedPropertyChangeObserver);
869 };
870
871 } // namespace
872
873 TEST_F(WindowObserverTest, SetSharedProperty) {
874 TestWindow w1;
875 w1.set_local_id(1);
876 gfx::Size size(100, 100);
877
878 {
879 // Change visibility from true to false and make sure we get notifications.
880 SharedPropertyChangeObserver observer(&w1);
881 w1.SetSharedProperty<gfx::Size>("size", size);
882 Changes changes = observer.GetAndClearChanges();
883 ASSERT_EQ(1U, changes.size());
884 EXPECT_EQ(
885 "window=1 shared property changed key=size old_value=NULL "
886 "new_value=100,100",
887 changes[0]);
888 EXPECT_EQ(1U, w1.shared_properties().size());
889 EXPECT_EQ(w1.GetSharedProperty<gfx::Size>("size"), size);
890 EXPECT_TRUE(w1.HasSharedProperty("size"));
891 }
892 {
893 // Set visible to existing value and verify no notifications.
894 SharedPropertyChangeObserver observer(&w1);
895 w1.SetSharedProperty<gfx::Size>("size", size);
896 EXPECT_TRUE(observer.GetAndClearChanges().empty());
897 EXPECT_EQ(1U, w1.shared_properties().size());
898 EXPECT_TRUE(w1.HasSharedProperty("size"));
899 }
900 {
901 // Clear the shared property.
902 // Change visibility from true to false and make sure we get notifications.
903 SharedPropertyChangeObserver observer(&w1);
904 w1.ClearSharedProperty("size");
905 Changes changes = observer.GetAndClearChanges();
906 ASSERT_EQ(1U, changes.size());
907 EXPECT_EQ(
908 "window=1 shared property changed key=size old_value=100,100 "
909 "new_value=NULL",
910 changes[0]);
911 EXPECT_EQ(0U, w1.shared_properties().size());
912 EXPECT_FALSE(w1.HasSharedProperty("size"));
913 }
914 {
915 // Clearing a non-existent property shouldn't update us.
916 SharedPropertyChangeObserver observer(&w1);
917 w1.ClearSharedProperty("size");
918 EXPECT_TRUE(observer.GetAndClearChanges().empty());
919 EXPECT_EQ(0U, w1.shared_properties().size());
920 EXPECT_FALSE(w1.HasSharedProperty("size"));
921 }
922 }
923
924 namespace {
925
926 typedef std::pair<const void*, intptr_t> PropertyChangeInfo;
927
928 class LocalPropertyChangeObserver : public WindowObserver {
929 public:
930 explicit LocalPropertyChangeObserver(Window* window)
931 : window_(window), property_key_(nullptr), old_property_value_(-1) {
932 window_->AddObserver(this);
933 }
934 ~LocalPropertyChangeObserver() override { window_->RemoveObserver(this); }
935
936 PropertyChangeInfo PropertyChangeInfoAndClear() {
937 PropertyChangeInfo result(property_key_, old_property_value_);
938 property_key_ = NULL;
939 old_property_value_ = -3;
940 return result;
941 }
942
943 private:
944 void OnWindowLocalPropertyChanged(Window* window,
945 const void* key,
946 intptr_t old) override {
947 property_key_ = key;
948 old_property_value_ = old;
949 }
950
951 Window* window_;
952 const void* property_key_;
953 intptr_t old_property_value_;
954
955 DISALLOW_COPY_AND_ASSIGN(LocalPropertyChangeObserver);
956 };
957
958 } // namespace
959
960 TEST_F(WindowObserverTest, LocalPropertyChanged) {
961 TestWindow w1;
962 LocalPropertyChangeObserver o(&w1);
963
964 static const WindowProperty<int> prop = {-2};
965
966 w1.SetLocalProperty(&prop, 1);
967 EXPECT_EQ(PropertyChangeInfo(&prop, -2), o.PropertyChangeInfoAndClear());
968 w1.SetLocalProperty(&prop, -2);
969 EXPECT_EQ(PropertyChangeInfo(&prop, 1), o.PropertyChangeInfoAndClear());
970 w1.SetLocalProperty(&prop, 3);
971 EXPECT_EQ(PropertyChangeInfo(&prop, -2), o.PropertyChangeInfoAndClear());
972 w1.ClearLocalProperty(&prop);
973 EXPECT_EQ(PropertyChangeInfo(&prop, 3), o.PropertyChangeInfoAndClear());
974
975 // Sanity check to see if |PropertyChangeInfoAndClear| really clears.
976 EXPECT_EQ(PropertyChangeInfo(reinterpret_cast<const void*>(NULL), -3),
977 o.PropertyChangeInfoAndClear());
978 }
979
980 TEST_F(WindowTest, RemoveTransientWindow) {
981 std::unique_ptr<TestWindow> w1(CreateTestWindow(nullptr));
982 std::unique_ptr<TestWindow> w11(CreateTestWindow(w1.get()));
983 TestWindow* w12 = CreateTestWindow(w1.get());
984 EXPECT_EQ(2u, w1->children().size());
985 // w12's lifetime is now tied to w11.
986 w11->AddTransientWindow(w12);
987 w11.reset();
988 EXPECT_EQ(0u, w1->children().size());
989 }
990
991 TEST_F(WindowTest, TransientWindow) {
992 std::unique_ptr<TestWindow> parent(CreateTestWindow(nullptr));
993 std::unique_ptr<TestWindow> w1(CreateTestWindow(parent.get()));
994 std::unique_ptr<TestWindow> w3(CreateTestWindow(parent.get()));
995
996 Window* w2 = CreateTestWindow(parent.get());
997 EXPECT_EQ(w2, parent->children().back());
998 ASSERT_EQ(3u, parent->children().size());
999
1000 w1->AddTransientWindow(w2);
1001 // Stack w1 at the top (end). This should force w2 to be last (on top of w1).
1002 w1->MoveToFront();
1003 ASSERT_EQ(3u, parent->children().size());
1004 EXPECT_EQ(w2, parent->children().back());
1005
1006 // Destroy w1, which should also destroy w3 (since it's a transient child).A
1007 w1.reset();
1008 w2 = nullptr;
1009 ASSERT_EQ(1u, parent->children().size());
1010 EXPECT_EQ(w3.get(), parent->children()[0]);
1011 }
1012
1013 // Tests that transient windows are stacked as a unit when using order above.
1014 TEST_F(WindowTest, TransientWindowsGroupAbove) {
1015 std::unique_ptr<TestWindow> parent(CreateTestWindow(0, nullptr));
1016 std::unique_ptr<TestWindow> w1(CreateTestWindow(1, parent.get()));
1017
1018 TestWindow* w11 = CreateTestWindow(11, parent.get());
1019 std::unique_ptr<TestWindow> w2(CreateTestWindow(2, parent.get()));
1020
1021 TestWindow* w21 = CreateTestWindow(21, parent.get());
1022 TestWindow* w211 = CreateTestWindow(211, parent.get());
1023 TestWindow* w212 = CreateTestWindow(212, parent.get());
1024 TestWindow* w213 = CreateTestWindow(213, parent.get());
1025 TestWindow* w22 = CreateTestWindow(22, parent.get());
1026 ASSERT_EQ(8u, parent->children().size());
1027
1028 // w11 is now owned by w1.
1029 w1->AddTransientWindow(w11);
1030 // w21 is now owned by w2.
1031 w2->AddTransientWindow(w21);
1032 // w22 is now owned by w2.
1033 w2->AddTransientWindow(w22);
1034 // w211 is now owned by w21.
1035 w21->AddTransientWindow(w211);
1036 // w212 is now owned by w21.
1037 w21->AddTransientWindow(w212);
1038 // w213 is now owned by w21.
1039 w21->AddTransientWindow(w213);
1040 EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
1041
1042 // Stack w1 at the top (end), this should force w11 to be last (on top of w1).
1043 w1->MoveToFront();
1044 EXPECT_EQ(w11, parent->children().back());
1045 EXPECT_EQ("2 21 211 212 213 22 1 11", ChildWindowIDsAsString(parent.get()));
1046
1047 // This tests that the order in children_ array rather than in
1048 // transient_children_ array is used when reinserting transient children.
1049 // If transient_children_ array was used '22' would be following '21'.
1050 w2->MoveToFront();
1051 EXPECT_EQ(w22, parent->children().back());
1052 EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
1053
1054 w11->Reorder(w2.get(), mojom::OrderDirection::ABOVE);
1055 EXPECT_EQ(w11, parent->children().back());
1056 EXPECT_EQ("2 21 211 212 213 22 1 11", ChildWindowIDsAsString(parent.get()));
1057
1058 w21->Reorder(w1.get(), mojom::OrderDirection::ABOVE);
1059 EXPECT_EQ(w22, parent->children().back());
1060 EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
1061
1062 w21->Reorder(w22, mojom::OrderDirection::ABOVE);
1063 EXPECT_EQ(w213, parent->children().back());
1064 EXPECT_EQ("1 11 2 22 21 211 212 213", ChildWindowIDsAsString(parent.get()));
1065
1066 w11->Reorder(w21, mojom::OrderDirection::ABOVE);
1067 EXPECT_EQ(w11, parent->children().back());
1068 EXPECT_EQ("2 22 21 211 212 213 1 11", ChildWindowIDsAsString(parent.get()));
1069
1070 w213->Reorder(w21, mojom::OrderDirection::ABOVE);
1071 EXPECT_EQ(w11, parent->children().back());
1072 EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
1073
1074 // No change when stacking a transient parent above its transient child.
1075 w21->Reorder(w211, mojom::OrderDirection::ABOVE);
1076 EXPECT_EQ(w11, parent->children().back());
1077 EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
1078
1079 // This tests that the order in children_ array rather than in
1080 // transient_children_ array is used when reinserting transient children.
1081 // If transient_children_ array was used '22' would be following '21'.
1082 w2->Reorder(w1.get(), mojom::OrderDirection::ABOVE);
1083 EXPECT_EQ(w212, parent->children().back());
1084 EXPECT_EQ("1 11 2 22 21 213 211 212", ChildWindowIDsAsString(parent.get()));
1085
1086 w11->Reorder(w213, mojom::OrderDirection::ABOVE);
1087 EXPECT_EQ(w11, parent->children().back());
1088 EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
1089 }
1090
1091 // Tests that transient children are stacked as a unit when using order below.
1092 TEST_F(WindowTest, TransientWindowsGroupBelow) {
1093 std::unique_ptr<TestWindow> parent(CreateTestWindow(0, nullptr));
1094 std::unique_ptr<TestWindow> w1(CreateTestWindow(1, parent.get()));
1095
1096 TestWindow* w11 = CreateTestWindow(11, parent.get());
1097 std::unique_ptr<TestWindow> w2(CreateTestWindow(2, parent.get()));
1098
1099 TestWindow* w21 = CreateTestWindow(21, parent.get());
1100 TestWindow* w211 = CreateTestWindow(211, parent.get());
1101 TestWindow* w212 = CreateTestWindow(212, parent.get());
1102 TestWindow* w213 = CreateTestWindow(213, parent.get());
1103 TestWindow* w22 = CreateTestWindow(22, parent.get());
1104 ASSERT_EQ(8u, parent->children().size());
1105
1106 // w11 is now owned by w1.
1107 w1->AddTransientWindow(w11);
1108 // w21 is now owned by w2.
1109 w2->AddTransientWindow(w21);
1110 // w22 is now owned by w2.
1111 w2->AddTransientWindow(w22);
1112 // w211 is now owned by w21.
1113 w21->AddTransientWindow(w211);
1114 // w212 is now owned by w21.
1115 w21->AddTransientWindow(w212);
1116 // w213 is now owned by w21.
1117 w21->AddTransientWindow(w213);
1118 EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
1119
1120 // Stack w2 at the bottom, this should force w11 to be last (on top of w1).
1121 // This also tests that the order in children_ array rather than in
1122 // transient_children_ array is used when reinserting transient children.
1123 // If transient_children_ array was used '22' would be following '21'.
1124 w2->MoveToBack();
1125 EXPECT_EQ(w11, parent->children().back());
1126 EXPECT_EQ("2 21 211 212 213 22 1 11", ChildWindowIDsAsString(parent.get()));
1127
1128 w1->MoveToBack();
1129 EXPECT_EQ(w22, parent->children().back());
1130 EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
1131
1132 w21->Reorder(w1.get(), mojom::OrderDirection::BELOW);
1133 EXPECT_EQ(w11, parent->children().back());
1134 EXPECT_EQ("2 21 211 212 213 22 1 11", ChildWindowIDsAsString(parent.get()));
1135
1136 w11->Reorder(w2.get(), mojom::OrderDirection::BELOW);
1137 EXPECT_EQ(w22, parent->children().back());
1138 EXPECT_EQ("1 11 2 21 211 212 213 22", ChildWindowIDsAsString(parent.get()));
1139
1140 w22->Reorder(w21, mojom::OrderDirection::BELOW);
1141 EXPECT_EQ(w213, parent->children().back());
1142 EXPECT_EQ("1 11 2 22 21 211 212 213", ChildWindowIDsAsString(parent.get()));
1143
1144 w21->Reorder(w11, mojom::OrderDirection::BELOW);
1145 EXPECT_EQ(w11, parent->children().back());
1146 EXPECT_EQ("2 22 21 211 212 213 1 11", ChildWindowIDsAsString(parent.get()));
1147
1148 w213->Reorder(w211, mojom::OrderDirection::BELOW);
1149 EXPECT_EQ(w11, parent->children().back());
1150 EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
1151
1152 // No change when stacking a transient parent below its transient child.
1153 w21->Reorder(w211, mojom::OrderDirection::BELOW);
1154 EXPECT_EQ(w11, parent->children().back());
1155 EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
1156
1157 w1->Reorder(w2.get(), mojom::OrderDirection::BELOW);
1158 EXPECT_EQ(w212, parent->children().back());
1159 EXPECT_EQ("1 11 2 22 21 213 211 212", ChildWindowIDsAsString(parent.get()));
1160
1161 w213->Reorder(w11, mojom::OrderDirection::BELOW);
1162 EXPECT_EQ(w11, parent->children().back());
1163 EXPECT_EQ("2 22 21 213 211 212 1 11", ChildWindowIDsAsString(parent.get()));
1164 }
1165
1166 // Tests that windows are restacked properly after a call to
1167 // AddTransientWindow() or RemoveTransientWindow).
1168 TEST_F(WindowTest, RestackUponAddOrRemoveTransientWindow) {
1169 std::unique_ptr<TestWindow> parent(CreateTestWindow(0, nullptr));
1170 std::unique_ptr<TestWindow> windows[4];
1171 for (int i = 0; i < 4; i++)
1172 windows[i].reset(CreateTestWindow(i, parent.get()));
1173
1174 EXPECT_EQ("0 1 2 3", ChildWindowIDsAsString(parent.get()));
1175
1176 windows[0]->AddTransientWindow(windows[2].get());
1177 EXPECT_EQ("0 2 1 3", ChildWindowIDsAsString(parent.get()));
1178
1179 windows[0]->AddTransientWindow(windows[3].get());
1180 EXPECT_EQ("0 2 3 1", ChildWindowIDsAsString(parent.get()));
1181
1182 windows[0]->RemoveTransientWindow(windows[2].get());
1183 EXPECT_EQ("0 3 2 1", ChildWindowIDsAsString(parent.get()));
1184
1185 windows[0]->RemoveTransientWindow(windows[3].get());
1186 EXPECT_EQ("0 3 2 1", ChildWindowIDsAsString(parent.get()));
1187 }
1188
1189 // Tests that transient windows are stacked properly when created.
1190 TEST_F(WindowTest, StackUponCreation) {
1191 std::unique_ptr<TestWindow> parent(CreateTestWindow(0, nullptr));
1192 std::unique_ptr<TestWindow> window0(CreateTestWindow(1, parent.get()));
1193 std::unique_ptr<TestWindow> window1(CreateTestWindow(2, parent.get()));
1194
1195 TestWindow* window2 = CreateTestWindow(3, parent.get());
1196
1197 window0->AddTransientWindow(window2);
1198 EXPECT_EQ("1 3 2", ChildWindowIDsAsString(parent.get()));
1199 }
1200
1201 } // namespace mus
OLDNEW
« no previous file with comments | « components/mus/public/cpp/tests/window_tree_client_unittest.cc ('k') | components/mus/public/cpp/window.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698