view_tree_validator_unittest.mm 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Copyright 2017 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. #include "ui/base/test/view_tree_validator.h"
  5. #include "testing/gtest/include/gtest/gtest.h"
  6. #include "ui/base/test/cocoa_helper.h"
  7. using ViewTreeValidatorTest = ui::CocoaTest;
  8. namespace {
  9. NSView* AutoreleasedButtonWithFrame(int x, int y, int w, int h) {
  10. return [[[NSButton alloc] initWithFrame:NSMakeRect(x, y, w, h)] autorelease];
  11. }
  12. NSView* AutoreleasedViewWithFrame(int x, int y, int w, int h) {
  13. return [[[NSView alloc] initWithFrame:NSMakeRect(x, y, w, h)] autorelease];
  14. }
  15. void AdjustWidth(NSView* view, int delta) {
  16. NSRect r = view.frame;
  17. r.size.width += delta;
  18. [view setFrame:r];
  19. }
  20. void AdjustHeight(NSView* view, int delta) {
  21. NSRect r = view.frame;
  22. r.size.height += delta;
  23. [view setFrame:r];
  24. }
  25. } // namespace
  26. TEST_F(ViewTreeValidatorTest, CorrectnessTest) {
  27. NSWindow* window = test_window();
  28. int width = NSWidth(window.contentView.frame);
  29. int height = NSHeight(window.contentView.frame);
  30. NSView* view_1 = AutoreleasedViewWithFrame(0, 0, width / 2, height);
  31. NSView* view_2 = AutoreleasedButtonWithFrame(width / 2, 0, width / 2, height);
  32. NSView* view_3 = AutoreleasedButtonWithFrame(0, 0, width / 2, height / 2);
  33. NSView* view_4 = AutoreleasedViewWithFrame(0, 0, width / 2, height / 2);
  34. NSView* view_5 =
  35. AutoreleasedViewWithFrame(0, height / 2, width / 2, height / 2);
  36. [view_2 addSubview:view_4];
  37. [view_2 addSubview:view_5];
  38. [view_1 addSubview:view_3];
  39. [window.contentView addSubview:view_1];
  40. [window.contentView addSubview:view_2];
  41. {
  42. // The original layout is well-formed.
  43. absl::optional<ui::ViewTreeProblemDetails> details =
  44. ui::ValidateViewTree(window.contentView);
  45. EXPECT_FALSE(details.has_value());
  46. }
  47. {
  48. // Make view_3 no longer contained within view_1.
  49. AdjustWidth(view_3, 1);
  50. absl::optional<ui::ViewTreeProblemDetails> details =
  51. ui::ValidateViewTree(window.contentView);
  52. ASSERT_TRUE(details.has_value());
  53. EXPECT_EQ(details->type, ui::ViewTreeProblemDetails::VIEW_OUTSIDE_PARENT);
  54. EXPECT_EQ(details->view_a, view_3);
  55. EXPECT_EQ(details->view_b, view_1);
  56. AdjustWidth(view_3, -1);
  57. }
  58. {
  59. // Make view_1 overlap view_2.
  60. AdjustWidth(view_1, 1);
  61. absl::optional<ui::ViewTreeProblemDetails> details =
  62. ui::ValidateViewTree(window.contentView);
  63. ASSERT_TRUE(details.has_value());
  64. EXPECT_EQ(details->type, ui::ViewTreeProblemDetails::VIEWS_OVERLAP);
  65. // Since there's no specified order for |view_a| and |view_b| for
  66. // VIEWS_OVERLAP, check that |view_1| and |view_2| both appear exactly once
  67. // in |view_a| and |view_b|.
  68. EXPECT_TRUE(details->view_a == view_1 || details->view_a == view_2);
  69. EXPECT_TRUE(details->view_b == view_1 || details->view_b == view_2);
  70. EXPECT_NE(details->view_a, details->view_b);
  71. AdjustWidth(view_1, -1);
  72. }
  73. {
  74. // Make view_4 overlap view_5. Since they're both not localizable, this
  75. // isn't an error.
  76. AdjustHeight(view_4, 1);
  77. absl::optional<ui::ViewTreeProblemDetails> details =
  78. ui::ValidateViewTree(window.contentView);
  79. EXPECT_FALSE(details.has_value());
  80. AdjustHeight(view_4, -1);
  81. }
  82. }