| Index: chrome/browser/cocoa/cocoa_test_helper.mm
|
| ===================================================================
|
| --- chrome/browser/cocoa/cocoa_test_helper.mm (revision 29916)
|
| +++ chrome/browser/cocoa/cocoa_test_helper.mm (working copy)
|
| @@ -3,6 +3,7 @@
|
| // found in the LICENSE file.
|
|
|
| #import "chrome/browser/cocoa/cocoa_test_helper.h"
|
| +#import "base/logging.h"
|
|
|
| @implementation CocoaTestHelperWindow
|
|
|
| @@ -17,6 +18,22 @@
|
| return [self initWithContentRect:NSMakeRect(0, 0, 800, 600)];
|
| }
|
|
|
| +- (void)dealloc {
|
| + // Just a good place to put breakpoints when having problems with
|
| + // unittests and CocoaTestHelperWindow.
|
| + [super dealloc];
|
| +}
|
| +
|
| +- (void)makePretendKeyWindowAndSetFirstResponder:(NSResponder*)responder {
|
| + EXPECT_TRUE([self makeFirstResponder:responder]);
|
| + [self setPretendIsKeyWindow:YES];
|
| +}
|
| +
|
| +- (void)clearPretendKeyWindowAndFirstResponder {
|
| + [self setPretendIsKeyWindow:NO];
|
| + EXPECT_TRUE([self makeFirstResponder:NSApp]);
|
| +}
|
| +
|
| - (void)setPretendIsKeyWindow:(BOOL)flag {
|
| pretendIsKeyWindow_ = flag;
|
| }
|
| @@ -26,3 +43,114 @@
|
| }
|
|
|
| @end
|
| +
|
| +CocoaTest::CocoaTest() : called_tear_down_(false), test_window_(nil) {
|
| + BootstrapCocoa();
|
| + // Set the duration of AppKit-evaluated animations (such as frame changes)
|
| + // to zero for testing purposes. That way they take effect immediately.
|
| + [[NSAnimationContext currentContext] setDuration:0.0];
|
| + // Collect the list of windows that were open when the test started so
|
| + // that we don't wait for them to close in TearDown. Has to be done
|
| + // after BootstrapCocoa is called.
|
| + initial_windows_ = ApplicationWindows();
|
| +}
|
| +
|
| +CocoaTest::~CocoaTest() {
|
| + // Must call CocoaTest's teardown from your overrides.
|
| + DCHECK(called_tear_down_);
|
| +}
|
| +
|
| +void CocoaTest::BootstrapCocoa() {
|
| + // Look in the framework bundle for resources.
|
| + FilePath path;
|
| + PathService::Get(base::DIR_EXE, &path);
|
| + path = path.Append(chrome::kFrameworkName);
|
| + mac_util::SetOverrideAppBundlePath(path);
|
| +
|
| + // Bootstrap Cocoa. It's very unhappy without this.
|
| + [NSApplication sharedApplication];
|
| +}
|
| +
|
| +void CocoaTest::TearDown() {
|
| + called_tear_down_ = true;
|
| + // Call close on our test_window to clean it up if one was opened.
|
| + [test_window_ close];
|
| + test_window_ = nil;
|
| +
|
| + // Recycle the pool to clean up any stuff that was put on the
|
| + // autorelease pool due to window or windowcontroller closures.
|
| + // Note that many controls (NSTextFields, NSComboboxes etc) may call
|
| + // performSelector:withDelay: to clean up drag handlers and other things.
|
| + // We must spin the event loop a bit to make sure that everything gets cleaned
|
| + // up correctly. We will wait up to one second for windows to clean themselves
|
| + // up (normally only takes one to two loops through the event loop).
|
| + // Radar 5851458 "Closing a window with a NSTextView in it should get rid of
|
| + // it immediately"
|
| + pool_.Recycle();
|
| + NSDate *start_date = [NSDate date];
|
| + const std::vector<NSWindow*> windows_waiting(ApplicationWindows());
|
| +
|
| + bool loop = windows_waiting.size() > 0;
|
| + while (loop) {
|
| + {
|
| + // Need an autorelease pool to wrap our event loop.
|
| + base::ScopedNSAutoreleasePool pool;
|
| + NSEvent *next_event = [NSApp nextEventMatchingMask:NSAnyEventMask
|
| + untilDate:nil
|
| + inMode:NSDefaultRunLoopMode
|
| + dequeue:YES];
|
| + [NSApp sendEvent:next_event];
|
| + [NSApp updateWindows];
|
| + }
|
| + // Check the windows after we have released the event loop pool so that
|
| + // all retains are cleaned up.
|
| + const std::vector<NSWindow*> current_windows(ApplicationWindows());
|
| + std::vector<NSWindow*> windows_left;
|
| + std::set_difference(current_windows.begin(),
|
| + current_windows.end(),
|
| + initial_windows_.begin(),
|
| + initial_windows_.end(),
|
| + inserter(windows_left, windows_left.begin()));
|
| +
|
| + if (windows_left.size() == 0) {
|
| + // All our windows are closed.
|
| + break;
|
| + }
|
| + if ([start_date timeIntervalSinceNow] < -1.0) {
|
| + // Took us over a second to shut down, and windows still exist.
|
| + // Log a failure and continue.
|
| + EXPECT_EQ(windows_left.size(), 0U);
|
| + for (size_t i = 0; i < windows_left.size(); ++i) {
|
| + const char* desc = [[windows_left[i] description] UTF8String];
|
| + LOG(WARNING) << "Didn't close window " << desc;
|
| + }
|
| + break;
|
| + }
|
| + }
|
| + PlatformTest::TearDown();
|
| +}
|
| +
|
| +std::vector<NSWindow*> CocoaTest::ApplicationWindows() {
|
| + // This must NOT retain the windows it is returning.
|
| + std::vector<NSWindow*> windows;
|
| + // Must create a pool here because [NSApp windows] has created an array
|
| + // with retains on all the windows in it.
|
| + base::ScopedNSAutoreleasePool pool;
|
| + NSArray *appWindows = [NSApp windows];
|
| + for (NSWindow *window in appWindows) {
|
| + windows.push_back(window);
|
| + }
|
| + return windows;
|
| +}
|
| +
|
| +CocoaTestHelperWindow* CocoaTest::test_window() {
|
| + if (!test_window_) {
|
| + test_window_ = [[CocoaTestHelperWindow alloc] init];
|
| + if (DebugUtil::BeingDebugged()) {
|
| + [test_window_ orderFront:nil];
|
| + } else {
|
| + [test_window_ orderBack:nil];
|
| + }
|
| + }
|
| + return test_window_;
|
| +}
|
|
|
| Property changes on: chrome/browser/cocoa/cocoa_test_helper.mm
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|