| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/scoped_nsobject.h" | 8 #include "base/scoped_nsobject.h" |
| 9 #import "chrome/browser/cocoa/bookmark_bar_controller.h" | 9 #import "chrome/browser/cocoa/bookmark_bar_controller.h" |
| 10 #include "chrome/browser/cocoa/browser_test_helper.h" | 10 #include "chrome/browser/cocoa/browser_test_helper.h" |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 | 47 |
| 48 - (id)initTextCell:(NSString*)string desiredSize:(NSSize)size { | 48 - (id)initTextCell:(NSString*)string desiredSize:(NSSize)size { |
| 49 if ((self = [super initTextCell:string])) { | 49 if ((self = [super initTextCell:string])) { |
| 50 cellSize_ = size; | 50 cellSize_ = size; |
| 51 } | 51 } |
| 52 return self; | 52 return self; |
| 53 } | 53 } |
| 54 | 54 |
| 55 @end | 55 @end |
| 56 | 56 |
| 57 // Remember the number of times we've gotten a frameDidChange notification. |
| 58 @interface BookmarkBarControllerTogglePong : BookmarkBarController { |
| 59 @private |
| 60 int toggles_; |
| 61 } |
| 62 @property (readonly) int toggles; |
| 63 @end |
| 64 |
| 65 @implementation BookmarkBarControllerTogglePong |
| 66 |
| 67 @synthesize toggles = toggles_; |
| 68 |
| 69 - (void)frameDidChange { |
| 70 toggles_++; |
| 71 } |
| 72 |
| 73 @end |
| 74 |
| 57 | 75 |
| 58 namespace { | 76 namespace { |
| 59 | 77 |
| 60 static const int kContentAreaHeight = 500; | 78 static const int kContentAreaHeight = 500; |
| 61 static const int kInfoBarViewHeight = 30; | 79 static const int kInfoBarViewHeight = 30; |
| 62 | 80 |
| 63 class BookmarkBarControllerTest : public testing::Test { | 81 class BookmarkBarControllerTest : public testing::Test { |
| 64 public: | 82 public: |
| 65 BookmarkBarControllerTest() { | 83 BookmarkBarControllerTest() { |
| 66 NSRect content_frame = NSMakeRect(0, 0, 800, kContentAreaHeight); | 84 NSRect content_frame = NSMakeRect(0, 0, 800, kContentAreaHeight); |
| 67 // |infobar_frame| is set to be directly above |content_frame|. | 85 // |infobar_frame| is set to be directly above |content_frame|. |
| 68 NSRect infobar_frame = NSMakeRect(0, kContentAreaHeight, | 86 NSRect infobar_frame = NSMakeRect(0, kContentAreaHeight, |
| 69 800, kInfoBarViewHeight); | 87 800, kInfoBarViewHeight); |
| 70 NSRect parent_frame = NSMakeRect(0, 0, 800, 50); | 88 NSRect parent_frame = NSMakeRect(0, 0, 800, 50); |
| 71 content_area_.reset([[NSView alloc] initWithFrame:content_frame]); | 89 content_area_.reset([[NSView alloc] initWithFrame:content_frame]); |
| 72 infobar_view_.reset([[NSView alloc] initWithFrame:infobar_frame]); | 90 infobar_view_.reset([[NSView alloc] initWithFrame:infobar_frame]); |
| 73 parent_view_.reset([[NSView alloc] initWithFrame:parent_frame]); | 91 parent_view_.reset([[NSView alloc] initWithFrame:parent_frame]); |
| 74 [parent_view_ setHidden:YES]; | 92 [parent_view_ setHidden:YES]; |
| 75 bar_.reset( | 93 bar_.reset( |
| 76 [[BookmarkBarController alloc] initWithProfile:helper_.profile() | 94 [[BookmarkBarController alloc] initWithProfile:helper_.profile() |
| 77 parentView:parent_view_.get() | 95 parentView:parent_view_.get() |
| 78 webContentView:content_area_.get() | 96 webContentView:content_area_.get() |
| 79 infoBarsView:infobar_view_.get() | 97 infoBarsView:infobar_view_.get() |
| 80 delegate:nil]); | 98 delegate:nil]); |
| 81 [bar_ view]; // force loading of the nib | |
| 82 | 99 |
| 83 // Awkwardness to look like we've been installed. | 100 InstallAndToggleBar(bar_.get()); |
| 84 [parent_view_ addSubview:[bar_ view]]; | |
| 85 NSRect frame = [[[bar_ view] superview] frame]; | |
| 86 frame.origin.y = 100; | |
| 87 [[[bar_ view] superview] setFrame:frame]; | |
| 88 | |
| 89 // make sure it's open so certain things aren't no-ops | |
| 90 [bar_ toggleBookmarkBar]; | |
| 91 | 101 |
| 92 // Create a menu/item to act like a sender | 102 // Create a menu/item to act like a sender |
| 93 menu_.reset([[NSMenu alloc] initWithTitle:@"I_dont_care"]); | 103 menu_.reset([[NSMenu alloc] initWithTitle:@"I_dont_care"]); |
| 94 menu_item_.reset([[NSMenuItem alloc] | 104 menu_item_.reset([[NSMenuItem alloc] |
| 95 initWithTitle:@"still_dont_care" | 105 initWithTitle:@"still_dont_care" |
| 96 action:NULL | 106 action:NULL |
| 97 keyEquivalent:@""]); | 107 keyEquivalent:@""]); |
| 98 cell_.reset([[NSButtonCell alloc] init]); | 108 cell_.reset([[NSButtonCell alloc] init]); |
| 99 [menu_item_ setMenu:menu_.get()]; | 109 [menu_item_ setMenu:menu_.get()]; |
| 100 [menu_ setDelegate:cell_.get()]; | 110 [menu_ setDelegate:cell_.get()]; |
| 101 } | 111 } |
| 102 | 112 |
| 113 void InstallAndToggleBar(BookmarkBarController* bar) { |
| 114 // Force loading of the nib. |
| 115 [bar view]; |
| 116 // Awkwardness to look like we've been installed. |
| 117 [parent_view_ addSubview:[bar view]]; |
| 118 NSRect frame = [[[bar view] superview] frame]; |
| 119 frame.origin.y = 100; |
| 120 [[[bar view] superview] setFrame:frame]; |
| 121 |
| 122 // make sure it's open so certain things aren't no-ops |
| 123 [bar toggleBookmarkBar]; |
| 124 } |
| 125 |
| 126 |
| 103 // Return a menu item that points to the right URL. | 127 // Return a menu item that points to the right URL. |
| 104 NSMenuItem* ItemForBookmarkBarMenu(GURL& gurl) { | 128 NSMenuItem* ItemForBookmarkBarMenu(GURL& gurl) { |
| 105 node_.reset(new BookmarkNode(gurl)); | 129 node_.reset(new BookmarkNode(gurl)); |
| 106 [cell_ setRepresentedObject:[NSValue valueWithPointer:node_.get()]]; | 130 [cell_ setRepresentedObject:[NSValue valueWithPointer:node_.get()]]; |
| 107 return menu_item_; | 131 return menu_item_; |
| 108 } | 132 } |
| 109 | 133 |
| 110 // Does NOT take ownership of node. | 134 // Does NOT take ownership of node. |
| 111 NSMenuItem* ItemForBookmarkBarMenu(const BookmarkNode* node) { | 135 NSMenuItem* ItemForBookmarkBarMenu(const BookmarkNode* node) { |
| 112 [cell_ setRepresentedObject:[NSValue valueWithPointer:node]]; | 136 [cell_ setRepresentedObject:[NSValue valueWithPointer:node]]; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 EXPECT_FALSE([bar_ isBookmarkBarVisible]); | 175 EXPECT_FALSE([bar_ isBookmarkBarVisible]); |
| 152 EXPECT_TRUE([[bar_ view] isHidden]); | 176 EXPECT_TRUE([[bar_ view] isHidden]); |
| 153 content_frame = [content_area_ frame]; | 177 content_frame = [content_area_ frame]; |
| 154 infobar_frame = [infobar_view_ frame]; | 178 infobar_frame = [infobar_view_ frame]; |
| 155 EXPECT_EQ(content_frame.size.height, kContentAreaHeight); | 179 EXPECT_EQ(content_frame.size.height, kContentAreaHeight); |
| 156 EXPECT_EQ(NSMaxY(content_frame), NSMinY(infobar_frame)); | 180 EXPECT_EQ(NSMaxY(content_frame), NSMinY(infobar_frame)); |
| 157 EXPECT_EQ(kInfoBarViewHeight, infobar_frame.size.height); | 181 EXPECT_EQ(kInfoBarViewHeight, infobar_frame.size.height); |
| 158 EXPECT_EQ([[bar_ view] frame].size.height, 0); | 182 EXPECT_EQ([[bar_ view] frame].size.height, 0); |
| 159 } | 183 } |
| 160 | 184 |
| 185 // Make sure we're watching for frame change notifications. |
| 186 TEST_F(BookmarkBarControllerTest, FrameChangeNotification) { |
| 187 scoped_nsobject<BookmarkBarControllerTogglePong> bar; |
| 188 bar.reset( |
| 189 [[BookmarkBarControllerTogglePong alloc] |
| 190 initWithProfile:helper_.profile() |
| 191 parentView:parent_view_.get() |
| 192 webContentView:content_area_.get() |
| 193 infoBarsView:infobar_view_.get() |
| 194 delegate:nil]); |
| 195 InstallAndToggleBar(bar.get()); |
| 196 |
| 197 EXPECT_GT([bar toggles], 0); |
| 198 |
| 199 // Hard to force toggles -- simple whacking the frame is inadequate. |
| 200 // TODO(jrg): find a way to set frame, force a toggle, and verify it. |
| 201 } |
| 202 |
| 203 // Confirm off the side button only enabled when reasonable. |
| 204 TEST_F(BookmarkBarControllerTest, OffTheSideButtonEnable) { |
| 205 BookmarkModel* model = helper_.profile()->GetBookmarkModel(); |
| 206 |
| 207 [bar_ loaded:model]; |
| 208 EXPECT_FALSE([bar_ offTheSideButtonIsEnabled]); |
| 209 |
| 210 for (int i = 0; i < 2; i++) { |
| 211 model->SetURLStarred(GURL("http://www.foo.com"), L"small", true); |
| 212 EXPECT_FALSE([bar_ offTheSideButtonIsEnabled]); |
| 213 } |
| 214 |
| 215 for (int i = 0; i < 20; i++) { |
| 216 const BookmarkNode* parent = model->GetBookmarkBarNode(); |
| 217 model->AddURL(parent, parent->GetChildCount(), |
| 218 L"super duper wide title", |
| 219 GURL("http://superfriends.hall-of-justice.edu")); |
| 220 } |
| 221 EXPECT_TRUE([bar_ offTheSideButtonIsEnabled]); |
| 222 } |
| 223 |
| 224 TEST_F(BookmarkBarControllerTest, TagMap) { |
| 225 int64 ids[] = { 1, 3, 4, 40, 400, 4000, 800000000, 2, 123456789 }; |
| 226 std::vector<int32> tags; |
| 227 |
| 228 // Generate some tags |
| 229 for (unsigned int i = 0; i < arraysize(ids); i++) { |
| 230 tags.push_back([bar_ menuTagFromNodeId:ids[i]]); |
| 231 } |
| 232 |
| 233 // Confirm reverse mapping. |
| 234 for (unsigned int i = 0; i < arraysize(ids); i++) { |
| 235 EXPECT_EQ(ids[i], [bar_ nodeIdFromMenuTag:tags[i]]); |
| 236 } |
| 237 |
| 238 // Confirm uniqueness. |
| 239 std::sort(tags.begin(), tags.end()); |
| 240 for (unsigned int i=0; i<(tags.size()-1); i++) { |
| 241 EXPECT_NE(tags[i], tags[i+1]); |
| 242 } |
| 243 } |
| 244 |
| 245 TEST_F(BookmarkBarControllerTest, MenuForFolderNode) { |
| 246 BookmarkModel* model = helper_.profile()->GetBookmarkModel(); |
| 247 |
| 248 // First make sure something (e.g. "(empty)" string) is always present. |
| 249 NSMenu* menu = [bar_ menuForFolderNode:model->GetBookmarkBarNode()]; |
| 250 EXPECT_GT([menu numberOfItems], 0); |
| 251 |
| 252 // Test two bookmarks. |
| 253 GURL gurl("http://www.foo.com"); |
| 254 model->SetURLStarred(gurl, L"small", true); |
| 255 model->SetURLStarred(GURL("http://www.cnn.com"), L"bigger title", true); |
| 256 menu = [bar_ menuForFolderNode:model->GetBookmarkBarNode()]; |
| 257 EXPECT_EQ([menu numberOfItems], 2); |
| 258 NSMenuItem *item = [menu itemWithTitle:@"bigger title"]; |
| 259 EXPECT_TRUE(item); |
| 260 item = [menu itemWithTitle:@"small"]; |
| 261 EXPECT_TRUE(item); |
| 262 if (item) { |
| 263 int64 tag = [bar_ nodeIdFromMenuTag:[item tag]]; |
| 264 const BookmarkNode* node = model->GetNodeByID(tag); |
| 265 EXPECT_TRUE(node); |
| 266 EXPECT_EQ(gurl, node->GetURL()); |
| 267 } |
| 268 |
| 269 // Test with an actual folder as well |
| 270 const BookmarkNode* parent = model->GetBookmarkBarNode(); |
| 271 const BookmarkNode* folder = model->AddGroup(parent, |
| 272 parent->GetChildCount(), |
| 273 L"group"); |
| 274 model->AddURL(folder, folder->GetChildCount(), |
| 275 L"f1", GURL("http://framma-lamma.com")); |
| 276 model->AddURL(folder, folder->GetChildCount(), |
| 277 L"f2", GURL("http://framma-lamma-ding-dong.com")); |
| 278 menu = [bar_ menuForFolderNode:model->GetBookmarkBarNode()]; |
| 279 EXPECT_EQ([menu numberOfItems], 3); |
| 280 |
| 281 item = [menu itemWithTitle:@"group"]; |
| 282 EXPECT_TRUE(item); |
| 283 EXPECT_TRUE([item hasSubmenu]); |
| 284 NSMenu *submenu = [item submenu]; |
| 285 EXPECT_TRUE(submenu); |
| 286 EXPECT_EQ(2, [submenu numberOfItems]); |
| 287 EXPECT_TRUE([submenu itemWithTitle:@"f1"]); |
| 288 EXPECT_TRUE([submenu itemWithTitle:@"f2"]); |
| 289 } |
| 290 |
| 161 // Confirm openBookmark: forwards the request to the controller's delegate | 291 // Confirm openBookmark: forwards the request to the controller's delegate |
| 162 TEST_F(BookmarkBarControllerTest, OpenBookmark) { | 292 TEST_F(BookmarkBarControllerTest, OpenBookmark) { |
| 163 GURL gurl("http://walla.walla.ding.dong.com"); | 293 GURL gurl("http://walla.walla.ding.dong.com"); |
| 164 scoped_ptr<BookmarkNode> node(new BookmarkNode(gurl)); | 294 scoped_ptr<BookmarkNode> node(new BookmarkNode(gurl)); |
| 165 scoped_nsobject<BookmarkURLOpenerPong> pong([[BookmarkURLOpenerPong alloc] | 295 scoped_nsobject<BookmarkURLOpenerPong> pong([[BookmarkURLOpenerPong alloc] |
| 166 init]); | 296 init]); |
| 167 [bar_ setDelegate:pong.get()]; | 297 [bar_ setDelegate:pong.get()]; |
| 168 | 298 |
| 169 scoped_nsobject<NSButtonCell> cell([[NSButtonCell alloc] init]); | 299 scoped_nsobject<NSButtonCell> cell([[NSButtonCell alloc] init]); |
| 170 scoped_nsobject<NSButton> button([[NSButton alloc] init]); | 300 scoped_nsobject<NSButton> button([[NSButton alloc] init]); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 withObject:ItemForBookmarkBarMenu(gurl)]; | 332 withObject:ItemForBookmarkBarMenu(gurl)]; |
| 203 EXPECT_EQ(pong.get()->urls_[0], gurl); | 333 EXPECT_EQ(pong.get()->urls_[0], gurl); |
| 204 EXPECT_EQ(pong.get()->dispositions_[0], dispositions[i]); | 334 EXPECT_EQ(pong.get()->dispositions_[0], dispositions[i]); |
| 205 [pong clear]; | 335 [pong clear]; |
| 206 } | 336 } |
| 207 [bar_ setDelegate:nil]; | 337 [bar_ setDelegate:nil]; |
| 208 } | 338 } |
| 209 | 339 |
| 210 TEST_F(BookmarkBarControllerTest, TestAddRemoveAndClear) { | 340 TEST_F(BookmarkBarControllerTest, TestAddRemoveAndClear) { |
| 211 BookmarkModel* model = helper_.profile()->GetBookmarkModel(); | 341 BookmarkModel* model = helper_.profile()->GetBookmarkModel(); |
| 212 | 342 NSView* buttonView = [bar_ buttonView]; |
| 213 EXPECT_EQ(0U, [[bar_ buttons] count]); | 343 EXPECT_EQ(0U, [[bar_ buttons] count]); |
| 214 unsigned int initial_subview_count = [[[bar_ view] subviews] count]; | 344 unsigned int initial_subview_count = [[buttonView subviews] count]; |
| 215 | 345 |
| 216 // Make sure a redundant call doesn't choke | 346 // Make sure a redundant call doesn't choke |
| 217 [bar_ clearBookmarkBar]; | 347 [bar_ clearBookmarkBar]; |
| 218 EXPECT_EQ(0U, [[bar_ buttons] count]); | 348 EXPECT_EQ(0U, [[bar_ buttons] count]); |
| 219 EXPECT_EQ(initial_subview_count, [[[bar_ view] subviews] count]); | 349 EXPECT_EQ(initial_subview_count, [[buttonView subviews] count]); |
| 220 | 350 |
| 221 GURL gurl1("http://superfriends.hall-of-justice.edu"); | 351 GURL gurl1("http://superfriends.hall-of-justice.edu"); |
| 222 std::wstring title1(L"Protectors of the Universe"); | 352 std::wstring title1(L"Protectors of the Universe"); |
| 223 model->SetURLStarred(gurl1, title1, true); | 353 model->SetURLStarred(gurl1, title1, true); |
| 224 EXPECT_EQ(1U, [[bar_ buttons] count]); | 354 EXPECT_EQ(1U, [[bar_ buttons] count]); |
| 225 EXPECT_EQ(1+initial_subview_count, [[[bar_ view] subviews] count]); | 355 EXPECT_EQ(1+initial_subview_count, [[buttonView subviews] count]); |
| 226 | 356 |
| 227 GURL gurl2("http://legion-of-doom.gov"); | 357 GURL gurl2("http://legion-of-doom.gov"); |
| 228 std::wstring title2(L"Bad doodz"); | 358 std::wstring title2(L"Bad doodz"); |
| 229 model->SetURLStarred(gurl2, title2, true); | 359 model->SetURLStarred(gurl2, title2, true); |
| 230 EXPECT_EQ(2U, [[bar_ buttons] count]); | 360 EXPECT_EQ(2U, [[bar_ buttons] count]); |
| 231 EXPECT_EQ(2+initial_subview_count, [[[bar_ view] subviews] count]); | 361 EXPECT_EQ(2+initial_subview_count, [[buttonView subviews] count]); |
| 232 | 362 |
| 233 for (int i = 0; i < 3; i++) { | 363 for (int i = 0; i < 3; i++) { |
| 234 // is_starred=false --> remove the bookmark | 364 // is_starred=false --> remove the bookmark |
| 235 model->SetURLStarred(gurl2, title2, false); | 365 model->SetURLStarred(gurl2, title2, false); |
| 236 EXPECT_EQ(1U, [[bar_ buttons] count]); | 366 EXPECT_EQ(1U, [[bar_ buttons] count]); |
| 237 EXPECT_EQ(1+initial_subview_count, [[[bar_ view] subviews] count]); | 367 EXPECT_EQ(1+initial_subview_count, [[buttonView subviews] count]); |
| 238 | 368 |
| 239 // and bring it back | 369 // and bring it back |
| 240 model->SetURLStarred(gurl2, title2, true); | 370 model->SetURLStarred(gurl2, title2, true); |
| 241 EXPECT_EQ(2U, [[bar_ buttons] count]); | 371 EXPECT_EQ(2U, [[bar_ buttons] count]); |
| 242 EXPECT_EQ(2+initial_subview_count, [[[bar_ view] subviews] count]); | 372 EXPECT_EQ(2+initial_subview_count, [[buttonView subviews] count]); |
| 243 } | 373 } |
| 244 | 374 |
| 245 [bar_ clearBookmarkBar]; | 375 [bar_ clearBookmarkBar]; |
| 246 EXPECT_EQ(0U, [[bar_ buttons] count]); | 376 EXPECT_EQ(0U, [[bar_ buttons] count]); |
| 247 EXPECT_EQ(initial_subview_count, [[[bar_ view] subviews] count]); | 377 EXPECT_EQ(initial_subview_count, [[buttonView subviews] count]); |
| 248 | 378 |
| 249 // Explicit test of loaded: since this is a convenient spot | 379 // Explicit test of loaded: since this is a convenient spot |
| 250 [bar_ loaded:model]; | 380 [bar_ loaded:model]; |
| 251 EXPECT_EQ(2U, [[bar_ buttons] count]); | 381 EXPECT_EQ(2U, [[bar_ buttons] count]); |
| 252 EXPECT_EQ(2+initial_subview_count, [[[bar_ view] subviews] count]); | 382 EXPECT_EQ(2+initial_subview_count, [[buttonView subviews] count]); |
| 253 } | 383 } |
| 254 | 384 |
| 255 // Make sure that each button we add marches to the right and does not | 385 // Make sure that each button we add marches to the right and does not |
| 256 // overlap with the previous one. | 386 // overlap with the previous one. |
| 257 TEST_F(BookmarkBarControllerTest, TestButtonMarch) { | 387 TEST_F(BookmarkBarControllerTest, TestButtonMarch) { |
| 258 scoped_nsobject<NSMutableArray> cells([[NSMutableArray alloc] init]); | 388 scoped_nsobject<NSMutableArray> cells([[NSMutableArray alloc] init]); |
| 259 | 389 |
| 260 CGFloat widths[] = { 10, 10, 100, 10, 500, 500, 80000, 60000, 1, 345 }; | 390 CGFloat widths[] = { 10, 10, 100, 10, 500, 500, 80000, 60000, 1, 345 }; |
| 261 for (unsigned int i = 0; i < arraysize(widths); i++) { | 391 for (unsigned int i = 0; i < arraysize(widths); i++) { |
| 262 NSCell* cell = [[CellWithDesiredSize alloc] | 392 NSCell* cell = [[CellWithDesiredSize alloc] |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 TEST_F(BookmarkBarControllerTest, Display) { | 517 TEST_F(BookmarkBarControllerTest, Display) { |
| 388 [[bar_ view] display]; | 518 [[bar_ view] display]; |
| 389 } | 519 } |
| 390 | 520 |
| 391 // Cannot test these methods since they simply call a single static | 521 // Cannot test these methods since they simply call a single static |
| 392 // method, BookmarkEditor::Show(), which is impossible to mock. | 522 // method, BookmarkEditor::Show(), which is impossible to mock. |
| 393 // editBookmark:, addPage: | 523 // editBookmark:, addPage: |
| 394 | 524 |
| 395 | 525 |
| 396 } // namespace | 526 } // namespace |
| OLD | NEW |