cocoa_helper.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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. #ifndef UI_BASE_TEST_COCOA_HELPER_H_
  5. #define UI_BASE_TEST_COCOA_HELPER_H_
  6. #include <set>
  7. #import <Cocoa/Cocoa.h>
  8. #import "base/mac/scoped_nsautorelease_pool.h"
  9. #import "base/mac/scoped_nsobject.h"
  10. #import "base/strings/sys_string_conversions.h"
  11. #include "testing/platform_test.h"
  12. #include "ui/display/screen.h"
  13. // CocoaTestHelperWindow behaves differently from a regular NSWindow in the
  14. // following ways:
  15. // - It allows -isKeyWindow to be manipulated to test things like focus rings
  16. // (which background windows won't normally display).
  17. // - It ignores the system setting for full keyboard access and returns a value
  18. // based on pretendFullKeyboardAccessIsEnabled.
  19. @interface CocoaTestHelperWindow : NSWindow
  20. // Value to return for -isKeyWindow.
  21. @property(nonatomic) BOOL pretendIsKeyWindow;
  22. // Value to return for -isOnActiveSpace. Posts
  23. // NSWorkspaceActiveSpaceDidChangeNotification when set.
  24. @property(nonatomic) BOOL pretendIsOnActiveSpace;
  25. // Whether to handle the key view loop as if full keyboard access is enabled.
  26. @property(nonatomic) BOOL pretendFullKeyboardAccessIsEnabled;
  27. // Whether to use or ignore the default contraints for window sizing and
  28. // placement.
  29. @property(nonatomic) BOOL useDefaultConstraints;
  30. // All of the window's valid key views, in order.
  31. @property(nonatomic, readonly) NSArray<NSView*>* validKeyViews;
  32. // Init a borderless non-deferred window with a backing store.
  33. - (instancetype)initWithContentRect:(NSRect)contentRect;
  34. // Init with a default frame.
  35. - (instancetype)init;
  36. // Sets the responder passed in as first responder, and sets the window
  37. // so that it will return "YES" if asked if it key window. It does not actually
  38. // make the window key.
  39. - (void)makePretendKeyWindowAndSetFirstResponder:(NSResponder*)responder;
  40. // Clears the first responder duty for the window and returns the window
  41. // to being non-key.
  42. - (void)clearPretendKeyWindowAndFirstResponder;
  43. - (BOOL)isKeyWindow;
  44. @end
  45. namespace ui {
  46. class CocoaTestHelper {
  47. public:
  48. CocoaTestHelper();
  49. virtual ~CocoaTestHelper();
  50. void MarkCurrentWindowsAsInitial();
  51. // Returns a test window that can be used by views and other UI objects
  52. // as part of their tests. Is created lazily, and will be closed correctly
  53. // in CocoaTest::TearDown. Note that it is a CocoaTestHelperWindow which
  54. // has special handling for being Key.
  55. CocoaTestHelperWindow* test_window();
  56. private:
  57. display::ScopedNativeScreen screen_;
  58. // Return a set of currently open windows. Avoiding NSArray so
  59. // contents aren't retained, the pointer values can only be used for
  60. // comparison purposes. Using std::set to make progress-checking
  61. // convenient.
  62. static std::set<NSWindow*> ApplicationWindows();
  63. // Return a set of windows which are in |ApplicationWindows()| but
  64. // not |initial_windows_|.
  65. std::set<NSWindow*> WindowsLeft();
  66. base::mac::ScopedNSAutoreleasePool pool_;
  67. // Windows which existed at the beginning of the test.
  68. std::set<NSWindow*> initial_windows_;
  69. // Strong. Lazily created. This isn't wrapped in a scoped_nsobject because
  70. // we want to call [close] to destroy it rather than calling [release]. We
  71. // want to verify that [close] is actually removing our window and that it's
  72. // not hanging around because releaseWhenClosed was set to "no" on the window.
  73. // It isn't wrapped in a different wrapper class to close it because we
  74. // need to close it at a very specific time; just before we enter our clean
  75. // up loop in TearDown.
  76. CocoaTestHelperWindow* test_window_ = nil;
  77. };
  78. // A test class that all tests that depend on AppKit should inherit from.
  79. // Sets up paths correctly, and makes sure that any windows created in the test
  80. // are closed down properly by the test.
  81. class CocoaTest : public PlatformTest {
  82. public:
  83. CocoaTest();
  84. ~CocoaTest() override;
  85. // Must be called by subclasses that override TearDown. We verify that it
  86. // is called in our destructor. Takes care of making sure that all windows
  87. // are closed off correctly. If your tests open windows, they must be sure
  88. // to close them before CocoaTest::TearDown is called. A standard way of doing
  89. // this would be to create them in SetUp (after calling CocoaTest::Setup) and
  90. // then close them in TearDown before calling CocoaTest::TearDown.
  91. void TearDown() override;
  92. CocoaTestHelperWindow* test_window() { return helper_->test_window(); }
  93. protected:
  94. void MarkCurrentWindowsAsInitial();
  95. private:
  96. std::unique_ptr<CocoaTestHelper> helper_;
  97. };
  98. } // namespace ui
  99. #endif // UI_BASE_TEST_COCOA_HELPER_H_