1 // Copyright (c) 2013 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 "ui/v2/public/view.h" 6 7 #include "base/logging.h" 8 #include "testing/gtest/include/gtest/gtest.h" 9 #include "ui/compositor/layer.h" 10 #include "ui/compositor/layer_type.h" 11 12 namespace v2 { 13 14 // View ------------------------------------------------------------------------ 15 16 typedef testing::Test ViewTest; 17 18 TEST_F(ViewTest, AddChild) { 19 View v1; 20 View* v11 = new View; 21 v1.AddChild(v11); 22 EXPECT_EQ(1U, v1.children().size()); 23 } 24 25 TEST_F(ViewTest, RemoveChild) { 26 View v1; 27 View* v11 = new View; 28 v1.AddChild(v11); 29 EXPECT_EQ(1U, v1.children().size()); 30 v1.RemoveChild(v11); 31 EXPECT_EQ(0U, v1.children().size()); 32 } 33 34 TEST_F(ViewTest, Reparent) { 35 View v1; 36 View v2; 37 View* v11 = new View; 38 v1.AddChild(v11); 39 EXPECT_EQ(1U, v1.children().size()); 40 v2.AddChild(v11); 41 EXPECT_EQ(1U, v2.children().size()); 42 EXPECT_EQ(0U, v1.children().size()); 43 } 44 45 TEST_F(ViewTest, Contains) { 46 View v1; 47 48 // Direct descendant. 49 View* v11 = new View; 50 v1.AddChild(v11); 51 EXPECT_TRUE(v1.Contains(v11)); 52 53 // Indirect descendant. 54 View* v111 = new View; 55 v11->AddChild(v111); 56 EXPECT_TRUE(v1.Contains(v111)); 57 } 58 59 TEST_F(ViewTest, Stacking) { 60 View v1; 61 View* v11 = new View; 62 View* v12 = new View; 63 View* v13 = new View; 64 v1.AddChild(v11); 65 v1.AddChild(v12); 66 v1.AddChild(v13); 67 68 // Order: v11, v12, v13 69 EXPECT_EQ(3U, v1.children().size()); 70 EXPECT_EQ(v11, v1.children().front()); 71 EXPECT_EQ(v13, v1.children().back()); 72 73 // Move v11 to front. 74 // Resulting order: v12, v13, v11 75 v1.StackChildAtTop(v11); 76 EXPECT_EQ(v12, v1.children().front()); 77 EXPECT_EQ(v11, v1.children().back()); 78 79 // Move v11 to back. 80 // Resulting order: v11, v12, v13 81 v1.StackChildAtBottom(v11); 82 EXPECT_EQ(v11, v1.children().front()); 83 EXPECT_EQ(v13, v1.children().back()); 84 85 // Move v11 above v12. 86 // Resulting order: v12. v11, v13 87 v1.StackChildAbove(v11, v12); 88 EXPECT_EQ(v12, v1.children().front()); 89 EXPECT_EQ(v13, v1.children().back()); 90 91 // Move v11 below v12. 92 // Resulting order: v11, v12, v13 93 v1.StackChildBelow(v11, v12); 94 EXPECT_EQ(v11, v1.children().front()); 95 EXPECT_EQ(v13, v1.children().back()); 96 } 97 98 TEST_F(ViewTest, Layer) { 99 View v1; 100 v1.CreateLayer(ui::LAYER_NOT_DRAWN); 101 EXPECT_TRUE(v1.HasLayer()); 102 v1.DestroyLayer(); 103 EXPECT_FALSE(v1.HasLayer()); 104 105 v1.CreateLayer(ui::LAYER_NOT_DRAWN); 106 scoped_ptr<ui::Layer>(v1.AcquireLayer()); 107 // Acquiring the layer transfers ownership to the scoped_ptr above, so this 108 // test passes if it doesn't crash. 109 } 110 111 // ViewObserver ---------------------------------------------------------------- 112 113 typedef testing::Test ViewObserverTest; 114 115 bool TreeChangeParamsMatch(const ViewObserver::TreeChangeParams& lhs, 116 const ViewObserver::TreeChangeParams& rhs) { 117 return lhs.target == rhs.target && lhs.old_parent == rhs.old_parent && 118 lhs.new_parent == rhs.new_parent && lhs.receiver == rhs.receiver && 119 lhs.phase == rhs.phase; 120 } 121 122 class TreeChangeObserver : public ViewObserver { 123 public: 124 explicit TreeChangeObserver(View* observee) : observee_(observee) { 125 observee_->AddObserver(this); 126 } 127 virtual ~TreeChangeObserver() { 128 observee_->RemoveObserver(this); 129 } 130 131 void Reset() { 132 received_params_.clear(); 133 } 134 135 const std::vector<TreeChangeParams>& received_params() { 136 return received_params_; 137 } 138 139 private: 140 // Overridden from ViewObserver: 141 virtual void OnViewTreeChange(const TreeChangeParams& params) OVERRIDE { 142 received_params_.push_back(params); 143 } 144 145 View* observee_; 146 std::vector<TreeChangeParams> received_params_; 147 148 DISALLOW_COPY_AND_ASSIGN(TreeChangeObserver); 149 }; 150 151 // Adds/Removes v11 to v1. 152 TEST_F(ViewObserverTest, TreeChange_SimpleAddRemove) { 153 View v1; 154 TreeChangeObserver o1(&v1); 155 EXPECT_TRUE(o1.received_params().empty()); 156 157 View v11; 158 v11.set_owned_by_parent(false); 159 TreeChangeObserver o11(&v11); 160 EXPECT_TRUE(o11.received_params().empty()); 161 162 // Add. 163 164 v1.AddChild(&v11); 165 166 EXPECT_EQ(1U, o1.received_params().size()); 167 ViewObserver::TreeChangeParams p1; 168 p1.target = &v11; 169 p1.receiver = &v1; 170 p1.old_parent = NULL; 171 p1.new_parent = &v1; 172 p1.phase = ViewObserver::DISPOSITION_CHANGED; 173 EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back())); 174 175 EXPECT_EQ(2U, o11.received_params().size()); 176 ViewObserver::TreeChangeParams p11 = p1; 177 p11.receiver = &v11; 178 p11.phase = ViewObserver::DISPOSITION_CHANGING; 179 EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front())); 180 p11.phase = ViewObserver::DISPOSITION_CHANGED; 181 EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back())); 182 183 o1.Reset(); 184 o11.Reset(); 185 EXPECT_TRUE(o1.received_params().empty()); 186 EXPECT_TRUE(o11.received_params().empty()); 187 188 // Remove. 189 190 v1.RemoveChild(&v11); 191 192 EXPECT_EQ(1U, o1.received_params().size()); 193 p1.target = &v11; 194 p1.receiver = &v1; 195 p1.old_parent = &v1; 196 p1.new_parent = NULL; 197 p1.phase = ViewObserver::DISPOSITION_CHANGING; 198 EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back())); 199 200 EXPECT_EQ(2U, o11.received_params().size()); 201 p11 = p1; 202 p11.receiver = &v11; 203 EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().front())); 204 p11.phase = ViewObserver::DISPOSITION_CHANGED; 205 EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back())); 206 } 207 208 // Creates these two trees: 209 // v1 210 // +- v11 211 // v111 212 // +- v1111 213 // +- v1112 214 // Then adds/removes v111 from v11. 215 TEST_F(ViewObserverTest, TreeChange_NestedAddRemove) { 216 View v1, v11, v111, v1111, v1112; 217 218 // Root tree. 219 v11.set_owned_by_parent(false); 220 v1.AddChild(&v11); 221 222 // Tree to be attached. 223 v111.set_owned_by_parent(false); 224 v1111.set_owned_by_parent(false); 225 v111.AddChild(&v1111); 226 v1112.set_owned_by_parent(false); 227 v111.AddChild(&v1112); 228 229 TreeChangeObserver o1(&v1), o11(&v11), o111(&v111), o1111(&v1111), 230 o1112(&v1112); 231 ViewObserver::TreeChangeParams p1, p11, p111, p1111, p1112; 232 233 // Add. 234 235 v11.AddChild(&v111); 236 237 EXPECT_EQ(1U, o1.received_params().size()); 238 p1.target = &v111; 239 p1.receiver = &v1; 240 p1.old_parent = NULL; 241 p1.new_parent = &v11; 242 p1.phase = ViewObserver::DISPOSITION_CHANGED; 243 EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back())); 244 245 EXPECT_EQ(1U, o11.received_params().size()); 246 p11 = p1; 247 p11.receiver = &v11; 248 EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back())); 249 250 EXPECT_EQ(2U, o111.received_params().size()); 251 p111 = p11; 252 p111.receiver = &v111; 253 p111.phase = ViewObserver::DISPOSITION_CHANGING; 254 EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front())); 255 p111.phase = ViewObserver::DISPOSITION_CHANGED; 256 EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back())); 257 258 EXPECT_EQ(2U, o1111.received_params().size()); 259 p1111 = p111; 260 p1111.receiver = &v1111; 261 p1111.phase = ViewObserver::DISPOSITION_CHANGING; 262 EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().front())); 263 p1111.phase = ViewObserver::DISPOSITION_CHANGED; 264 EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().back())); 265 266 EXPECT_EQ(2U, o1112.received_params().size()); 267 p1112 = p111; 268 p1112.receiver = &v1112; 269 p1112.phase = ViewObserver::DISPOSITION_CHANGING; 270 EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().front())); 271 p1112.phase = ViewObserver::DISPOSITION_CHANGED; 272 EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().back())); 273 274 // Remove. 275 o1.Reset(); 276 o11.Reset(); 277 o111.Reset(); 278 o1111.Reset(); 279 o1112.Reset(); 280 EXPECT_TRUE(o1.received_params().empty()); 281 EXPECT_TRUE(o11.received_params().empty()); 282 EXPECT_TRUE(o111.received_params().empty()); 283 EXPECT_TRUE(o1111.received_params().empty()); 284 EXPECT_TRUE(o1112.received_params().empty()); 285 286 v11.RemoveChild(&v111); 287 288 EXPECT_EQ(1U, o1.received_params().size()); 289 p1.target = &v111; 290 p1.receiver = &v1; 291 p1.old_parent = &v11; 292 p1.new_parent = NULL; 293 p1.phase = ViewObserver::DISPOSITION_CHANGING; 294 EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back())); 295 296 EXPECT_EQ(1U, o11.received_params().size()); 297 p11 = p1; 298 p11.receiver = &v11; 299 EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back())); 300 301 EXPECT_EQ(2U, o111.received_params().size()); 302 p111 = p11; 303 p111.receiver = &v111; 304 p111.phase = ViewObserver::DISPOSITION_CHANGING; 305 EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front())); 306 p111.phase = ViewObserver::DISPOSITION_CHANGED; 307 EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back())); 308 309 EXPECT_EQ(2U, o1111.received_params().size()); 310 p1111 = p111; 311 p1111.receiver = &v1111; 312 p1111.phase = ViewObserver::DISPOSITION_CHANGING; 313 EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().front())); 314 p1111.phase = ViewObserver::DISPOSITION_CHANGED; 315 EXPECT_TRUE(TreeChangeParamsMatch(p1111, o1111.received_params().back())); 316 317 EXPECT_EQ(2U, o1112.received_params().size()); 318 p1112 = p111; 319 p1112.receiver = &v1112; 320 p1112.phase = ViewObserver::DISPOSITION_CHANGING; 321 EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().front())); 322 p1112.phase = ViewObserver::DISPOSITION_CHANGED; 323 EXPECT_TRUE(TreeChangeParamsMatch(p1112, o1112.received_params().back())); 324 } 325 326 TEST_F(ViewObserverTest, TreeChange_Reparent) { 327 View v1, v11, v12, v111; 328 v11.set_owned_by_parent(false); 329 v111.set_owned_by_parent(false); 330 v12.set_owned_by_parent(false); 331 v1.AddChild(&v11); 332 v1.AddChild(&v12); 333 v11.AddChild(&v111); 334 335 TreeChangeObserver o1(&v1), o11(&v11), o12(&v12), o111(&v111); 336 337 // Reparent. 338 v12.AddChild(&v111); 339 340 // v1 (root) should see both changing and changed notifications. 341 EXPECT_EQ(2U, o1.received_params().size()); 342 ViewObserver::TreeChangeParams p1; 343 p1.target = &v111; 344 p1.receiver = &v1; 345 p1.old_parent = &v11; 346 p1.new_parent = &v12; 347 p1.phase = ViewObserver::DISPOSITION_CHANGING; 348 EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().front())); 349 p1.phase = ViewObserver::DISPOSITION_CHANGED; 350 EXPECT_TRUE(TreeChangeParamsMatch(p1, o1.received_params().back())); 351 352 // v11 should see changing notifications. 353 EXPECT_EQ(1U, o11.received_params().size()); 354 ViewObserver::TreeChangeParams p11; 355 p11 = p1; 356 p11.receiver = &v11; 357 p11.phase = ViewObserver::DISPOSITION_CHANGING; 358 EXPECT_TRUE(TreeChangeParamsMatch(p11, o11.received_params().back())); 359 360 // v12 should see changed notifications. 361 EXPECT_EQ(1U, o12.received_params().size()); 362 ViewObserver::TreeChangeParams p12; 363 p12 = p1; 364 p12.receiver = &v12; 365 p12.phase = ViewObserver::DISPOSITION_CHANGED; 366 EXPECT_TRUE(TreeChangeParamsMatch(p12, o12.received_params().back())); 367 368 // v111 should see both changing and changed notifications. 369 EXPECT_EQ(2U, o111.received_params().size()); 370 ViewObserver::TreeChangeParams p111; 371 p111 = p1; 372 p111.receiver = &v111; 373 p111.phase = ViewObserver::DISPOSITION_CHANGING; 374 EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().front())); 375 p111.phase = ViewObserver::DISPOSITION_CHANGED; 376 EXPECT_TRUE(TreeChangeParamsMatch(p111, o111.received_params().back())); 377 } 378 379 class VisibilityObserver : public ViewObserver { 380 public: 381 typedef std::pair<ViewObserver::DispositionChangePhase, bool> LogEntry; 382 typedef std::vector<LogEntry> LogEntries; 383 384 VisibilityObserver(View* view) : view_(view) { 385 view_->AddObserver(this); 386 } 387 virtual ~VisibilityObserver() { 388 view_->RemoveObserver(this); 389 } 390 391 const LogEntries& log_entries() const { return log_entries_; } 392 393 private: 394 // Overridden from ViewObserver: 395 virtual void OnViewVisibilityChange( 396 View* view, 397 ViewObserver::DispositionChangePhase phase) OVERRIDE { 398 DCHECK_EQ(view_, view); 399 log_entries_.push_back(std::make_pair(phase, view->visible())); 400 } 401 402 View* view_; 403 LogEntries log_entries_; 404 405 DISALLOW_COPY_AND_ASSIGN(VisibilityObserver); 406 }; 407 408 TEST_F(ViewObserverTest, VisibilityChange) { 409 View v1; // Starts out visible. 410 411 VisibilityObserver o1(&v1); 412 413 v1.SetVisible(false); 414 415 EXPECT_EQ(2U, o1.log_entries().size()); 416 EXPECT_EQ(ViewObserver::DISPOSITION_CHANGING, o1.log_entries().front().first); 417 EXPECT_EQ(o1.log_entries().front().second, true); 418 EXPECT_EQ(ViewObserver::DISPOSITION_CHANGED, o1.log_entries().back().first); 419 EXPECT_EQ(o1.log_entries().back().second, false); 420 } 421 422 class BoundsObserver : public ViewObserver { 423 public: 424 typedef std::pair<gfx::Rect, gfx::Rect> BoundsChange; 425 typedef std::vector<BoundsChange> BoundsChanges; 426 427 explicit BoundsObserver(View* view) : view_(view) { 428 view_->AddObserver(this); 429 } 430 virtual ~BoundsObserver() { 431 view_->RemoveObserver(this); 432 } 433 434 const BoundsChanges& bounds_changes() const { return bounds_changes_; } 435 436 private: 437 virtual void OnViewBoundsChanged(View* view, 438 const gfx::Rect& old_bounds, 439 const gfx::Rect& new_bounds) OVERRIDE { 440 DCHECK_EQ(view_, view); 441 bounds_changes_.push_back(std::make_pair(old_bounds, new_bounds)); 442 } 443 444 View* view_; 445 BoundsChanges bounds_changes_; 446 447 DISALLOW_COPY_AND_ASSIGN(BoundsObserver); 448 }; 449 450 TEST_F(ViewObserverTest, BoundsChanged) { 451 View v1; 452 BoundsObserver o1(&v1); 453 454 gfx::Rect new_bounds(0, 0, 10, 10); 455 456 v1.SetBounds(new_bounds); 457 EXPECT_EQ(1U, o1.bounds_changes().size()); 458 EXPECT_EQ(gfx::Rect(), o1.bounds_changes().front().first); 459 EXPECT_EQ(new_bounds, o1.bounds_changes().front().second); 460 } 461 462 } // namespace v2 463