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