| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import <Cocoa/Cocoa.h> | 5 #import <Cocoa/Cocoa.h> |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/memory/scoped_nsobject.h" | 8 #include "base/memory/scoped_nsobject.h" |
| 9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
| 10 #include "chrome/browser/bookmarks/bookmark_model.h" | 10 #include "chrome/browser/bookmarks/bookmark_model.h" |
| 11 #import "chrome/browser/ui/cocoa/animation_utils.h" | |
| 12 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_constants.h" | 11 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_constants.h" |
| 13 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h" | 12 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_controller.h" |
| 14 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.h" | 13 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_button_cell.h" |
| 15 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.h" | 14 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_folder_controller.h" |
| 15 #include "chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.h" |
| 16 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_unittest_helper.h" | 16 #import "chrome/browser/ui/cocoa/bookmarks/bookmark_bar_unittest_helper.h" |
| 17 #include "chrome/browser/ui/cocoa/browser_test_helper.h" | 17 #include "chrome/browser/ui/cocoa/browser_test_helper.h" |
| 18 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" | 18 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" |
| 19 #import "chrome/browser/ui/cocoa/view_resizer_pong.h" | 19 #import "chrome/browser/ui/cocoa/view_resizer_pong.h" |
| 20 #include "chrome/test/base/model_test_utils.h" | 20 #include "chrome/test/base/model_test_utils.h" |
| 21 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| 22 #import "testing/gtest_mac.h" | 22 #import "testing/gtest_mac.h" |
| 23 #include "testing/platform_test.h" | 23 #include "testing/platform_test.h" |
| 24 | 24 |
| 25 // Add a redirect to make testing easier. | |
| 26 @interface BookmarkBarFolderController(MakeTestingEasier) | |
| 27 - (IBAction)openBookmarkFolderFromButton:(id)sender; | |
| 28 - (void)validateMenuSpacing; | |
| 29 @end | |
| 30 | |
| 31 @implementation BookmarkBarFolderController(MakeTestingEasier) | |
| 32 - (IBAction)openBookmarkFolderFromButton:(id)sender { | |
| 33 [[self folderTarget] openBookmarkFolderFromButton:sender]; | |
| 34 } | |
| 35 | |
| 36 // Utility function to verify that the buttons in this folder are all | |
| 37 // evenly spaced in a progressive manner. | |
| 38 - (void)validateMenuSpacing { | |
| 39 BOOL firstButton = YES; | |
| 40 CGFloat lastVerticalOffset = 0.0; | |
| 41 for (BookmarkButton* button in [self buttons]) { | |
| 42 if (firstButton) { | |
| 43 firstButton = NO; | |
| 44 lastVerticalOffset = [button frame].origin.y; | |
| 45 } else { | |
| 46 CGFloat nextVerticalOffset = [button frame].origin.y; | |
| 47 EXPECT_CGFLOAT_EQ(lastVerticalOffset - | |
| 48 bookmarks::kBookmarkFolderButtonHeight, | |
| 49 nextVerticalOffset); | |
| 50 lastVerticalOffset = nextVerticalOffset; | |
| 51 } | |
| 52 } | |
| 53 } | |
| 54 @end | |
| 55 | |
| 56 // Don't use a high window level when running unit tests -- it'll | |
| 57 // interfere with anything else you are working on. | |
| 58 // For testing. | |
| 59 @interface BookmarkBarFolderControllerNoLevel : BookmarkBarFolderController | |
| 60 @end | |
| 61 | |
| 62 @implementation BookmarkBarFolderControllerNoLevel | |
| 63 - (void)configureWindowLevel { | |
| 64 // Intentionally empty. | |
| 65 } | |
| 66 @end | |
| 67 | |
| 68 @interface BookmarkBarFolderControllerPong : BookmarkBarFolderController { | |
| 69 BOOL childFolderWillShow_; | |
| 70 BOOL childFolderWillClose_; | |
| 71 } | |
| 72 @property (nonatomic, readonly) BOOL childFolderWillShow; | |
| 73 @property (nonatomic, readonly) BOOL childFolderWillClose; | |
| 74 @end | |
| 75 | |
| 76 @implementation BookmarkBarFolderControllerPong | |
| 77 @synthesize childFolderWillShow = childFolderWillShow_; | |
| 78 @synthesize childFolderWillClose = childFolderWillClose_; | |
| 79 | |
| 80 - (void)childFolderWillShow:(id<BookmarkButtonControllerProtocol>)child { | |
| 81 childFolderWillShow_ = YES; | |
| 82 } | |
| 83 | |
| 84 - (void)childFolderWillClose:(id<BookmarkButtonControllerProtocol>)child { | |
| 85 childFolderWillClose_ = YES; | |
| 86 } | |
| 87 | |
| 88 // We don't have a real BookmarkBarController as our parent root so | |
| 89 // we fake this one out. | |
| 90 - (void)closeAllBookmarkFolders { | |
| 91 [self closeBookmarkFolder:self]; | |
| 92 } | |
| 93 | |
| 94 @end | |
| 95 | |
| 96 namespace { | 25 namespace { |
| 97 const int kLotsOfNodesCount = 150; | 26 const int kLotsOfNodesCount = 150; |
| 27 const NSUInteger kBottomItemCount = 4; |
| 98 }; | 28 }; |
| 99 | 29 |
| 100 | |
| 101 // Redirect certain calls so they can be seen by tests. | |
| 102 | |
| 103 @interface BookmarkBarControllerChildFolderRedirect : BookmarkBarController { | |
| 104 BookmarkBarFolderController* childFolderDelegate_; | |
| 105 } | |
| 106 @property (nonatomic, assign) BookmarkBarFolderController* childFolderDelegate; | |
| 107 @end | |
| 108 | |
| 109 @implementation BookmarkBarControllerChildFolderRedirect | |
| 110 | |
| 111 @synthesize childFolderDelegate = childFolderDelegate_; | |
| 112 | |
| 113 - (void)childFolderWillShow:(id<BookmarkButtonControllerProtocol>)child { | |
| 114 [childFolderDelegate_ childFolderWillShow:child]; | |
| 115 } | |
| 116 | |
| 117 - (void)childFolderWillClose:(id<BookmarkButtonControllerProtocol>)child { | |
| 118 [childFolderDelegate_ childFolderWillClose:child]; | |
| 119 } | |
| 120 | |
| 121 @end | |
| 122 | |
| 123 | |
| 124 class BookmarkBarFolderControllerTest : public CocoaTest { | 30 class BookmarkBarFolderControllerTest : public CocoaTest { |
| 125 public: | 31 public: |
| 126 BrowserTestHelper helper_; | 32 BookmarkModel* GetModel() { |
| 127 scoped_nsobject<BookmarkBarControllerChildFolderRedirect> bar_; | 33 return helper_.profile()->GetBookmarkModel(); |
| 128 const BookmarkNode* folderA_; // Owned by model. | 34 } |
| 129 const BookmarkNode* longTitleNode_; // Owned by model. | |
| 130 | 35 |
| 131 BookmarkBarFolderControllerTest() { | 36 BookmarkBarFolderController* CreateController(const BookmarkNode* node) { |
| 132 BookmarkModel* model = helper_.profile()->GetBookmarkModel(); | 37 // The button will be owned by the controller. |
| 133 const BookmarkNode* parent = model->bookmark_bar_node(); | 38 scoped_nsobject<BookmarkButton> button( |
| 134 const BookmarkNode* folderA = model->AddFolder(parent, | 39 [[BookmarkButton alloc] initWithFrame:NSMakeRect(0, 0, 500, 500)]); |
| 135 parent->child_count(), | 40 scoped_nsobject<BookmarkButtonCell> cell( |
| 136 ASCIIToUTF16("folder")); | 41 [[BookmarkButtonCell alloc] initTextCell:@"foo"]); |
| 137 folderA_ = folderA; | 42 [button setCell:cell]; |
| 138 model->AddFolder(parent, parent->child_count(), | 43 [cell setBookmarkNode:node]; |
| 139 ASCIIToUTF16("sibbling folder")); | |
| 140 const BookmarkNode* folderB = model->AddFolder(folderA, | |
| 141 folderA->child_count(), | |
| 142 ASCIIToUTF16("subfolder 1")); | |
| 143 model->AddFolder(folderA, | |
| 144 folderA->child_count(), | |
| 145 ASCIIToUTF16("subfolder 2")); | |
| 146 model->AddURL(folderA, folderA->child_count(), ASCIIToUTF16("title a"), | |
| 147 GURL("http://www.google.com/a")); | |
| 148 longTitleNode_ = model->AddURL( | |
| 149 folderA, folderA->child_count(), | |
| 150 ASCIIToUTF16("title super duper long long whoa momma title you betcha"), | |
| 151 GURL("http://www.google.com/b")); | |
| 152 model->AddURL(folderB, folderB->child_count(), ASCIIToUTF16("t"), | |
| 153 GURL("http://www.google.com/c")); | |
| 154 | 44 |
| 155 bar_.reset( | 45 BookmarkModel* model = GetModel(); |
| 156 [[BookmarkBarControllerChildFolderRedirect alloc] | 46 return [[BookmarkBarFolderController alloc] initWithParentButton:button |
| 157 initWithBrowser:helper_.browser() | 47 bookmarkModel:model |
| 158 initialWidth:300 | 48 barController:nil]; |
| 159 delegate:nil | 49 } |
| 160 resizeDelegate:nil]); | 50 |
| 161 [bar_ loaded:model]; | 51 void VerifyBottomItems(NSArray* items) { |
| 162 // Make parent frame for bookmark bar then open it. | 52 const NSUInteger count = [items count]; |
| 163 NSRect frame = [[test_window() contentView] frame]; | 53 ASSERT_GE(count, 4U); |
| 164 frame = NSMakeRect(frame.origin.x, | 54 |
| 165 frame.size.height - bookmarks::kNTPBookmarkBarHeight, | 55 NSMenuItem* item = [items objectAtIndex:count - 1]; |
| 166 frame.size.width, bookmarks::kNTPBookmarkBarHeight); | 56 EXPECT_EQ(@selector(openAllBookmarksIncognitoWindow:), [item action]); |
| 167 NSView* fakeToolbarView = [[[NSView alloc] initWithFrame:frame] | 57 |
| 168 autorelease]; | 58 item = [items objectAtIndex:count - 2]; |
| 169 [[test_window() contentView] addSubview:fakeToolbarView]; | 59 EXPECT_EQ(@selector(openAllBookmarksNewWindow:), [item action]); |
| 170 [fakeToolbarView addSubview:[bar_ view]]; | 60 |
| 171 [bar_ setBookmarkBarEnabled:YES]; | 61 item = [items objectAtIndex:count - 3]; |
| 62 EXPECT_EQ(@selector(openAllBookmarks:), [item action]); |
| 63 |
| 64 item = [items objectAtIndex:count - 4]; |
| 65 EXPECT_TRUE([item isSeparatorItem]); |
| 172 } | 66 } |
| 173 | 67 |
| 174 // Remove the bookmark with the long title. | 68 NSMenu* GetMenu(BookmarkBarFolderController* controller) { |
| 175 void RemoveLongTitleNode() { | 69 return [[controller menuBridge]->controller() menu]; |
| 176 BookmarkModel* model = helper_.profile()->GetBookmarkModel(); | |
| 177 model->Remove(longTitleNode_->parent(), | |
| 178 longTitleNode_->parent()->GetIndexOf(longTitleNode_)); | |
| 179 } | 70 } |
| 180 | 71 |
| 181 // Add LOTS of nodes to our model if needed (e.g. scrolling). | 72 private: |
| 182 // Returns the number of nodes added. | 73 BrowserTestHelper helper_; |
| 183 int AddLotsOfNodes() { | |
| 184 BookmarkModel* model = helper_.profile()->GetBookmarkModel(); | |
| 185 for (int i = 0; i < kLotsOfNodesCount; i++) { | |
| 186 model->AddURL(folderA_, folderA_->child_count(), | |
| 187 ASCIIToUTF16("repeated title"), | |
| 188 GURL("http://www.google.com/repeated/url")); | |
| 189 } | |
| 190 return kLotsOfNodesCount; | |
| 191 } | |
| 192 | |
| 193 // Return a simple BookmarkBarFolderController. | |
| 194 BookmarkBarFolderControllerPong* SimpleBookmarkBarFolderController() { | |
| 195 BookmarkButton* parentButton = [[bar_ buttons] objectAtIndex:0]; | |
| 196 BookmarkBarFolderControllerPong* c = | |
| 197 [[BookmarkBarFolderControllerPong alloc] | |
| 198 initWithParentButton:parentButton | |
| 199 parentController:nil | |
| 200 barController:bar_]; | |
| 201 [c window]; // Force nib load. | |
| 202 return c; | |
| 203 } | |
| 204 }; | 74 }; |
| 205 | 75 |
| 206 TEST_F(BookmarkBarFolderControllerTest, InitCreateAndDelete) { | 76 TEST_F(BookmarkBarFolderControllerTest, SimpleFolder) { |
| 207 scoped_nsobject<BookmarkBarFolderController> bbfc; | 77 // Create the model. |
| 208 bbfc.reset(SimpleBookmarkBarFolderController()); | 78 BookmarkModel* model = GetModel(); |
| 79 const BookmarkNode* root = model->bookmark_bar_node(); |
| 209 | 80 |
| 210 // Make sure none of the buttons overlap, that all are inside | 81 model->AddURL(root, root->child_count(), ASCIIToUTF16("ignored"), |
| 211 // the content frame, and their cells are of the proper class. | 82 GURL("http://example.com")); |
| 212 NSArray* buttons = [bbfc buttons]; | |
| 213 EXPECT_TRUE([buttons count]); | |
| 214 for (unsigned int i = 0; i < ([buttons count]-1); i++) { | |
| 215 EXPECT_FALSE(NSContainsRect([[buttons objectAtIndex:i] frame], | |
| 216 [[buttons objectAtIndex:i+1] frame])); | |
| 217 } | |
| 218 Class cellClass = [BookmarkBarFolderButtonCell class]; | |
| 219 for (BookmarkButton* button in buttons) { | |
| 220 NSRect r = [[bbfc folderView] convertRect:[button frame] fromView:button]; | |
| 221 // TODO(jrg): remove this adjustment. | |
| 222 NSRect bigger = NSInsetRect([[bbfc folderView] frame], -2, 0); | |
| 223 EXPECT_TRUE(NSContainsRect(bigger, r)); | |
| 224 EXPECT_TRUE([[button cell] isKindOfClass:cellClass]); | |
| 225 } | |
| 226 | 83 |
| 227 // Confirm folder buttons have no tooltip. The important thing | 84 const BookmarkNode* folder = model->AddFolder(root, root->child_count(), |
| 228 // really is that we insure folders and non-folders are treated | 85 ASCIIToUTF16("folder")); |
| 229 // differently; not sure of any other generic way to do this. | 86 model->AddURL(folder, folder->child_count(), ASCIIToUTF16("item 1"), |
| 230 for (BookmarkButton* button in buttons) { | 87 GURL("http://www.google.com/")); |
| 231 if ([button isFolder]) | 88 model->AddURL(folder, folder->child_count(), ASCIIToUTF16("item 2"), |
| 232 EXPECT_FALSE([button toolTip]); | 89 GURL("http://www.chromium.org/")); |
| 233 else | 90 model->AddURL(folder, folder->child_count(), ASCIIToUTF16("item 3"), |
| 234 EXPECT_TRUE([button toolTip]); | 91 GURL("http://build.chromium.org/")); |
| 235 } | 92 |
| 93 model->AddURL(root, root->child_count(), ASCIIToUTF16("ignored 2"), |
| 94 GURL("http://example2.com")); |
| 95 |
| 96 // Create the controller and menu. |
| 97 scoped_nsobject<BookmarkBarFolderController> bbfc(CreateController(folder)); |
| 98 CloseFolderSoon(bbfc, 0.1); |
| 99 [bbfc openMenu]; |
| 100 |
| 101 NSArray* items = [GetMenu(bbfc) itemArray]; |
| 102 ASSERT_EQ(3 + kBottomItemCount, [items count]); |
| 103 |
| 104 EXPECT_NSEQ(@"item 1", [[items objectAtIndex:0] title]); |
| 105 EXPECT_NSEQ(@"item 2", [[items objectAtIndex:1] title]); |
| 106 EXPECT_NSEQ(@"item 3", [[items objectAtIndex:2] title]); |
| 107 |
| 108 VerifyBottomItems(items); |
| 236 } | 109 } |
| 237 | 110 |
| 238 // Make sure closing of the window releases the controller. | 111 TEST_F(BookmarkBarFolderControllerTest, NestedFolder) { |
| 239 // (e.g. valgrind shouldn't complain if we do this). | 112 // Create the model. |
| 240 TEST_F(BookmarkBarFolderControllerTest, ReleaseOnClose) { | 113 BookmarkModel* model = GetModel(); |
| 241 scoped_nsobject<BookmarkBarFolderController> bbfc; | 114 const BookmarkNode* root = model->bookmark_bar_node(); |
| 242 bbfc.reset(SimpleBookmarkBarFolderController()); | |
| 243 EXPECT_TRUE(bbfc.get()); | |
| 244 | 115 |
| 245 [bbfc retain]; // stop the scoped_nsobject from doing anything | 116 model->AddURL(root, root->child_count(), ASCIIToUTF16("ignored"), |
| 246 [[bbfc window] close]; // trigger an autorelease of bbfc.get() | 117 GURL("http://example.com")); |
| 118 model->AddURL(root, root->child_count(), ASCIIToUTF16("ignored 2"), |
| 119 GURL("http://example2.com")); |
| 120 |
| 121 const BookmarkNode* folder = model->AddFolder(root, root->child_count(), |
| 122 ASCIIToUTF16("folder")); |
| 123 model->AddURL(folder, folder->child_count(), ASCIIToUTF16("item 1"), |
| 124 GURL("http://www.google.com/")); |
| 125 model->AddURL(folder, folder->child_count(), ASCIIToUTF16("item 2"), |
| 126 GURL("http://www.chromium.org/")); |
| 127 model->AddURL(folder, folder->child_count(), ASCIIToUTF16("item 3"), |
| 128 GURL("http://build.chromium.org/")); |
| 129 const BookmarkNode* subfolder = model->AddFolder(folder, |
| 130 folder->child_count(), ASCIIToUTF16("subfolder")); |
| 131 model->AddURL(folder, folder->child_count(), ASCIIToUTF16("item 4"), |
| 132 GURL("http://dev.chromium.org/")); |
| 133 |
| 134 model->AddURL(subfolder, subfolder->child_count(), ASCIIToUTF16("subitem 1"), |
| 135 GURL("http://gmail.com")); |
| 136 model->AddURL(subfolder, subfolder->child_count(), ASCIIToUTF16("subitem 2"), |
| 137 GURL("http://google.com/+")); |
| 138 |
| 139 // Create the controller and menu. |
| 140 scoped_nsobject<BookmarkBarFolderController> bbfc(CreateController(folder)); |
| 141 CloseFolderSoon(bbfc, 0.1); |
| 142 [bbfc openMenu]; |
| 143 |
| 144 NSArray* items = [GetMenu(bbfc) itemArray]; |
| 145 ASSERT_EQ(5 + kBottomItemCount, [items count]); |
| 146 |
| 147 EXPECT_NSEQ(@"item 1", [[items objectAtIndex:0] title]); |
| 148 EXPECT_NSEQ(@"item 2", [[items objectAtIndex:1] title]); |
| 149 EXPECT_NSEQ(@"item 3", [[items objectAtIndex:2] title]); |
| 150 EXPECT_NSEQ(@"subfolder", [[items objectAtIndex:3] title]); |
| 151 EXPECT_NSEQ(@"item 4", [[items objectAtIndex:4] title]); |
| 152 VerifyBottomItems(items); |
| 153 |
| 154 NSArray* subitems = [[[items objectAtIndex:3] submenu] itemArray]; |
| 155 ASSERT_EQ(2 + kBottomItemCount, [subitems count]); |
| 156 EXPECT_NSEQ(@"subitem 1", [[subitems objectAtIndex:0] title]); |
| 157 EXPECT_NSEQ(@"subitem 2", [[subitems objectAtIndex:1] title]); |
| 158 VerifyBottomItems(subitems); |
| 247 } | 159 } |
| 248 | |
| 249 TEST_F(BookmarkBarFolderControllerTest, BasicPosition) { | |
| 250 BookmarkButton* parentButton = [[bar_ buttons] objectAtIndex:0]; | |
| 251 EXPECT_TRUE(parentButton); | |
| 252 | |
| 253 // If parent is a BookmarkBarController, grow down. | |
| 254 scoped_nsobject<BookmarkBarFolderController> bbfc; | |
| 255 bbfc.reset([[BookmarkBarFolderController alloc] | |
| 256 initWithParentButton:parentButton | |
| 257 parentController:nil | |
| 258 barController:bar_]); | |
| 259 [bbfc window]; | |
| 260 NSPoint pt = [bbfc windowTopLeftForWidth:0 height:100]; // screen coords | |
| 261 NSPoint buttonOriginInScreen = | |
| 262 [[parentButton window] | |
| 263 convertBaseToScreen:[parentButton | |
| 264 convertRectToBase:[parentButton frame]].origin]; | |
| 265 // Within margin | |
| 266 EXPECT_LE(abs(pt.x - buttonOriginInScreen.x), | |
| 267 bookmarks::kBookmarkMenuOverlap+1); | |
| 268 EXPECT_LE(abs(pt.y - buttonOriginInScreen.y), | |
| 269 bookmarks::kBookmarkMenuOverlap+1); | |
| 270 | |
| 271 // Make sure we see the window shift left if it spills off the screen | |
| 272 pt = [bbfc windowTopLeftForWidth:0 height:100]; | |
| 273 NSPoint shifted = [bbfc windowTopLeftForWidth:9999999 height:100]; | |
| 274 EXPECT_LT(shifted.x, pt.x); | |
| 275 | |
| 276 // If parent is a BookmarkBarFolderController, grow right. | |
| 277 scoped_nsobject<BookmarkBarFolderController> bbfc2; | |
| 278 bbfc2.reset([[BookmarkBarFolderController alloc] | |
| 279 initWithParentButton:[[bbfc buttons] objectAtIndex:0] | |
| 280 parentController:bbfc.get() | |
| 281 barController:bar_]); | |
| 282 [bbfc2 window]; | |
| 283 pt = [bbfc2 windowTopLeftForWidth:0 height:100]; | |
| 284 // We're now overlapping the window a bit. | |
| 285 EXPECT_EQ(pt.x, NSMaxX([[bbfc.get() window] frame]) - | |
| 286 bookmarks::kBookmarkMenuOverlap); | |
| 287 } | |
| 288 | |
| 289 // Confirm we grow right until end of screen, then start growing left | |
| 290 // until end of screen again, then right. | |
| 291 TEST_F(BookmarkBarFolderControllerTest, PositionRightLeftRight) { | |
| 292 BookmarkModel* model = helper_.profile()->GetBookmarkModel(); | |
| 293 const BookmarkNode* parent = model->bookmark_bar_node(); | |
| 294 const BookmarkNode* folder = parent; | |
| 295 | |
| 296 const int count = 100; | |
| 297 int i; | |
| 298 // Make some super duper deeply nested folders. | |
| 299 for (i = 0; i < count; i++) { | |
| 300 folder = model->AddFolder(folder, 0, ASCIIToUTF16("nested folder")); | |
| 301 } | |
| 302 | |
| 303 // Setup initial state for opening all folders. | |
| 304 folder = parent; | |
| 305 BookmarkButton* parentButton = [[bar_ buttons] objectAtIndex:0]; | |
| 306 BookmarkBarFolderController* parentController = nil; | |
| 307 EXPECT_TRUE(parentButton); | |
| 308 | |
| 309 // Open them all. | |
| 310 scoped_nsobject<NSMutableArray> folder_controller_array; | |
| 311 folder_controller_array.reset([[NSMutableArray array] retain]); | |
| 312 for (i=0; i<count; i++) { | |
| 313 BookmarkBarFolderControllerNoLevel* bbfcl = | |
| 314 [[BookmarkBarFolderControllerNoLevel alloc] | |
| 315 initWithParentButton:parentButton | |
| 316 parentController:parentController | |
| 317 barController:bar_]; | |
| 318 [folder_controller_array addObject:bbfcl]; | |
| 319 [bbfcl autorelease]; | |
| 320 [bbfcl window]; | |
| 321 parentController = bbfcl; | |
| 322 parentButton = [[bbfcl buttons] objectAtIndex:0]; | |
| 323 } | |
| 324 | |
| 325 // Make vector of all x positions. | |
| 326 std::vector<CGFloat> leftPositions; | |
| 327 for (i=0; i<count; i++) { | |
| 328 CGFloat x = [[[folder_controller_array objectAtIndex:i] window] | |
| 329 frame].origin.x; | |
| 330 leftPositions.push_back(x); | |
| 331 } | |
| 332 | |
| 333 // Make sure the first few grow right. | |
| 334 for (i=0; i<3; i++) | |
| 335 EXPECT_TRUE(leftPositions[i+1] > leftPositions[i]); | |
| 336 | |
| 337 // Look for the first "grow left". | |
| 338 while (leftPositions[i] > leftPositions[i-1]) | |
| 339 i++; | |
| 340 // Confirm the next few also grow left. | |
| 341 int j; | |
| 342 for (j=i; j<i+3; j++) | |
| 343 EXPECT_TRUE(leftPositions[j+1] < leftPositions[j]); | |
| 344 i = j; | |
| 345 | |
| 346 // Finally, confirm we see a "grow right" once more. | |
| 347 while (leftPositions[i] < leftPositions[i-1]) | |
| 348 i++; | |
| 349 // (No need to EXPECT a final "grow right"; if we didn't find one | |
| 350 // we'd get a C++ array bounds exception). | |
| 351 } | |
| 352 | |
| 353 TEST_F(BookmarkBarFolderControllerTest, DropDestination) { | |
| 354 scoped_nsobject<BookmarkBarFolderController> bbfc; | |
| 355 bbfc.reset(SimpleBookmarkBarFolderController()); | |
| 356 EXPECT_TRUE(bbfc.get()); | |
| 357 | |
| 358 // Confirm "off the top" and "off the bottom" match no buttons. | |
| 359 NSPoint p = NSMakePoint(NSMidX([[bbfc folderView] frame]), 10000); | |
| 360 EXPECT_FALSE([bbfc buttonForDroppingOnAtPoint:p]); | |
| 361 EXPECT_TRUE([bbfc shouldShowIndicatorShownForPoint:p]); | |
| 362 p = NSMakePoint(NSMidX([[bbfc folderView] frame]), -1); | |
| 363 EXPECT_FALSE([bbfc buttonForDroppingOnAtPoint:p]); | |
| 364 EXPECT_TRUE([bbfc shouldShowIndicatorShownForPoint:p]); | |
| 365 | |
| 366 // Confirm "right in the center" (give or take a pixel) is a match, | |
| 367 // and confirm "just barely in the button" is not. Anything more | |
| 368 // specific seems likely to be tweaked. We don't loop over all | |
| 369 // buttons because the scroll view makes them not visible. | |
| 370 for (BookmarkButton* button in [bbfc buttons]) { | |
| 371 CGFloat x = NSMidX([button frame]); | |
| 372 CGFloat y = NSMidY([button frame]); | |
| 373 // Somewhere near the center: a match (but only if a folder!) | |
| 374 if ([button isFolder]) { | |
| 375 EXPECT_EQ(button, | |
| 376 [bbfc buttonForDroppingOnAtPoint:NSMakePoint(x-1, y+1)]); | |
| 377 EXPECT_EQ(button, | |
| 378 [bbfc buttonForDroppingOnAtPoint:NSMakePoint(x+1, y-1)]); | |
| 379 EXPECT_FALSE([bbfc shouldShowIndicatorShownForPoint:NSMakePoint(x, y)]);; | |
| 380 } else { | |
| 381 // If not a folder we don't drop into it. | |
| 382 EXPECT_FALSE([bbfc buttonForDroppingOnAtPoint:NSMakePoint(x-1, y+1)]); | |
| 383 EXPECT_FALSE([bbfc buttonForDroppingOnAtPoint:NSMakePoint(x+1, y-1)]); | |
| 384 EXPECT_TRUE([bbfc shouldShowIndicatorShownForPoint:NSMakePoint(x, y)]);; | |
| 385 } | |
| 386 } | |
| 387 } | |
| 388 | |
| 389 TEST_F(BookmarkBarFolderControllerTest, OpenFolder) { | |
| 390 scoped_nsobject<BookmarkBarFolderController> bbfc; | |
| 391 bbfc.reset(SimpleBookmarkBarFolderController()); | |
| 392 EXPECT_TRUE(bbfc.get()); | |
| 393 | |
| 394 EXPECT_FALSE([bbfc folderController]); | |
| 395 BookmarkButton* button = [[bbfc buttons] objectAtIndex:0]; | |
| 396 [bbfc openBookmarkFolderFromButton:button]; | |
| 397 id controller = [bbfc folderController]; | |
| 398 EXPECT_TRUE(controller); | |
| 399 EXPECT_EQ([controller parentButton], button); | |
| 400 | |
| 401 // Click the same one --> it gets closed. | |
| 402 [bbfc openBookmarkFolderFromButton:[[bbfc buttons] objectAtIndex:0]]; | |
| 403 EXPECT_FALSE([bbfc folderController]); | |
| 404 | |
| 405 // Open a new one --> change. | |
| 406 [bbfc openBookmarkFolderFromButton:[[bbfc buttons] objectAtIndex:1]]; | |
| 407 EXPECT_NE(controller, [bbfc folderController]); | |
| 408 EXPECT_NE([[bbfc folderController] parentButton], button); | |
| 409 | |
| 410 // Close it --> all gone! | |
| 411 [bbfc closeBookmarkFolder:nil]; | |
| 412 EXPECT_FALSE([bbfc folderController]); | |
| 413 } | |
| 414 | |
| 415 TEST_F(BookmarkBarFolderControllerTest, ChildFolderCallbacks) { | |
| 416 scoped_nsobject<BookmarkBarFolderControllerPong> bbfc; | |
| 417 bbfc.reset(SimpleBookmarkBarFolderController()); | |
| 418 EXPECT_TRUE(bbfc.get()); | |
| 419 [bar_ setChildFolderDelegate:bbfc.get()]; | |
| 420 | |
| 421 EXPECT_FALSE([bbfc childFolderWillShow]); | |
| 422 [bbfc openBookmarkFolderFromButton:[[bbfc buttons] objectAtIndex:0]]; | |
| 423 EXPECT_TRUE([bbfc childFolderWillShow]); | |
| 424 | |
| 425 EXPECT_FALSE([bbfc childFolderWillClose]); | |
| 426 [bbfc closeBookmarkFolder:nil]; | |
| 427 EXPECT_TRUE([bbfc childFolderWillClose]); | |
| 428 | |
| 429 [bar_ setChildFolderDelegate:nil]; | |
| 430 } | |
| 431 | |
| 432 // Make sure bookmark folders have variable widths. | |
| 433 TEST_F(BookmarkBarFolderControllerTest, ChildFolderWidth) { | |
| 434 scoped_nsobject<BookmarkBarFolderController> bbfc; | |
| 435 | |
| 436 bbfc.reset(SimpleBookmarkBarFolderController()); | |
| 437 EXPECT_TRUE(bbfc.get()); | |
| 438 [bbfc showWindow:bbfc.get()]; | |
| 439 CGFloat wideWidth = NSWidth([[bbfc window] frame]); | |
| 440 | |
| 441 RemoveLongTitleNode(); | |
| 442 bbfc.reset(SimpleBookmarkBarFolderController()); | |
| 443 EXPECT_TRUE(bbfc.get()); | |
| 444 CGFloat thinWidth = NSWidth([[bbfc window] frame]); | |
| 445 | |
| 446 // Make sure window size changed as expected. | |
| 447 EXPECT_GT(wideWidth, thinWidth); | |
| 448 } | |
| 449 | |
| 450 // Simple scrolling tests. | |
| 451 // Currently flaky due to a changed definition of the correct menu boundaries. | |
| 452 TEST_F(BookmarkBarFolderControllerTest, DISABLED_SimpleScroll) { | |
| 453 scoped_nsobject<BookmarkBarFolderController> bbfc; | |
| 454 NSRect screenFrame = [[NSScreen mainScreen] visibleFrame]; | |
| 455 CGFloat screenHeight = NSHeight(screenFrame); | |
| 456 int nodecount = AddLotsOfNodes(); | |
| 457 bbfc.reset(SimpleBookmarkBarFolderController()); | |
| 458 EXPECT_TRUE(bbfc.get()); | |
| 459 [bbfc showWindow:bbfc.get()]; | |
| 460 NSWindow* window = [bbfc window]; | |
| 461 | |
| 462 // The window should be shorter than the screen but reach exactly to the | |
| 463 // bottom of the screen since it's scrollable. | |
| 464 EXPECT_LT(NSHeight([window frame]), screenHeight); | |
| 465 EXPECT_CGFLOAT_EQ(0.0, [window frame].origin.y); | |
| 466 | |
| 467 // Initially, should show scroll-up but not scroll-down. | |
| 468 EXPECT_TRUE([bbfc canScrollUp]); | |
| 469 EXPECT_FALSE([bbfc canScrollDown]); | |
| 470 | |
| 471 // Scroll up a bit. Make sure the window has gotten bigger each time. | |
| 472 // Also, for each scroll, make sure our hit test finds a new button | |
| 473 // (to confirm the content area changed). | |
| 474 NSView* savedHit = nil; | |
| 475 NSScrollView* scrollView = [bbfc scrollView]; | |
| 476 | |
| 477 // Find the next-to-last button showing at the bottom of the window and | |
| 478 // use its center for hit testing. | |
| 479 BookmarkButton* targetButton = nil; | |
| 480 NSPoint scrollPoint = [scrollView documentVisibleRect].origin; | |
| 481 for (BookmarkButton* button in [bbfc buttons]) { | |
| 482 NSRect buttonFrame = [button frame]; | |
| 483 buttonFrame.origin.y -= scrollPoint.y; | |
| 484 if (buttonFrame.origin.y < 0.0) | |
| 485 break; | |
| 486 targetButton = button; | |
| 487 } | |
| 488 EXPECT_TRUE(targetButton != nil); | |
| 489 NSPoint hitPoint = [targetButton frame].origin; | |
| 490 hitPoint.x += 50.0; | |
| 491 hitPoint.y += (bookmarks::kBookmarkFolderButtonHeight / 2.0) - scrollPoint.y; | |
| 492 hitPoint = [targetButton convertPoint:hitPoint toView:scrollView]; | |
| 493 | |
| 494 for (int i = 0; i < 3; i++) { | |
| 495 CGFloat height = NSHeight([window frame]); | |
| 496 [bbfc performOneScroll:60]; | |
| 497 EXPECT_GT(NSHeight([window frame]), height); | |
| 498 NSView* hit = [scrollView hitTest:hitPoint]; | |
| 499 // We should hit a bookmark button. | |
| 500 EXPECT_TRUE([[hit className] isEqualToString:@"BookmarkButton"]); | |
| 501 EXPECT_NE(hit, savedHit); | |
| 502 savedHit = hit; | |
| 503 } | |
| 504 | |
| 505 // Keep scrolling up; make sure we never get bigger than the screen. | |
| 506 // Also confirm we never scroll the window off the screen. | |
| 507 bool bothAtOnce = false; | |
| 508 while ([bbfc canScrollUp]) { | |
| 509 [bbfc performOneScroll:60]; | |
| 510 EXPECT_TRUE(NSContainsRect([[NSScreen mainScreen] frame], [window frame])); | |
| 511 // Make sure, sometime during our scroll, we have the ability to | |
| 512 // scroll in either direction. | |
| 513 if ([bbfc canScrollUp] && | |
| 514 [bbfc canScrollDown]) | |
| 515 bothAtOnce = true; | |
| 516 } | |
| 517 EXPECT_TRUE(bothAtOnce); | |
| 518 | |
| 519 // Once we've scrolled to the end, our only option should be to scroll back. | |
| 520 EXPECT_FALSE([bbfc canScrollUp]); | |
| 521 EXPECT_TRUE([bbfc canScrollDown]); | |
| 522 | |
| 523 NSRect wholeScreenRect = [[NSScreen mainScreen] frame]; | |
| 524 | |
| 525 // Now scroll down and make sure the window size does not change. | |
| 526 // Also confirm we never scroll the window off the screen the other | |
| 527 // way. | |
| 528 for (int i = 0; i < nodecount+50; ++i) { | |
| 529 [bbfc performOneScroll:-60]; | |
| 530 // Once we can no longer scroll down the window height changes. | |
| 531 if (![bbfc canScrollDown]) | |
| 532 break; | |
| 533 EXPECT_TRUE(NSContainsRect(wholeScreenRect, [window frame])); | |
| 534 } | |
| 535 | |
| 536 EXPECT_GT(NSHeight(wholeScreenRect), NSHeight([window frame])); | |
| 537 EXPECT_TRUE(NSContainsRect(wholeScreenRect, [window frame])); | |
| 538 } | |
| 539 | |
| 540 // Folder menu sizing and placement while deleting bookmarks | |
| 541 // and scrolling tests. | |
| 542 TEST_F(BookmarkBarFolderControllerTest, MenuPlacementWhileScrollingDeleting) { | |
| 543 scoped_nsobject<BookmarkBarFolderController> bbfc; | |
| 544 AddLotsOfNodes(); | |
| 545 bbfc.reset(SimpleBookmarkBarFolderController()); | |
| 546 [bbfc showWindow:bbfc.get()]; | |
| 547 NSWindow* menuWindow = [bbfc window]; | |
| 548 BookmarkBarFolderController* folder = [bar_ folderController]; | |
| 549 NSArray* buttons = [folder buttons]; | |
| 550 | |
| 551 // Before scrolling any, delete a bookmark and make sure the window top has | |
| 552 // not moved. Pick a button which is near the top and visible. | |
| 553 CGFloat oldTop = [menuWindow frame].origin.y + NSHeight([menuWindow frame]); | |
| 554 BookmarkButton* button = [buttons objectAtIndex:3]; | |
| 555 [folder deleteBookmark:button]; | |
| 556 CGFloat newTop = [menuWindow frame].origin.y + NSHeight([menuWindow frame]); | |
| 557 EXPECT_CGFLOAT_EQ(oldTop, newTop); | |
| 558 | |
| 559 // Scroll so that both the top and bottom scroll arrows show, make sure | |
| 560 // the top of the window has moved up, then delete a visible button and | |
| 561 // make sure the top has not moved. | |
| 562 oldTop = newTop; | |
| 563 const CGFloat scrollOneBookmark = bookmarks::kBookmarkFolderButtonHeight + | |
| 564 bookmarks::kBookmarkVerticalPadding; | |
| 565 NSUInteger buttonCounter = 0; | |
| 566 NSUInteger extraButtonLimit = 3; | |
| 567 while (![bbfc canScrollDown] || extraButtonLimit > 0) { | |
| 568 [bbfc performOneScroll:scrollOneBookmark]; | |
| 569 ++buttonCounter; | |
| 570 if ([bbfc canScrollDown]) | |
| 571 --extraButtonLimit; | |
| 572 } | |
| 573 newTop = [menuWindow frame].origin.y + NSHeight([menuWindow frame]); | |
| 574 EXPECT_NE(oldTop, newTop); | |
| 575 oldTop = newTop; | |
| 576 button = [buttons objectAtIndex:buttonCounter + 3]; | |
| 577 [folder deleteBookmark:button]; | |
| 578 newTop = [menuWindow frame].origin.y + NSHeight([menuWindow frame]); | |
| 579 EXPECT_CGFLOAT_EQ(oldTop, newTop); | |
| 580 | |
| 581 // Scroll so that the top scroll arrow is no longer showing, make sure | |
| 582 // the top of the window has not moved, then delete a visible button and | |
| 583 // make sure the top has not moved. | |
| 584 while ([bbfc canScrollDown]) { | |
| 585 [bbfc performOneScroll:-scrollOneBookmark]; | |
| 586 --buttonCounter; | |
| 587 } | |
| 588 button = [buttons objectAtIndex:buttonCounter + 3]; | |
| 589 [folder deleteBookmark:button]; | |
| 590 newTop = [menuWindow frame].origin.y + NSHeight([menuWindow frame]); | |
| 591 EXPECT_CGFLOAT_EQ(oldTop - bookmarks::kScrollWindowVerticalMargin, newTop); | |
| 592 } | |
| 593 | |
| 594 @interface FakedDragInfo : NSObject { | |
| 595 @public | |
| 596 NSPoint dropLocation_; | |
| 597 NSDragOperation sourceMask_; | |
| 598 } | |
| 599 @property (nonatomic, assign) NSPoint dropLocation; | |
| 600 - (void)setDraggingSourceOperationMask:(NSDragOperation)mask; | |
| 601 @end | |
| 602 | |
| 603 @implementation FakedDragInfo | |
| 604 | |
| 605 @synthesize dropLocation = dropLocation_; | |
| 606 | |
| 607 - (id)init { | |
| 608 if ((self = [super init])) { | |
| 609 dropLocation_ = NSZeroPoint; | |
| 610 sourceMask_ = NSDragOperationMove; | |
| 611 } | |
| 612 return self; | |
| 613 } | |
| 614 | |
| 615 // NSDraggingInfo protocol functions. | |
| 616 | |
| 617 - (id)draggingPasteboard { | |
| 618 return self; | |
| 619 } | |
| 620 | |
| 621 - (id)draggingSource { | |
| 622 return self; | |
| 623 } | |
| 624 | |
| 625 - (NSDragOperation)draggingSourceOperationMask { | |
| 626 return sourceMask_; | |
| 627 } | |
| 628 | |
| 629 - (NSPoint)draggingLocation { | |
| 630 return dropLocation_; | |
| 631 } | |
| 632 | |
| 633 // Other functions. | |
| 634 | |
| 635 - (void)setDraggingSourceOperationMask:(NSDragOperation)mask { | |
| 636 sourceMask_ = mask; | |
| 637 } | |
| 638 | |
| 639 @end | |
| 640 | |
| 641 | |
| 642 class BookmarkBarFolderControllerMenuTest : public CocoaTest { | |
| 643 public: | |
| 644 BrowserTestHelper helper_; | |
| 645 scoped_nsobject<NSView> parent_view_; | |
| 646 scoped_nsobject<ViewResizerPong> resizeDelegate_; | |
| 647 scoped_nsobject<BookmarkBarController> bar_; | |
| 648 | |
| 649 BookmarkBarFolderControllerMenuTest() { | |
| 650 resizeDelegate_.reset([[ViewResizerPong alloc] init]); | |
| 651 NSRect parent_frame = NSMakeRect(0, 0, 800, 50); | |
| 652 parent_view_.reset([[NSView alloc] initWithFrame:parent_frame]); | |
| 653 [parent_view_ setHidden:YES]; | |
| 654 bar_.reset([[BookmarkBarController alloc] | |
| 655 initWithBrowser:helper_.browser() | |
| 656 initialWidth:NSWidth(parent_frame) | |
| 657 delegate:nil | |
| 658 resizeDelegate:resizeDelegate_.get()]); | |
| 659 InstallAndToggleBar(bar_.get()); | |
| 660 } | |
| 661 | |
| 662 void InstallAndToggleBar(BookmarkBarController* bar) { | |
| 663 // Force loading of the nib. | |
| 664 [bar view]; | |
| 665 // Awkwardness to look like we've been installed. | |
| 666 [parent_view_ addSubview:[bar view]]; | |
| 667 NSRect frame = [[[bar view] superview] frame]; | |
| 668 frame.origin.y = 400; | |
| 669 [[[bar view] superview] setFrame:frame]; | |
| 670 | |
| 671 // Make sure it's on in a window so viewDidMoveToWindow is called | |
| 672 [[test_window() contentView] addSubview:parent_view_]; | |
| 673 | |
| 674 // Make sure it's open so certain things aren't no-ops. | |
| 675 [bar updateAndShowNormalBar:YES | |
| 676 showDetachedBar:NO | |
| 677 withAnimation:NO]; | |
| 678 } | |
| 679 }; | |
| 680 | |
| 681 TEST_F(BookmarkBarFolderControllerMenuTest, DragMoveBarBookmarkToFolder) { | |
| 682 WithNoAnimation at_all; | |
| 683 BookmarkModel& model(*helper_.profile()->GetBookmarkModel()); | |
| 684 const BookmarkNode* root = model.bookmark_bar_node(); | |
| 685 const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b " | |
| 686 "2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ 4f2f1b " | |
| 687 "4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b "); | |
| 688 model_test_utils::AddNodesFromModelString(model, root, model_string); | |
| 689 | |
| 690 // Validate initial model. | |
| 691 std::string actualModelString = model_test_utils::ModelStringFromNode(root); | |
| 692 EXPECT_EQ(model_string, actualModelString); | |
| 693 | |
| 694 // Pop up a folder menu and drag in a button from the bar. | |
| 695 BookmarkButton* toFolder = [bar_ buttonWithTitleEqualTo:@"2f"]; | |
| 696 NSRect oldToFolderFrame = [toFolder frame]; | |
| 697 [[toFolder target] performSelector:@selector(openBookmarkFolderFromButton:) | |
| 698 withObject:toFolder]; | |
| 699 BookmarkBarFolderController* folderController = [bar_ folderController]; | |
| 700 EXPECT_TRUE(folderController); | |
| 701 NSWindow* toWindow = [folderController window]; | |
| 702 EXPECT_TRUE(toWindow); | |
| 703 NSRect oldToWindowFrame = [toWindow frame]; | |
| 704 // Drag a bar button onto a bookmark (i.e. not a folder) in a folder | |
| 705 // so it should end up below the target bookmark. | |
| 706 BookmarkButton* draggedButton = [bar_ buttonWithTitleEqualTo:@"1b"]; | |
| 707 ASSERT_TRUE(draggedButton); | |
| 708 CGFloat horizontalShift = | |
| 709 NSWidth([draggedButton frame]) + bookmarks::kBookmarkHorizontalPadding; | |
| 710 BookmarkButton* targetButton = | |
| 711 [folderController buttonWithTitleEqualTo:@"2f1b"]; | |
| 712 ASSERT_TRUE(targetButton); | |
| 713 [folderController dragButton:draggedButton | |
| 714 to:[targetButton center] | |
| 715 copy:NO]; | |
| 716 // The button should have landed just after "2f1b". | |
| 717 const std::string expected_string("2f:[ 2f1b 1b 2f2f:[ 2f2f1b " | |
| 718 "2f2f2b 2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ " | |
| 719 "4f2f1b 4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b "); | |
| 720 EXPECT_EQ(expected_string, model_test_utils::ModelStringFromNode(root)); | |
| 721 | |
| 722 // Verify the window still appears by looking for its controller. | |
| 723 EXPECT_TRUE([bar_ folderController]); | |
| 724 | |
| 725 // Gather the new frames. | |
| 726 NSRect newToFolderFrame = [toFolder frame]; | |
| 727 NSRect newToWindowFrame = [toWindow frame]; | |
| 728 // The toFolder should have shifted left horizontally but not vertically. | |
| 729 NSRect expectedToFolderFrame = | |
| 730 NSOffsetRect(oldToFolderFrame, -horizontalShift, 0); | |
| 731 EXPECT_NSRECT_EQ(expectedToFolderFrame, newToFolderFrame); | |
| 732 // The toWindow should have shifted left horizontally, down vertically, | |
| 733 // and grown vertically. | |
| 734 NSRect expectedToWindowFrame = oldToWindowFrame; | |
| 735 expectedToWindowFrame.origin.x -= horizontalShift; | |
| 736 expectedToWindowFrame.origin.y -= bookmarks::kBookmarkFolderButtonHeight; | |
| 737 expectedToWindowFrame.size.height += bookmarks::kBookmarkFolderButtonHeight; | |
| 738 EXPECT_NSRECT_EQ(expectedToWindowFrame, newToWindowFrame); | |
| 739 | |
| 740 // Check button spacing. | |
| 741 [folderController validateMenuSpacing]; | |
| 742 | |
| 743 // Move the button back to the bar at the beginning. | |
| 744 draggedButton = [folderController buttonWithTitleEqualTo:@"1b"]; | |
| 745 ASSERT_TRUE(draggedButton); | |
| 746 targetButton = [bar_ buttonWithTitleEqualTo:@"2f"]; | |
| 747 ASSERT_TRUE(targetButton); | |
| 748 [bar_ dragButton:draggedButton | |
| 749 to:[targetButton left] | |
| 750 copy:NO]; | |
| 751 EXPECT_EQ(model_string, model_test_utils::ModelStringFromNode(root)); | |
| 752 // Don't check the folder window since it's not supposed to be showing. | |
| 753 } | |
| 754 | |
| 755 TEST_F(BookmarkBarFolderControllerMenuTest, DragCopyBarBookmarkToFolder) { | |
| 756 BookmarkModel& model(*helper_.profile()->GetBookmarkModel()); | |
| 757 const BookmarkNode* root = model.bookmark_bar_node(); | |
| 758 const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b " | |
| 759 "2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ 4f2f1b " | |
| 760 "4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b "); | |
| 761 model_test_utils::AddNodesFromModelString(model, root, model_string); | |
| 762 | |
| 763 // Validate initial model. | |
| 764 std::string actualModelString = model_test_utils::ModelStringFromNode(root); | |
| 765 EXPECT_EQ(model_string, actualModelString); | |
| 766 | |
| 767 // Pop up a folder menu and copy in a button from the bar. | |
| 768 BookmarkButton* toFolder = [bar_ buttonWithTitleEqualTo:@"2f"]; | |
| 769 ASSERT_TRUE(toFolder); | |
| 770 NSRect oldToFolderFrame = [toFolder frame]; | |
| 771 [[toFolder target] performSelector:@selector(openBookmarkFolderFromButton:) | |
| 772 withObject:toFolder]; | |
| 773 BookmarkBarFolderController* folderController = [bar_ folderController]; | |
| 774 EXPECT_TRUE(folderController); | |
| 775 NSWindow* toWindow = [folderController window]; | |
| 776 EXPECT_TRUE(toWindow); | |
| 777 NSRect oldToWindowFrame = [toWindow frame]; | |
| 778 // Drag a bar button onto a bookmark (i.e. not a folder) in a folder | |
| 779 // so it should end up below the target bookmark. | |
| 780 BookmarkButton* draggedButton = [bar_ buttonWithTitleEqualTo:@"1b"]; | |
| 781 ASSERT_TRUE(draggedButton); | |
| 782 BookmarkButton* targetButton = | |
| 783 [folderController buttonWithTitleEqualTo:@"2f1b"]; | |
| 784 ASSERT_TRUE(targetButton); | |
| 785 [folderController dragButton:draggedButton | |
| 786 to:[targetButton center] | |
| 787 copy:YES]; | |
| 788 // The button should have landed just after "2f1b". | |
| 789 const std::string expected_1("1b 2f:[ 2f1b 1b 2f2f:[ 2f2f1b " | |
| 790 "2f2f2b 2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ " | |
| 791 "4f2f1b 4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b "); | |
| 792 EXPECT_EQ(expected_1, model_test_utils::ModelStringFromNode(root)); | |
| 793 | |
| 794 // Gather the new frames. | |
| 795 NSRect newToFolderFrame = [toFolder frame]; | |
| 796 NSRect newToWindowFrame = [toWindow frame]; | |
| 797 // The toFolder should have shifted. | |
| 798 EXPECT_NSRECT_EQ(oldToFolderFrame, newToFolderFrame); | |
| 799 // The toWindow should have shifted down vertically and grown vertically. | |
| 800 NSRect expectedToWindowFrame = oldToWindowFrame; | |
| 801 expectedToWindowFrame.origin.y -= bookmarks::kBookmarkFolderButtonHeight; | |
| 802 expectedToWindowFrame.size.height += bookmarks::kBookmarkFolderButtonHeight; | |
| 803 EXPECT_NSRECT_EQ(expectedToWindowFrame, newToWindowFrame); | |
| 804 | |
| 805 // Copy the button back to the bar after "3b". | |
| 806 draggedButton = [folderController buttonWithTitleEqualTo:@"1b"]; | |
| 807 ASSERT_TRUE(draggedButton); | |
| 808 targetButton = [bar_ buttonWithTitleEqualTo:@"4f"]; | |
| 809 ASSERT_TRUE(targetButton); | |
| 810 [bar_ dragButton:draggedButton | |
| 811 to:[targetButton left] | |
| 812 copy:YES]; | |
| 813 const std::string expected_2("1b 2f:[ 2f1b 1b 2f2f:[ 2f2f1b " | |
| 814 "2f2f2b 2f2f3b ] 2f3b ] 3b 1b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ " | |
| 815 "4f2f1b 4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b "); | |
| 816 EXPECT_EQ(expected_2, model_test_utils::ModelStringFromNode(root)); | |
| 817 } | |
| 818 | |
| 819 TEST_F(BookmarkBarFolderControllerMenuTest, DragMoveBarBookmarkToSubfolder) { | |
| 820 BookmarkModel& model(*helper_.profile()->GetBookmarkModel()); | |
| 821 const BookmarkNode* root = model.bookmark_bar_node(); | |
| 822 const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b " | |
| 823 "2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ 4f2f1b " | |
| 824 "4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b "); | |
| 825 model_test_utils::AddNodesFromModelString(model, root, model_string); | |
| 826 | |
| 827 // Validate initial model. | |
| 828 std::string actualModelString = model_test_utils::ModelStringFromNode(root); | |
| 829 EXPECT_EQ(model_string, actualModelString); | |
| 830 | |
| 831 // Pop up a folder menu and a subfolder menu. | |
| 832 BookmarkButton* toFolder = [bar_ buttonWithTitleEqualTo:@"4f"]; | |
| 833 ASSERT_TRUE(toFolder); | |
| 834 [[toFolder target] performSelector:@selector(openBookmarkFolderFromButton:) | |
| 835 withObject:toFolder]; | |
| 836 BookmarkBarFolderController* folderController = [bar_ folderController]; | |
| 837 EXPECT_TRUE(folderController); | |
| 838 NSWindow* toWindow = [folderController window]; | |
| 839 EXPECT_TRUE(toWindow); | |
| 840 NSRect oldToWindowFrame = [toWindow frame]; | |
| 841 BookmarkButton* toSubfolder = | |
| 842 [folderController buttonWithTitleEqualTo:@"4f2f"]; | |
| 843 ASSERT_TRUE(toSubfolder); | |
| 844 [[toSubfolder target] performSelector:@selector(openBookmarkFolderFromButton:) | |
| 845 withObject:toSubfolder]; | |
| 846 BookmarkBarFolderController* subfolderController = | |
| 847 [folderController folderController]; | |
| 848 EXPECT_TRUE(subfolderController); | |
| 849 NSWindow* toSubwindow = [subfolderController window]; | |
| 850 EXPECT_TRUE(toSubwindow); | |
| 851 NSRect oldToSubwindowFrame = [toSubwindow frame]; | |
| 852 // Drag a bar button onto a bookmark (i.e. not a folder) in a folder | |
| 853 // so it should end up below the target bookmark. | |
| 854 BookmarkButton* draggedButton = [bar_ buttonWithTitleEqualTo:@"5b"]; | |
| 855 ASSERT_TRUE(draggedButton); | |
| 856 BookmarkButton* targetButton = | |
| 857 [subfolderController buttonWithTitleEqualTo:@"4f2f3b"]; | |
| 858 ASSERT_TRUE(targetButton); | |
| 859 [subfolderController dragButton:draggedButton | |
| 860 to:[targetButton center] | |
| 861 copy:NO]; | |
| 862 // The button should have landed just after "2f". | |
| 863 const std::string expected_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b " | |
| 864 "2f2f2b 2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ " | |
| 865 "4f2f1b 4f2f2b 4f2f3b 5b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] "); | |
| 866 EXPECT_EQ(expected_string, model_test_utils::ModelStringFromNode(root)); | |
| 867 | |
| 868 // Check button spacing. | |
| 869 [folderController validateMenuSpacing]; | |
| 870 [subfolderController validateMenuSpacing]; | |
| 871 | |
| 872 // Check the window layouts. The folder window should not have changed, | |
| 873 // but the subfolder window should have shifted vertically and grown. | |
| 874 NSRect newToWindowFrame = [toWindow frame]; | |
| 875 EXPECT_NSRECT_EQ(oldToWindowFrame, newToWindowFrame); | |
| 876 NSRect newToSubwindowFrame = [toSubwindow frame]; | |
| 877 NSRect expectedToSubwindowFrame = oldToSubwindowFrame; | |
| 878 expectedToSubwindowFrame.origin.y -= bookmarks::kBookmarkFolderButtonHeight; | |
| 879 expectedToSubwindowFrame.size.height += | |
| 880 bookmarks::kBookmarkFolderButtonHeight; | |
| 881 EXPECT_NSRECT_EQ(expectedToSubwindowFrame, newToSubwindowFrame); | |
| 882 } | |
| 883 | |
| 884 TEST_F(BookmarkBarFolderControllerMenuTest, DragMoveWithinFolder) { | |
| 885 BookmarkModel& model(*helper_.profile()->GetBookmarkModel()); | |
| 886 const BookmarkNode* root = model.bookmark_bar_node(); | |
| 887 const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b " | |
| 888 "2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ 4f2f1b " | |
| 889 "4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b "); | |
| 890 model_test_utils::AddNodesFromModelString(model, root, model_string); | |
| 891 | |
| 892 // Validate initial model. | |
| 893 std::string actualModelString = model_test_utils::ModelStringFromNode(root); | |
| 894 EXPECT_EQ(model_string, actualModelString); | |
| 895 | |
| 896 // Pop up a folder menu. | |
| 897 BookmarkButton* toFolder = [bar_ buttonWithTitleEqualTo:@"4f"]; | |
| 898 ASSERT_TRUE(toFolder); | |
| 899 [[toFolder target] performSelector:@selector(openBookmarkFolderFromButton:) | |
| 900 withObject:toFolder]; | |
| 901 BookmarkBarFolderController* folderController = [bar_ folderController]; | |
| 902 EXPECT_TRUE(folderController); | |
| 903 NSWindow* toWindow = [folderController window]; | |
| 904 EXPECT_TRUE(toWindow); | |
| 905 NSRect oldToWindowFrame = [toWindow frame]; | |
| 906 // Drag a folder button to the top within the same parent. | |
| 907 BookmarkButton* draggedButton = | |
| 908 [folderController buttonWithTitleEqualTo:@"4f2f"]; | |
| 909 ASSERT_TRUE(draggedButton); | |
| 910 BookmarkButton* targetButton = | |
| 911 [folderController buttonWithTitleEqualTo:@"4f1f"]; | |
| 912 ASSERT_TRUE(targetButton); | |
| 913 [folderController dragButton:draggedButton | |
| 914 to:[targetButton top] | |
| 915 copy:NO]; | |
| 916 // The button should have landed above "4f1f". | |
| 917 const std::string expected_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b " | |
| 918 "2f2f2b 2f2f3b ] 2f3b ] 3b 4f:[ 4f2f:[ 4f2f1b 4f2f2b 4f2f3b ] " | |
| 919 "4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b "); | |
| 920 EXPECT_EQ(expected_string, model_test_utils::ModelStringFromNode(root)); | |
| 921 | |
| 922 // The window should not have gone away. | |
| 923 EXPECT_TRUE([bar_ folderController]); | |
| 924 | |
| 925 // The folder window should not have changed. | |
| 926 NSRect newToWindowFrame = [toWindow frame]; | |
| 927 EXPECT_NSRECT_EQ(oldToWindowFrame, newToWindowFrame); | |
| 928 | |
| 929 // Check button spacing. | |
| 930 [folderController validateMenuSpacing]; | |
| 931 } | |
| 932 | |
| 933 TEST_F(BookmarkBarFolderControllerMenuTest, DragParentOntoChild) { | |
| 934 BookmarkModel& model(*helper_.profile()->GetBookmarkModel()); | |
| 935 const BookmarkNode* root = model.bookmark_bar_node(); | |
| 936 const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b " | |
| 937 "2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ 4f2f1b " | |
| 938 "4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b "); | |
| 939 model_test_utils::AddNodesFromModelString(model, root, model_string); | |
| 940 | |
| 941 // Validate initial model. | |
| 942 std::string actualModelString = model_test_utils::ModelStringFromNode(root); | |
| 943 EXPECT_EQ(model_string, actualModelString); | |
| 944 | |
| 945 // Pop up a folder menu. | |
| 946 BookmarkButton* toFolder = [bar_ buttonWithTitleEqualTo:@"4f"]; | |
| 947 ASSERT_TRUE(toFolder); | |
| 948 [[toFolder target] performSelector:@selector(openBookmarkFolderFromButton:) | |
| 949 withObject:toFolder]; | |
| 950 BookmarkBarFolderController* folderController = [bar_ folderController]; | |
| 951 EXPECT_TRUE(folderController); | |
| 952 NSWindow* toWindow = [folderController window]; | |
| 953 EXPECT_TRUE(toWindow); | |
| 954 // Drag a folder button to one of its children. | |
| 955 BookmarkButton* draggedButton = [bar_ buttonWithTitleEqualTo:@"4f"]; | |
| 956 ASSERT_TRUE(draggedButton); | |
| 957 BookmarkButton* targetButton = | |
| 958 [folderController buttonWithTitleEqualTo:@"4f3f"]; | |
| 959 ASSERT_TRUE(targetButton); | |
| 960 [folderController dragButton:draggedButton | |
| 961 to:[targetButton top] | |
| 962 copy:NO]; | |
| 963 // The model should not have changed. | |
| 964 EXPECT_EQ(model_string, model_test_utils::ModelStringFromNode(root)); | |
| 965 | |
| 966 // Check button spacing. | |
| 967 [folderController validateMenuSpacing]; | |
| 968 } | |
| 969 | |
| 970 TEST_F(BookmarkBarFolderControllerMenuTest, DragMoveChildToParent) { | |
| 971 BookmarkModel& model(*helper_.profile()->GetBookmarkModel()); | |
| 972 const BookmarkNode* root = model.bookmark_bar_node(); | |
| 973 const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b " | |
| 974 "2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f:[ 4f2f1b " | |
| 975 "4f2f2b 4f2f3b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b "); | |
| 976 model_test_utils::AddNodesFromModelString(model, root, model_string); | |
| 977 | |
| 978 // Validate initial model. | |
| 979 std::string actualModelString = model_test_utils::ModelStringFromNode(root); | |
| 980 EXPECT_EQ(model_string, actualModelString); | |
| 981 | |
| 982 // Pop up a folder menu and a subfolder menu. | |
| 983 BookmarkButton* toFolder = [bar_ buttonWithTitleEqualTo:@"4f"]; | |
| 984 ASSERT_TRUE(toFolder); | |
| 985 [[toFolder target] performSelector:@selector(openBookmarkFolderFromButton:) | |
| 986 withObject:toFolder]; | |
| 987 BookmarkBarFolderController* folderController = [bar_ folderController]; | |
| 988 EXPECT_TRUE(folderController); | |
| 989 BookmarkButton* toSubfolder = | |
| 990 [folderController buttonWithTitleEqualTo:@"4f2f"]; | |
| 991 ASSERT_TRUE(toSubfolder); | |
| 992 [[toSubfolder target] performSelector:@selector(openBookmarkFolderFromButton:) | |
| 993 withObject:toSubfolder]; | |
| 994 BookmarkBarFolderController* subfolderController = | |
| 995 [folderController folderController]; | |
| 996 EXPECT_TRUE(subfolderController); | |
| 997 | |
| 998 // Drag a subfolder bookmark to the parent folder. | |
| 999 BookmarkButton* draggedButton = | |
| 1000 [subfolderController buttonWithTitleEqualTo:@"4f2f3b"]; | |
| 1001 ASSERT_TRUE(draggedButton); | |
| 1002 BookmarkButton* targetButton = | |
| 1003 [folderController buttonWithTitleEqualTo:@"4f2f"]; | |
| 1004 ASSERT_TRUE(targetButton); | |
| 1005 [folderController dragButton:draggedButton | |
| 1006 to:[targetButton top] | |
| 1007 copy:NO]; | |
| 1008 // The button should have landed above "4f2f". | |
| 1009 const std::string expected_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b " | |
| 1010 "2f2f3b ] 2f3b ] 3b 4f:[ 4f1f:[ 4f1f1b 4f1f2b 4f1f3b ] 4f2f3b 4f2f:[ " | |
| 1011 "4f2f1b 4f2f2b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b "); | |
| 1012 EXPECT_EQ(expected_string, model_test_utils::ModelStringFromNode(root)); | |
| 1013 | |
| 1014 // Check button spacing. | |
| 1015 [folderController validateMenuSpacing]; | |
| 1016 // The window should not have gone away. | |
| 1017 EXPECT_TRUE([bar_ folderController]); | |
| 1018 // The subfolder should have gone away. | |
| 1019 EXPECT_FALSE([folderController folderController]); | |
| 1020 } | |
| 1021 | |
| 1022 TEST_F(BookmarkBarFolderControllerMenuTest, DragWindowResizing) { | |
| 1023 BookmarkModel& model(*helper_.profile()->GetBookmarkModel()); | |
| 1024 const BookmarkNode* root = model.bookmark_bar_node(); | |
| 1025 const std::string | |
| 1026 model_string("a b:[ b1 b2 b3 ] reallyReallyLongBookmarkName c "); | |
| 1027 model_test_utils::AddNodesFromModelString(model, root, model_string); | |
| 1028 | |
| 1029 // Validate initial model. | |
| 1030 std::string actualModelString = model_test_utils::ModelStringFromNode(root); | |
| 1031 EXPECT_EQ(model_string, actualModelString); | |
| 1032 | |
| 1033 // Pop up a folder menu. | |
| 1034 BookmarkButton* toFolder = [bar_ buttonWithTitleEqualTo:@"b"]; | |
| 1035 ASSERT_TRUE(toFolder); | |
| 1036 [[toFolder target] performSelector:@selector(openBookmarkFolderFromButton:) | |
| 1037 withObject:toFolder]; | |
| 1038 BookmarkBarFolderController* folderController = [bar_ folderController]; | |
| 1039 EXPECT_TRUE(folderController); | |
| 1040 NSWindow* toWindow = [folderController window]; | |
| 1041 EXPECT_TRUE(toWindow); | |
| 1042 CGFloat oldWidth = NSWidth([toWindow frame]); | |
| 1043 // Drag the bookmark with a long name to the folder. | |
| 1044 BookmarkButton* draggedButton = | |
| 1045 [bar_ buttonWithTitleEqualTo:@"reallyReallyLongBookmarkName"]; | |
| 1046 ASSERT_TRUE(draggedButton); | |
| 1047 BookmarkButton* targetButton = | |
| 1048 [folderController buttonWithTitleEqualTo:@"b1"]; | |
| 1049 ASSERT_TRUE(targetButton); | |
| 1050 [folderController dragButton:draggedButton | |
| 1051 to:[targetButton center] | |
| 1052 copy:NO]; | |
| 1053 // Verify the model change. | |
| 1054 const std::string | |
| 1055 expected_string("a b:[ b1 reallyReallyLongBookmarkName b2 b3 ] c "); | |
| 1056 EXPECT_EQ(expected_string, model_test_utils::ModelStringFromNode(root)); | |
| 1057 // Verify the window grew. Just test a reasonable width gain. | |
| 1058 CGFloat newWidth = NSWidth([toWindow frame]); | |
| 1059 EXPECT_LT(oldWidth + 30.0, newWidth); | |
| 1060 } | |
| 1061 | |
| 1062 TEST_F(BookmarkBarFolderControllerMenuTest, MoveRemoveAddButtons) { | |
| 1063 BookmarkModel& model(*helper_.profile()->GetBookmarkModel()); | |
| 1064 const BookmarkNode* root = model.bookmark_bar_node(); | |
| 1065 const std::string model_string("1b 2f:[ 2f1b 2f2b 2f3b ] 3b 4b "); | |
| 1066 model_test_utils::AddNodesFromModelString(model, root, model_string); | |
| 1067 | |
| 1068 // Validate initial model. | |
| 1069 std::string actualModelString = model_test_utils::ModelStringFromNode(root); | |
| 1070 EXPECT_EQ(model_string, actualModelString); | |
| 1071 | |
| 1072 // Pop up a folder menu. | |
| 1073 BookmarkButton* toFolder = [bar_ buttonWithTitleEqualTo:@"2f"]; | |
| 1074 ASSERT_TRUE(toFolder); | |
| 1075 [[toFolder target] performSelector:@selector(openBookmarkFolderFromButton:) | |
| 1076 withObject:toFolder]; | |
| 1077 BookmarkBarFolderController* folder = [bar_ folderController]; | |
| 1078 EXPECT_TRUE(folder); | |
| 1079 | |
| 1080 // Remember how many buttons are showing. | |
| 1081 NSArray* buttons = [folder buttons]; | |
| 1082 NSUInteger oldDisplayedButtons = [buttons count]; | |
| 1083 | |
| 1084 // Move a button around a bit. | |
| 1085 [folder moveButtonFromIndex:0 toIndex:2]; | |
| 1086 EXPECT_NSEQ(@"2f2b", [[buttons objectAtIndex:0] title]); | |
| 1087 EXPECT_NSEQ(@"2f3b", [[buttons objectAtIndex:1] title]); | |
| 1088 EXPECT_NSEQ(@"2f1b", [[buttons objectAtIndex:2] title]); | |
| 1089 EXPECT_EQ(oldDisplayedButtons, [buttons count]); | |
| 1090 [folder moveButtonFromIndex:2 toIndex:0]; | |
| 1091 EXPECT_NSEQ(@"2f1b", [[buttons objectAtIndex:0] title]); | |
| 1092 EXPECT_NSEQ(@"2f2b", [[buttons objectAtIndex:1] title]); | |
| 1093 EXPECT_NSEQ(@"2f3b", [[buttons objectAtIndex:2] title]); | |
| 1094 EXPECT_EQ(oldDisplayedButtons, [buttons count]); | |
| 1095 | |
| 1096 // Add a couple of buttons. | |
| 1097 const BookmarkNode* node = root->GetChild(2); // Purloin an existing node. | |
| 1098 [folder addButtonForNode:node atIndex:0]; | |
| 1099 EXPECT_NSEQ(@"3b", [[buttons objectAtIndex:0] title]); | |
| 1100 EXPECT_NSEQ(@"2f1b", [[buttons objectAtIndex:1] title]); | |
| 1101 EXPECT_NSEQ(@"2f2b", [[buttons objectAtIndex:2] title]); | |
| 1102 EXPECT_NSEQ(@"2f3b", [[buttons objectAtIndex:3] title]); | |
| 1103 EXPECT_EQ(oldDisplayedButtons + 1, [buttons count]); | |
| 1104 node = root->GetChild(3); | |
| 1105 [folder addButtonForNode:node atIndex:-1]; | |
| 1106 EXPECT_NSEQ(@"3b", [[buttons objectAtIndex:0] title]); | |
| 1107 EXPECT_NSEQ(@"2f1b", [[buttons objectAtIndex:1] title]); | |
| 1108 EXPECT_NSEQ(@"2f2b", [[buttons objectAtIndex:2] title]); | |
| 1109 EXPECT_NSEQ(@"2f3b", [[buttons objectAtIndex:3] title]); | |
| 1110 EXPECT_NSEQ(@"4b", [[buttons objectAtIndex:4] title]); | |
| 1111 EXPECT_EQ(oldDisplayedButtons + 2, [buttons count]); | |
| 1112 | |
| 1113 // Remove a couple of buttons. | |
| 1114 [folder removeButton:4 animate:NO]; | |
| 1115 [folder removeButton:1 animate:NO]; | |
| 1116 EXPECT_NSEQ(@"3b", [[buttons objectAtIndex:0] title]); | |
| 1117 EXPECT_NSEQ(@"2f2b", [[buttons objectAtIndex:1] title]); | |
| 1118 EXPECT_NSEQ(@"2f3b", [[buttons objectAtIndex:2] title]); | |
| 1119 EXPECT_EQ(oldDisplayedButtons, [buttons count]); | |
| 1120 | |
| 1121 // Check button spacing. | |
| 1122 [folder validateMenuSpacing]; | |
| 1123 } | |
| 1124 | |
| 1125 TEST_F(BookmarkBarFolderControllerMenuTest, ControllerForNode) { | |
| 1126 BookmarkModel& model(*helper_.profile()->GetBookmarkModel()); | |
| 1127 const BookmarkNode* root = model.bookmark_bar_node(); | |
| 1128 const std::string model_string("1b 2f:[ 2f1b 2f2b ] 3b "); | |
| 1129 model_test_utils::AddNodesFromModelString(model, root, model_string); | |
| 1130 | |
| 1131 // Validate initial model. | |
| 1132 std::string actualModelString = model_test_utils::ModelStringFromNode(root); | |
| 1133 EXPECT_EQ(model_string, actualModelString); | |
| 1134 | |
| 1135 // Find the main bar controller. | |
| 1136 const void* expectedController = bar_; | |
| 1137 const void* actualController = [bar_ controllerForNode:root]; | |
| 1138 EXPECT_EQ(expectedController, actualController); | |
| 1139 | |
| 1140 // Pop up the folder menu. | |
| 1141 BookmarkButton* targetFolder = [bar_ buttonWithTitleEqualTo:@"2f"]; | |
| 1142 ASSERT_TRUE(targetFolder); | |
| 1143 [[targetFolder target] | |
| 1144 performSelector:@selector(openBookmarkFolderFromButton:) | |
| 1145 withObject:targetFolder]; | |
| 1146 BookmarkBarFolderController* folder = [bar_ folderController]; | |
| 1147 EXPECT_TRUE(folder); | |
| 1148 | |
| 1149 // Find the folder controller using the folder controller. | |
| 1150 const BookmarkNode* targetNode = root->GetChild(1); | |
| 1151 expectedController = folder; | |
| 1152 actualController = [bar_ controllerForNode:targetNode]; | |
| 1153 EXPECT_EQ(expectedController, actualController); | |
| 1154 | |
| 1155 // Find the folder controller from the bar. | |
| 1156 actualController = [folder controllerForNode:targetNode]; | |
| 1157 EXPECT_EQ(expectedController, actualController); | |
| 1158 } | |
| 1159 | |
| 1160 TEST_F(BookmarkBarFolderControllerMenuTest, MenuSizingAndScrollArrows) { | |
| 1161 BookmarkModel& model(*helper_.profile()->GetBookmarkModel()); | |
| 1162 const BookmarkNode* root = model.bookmark_bar_node(); | |
| 1163 const std::string model_string("1b 2b 3b "); | |
| 1164 model_test_utils::AddNodesFromModelString(model, root, model_string); | |
| 1165 | |
| 1166 // Validate initial model. | |
| 1167 std::string actualModelString = model_test_utils::ModelStringFromNode(root); | |
| 1168 EXPECT_EQ(model_string, actualModelString); | |
| 1169 | |
| 1170 const BookmarkNode* parent = model.bookmark_bar_node(); | |
| 1171 const BookmarkNode* folder = model.AddFolder(parent, | |
| 1172 parent->child_count(), | |
| 1173 ASCIIToUTF16("BIG")); | |
| 1174 | |
| 1175 // Pop open the new folder window and verify it has one (empty) item. | |
| 1176 BookmarkButton* button = [bar_ buttonWithTitleEqualTo:@"BIG"]; | |
| 1177 [[button target] performSelector:@selector(openBookmarkFolderFromButton:) | |
| 1178 withObject:button]; | |
| 1179 BookmarkBarFolderController* folderController = [bar_ folderController]; | |
| 1180 EXPECT_TRUE(folderController); | |
| 1181 NSWindow* folderWindow = [folderController window]; | |
| 1182 EXPECT_TRUE(folderWindow); | |
| 1183 CGFloat expectedHeight = (CGFloat)bookmarks::kBookmarkFolderButtonHeight + | |
| 1184 (2*bookmarks::kBookmarkVerticalPadding); | |
| 1185 NSRect windowFrame = [folderWindow frame]; | |
| 1186 CGFloat windowHeight = NSHeight(windowFrame); | |
| 1187 EXPECT_CGFLOAT_EQ(expectedHeight, windowHeight); | |
| 1188 EXPECT_FALSE([folderController canScrollUp]); | |
| 1189 EXPECT_FALSE([folderController canScrollDown]); | |
| 1190 | |
| 1191 // Now add a real bookmark and reopen. | |
| 1192 model.AddURL(folder, folder->child_count(), ASCIIToUTF16("a"), | |
| 1193 GURL("http://a.com/")); | |
| 1194 folderController = [bar_ folderController]; | |
| 1195 EXPECT_TRUE(folderController); | |
| 1196 NSView* folderView = [folderController folderView]; | |
| 1197 EXPECT_TRUE(folderView); | |
| 1198 NSRect menuFrame = [folderView frame]; | |
| 1199 NSView* visibleView = [folderController visibleView]; | |
| 1200 NSRect visibleFrame = [visibleView frame]; | |
| 1201 NSScrollView* scrollView = [folderController scrollView]; | |
| 1202 NSRect scrollFrame = [scrollView frame]; | |
| 1203 | |
| 1204 // Determine the margins between the scroll frame and the visible frame. | |
| 1205 CGFloat widthDelta = NSWidth(visibleFrame) - NSWidth(scrollFrame); | |
| 1206 | |
| 1207 CGFloat menuHeight = NSHeight(menuFrame); | |
| 1208 EXPECT_CGFLOAT_EQ(expectedHeight, menuHeight); | |
| 1209 CGFloat scrollerWidth = NSWidth(scrollFrame); | |
| 1210 button = [folderController buttonWithTitleEqualTo:@"a"]; | |
| 1211 CGFloat buttonWidth = NSWidth([button frame]); | |
| 1212 EXPECT_CGFLOAT_EQ(scrollerWidth, buttonWidth); | |
| 1213 CGFloat visibleWidth = NSWidth(visibleFrame); | |
| 1214 EXPECT_CGFLOAT_EQ(visibleWidth - widthDelta, buttonWidth); | |
| 1215 EXPECT_LT(scrollerWidth, NSWidth([folderView frame])); | |
| 1216 | |
| 1217 // Add a wider bookmark and make sure the button widths match. | |
| 1218 int reallyWideButtonNumber = folder->child_count(); | |
| 1219 model.AddURL(folder, reallyWideButtonNumber, | |
| 1220 ASCIIToUTF16("A really, really, really, really, really, " | |
| 1221 "really long name"), | |
| 1222 GURL("http://www.google.com/a")); | |
| 1223 BookmarkButton* bigButton = | |
| 1224 [folderController buttonWithTitleEqualTo: | |
| 1225 @"A really, really, really, really, really, really long name"]; | |
| 1226 EXPECT_TRUE(bigButton); | |
| 1227 CGFloat buttonWidthB = NSWidth([bigButton frame]); | |
| 1228 EXPECT_LT(buttonWidth, buttonWidthB); | |
| 1229 // Add a bunch of bookmarks until the window becomes scrollable, then check | |
| 1230 // for a scroll up arrow. | |
| 1231 NSUInteger tripWire = 0; // Prevent a runaway. | |
| 1232 while (![folderController canScrollUp] && ++tripWire < 1000) { | |
| 1233 model.AddURL(folder, folder->child_count(), ASCIIToUTF16("B"), | |
| 1234 GURL("http://b.com/")); | |
| 1235 } | |
| 1236 EXPECT_TRUE([folderController canScrollUp]); | |
| 1237 | |
| 1238 // Remove one bookmark and make sure the scroll down arrow has been removed. | |
| 1239 // We'll remove the really long node so we can see if the buttons get resized. | |
| 1240 scrollerWidth = NSWidth([folderView frame]); | |
| 1241 buttonWidth = NSWidth([button frame]); | |
| 1242 model.Remove(folder, reallyWideButtonNumber); | |
| 1243 EXPECT_FALSE([folderController canScrollUp]); | |
| 1244 EXPECT_FALSE([folderController canScrollDown]); | |
| 1245 | |
| 1246 // Check the size. It should have reduced. | |
| 1247 EXPECT_GT(scrollerWidth, NSWidth([folderView frame])); | |
| 1248 EXPECT_GT(buttonWidth, NSWidth([button frame])); | |
| 1249 | |
| 1250 // Check button spacing. | |
| 1251 [folderController validateMenuSpacing]; | |
| 1252 } | |
| 1253 | |
| 1254 // See http://crbug.com/46101 | |
| 1255 TEST_F(BookmarkBarFolderControllerMenuTest, HoverThenDeleteBookmark) { | |
| 1256 BookmarkModel& model(*helper_.profile()->GetBookmarkModel()); | |
| 1257 const BookmarkNode* root = model.bookmark_bar_node(); | |
| 1258 const BookmarkNode* folder = model.AddFolder(root, | |
| 1259 root->child_count(), | |
| 1260 ASCIIToUTF16("BIG")); | |
| 1261 for (int i = 0; i < kLotsOfNodesCount; i++) | |
| 1262 model.AddURL(folder, folder->child_count(), ASCIIToUTF16("kid"), | |
| 1263 GURL("http://kid.com/smile")); | |
| 1264 | |
| 1265 // Pop open the new folder window and hover one of its kids. | |
| 1266 BookmarkButton* button = [bar_ buttonWithTitleEqualTo:@"BIG"]; | |
| 1267 [[button target] performSelector:@selector(openBookmarkFolderFromButton:) | |
| 1268 withObject:button]; | |
| 1269 BookmarkBarFolderController* bbfc = [bar_ folderController]; | |
| 1270 NSArray* buttons = [bbfc buttons]; | |
| 1271 | |
| 1272 // Hover over a button and verify that it is now known. | |
| 1273 button = [buttons objectAtIndex:3]; | |
| 1274 BookmarkButton* buttonThatMouseIsIn = [bbfc buttonThatMouseIsIn]; | |
| 1275 EXPECT_FALSE(buttonThatMouseIsIn); | |
| 1276 [bbfc mouseEnteredButton:button event:nil]; | |
| 1277 buttonThatMouseIsIn = [bbfc buttonThatMouseIsIn]; | |
| 1278 EXPECT_EQ(button, buttonThatMouseIsIn); | |
| 1279 | |
| 1280 // Delete the bookmark and verify that it is now not known. | |
| 1281 model.Remove(folder, 3); | |
| 1282 buttonThatMouseIsIn = [bbfc buttonThatMouseIsIn]; | |
| 1283 EXPECT_FALSE(buttonThatMouseIsIn); | |
| 1284 } | |
| 1285 | |
| 1286 // Just like a BookmarkBarFolderController but intercedes when providing | |
| 1287 // pasteboard drag data. | |
| 1288 @interface BookmarkBarFolderControllerDragData : BookmarkBarFolderController { | |
| 1289 const BookmarkNode* dragDataNode_; // Weak | |
| 1290 } | |
| 1291 - (void)setDragDataNode:(const BookmarkNode*)node; | |
| 1292 @end | |
| 1293 | |
| 1294 @implementation BookmarkBarFolderControllerDragData | |
| 1295 | |
| 1296 - (id)initWithParentButton:(BookmarkButton*)button | |
| 1297 parentController:(BookmarkBarFolderController*)parentController | |
| 1298 barController:(BookmarkBarController*)barController { | |
| 1299 if ((self = [super initWithParentButton:button | |
| 1300 parentController:parentController | |
| 1301 barController:barController])) { | |
| 1302 dragDataNode_ = NULL; | |
| 1303 } | |
| 1304 return self; | |
| 1305 } | |
| 1306 | |
| 1307 - (void)setDragDataNode:(const BookmarkNode*)node { | |
| 1308 dragDataNode_ = node; | |
| 1309 } | |
| 1310 | |
| 1311 - (std::vector<const BookmarkNode*>)retrieveBookmarkNodeData { | |
| 1312 std::vector<const BookmarkNode*> dragDataNodes; | |
| 1313 if(dragDataNode_) { | |
| 1314 dragDataNodes.push_back(dragDataNode_); | |
| 1315 } | |
| 1316 return dragDataNodes; | |
| 1317 } | |
| 1318 | |
| 1319 @end | |
| 1320 | |
| 1321 TEST_F(BookmarkBarFolderControllerMenuTest, DragBookmarkData) { | |
| 1322 BookmarkModel& model(*helper_.profile()->GetBookmarkModel()); | |
| 1323 const BookmarkNode* root = model.bookmark_bar_node(); | |
| 1324 const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] " | |
| 1325 "2f3b ] 3b 4b "); | |
| 1326 model_test_utils::AddNodesFromModelString(model, root, model_string); | |
| 1327 const BookmarkNode* other = model.other_node(); | |
| 1328 const std::string other_string("O1b O2b O3f:[ O3f1b O3f2f ] " | |
| 1329 "O4f:[ O4f1b O4f2f ] 05b "); | |
| 1330 model_test_utils::AddNodesFromModelString(model, other, other_string); | |
| 1331 | |
| 1332 // Validate initial model. | |
| 1333 std::string actual = model_test_utils::ModelStringFromNode(root); | |
| 1334 EXPECT_EQ(model_string, actual); | |
| 1335 actual = model_test_utils::ModelStringFromNode(other); | |
| 1336 EXPECT_EQ(other_string, actual); | |
| 1337 | |
| 1338 // Pop open a folder. | |
| 1339 BookmarkButton* button = [bar_ buttonWithTitleEqualTo:@"2f"]; | |
| 1340 scoped_nsobject<BookmarkBarFolderControllerDragData> folderController; | |
| 1341 folderController.reset([[BookmarkBarFolderControllerDragData alloc] | |
| 1342 initWithParentButton:button | |
| 1343 parentController:nil | |
| 1344 barController:bar_]); | |
| 1345 BookmarkButton* targetButton = | |
| 1346 [folderController buttonWithTitleEqualTo:@"2f1b"]; | |
| 1347 ASSERT_TRUE(targetButton); | |
| 1348 | |
| 1349 // Gen up some dragging data. | |
| 1350 const BookmarkNode* newNode = other->GetChild(2); | |
| 1351 [folderController setDragDataNode:newNode]; | |
| 1352 scoped_nsobject<FakedDragInfo> dragInfo([[FakedDragInfo alloc] init]); | |
| 1353 [dragInfo setDropLocation:[targetButton top]]; | |
| 1354 [folderController dragBookmarkData:(id<NSDraggingInfo>)dragInfo.get()]; | |
| 1355 | |
| 1356 // Verify the model. | |
| 1357 const std::string expected("1b 2f:[ O3f:[ O3f1b O3f2f ] 2f1b 2f2f:[ 2f2f1b " | |
| 1358 "2f2f2b 2f2f3b ] 2f3b ] 3b 4b "); | |
| 1359 actual = model_test_utils::ModelStringFromNode(root); | |
| 1360 EXPECT_EQ(expected, actual); | |
| 1361 | |
| 1362 // Now drag over a folder button. | |
| 1363 targetButton = [folderController buttonWithTitleEqualTo:@"2f2f"]; | |
| 1364 ASSERT_TRUE(targetButton); | |
| 1365 newNode = other->GetChild(2); // Should be O4f. | |
| 1366 EXPECT_EQ(newNode->GetTitle(), ASCIIToUTF16("O4f")); | |
| 1367 [folderController setDragDataNode:newNode]; | |
| 1368 [dragInfo setDropLocation:[targetButton center]]; | |
| 1369 [folderController dragBookmarkData:(id<NSDraggingInfo>)dragInfo.get()]; | |
| 1370 | |
| 1371 // Verify the model. | |
| 1372 const std::string expectedA("1b 2f:[ O3f:[ O3f1b O3f2f ] 2f1b 2f2f:[ " | |
| 1373 "2f2f1b 2f2f2b 2f2f3b O4f:[ O4f1b O4f2f ] ] " | |
| 1374 "2f3b ] 3b 4b "); | |
| 1375 actual = model_test_utils::ModelStringFromNode(root); | |
| 1376 EXPECT_EQ(expectedA, actual); | |
| 1377 | |
| 1378 // Check button spacing. | |
| 1379 [folderController validateMenuSpacing]; | |
| 1380 } | |
| 1381 | |
| 1382 TEST_F(BookmarkBarFolderControllerMenuTest, DragBookmarkDataToTrash) { | |
| 1383 BookmarkModel& model(*helper_.profile()->GetBookmarkModel()); | |
| 1384 const BookmarkNode* root = model.bookmark_bar_node(); | |
| 1385 const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] " | |
| 1386 "2f3b ] 3b 4b "); | |
| 1387 model_test_utils::AddNodesFromModelString(model, root, model_string); | |
| 1388 | |
| 1389 // Validate initial model. | |
| 1390 std::string actual = model_test_utils::ModelStringFromNode(root); | |
| 1391 EXPECT_EQ(model_string, actual); | |
| 1392 | |
| 1393 const BookmarkNode* folderNode = root->GetChild(1); | |
| 1394 int oldFolderChildCount = folderNode->child_count(); | |
| 1395 | |
| 1396 // Pop open a folder. | |
| 1397 BookmarkButton* button = [bar_ buttonWithTitleEqualTo:@"2f"]; | |
| 1398 scoped_nsobject<BookmarkBarFolderControllerDragData> folderController; | |
| 1399 folderController.reset([[BookmarkBarFolderControllerDragData alloc] | |
| 1400 initWithParentButton:button | |
| 1401 parentController:nil | |
| 1402 barController:bar_]); | |
| 1403 | |
| 1404 // Drag a button to the trash. | |
| 1405 BookmarkButton* buttonToDelete = | |
| 1406 [folderController buttonWithTitleEqualTo:@"2f1b"]; | |
| 1407 ASSERT_TRUE(buttonToDelete); | |
| 1408 EXPECT_TRUE([folderController canDragBookmarkButtonToTrash:buttonToDelete]); | |
| 1409 [folderController didDragBookmarkToTrash:buttonToDelete]; | |
| 1410 | |
| 1411 // There should be one less button in the folder. | |
| 1412 int newFolderChildCount = folderNode->child_count(); | |
| 1413 EXPECT_EQ(oldFolderChildCount - 1, newFolderChildCount); | |
| 1414 // Verify the model. | |
| 1415 const std::string expected("1b 2f:[ 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] " | |
| 1416 "2f3b ] 3b 4b "); | |
| 1417 actual = model_test_utils::ModelStringFromNode(root); | |
| 1418 EXPECT_EQ(expected, actual); | |
| 1419 | |
| 1420 // Check button spacing. | |
| 1421 [folderController validateMenuSpacing]; | |
| 1422 } | |
| 1423 | |
| 1424 TEST_F(BookmarkBarFolderControllerMenuTest, AddURLs) { | |
| 1425 BookmarkModel& model(*helper_.profile()->GetBookmarkModel()); | |
| 1426 const BookmarkNode* root = model.bookmark_bar_node(); | |
| 1427 const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] " | |
| 1428 "2f3b ] 3b 4b "); | |
| 1429 model_test_utils::AddNodesFromModelString(model, root, model_string); | |
| 1430 | |
| 1431 // Validate initial model. | |
| 1432 std::string actual = model_test_utils::ModelStringFromNode(root); | |
| 1433 EXPECT_EQ(model_string, actual); | |
| 1434 | |
| 1435 // Pop open a folder. | |
| 1436 BookmarkButton* button = [bar_ buttonWithTitleEqualTo:@"2f"]; | |
| 1437 [[button target] performSelector:@selector(openBookmarkFolderFromButton:) | |
| 1438 withObject:button]; | |
| 1439 BookmarkBarFolderController* folderController = [bar_ folderController]; | |
| 1440 EXPECT_TRUE(folderController); | |
| 1441 NSArray* buttons = [folderController buttons]; | |
| 1442 EXPECT_TRUE(buttons); | |
| 1443 | |
| 1444 // Remember how many buttons are showing. | |
| 1445 int oldDisplayedButtons = [buttons count]; | |
| 1446 | |
| 1447 BookmarkButton* targetButton = | |
| 1448 [folderController buttonWithTitleEqualTo:@"2f1b"]; | |
| 1449 ASSERT_TRUE(targetButton); | |
| 1450 | |
| 1451 NSArray* urls = [NSArray arrayWithObjects: @"http://www.a.com/", | |
| 1452 @"http://www.b.com/", nil]; | |
| 1453 NSArray* titles = [NSArray arrayWithObjects: @"SiteA", @"SiteB", nil]; | |
| 1454 [folderController addURLs:urls withTitles:titles at:[targetButton top]]; | |
| 1455 | |
| 1456 // There should two more buttons in the folder. | |
| 1457 int newDisplayedButtons = [buttons count]; | |
| 1458 EXPECT_EQ(oldDisplayedButtons + 2, newDisplayedButtons); | |
| 1459 // Verify the model. | |
| 1460 const std::string expected("1b 2f:[ SiteA SiteB 2f1b 2f2f:[ 2f2f1b 2f2f2b " | |
| 1461 "2f2f3b ] 2f3b ] 3b 4b "); | |
| 1462 actual = model_test_utils::ModelStringFromNode(root); | |
| 1463 EXPECT_EQ(expected, actual); | |
| 1464 | |
| 1465 // Check button spacing. | |
| 1466 [folderController validateMenuSpacing]; | |
| 1467 } | |
| 1468 | |
| 1469 TEST_F(BookmarkBarFolderControllerMenuTest, DropPositionIndicator) { | |
| 1470 BookmarkModel& model(*helper_.profile()->GetBookmarkModel()); | |
| 1471 const BookmarkNode* root = model.bookmark_bar_node(); | |
| 1472 const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b 2f2f3b ] " | |
| 1473 "2f3b ] 3b 4b "); | |
| 1474 model_test_utils::AddNodesFromModelString(model, root, model_string); | |
| 1475 | |
| 1476 // Validate initial model. | |
| 1477 std::string actual = model_test_utils::ModelStringFromNode(root); | |
| 1478 EXPECT_EQ(model_string, actual); | |
| 1479 | |
| 1480 // Pop open the folder. | |
| 1481 BookmarkButton* button = [bar_ buttonWithTitleEqualTo:@"2f"]; | |
| 1482 [[button target] performSelector:@selector(openBookmarkFolderFromButton:) | |
| 1483 withObject:button]; | |
| 1484 BookmarkBarFolderController* folder = [bar_ folderController]; | |
| 1485 EXPECT_TRUE(folder); | |
| 1486 | |
| 1487 // Test a series of points starting at the top of the folder. | |
| 1488 const CGFloat yOffset = 0.5 * bookmarks::kBookmarkVerticalPadding; | |
| 1489 BookmarkButton* targetButton = [folder buttonWithTitleEqualTo:@"2f1b"]; | |
| 1490 ASSERT_TRUE(targetButton); | |
| 1491 NSPoint targetPoint = [targetButton top]; | |
| 1492 CGFloat pos = [folder indicatorPosForDragToPoint:targetPoint]; | |
| 1493 EXPECT_CGFLOAT_EQ(targetPoint.y + yOffset, pos); | |
| 1494 pos = [folder indicatorPosForDragToPoint:[targetButton bottom]]; | |
| 1495 targetButton = [folder buttonWithTitleEqualTo:@"2f2f"]; | |
| 1496 EXPECT_CGFLOAT_EQ([targetButton top].y + yOffset, pos); | |
| 1497 pos = [folder indicatorPosForDragToPoint:NSMakePoint(10,0)]; | |
| 1498 targetButton = [folder buttonWithTitleEqualTo:@"2f3b"]; | |
| 1499 EXPECT_CGFLOAT_EQ([targetButton bottom].y - yOffset, pos); | |
| 1500 } | |
| 1501 | |
| 1502 @interface BookmarkBarControllerNoDelete : BookmarkBarController | |
| 1503 - (IBAction)deleteBookmark:(id)sender; | |
| 1504 @end | |
| 1505 | |
| 1506 @implementation BookmarkBarControllerNoDelete | |
| 1507 - (IBAction)deleteBookmark:(id)sender { | |
| 1508 // NOP | |
| 1509 } | |
| 1510 @end | |
| 1511 | |
| 1512 class BookmarkBarFolderControllerClosingTest : public | |
| 1513 BookmarkBarFolderControllerMenuTest { | |
| 1514 public: | |
| 1515 BookmarkBarFolderControllerClosingTest() { | |
| 1516 bar_.reset([[BookmarkBarControllerNoDelete alloc] | |
| 1517 initWithBrowser:helper_.browser() | |
| 1518 initialWidth:NSWidth([parent_view_ frame]) | |
| 1519 delegate:nil | |
| 1520 resizeDelegate:resizeDelegate_.get()]); | |
| 1521 InstallAndToggleBar(bar_.get()); | |
| 1522 } | |
| 1523 }; | |
| 1524 | |
| 1525 TEST_F(BookmarkBarFolderControllerClosingTest, DeleteClosesFolder) { | |
| 1526 BookmarkModel& model(*helper_.profile()->GetBookmarkModel()); | |
| 1527 const BookmarkNode* root = model.bookmark_bar_node(); | |
| 1528 const std::string model_string("1b 2f:[ 2f1b 2f2f:[ 2f2f1b 2f2f2b ] " | |
| 1529 "2f3b ] 3b "); | |
| 1530 model_test_utils::AddNodesFromModelString(model, root, model_string); | |
| 1531 | |
| 1532 // Validate initial model. | |
| 1533 std::string actualModelString = model_test_utils::ModelStringFromNode(root); | |
| 1534 EXPECT_EQ(model_string, actualModelString); | |
| 1535 | |
| 1536 // Open the folder menu and submenu. | |
| 1537 BookmarkButton* target = [bar_ buttonWithTitleEqualTo:@"2f"]; | |
| 1538 ASSERT_TRUE(target); | |
| 1539 [[target target] performSelector:@selector(openBookmarkFolderFromButton:) | |
| 1540 withObject:target]; | |
| 1541 BookmarkBarFolderController* folder = [bar_ folderController]; | |
| 1542 EXPECT_TRUE(folder); | |
| 1543 BookmarkButton* subTarget = [folder buttonWithTitleEqualTo:@"2f2f"]; | |
| 1544 ASSERT_TRUE(subTarget); | |
| 1545 [[subTarget target] performSelector:@selector(openBookmarkFolderFromButton:) | |
| 1546 withObject:subTarget]; | |
| 1547 BookmarkBarFolderController* subFolder = [folder folderController]; | |
| 1548 EXPECT_TRUE(subFolder); | |
| 1549 | |
| 1550 // Delete the folder node and verify the window closed down by looking | |
| 1551 // for its controller again. | |
| 1552 [folder deleteBookmark:folder]; | |
| 1553 EXPECT_FALSE([folder folderController]); | |
| 1554 } | |
| 1555 | |
| 1556 // TODO(jrg): draggingEntered: and draggingExited: trigger timers so | |
| 1557 // they are hard to test. Factor out "fire timers" into routines | |
| 1558 // which can be overridden to fire immediately to make behavior | |
| 1559 // confirmable. | |
| 1560 // There is a similar problem with mouseEnteredButton: and | |
| 1561 // mouseExitedButton:. | |
| OLD | NEW |