1// Copyright (c) 2012 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#import "chrome/browser/ui/cocoa/history_overlay_controller.h" 6 7#import <QuartzCore/QuartzCore.h> 8 9#include "base/memory/scoped_ptr.h" 10#include "base/message_loop/message_pump_mac.h" 11#import "chrome/browser/ui/cocoa/cocoa_test_helper.h" 12#import "third_party/ocmock/gtest_support.h" 13#import "third_party/ocmock/OCMock/OCMock.h" 14 15class HistoryOverlayControllerTest : public CocoaTest { 16 public: 17 virtual void SetUp() { 18 CocoaTest::SetUp(); 19 20 // The overlay controller shows the panel as a subview of the given view. 21 test_view_.reset([[NSView alloc] initWithFrame:NSMakeRect(10, 10, 10, 10)]); 22 23 // We add it to the test_window for authenticity. 24 [[test_window() contentView] addSubview:test_view_]; 25 } 26 27 NSView* test_view() { 28 return test_view_; 29 } 30 31 private: 32 base::scoped_nsobject<NSView> test_view_; 33}; 34 35// Tests that when the controller is |-dismiss|ed, the animation runs and then 36// is removed when the animation completes. The view should be added and 37// removed at the appropriate times. 38TEST_F(HistoryOverlayControllerTest, DismissClearsAnimationsAndRemovesView) { 39 EXPECT_EQ(0u, [[test_view() subviews] count]); 40 41 base::scoped_nsobject<HistoryOverlayController> controller( 42 [[HistoryOverlayController alloc] initForMode:kHistoryOverlayModeBack]); 43 [controller showPanelForView:test_view()]; 44 EXPECT_EQ(1u, [[test_view() subviews] count]); 45 46 scoped_ptr<base::MessagePumpNSRunLoop> message_pump( 47 new base::MessagePumpNSRunLoop); 48 49 id mock = [OCMockObject partialMockForObject:controller]; 50 [mock setExpectationOrderMatters:YES]; 51 [[[mock expect] andForwardToRealObject] dismiss]; 52 53 // Called after |-animationDidStop:finished:|. 54 base::MessagePumpNSRunLoop* weak_message_pump = message_pump.get(); 55 void (^quit_loop)(NSInvocation* invocation) = ^(NSInvocation* invocation) { 56 weak_message_pump->Quit(); 57 }; 58 // Set up the mock to first forward to the real implementation and then call 59 // the above block to quit the run loop. 60 [[[[mock expect] andForwardToRealObject] andDo:quit_loop] 61 animationDidStop:[OCMArg isNotNil] finished:YES]; 62 63 // CAAnimations must be committed within a run loop. It is not sufficient 64 // to commit them and activate the loop after the fact. Schedule a block to 65 // dismiss the controller from within the run loop, which begins the 66 // animation. 67 CFRunLoopPerformBlock(CFRunLoopGetCurrent(), 68 kCFRunLoopDefaultMode, 69 ^(void) { 70 [mock dismiss]; 71 }); 72 73 // Run the loop, which will dismiss the overlay. 74 message_pump->Run(NULL); 75 76 EXPECT_OCMOCK_VERIFY(mock); 77 78 // After the animation runs, there should be no more animations. 79 EXPECT_FALSE([[controller view] animations]); 80 81 EXPECT_EQ(0u, [[test_view() subviews] count]); 82} 83