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