Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(343)

Unified Diff: chrome/browser/ui/panels/panel_browser_window_cocoa_unittest.mm

Issue 7694014: Reland: Implement correct Panel closing sequence for Mac. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed random result of CreateClose unittest caused by using a freed object. Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/panels/panel_browser_window_cocoa_unittest.mm
diff --git a/chrome/browser/ui/panels/panel_browser_window_cocoa_unittest.mm b/chrome/browser/ui/panels/panel_browser_window_cocoa_unittest.mm
index 134b1c108bbb0fd5de66a11b182359e90fa1a8ee..e667d9c2b961e2c214d8fa8da5e7aad41e3cafcf 100644
--- a/chrome/browser/ui/panels/panel_browser_window_cocoa_unittest.mm
+++ b/chrome/browser/ui/panels/panel_browser_window_cocoa_unittest.mm
@@ -8,8 +8,11 @@
#include "base/command_line.h"
#include "base/debug/debugger.h"
+#include "base/mac/scoped_nsautorelease_pool.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/app/chrome_command_ids.h" // IDC_*
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_list.h"
#import "chrome/browser/ui/cocoa/browser_test_helper.h"
#import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
#include "chrome/browser/ui/panels/panel.h"
@@ -17,7 +20,9 @@
#import "chrome/browser/ui/panels/panel_titlebar_view_cocoa.h"
#import "chrome/browser/ui/panels/panel_window_controller_cocoa.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
+#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_switches.h"
+#include "chrome/test/base/ui_test_utils.h"
#include "content/browser/tab_contents/test_tab_contents.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -30,6 +35,14 @@ class PanelBrowserWindowCocoaTest : public CocoaTest {
}
Panel* CreateTestPanel(const std::string& panel_name) {
+ // Opening panels on a Mac causes NSWindowController of the Panel window
+ // to be autoreleased. We need a pool drained after it's done so the test
+ // can close correctly.
+ base::mac::ScopedNSAutoreleasePool autorelease_pool;
+
+ PanelManager* manager = PanelManager::GetInstance();
+ int panels_count = manager->num_panels();
+
Browser* panel_browser = Browser::CreateForApp(Browser::TYPE_PANEL,
panel_name,
gfx::Rect(),
@@ -39,7 +52,26 @@ class PanelBrowserWindowCocoaTest : public CocoaTest {
new TestTabContents(browser_helper_.profile(), NULL));
panel_browser->AddTab(tab_contents, PageTransition::LINK);
- return static_cast<Panel*>(panel_browser->window());
+ // We just created one new panel.
+ EXPECT_EQ(panels_count + 1, manager->num_panels());
+
+ Panel* panel = static_cast<Panel*>(panel_browser->window());
+ EXPECT_TRUE(panel);
+ EXPECT_TRUE(panel->native_panel()); // Native panel is created right away.
+ PanelBrowserWindowCocoa* native_window =
+ static_cast<PanelBrowserWindowCocoa*>(panel->native_panel());
+ EXPECT_EQ(panel, native_window->panel_); // Back pointer initialized.
+
+ // Window should not load before Show().
+ // Note: Loading the wnidow causes Cocoa to autorelease a few objects.
+ // This is the reason we do this within the scope of the
+ // ScopedNSAutoreleasePool.
+ EXPECT_FALSE([native_window->controller_ isWindowLoaded]);
+ panel->Show();
+ EXPECT_TRUE([native_window->controller_ isWindowLoaded]);
+ EXPECT_TRUE([native_window->controller_ window]);
+
+ return panel;
}
void VerifyTitlebarLocation(NSView* contentView, NSView* titlebar) {
@@ -53,6 +85,20 @@ class PanelBrowserWindowCocoaTest : public CocoaTest {
EXPECT_EQ(NSHeight([[titlebar superview] bounds]), NSMaxY(titlebar_frame));
}
+ void ClosePanelAndWait(Browser* browser) {
+ EXPECT_TRUE(browser);
+ // Closing a browser window may involve several async tasks. Need to use
+ // message pump and wait for the notification.
+ size_t browser_count = BrowserList::size();
+ ui_test_utils::WindowedNotificationObserver signal(
+ chrome::NOTIFICATION_BROWSER_CLOSED,
+ Source<Browser>(browser));
+ browser->CloseWindow();
+ signal.Wait();
+ // Now we have one less browser instance.
+ EXPECT_EQ(browser_count - 1, BrowserList::size());
+ }
+
NSMenuItem* CreateMenuItem(NSMenu* menu, int command_id) {
NSMenuItem* item =
[menu addItemWithTitle:@""
@@ -71,45 +117,28 @@ TEST_F(PanelBrowserWindowCocoaTest, CreateClose) {
EXPECT_EQ(0, manager->num_panels()); // No panels initially.
Panel* panel = CreateTestPanel("Test Panel");
- EXPECT_TRUE(panel);
- EXPECT_TRUE(panel->native_panel()); // Native panel is created right away.
- PanelBrowserWindowCocoa* native_window =
- static_cast<PanelBrowserWindowCocoa*>(panel->native_panel());
-
- EXPECT_EQ(panel, native_window->panel_); // Back pointer initialized.
- EXPECT_EQ(1, manager->num_panels());
-
- // Window should not load before Show()
- EXPECT_FALSE([native_window->controller_ isWindowLoaded]);
- panel->Show();
- EXPECT_TRUE([native_window->controller_ isWindowLoaded]);
- EXPECT_TRUE([native_window->controller_ window]);
+ ASSERT_TRUE(panel);
gfx::Rect bounds = panel->GetBounds();
EXPECT_TRUE(bounds.width() > 0);
EXPECT_TRUE(bounds.height() > 0);
+ PanelBrowserWindowCocoa* native_window =
+ static_cast<PanelBrowserWindowCocoa*>(panel->native_panel());
+ ASSERT_TRUE(native_window);
// NSWindows created by NSWindowControllers don't have this bit even if
// their NIB has it. The controller's lifetime is the window's lifetime.
EXPECT_EQ(NO, [[native_window->controller_ window] isReleasedWhenClosed]);
- panel->Close();
+ ASSERT_TRUE(panel->browser());
+ ClosePanelAndWait(panel->browser());
EXPECT_EQ(0, manager->num_panels());
- // Close() destroys the controller, which destroys the NSWindow. CocoaTest
- // base class verifies that there is no remaining open windows after the test.
- EXPECT_FALSE(native_window->controller_);
}
TEST_F(PanelBrowserWindowCocoaTest, AssignedBounds) {
- PanelManager* manager = PanelManager::GetInstance();
Panel* panel1 = CreateTestPanel("Test Panel 1");
Panel* panel2 = CreateTestPanel("Test Panel 2");
Panel* panel3 = CreateTestPanel("Test Panel 3");
- EXPECT_EQ(3, manager->num_panels());
-
- panel1->Show();
- panel2->Show();
- panel3->Show();
gfx::Rect bounds1 = panel1->GetBounds();
gfx::Rect bounds2 = panel2->GetBounds();
@@ -123,31 +152,22 @@ TEST_F(PanelBrowserWindowCocoaTest, AssignedBounds) {
EXPECT_EQ(bounds2.y(), bounds3.y());
// After panel2 is closed, panel3 should take its place.
- panel2->Close();
+ ClosePanelAndWait(panel2->browser());
bounds3 = panel3->GetBounds();
EXPECT_EQ(bounds2, bounds3);
- EXPECT_EQ(2, manager->num_panels());
// After panel1 is closed, panel3 should take its place.
- panel1->Close();
+ ClosePanelAndWait(panel1->browser());
EXPECT_EQ(bounds1, panel3->GetBounds());
- EXPECT_EQ(1, manager->num_panels());
- panel3->Close();
- EXPECT_EQ(0, manager->num_panels());
+ ClosePanelAndWait(panel3->browser());
}
// Same test as AssignedBounds, but checks actual bounds on native OS windows.
TEST_F(PanelBrowserWindowCocoaTest, NativeBounds) {
- PanelManager* manager = PanelManager::GetInstance();
Panel* panel1 = CreateTestPanel("Test Panel 1");
Panel* panel2 = CreateTestPanel("Test Panel 2");
Panel* panel3 = CreateTestPanel("Test Panel 3");
- EXPECT_EQ(3, manager->num_panels());
-
- panel1->Show();
- panel2->Show();
- panel3->Show();
PanelBrowserWindowCocoa* native_window1 =
static_cast<PanelBrowserWindowCocoa*>(panel1->native_panel());
@@ -166,31 +186,27 @@ TEST_F(PanelBrowserWindowCocoaTest, NativeBounds) {
EXPECT_EQ(bounds2.origin.y, bounds3.origin.y);
// After panel2 is closed, panel3 should take its place.
- panel2->Close();
+ ClosePanelAndWait(panel2->browser());
bounds3 = [[native_window3->controller_ window] frame];
EXPECT_EQ(bounds2.origin.x, bounds3.origin.x);
EXPECT_EQ(bounds2.origin.y, bounds3.origin.y);
EXPECT_EQ(bounds2.size.width, bounds3.size.width);
EXPECT_EQ(bounds2.size.height, bounds3.size.height);
- EXPECT_EQ(2, manager->num_panels());
// After panel1 is closed, panel3 should take its place.
- panel1->Close();
+ ClosePanelAndWait(panel1->browser());
bounds3 = [[native_window3->controller_ window] frame];
EXPECT_EQ(bounds1.origin.x, bounds3.origin.x);
EXPECT_EQ(bounds1.origin.y, bounds3.origin.y);
EXPECT_EQ(bounds1.size.width, bounds3.size.width);
EXPECT_EQ(bounds1.size.height, bounds3.size.height);
- EXPECT_EQ(1, manager->num_panels());
- panel3->Close();
- EXPECT_EQ(0, manager->num_panels());
+ ClosePanelAndWait(panel3->browser());
}
// Verify the titlebar is being created.
TEST_F(PanelBrowserWindowCocoaTest, TitlebarViewCreate) {
Panel* panel = CreateTestPanel("Test Panel");
- panel->Show();
PanelBrowserWindowCocoa* native_window =
static_cast<PanelBrowserWindowCocoa*>(panel->native_panel());
@@ -199,13 +215,12 @@ TEST_F(PanelBrowserWindowCocoaTest, TitlebarViewCreate) {
EXPECT_TRUE(titlebar);
EXPECT_EQ(native_window->controller_, [titlebar controller]);
- panel->Close();
+ ClosePanelAndWait(panel->browser());
}
// Verify the sizing of titlebar - should be affixed on top of regular titlebar.
TEST_F(PanelBrowserWindowCocoaTest, TitlebarViewSizing) {
Panel* panel = CreateTestPanel("Test Panel");
- panel->Show();
PanelBrowserWindowCocoa* native_window =
static_cast<PanelBrowserWindowCocoa*>(panel->native_panel());
@@ -236,14 +251,12 @@ TEST_F(PanelBrowserWindowCocoaTest, TitlebarViewSizing) {
// Verify the titlebar is still on top of regular titlebar.
VerifyTitlebarLocation(contentView, titlebar);
- panel->Close();
+ ClosePanelAndWait(panel->browser());
}
// Verify closing behavior of titlebar close button.
TEST_F(PanelBrowserWindowCocoaTest, TitlebarViewClose) {
- PanelManager* manager = PanelManager::GetInstance();
Panel* panel = CreateTestPanel("Test Panel");
- panel->Show();
PanelBrowserWindowCocoa* native_window =
static_cast<PanelBrowserWindowCocoa*>(panel->native_panel());
@@ -251,16 +264,20 @@ TEST_F(PanelBrowserWindowCocoaTest, TitlebarViewClose) {
PanelTitlebarViewCocoa* titlebar = [native_window->controller_ titlebarView];
EXPECT_TRUE(titlebar);
+ PanelManager* manager = PanelManager::GetInstance();
EXPECT_EQ(1, manager->num_panels());
- // Simulate clicking Close Button. This should close the Panel as well.
+ // Simulate clicking Close Button and wait until the Panel closes.
+ ui_test_utils::WindowedNotificationObserver signal(
+ chrome::NOTIFICATION_BROWSER_CLOSED,
+ Source<Browser>(panel->browser()));
[titlebar simulateCloseButtonClick];
+ signal.Wait();
EXPECT_EQ(0, manager->num_panels());
}
// Verify some menu items being properly enabled/disabled for panels.
TEST_F(PanelBrowserWindowCocoaTest, MenuItems) {
Panel* panel = CreateTestPanel("Test Panel");
- panel->Show();
scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@""]);
NSMenuItem* close_tab_menu_item = CreateMenuItem(menu, IDC_CLOSE_TAB);
@@ -289,5 +306,5 @@ TEST_F(PanelBrowserWindowCocoaTest, MenuItems) {
EXPECT_FALSE([presentation_menu_item isEnabled]);
EXPECT_FALSE([bookmarks_menu_item isEnabled]);
- panel->Close();
+ ClosePanelAndWait(panel->browser());
}
« no previous file with comments | « chrome/browser/ui/panels/panel_browser_window_cocoa.mm ('k') | chrome/browser/ui/panels/panel_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698