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 #import <Cocoa/Cocoa.h> 6 7 #import "chrome/browser/ui/cocoa/window_size_autosaver.h" 8 9 #include "base/memory/scoped_nsobject.h" 10 #include "chrome/browser/prefs/pref_service.h" 11 #include "chrome/browser/prefs/scoped_user_pref_update.h" 12 #include "chrome/browser/ui/cocoa/browser_test_helper.h" 13 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" 14 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/platform_test.h" 16 17 namespace { 18 19 class WindowSizeAutosaverTest : public CocoaTest { 20 virtual void SetUp() { 21 CocoaTest::SetUp(); 22 path_ = "WindowSizeAutosaverTest"; 23 window_ = 24 [[NSWindow alloc] initWithContentRect:NSMakeRect(100, 101, 150, 151) 25 styleMask:NSTitledWindowMask| 26 NSResizableWindowMask 27 backing:NSBackingStoreBuffered 28 defer:NO]; 29 browser_helper_.profile()->GetPrefs()->RegisterDictionaryPref(path_); 30 } 31 32 virtual void TearDown() { 33 [window_ close]; 34 CocoaTest::TearDown(); 35 } 36 37 public: 38 BrowserTestHelper browser_helper_; 39 NSWindow* window_; 40 const char* path_; 41 }; 42 43 TEST_F(WindowSizeAutosaverTest, RestoresAndSavesPos) { 44 PrefService* pref = browser_helper_.profile()->GetPrefs(); 45 ASSERT_TRUE(pref != NULL); 46 47 // Check to make sure there is no existing pref for window placement. 48 const DictionaryValue* placement = pref->GetDictionary(path_); 49 ASSERT_TRUE(placement); 50 EXPECT_TRUE(placement->empty()); 51 52 // Replace the window with one that doesn't have resize controls. 53 [window_ close]; 54 window_ = 55 [[NSWindow alloc] initWithContentRect:NSMakeRect(100, 101, 150, 151) 56 styleMask:NSTitledWindowMask 57 backing:NSBackingStoreBuffered 58 defer:NO]; 59 60 // Ask the window to save its position, then check that a preference 61 // exists. We're technically passing in a pointer to the user prefs 62 // and not the local state prefs, but a PrefService* is a 63 // PrefService*, and this is a unittest. 64 65 { 66 NSRect frame = [window_ frame]; 67 // Empty state, shouldn't restore: 68 scoped_nsobject<WindowSizeAutosaver> sizeSaver([[WindowSizeAutosaver alloc] 69 initWithWindow:window_ 70 prefService:pref 71 path:path_]); 72 EXPECT_EQ(NSMinX(frame), NSMinX([window_ frame])); 73 EXPECT_EQ(NSMinY(frame), NSMinY([window_ frame])); 74 EXPECT_EQ(NSWidth(frame), NSWidth([window_ frame])); 75 EXPECT_EQ(NSHeight(frame), NSHeight([window_ frame])); 76 77 // Move and resize window, should store position but not size. 78 [window_ setFrame:NSMakeRect(300, 310, 250, 252) display:NO]; 79 } 80 81 // Another window movement -- shouldn't be recorded. 82 [window_ setFrame:NSMakeRect(400, 420, 160, 162) display:NO]; 83 84 { 85 // Should restore last stored position, but not size. 86 scoped_nsobject<WindowSizeAutosaver> sizeSaver([[WindowSizeAutosaver alloc] 87 initWithWindow:window_ 88 prefService:pref 89 path:path_]); 90 EXPECT_EQ(300, NSMinX([window_ frame])); 91 EXPECT_EQ(310, NSMinY([window_ frame])); 92 EXPECT_EQ(160, NSWidth([window_ frame])); 93 EXPECT_EQ(162, NSHeight([window_ frame])); 94 } 95 96 // ...and it should be in the profile, too. 97 EXPECT_TRUE(pref->GetDictionary(path_) != NULL); 98 int x, y; 99 const DictionaryValue* windowPref = pref->GetDictionary(path_); 100 EXPECT_FALSE(windowPref->GetInteger("left", &x)); 101 EXPECT_FALSE(windowPref->GetInteger("right", &x)); 102 EXPECT_FALSE(windowPref->GetInteger("top", &x)); 103 EXPECT_FALSE(windowPref->GetInteger("bottom", &x)); 104 ASSERT_TRUE(windowPref->GetInteger("x", &x)); 105 ASSERT_TRUE(windowPref->GetInteger("y", &y)); 106 EXPECT_EQ(300, x); 107 EXPECT_EQ(310, y); 108 } 109 110 TEST_F(WindowSizeAutosaverTest, RestoresAndSavesRect) { 111 PrefService* pref = browser_helper_.profile()->GetPrefs(); 112 ASSERT_TRUE(pref != NULL); 113 114 // Check to make sure there is no existing pref for window placement. 115 const DictionaryValue* placement = pref->GetDictionary(path_); 116 ASSERT_TRUE(placement); 117 EXPECT_TRUE(placement->empty()); 118 119 // Ask the window to save its position, then check that a preference 120 // exists. We're technically passing in a pointer to the user prefs 121 // and not the local state prefs, but a PrefService* is a 122 // PrefService*, and this is a unittest. 123 124 { 125 NSRect frame = [window_ frame]; 126 // Empty state, shouldn't restore: 127 scoped_nsobject<WindowSizeAutosaver> sizeSaver([[WindowSizeAutosaver alloc] 128 initWithWindow:window_ 129 prefService:pref 130 path:path_]); 131 EXPECT_EQ(NSMinX(frame), NSMinX([window_ frame])); 132 EXPECT_EQ(NSMinY(frame), NSMinY([window_ frame])); 133 EXPECT_EQ(NSWidth(frame), NSWidth([window_ frame])); 134 EXPECT_EQ(NSHeight(frame), NSHeight([window_ frame])); 135 136 // Move and resize window, should store 137 [window_ setFrame:NSMakeRect(300, 310, 250, 252) display:NO]; 138 } 139 140 // Another window movement -- shouldn't be recorded. 141 [window_ setFrame:NSMakeRect(400, 420, 160, 162) display:NO]; 142 143 { 144 // Should restore last stored size 145 scoped_nsobject<WindowSizeAutosaver> sizeSaver([[WindowSizeAutosaver alloc] 146 initWithWindow:window_ 147 prefService:pref 148 path:path_]); 149 EXPECT_EQ(300, NSMinX([window_ frame])); 150 EXPECT_EQ(310, NSMinY([window_ frame])); 151 EXPECT_EQ(250, NSWidth([window_ frame])); 152 EXPECT_EQ(252, NSHeight([window_ frame])); 153 } 154 155 // ...and it should be in the profile, too. 156 EXPECT_TRUE(pref->GetDictionary(path_) != NULL); 157 int x1, y1, x2, y2; 158 const DictionaryValue* windowPref = pref->GetDictionary(path_); 159 EXPECT_FALSE(windowPref->GetInteger("x", &x1)); 160 EXPECT_FALSE(windowPref->GetInteger("y", &x1)); 161 ASSERT_TRUE(windowPref->GetInteger("left", &x1)); 162 ASSERT_TRUE(windowPref->GetInteger("right", &x2)); 163 ASSERT_TRUE(windowPref->GetInteger("top", &y1)); 164 ASSERT_TRUE(windowPref->GetInteger("bottom", &y2)); 165 EXPECT_EQ(300, x1); 166 EXPECT_EQ(310, y1); 167 EXPECT_EQ(300 + 250, x2); 168 EXPECT_EQ(310 + 252, y2); 169 } 170 171 // http://crbug.com/39625 172 TEST_F(WindowSizeAutosaverTest, DoesNotRestoreButClearsEmptyRect) { 173 PrefService* pref = browser_helper_.profile()->GetPrefs(); 174 ASSERT_TRUE(pref != NULL); 175 176 DictionaryPrefUpdate update(pref, path_); 177 DictionaryValue* windowPref = update.Get(); 178 windowPref->SetInteger("left", 50); 179 windowPref->SetInteger("right", 50); 180 windowPref->SetInteger("top", 60); 181 windowPref->SetInteger("bottom", 60); 182 183 { 184 // Window rect shouldn't change... 185 NSRect frame = [window_ frame]; 186 scoped_nsobject<WindowSizeAutosaver> sizeSaver([[WindowSizeAutosaver alloc] 187 initWithWindow:window_ 188 prefService:pref 189 path:path_]); 190 EXPECT_EQ(NSMinX(frame), NSMinX([window_ frame])); 191 EXPECT_EQ(NSMinY(frame), NSMinY([window_ frame])); 192 EXPECT_EQ(NSWidth(frame), NSWidth([window_ frame])); 193 EXPECT_EQ(NSHeight(frame), NSHeight([window_ frame])); 194 } 195 196 // ...and it should be gone from the profile, too. 197 EXPECT_TRUE(pref->GetDictionary(path_) != NULL); 198 int x1, y1, x2, y2; 199 EXPECT_FALSE(windowPref->GetInteger("x", &x1)); 200 EXPECT_FALSE(windowPref->GetInteger("y", &x1)); 201 ASSERT_FALSE(windowPref->GetInteger("left", &x1)); 202 ASSERT_FALSE(windowPref->GetInteger("right", &x2)); 203 ASSERT_FALSE(windowPref->GetInteger("top", &y1)); 204 ASSERT_FALSE(windowPref->GetInteger("bottom", &y2)); 205 } 206 207 } // namespace 208