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 #ifndef UI_GFX_TEST_UI_COCOA_TEST_HELPER_H_
6 #define UI_GFX_TEST_UI_COCOA_TEST_HELPER_H_
10 #import <Cocoa/Cocoa.h>
12 #include "base/compiler_specific.h"
13 #import "base/mac/scoped_nsautorelease_pool.h"
14 #include "testing/platform_test.h"
16 // Background windows normally will not display things such as focus
17 // rings. This class allows -isKeyWindow to be manipulated to test
19 @interface CocoaTestHelperWindow
: NSWindow
{
21 BOOL pretendIsKeyWindow_
;
22 BOOL useDefaultConstraints_
;
25 // Init a borderless non-deferred window with a backing store.
26 - (id
)initWithContentRect
:(NSRect
)contentRect
;
28 // Init with a default frame.
31 // Sets the responder passed in as first responder, and sets the window
32 // so that it will return "YES" if asked if it key window. It does not actually
33 // make the window key.
34 - (void)makePretendKeyWindowAndSetFirstResponder
:(NSResponder
*)responder
;
36 // Clears the first responder duty for the window and returns the window
38 - (void)clearPretendKeyWindowAndFirstResponder
;
40 // Set value to return for -isKeyWindow.
41 - (void)setPretendIsKeyWindow
:(BOOL
)isKeyWindow
;
43 // Whether to use or ignore the default contraints for window sizing and
45 - (void)setUseDefaultConstraints
:(BOOL
)useDefaultConstraints
;
53 // A test class that all tests that depend on AppKit should inherit from.
54 // Sets up paths correctly, and makes sure that any windows created in the test
55 // are closed down properly by the test.
56 class CocoaTest
: public PlatformTest
{
59 ~CocoaTest() override
;
61 // Must be called by subclasses that override TearDown. We verify that it
62 // is called in our destructor. Takes care of making sure that all windows
63 // are closed off correctly. If your tests open windows, they must be sure
64 // to close them before CocoaTest::TearDown is called. A standard way of doing
65 // this would be to create them in SetUp (after calling CocoaTest::Setup) and
66 // then close them in TearDown before calling CocoaTest::TearDown.
67 void TearDown() override
;
69 // Retuns a test window that can be used by views and other UI objects
70 // as part of their tests. Is created lazily, and will be closed correctly
71 // in CocoaTest::TearDown. Note that it is a CocoaTestHelperWindow which
72 // has special handling for being Key.
73 CocoaTestHelperWindow
* test_window();
76 // Allows subclasses to do initialization before calling through to the base
77 // class's initialization.
81 // Return a set of currently open windows. Avoiding NSArray so
82 // contents aren't retained, the pointer values can only be used for
83 // comparison purposes. Using std::set to make progress-checking
85 static std::set
<NSWindow
*> ApplicationWindows();
87 // Return a set of windows which are in |ApplicationWindows()| but
88 // not |initial_windows_|.
89 std::set
<NSWindow
*> WindowsLeft();
91 bool called_tear_down_
;
92 base::mac::ScopedNSAutoreleasePool pool_
;
94 // Windows which existed at the beginning of the test.
95 std::set
<NSWindow
*> initial_windows_
;
97 // Strong. Lazily created. This isn't wrapped in a scoped_nsobject because
98 // we want to call [close] to destroy it rather than calling [release]. We
99 // want to verify that [close] is actually removing our window and that it's
100 // not hanging around because releaseWhenClosed was set to "no" on the window.
101 // It isn't wrapped in a different wrapper class to close it because we
102 // need to close it at a very specific time; just before we enter our clean
103 // up loop in TearDown.
104 CocoaTestHelperWindow
* test_window_
;
109 // A macro defining a standard set of tests to run on a view. Since we can't
110 // inherit tests, this macro saves us a lot of duplicate code. Handles simply
111 // displaying the view to make sure it won't crash, as well as removing it
112 // from a window. All tests that work with NSView subclasses and/or
113 // NSViewController subclasses should use it.
114 #define TEST_VIEW(test_fixture, test_view) \
115 TEST_F(test_fixture, test_fixture##_TestViewMacroAddRemove) { \
116 base::scoped_nsobject<NSView> view([test_view retain]); \
117 EXPECT_EQ([test_window() contentView], [view superview]); \
118 [view removeFromSuperview]; \
119 EXPECT_FALSE([view superview]); \
121 TEST_F(test_fixture, test_fixture##_TestViewMacroDisplay) { \
122 [test_view display]; \
125 // A macro which determines the proper float epsilon for a CGFloat.
126 #if CGFLOAT_IS_DOUBLE
127 #define CGFLOAT_EPSILON DBL_EPSILON
129 #define CGFLOAT_EPSILON FLT_EPSILON
132 // A macro which which determines if two CGFloats are equal taking a
133 // proper epsilon into consideration.
134 #define CGFLOAT_EQ(expected, actual) \
135 (actual >= (expected - CGFLOAT_EPSILON) && \
136 actual <= (expected + CGFLOAT_EPSILON))
138 // A test support macro which ascertains if two CGFloats are equal.
139 #define EXPECT_CGFLOAT_EQ(expected, actual) \
140 EXPECT_TRUE(CGFLOAT_EQ(expected, actual)) << \
141 expected << " != " << actual
143 // A test support macro which compares two NSRects for equality taking
144 // the float epsilon into consideration.
145 #define EXPECT_NSRECT_EQ(expected, actual) \
146 EXPECT_TRUE(CGFLOAT_EQ(expected.origin.x, actual.origin.x) && \
147 CGFLOAT_EQ(expected.origin.y, actual.origin.y) && \
148 CGFLOAT_EQ(expected.size.width, actual.size.width) && \
149 CGFLOAT_EQ(expected.size.height, actual.size.height)) << \
150 "Rects do not match: " << \
151 [NSStringFromRect(expected) UTF8String] << \
152 " != " << [NSStringFromRect(actual) UTF8String]
154 #endif // UI_GFX_TEST_UI_COCOA_TEST_HELPER_H_