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