| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "app/menus/simple_menu_model.h" | 7 #include "app/menus/simple_menu_model.h" |
| 8 #include "app/resource_bundle.h" |
| 8 #include "base/sys_string_conversions.h" | 9 #include "base/sys_string_conversions.h" |
| 9 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
| 10 #include "chrome/browser/ui/cocoa/cocoa_test_helper.h" | 11 #include "chrome/browser/ui/cocoa/cocoa_test_helper.h" |
| 11 #include "chrome/browser/ui/cocoa/menu_controller.h" | 12 #include "chrome/browser/ui/cocoa/menu_controller.h" |
| 13 #include "grit/app_resources.h" |
| 12 #include "grit/generated_resources.h" | 14 #include "grit/generated_resources.h" |
| 15 #include "third_party/skia/include/core/SkBitmap.h" |
| 13 | 16 |
| 14 class MenuControllerTest : public CocoaTest { | 17 class MenuControllerTest : public CocoaTest { |
| 15 }; | 18 }; |
| 16 | 19 |
| 17 // A menu delegate that counts the number of times certain things are called | 20 // A menu delegate that counts the number of times certain things are called |
| 18 // to make sure things are hooked up properly. | 21 // to make sure things are hooked up properly. |
| 19 class Delegate : public menus::SimpleMenuModel::Delegate { | 22 class Delegate : public menus::SimpleMenuModel::Delegate { |
| 20 public: | 23 public: |
| 21 Delegate() : execute_count_(0), enable_count_(0) { } | 24 Delegate() : execute_count_(0), enable_count_(0) { } |
| 22 | 25 |
| 23 virtual bool IsCommandIdChecked(int command_id) const { return false; } | 26 virtual bool IsCommandIdChecked(int command_id) const { return false; } |
| 24 virtual bool IsCommandIdEnabled(int command_id) const { | 27 virtual bool IsCommandIdEnabled(int command_id) const { |
| 25 ++enable_count_; | 28 ++enable_count_; |
| 26 return true; | 29 return true; |
| 27 } | 30 } |
| 28 virtual bool GetAcceleratorForCommandId( | 31 virtual bool GetAcceleratorForCommandId( |
| 29 int command_id, | 32 int command_id, |
| 30 menus::Accelerator* accelerator) { return false; } | 33 menus::Accelerator* accelerator) { return false; } |
| 31 virtual void ExecuteCommand(int command_id) { ++execute_count_; } | 34 virtual void ExecuteCommand(int command_id) { ++execute_count_; } |
| 32 | 35 |
| 33 int execute_count_; | 36 int execute_count_; |
| 34 mutable int enable_count_; | 37 mutable int enable_count_; |
| 35 }; | 38 }; |
| 36 | 39 |
| 40 // Just like Delegate, except the items are treated as "dynamic" so updates to |
| 41 // the label/icon in the model are reflected in the menu. |
| 42 class DynamicDelegate : public Delegate { |
| 43 public: |
| 44 DynamicDelegate() : icon_(NULL) {} |
| 45 virtual bool IsItemForCommandIdDynamic(int command_id) const { return true; } |
| 46 virtual string16 GetLabelForCommandId(int command_id) const { return label_; } |
| 47 virtual bool GetIconForCommandId(int command_id, SkBitmap* icon) const { |
| 48 if (icon_) { |
| 49 *icon = *icon_; |
| 50 return true; |
| 51 } else { |
| 52 return false; |
| 53 } |
| 54 } |
| 55 void SetDynamicLabel(string16 label) { label_ = label; } |
| 56 void SetDynamicIcon(SkBitmap* icon) { icon_ = icon; } |
| 57 |
| 58 private: |
| 59 string16 label_; |
| 60 SkBitmap* icon_; |
| 61 }; |
| 62 |
| 37 TEST_F(MenuControllerTest, EmptyMenu) { | 63 TEST_F(MenuControllerTest, EmptyMenu) { |
| 38 Delegate delegate; | 64 Delegate delegate; |
| 39 menus::SimpleMenuModel model(&delegate); | 65 menus::SimpleMenuModel model(&delegate); |
| 40 scoped_nsobject<MenuController> menu( | 66 scoped_nsobject<MenuController> menu( |
| 41 [[MenuController alloc] initWithModel:&model useWithPopUpButtonCell:NO]); | 67 [[MenuController alloc] initWithModel:&model useWithPopUpButtonCell:NO]); |
| 42 EXPECT_EQ([[menu menu] numberOfItems], 0); | 68 EXPECT_EQ([[menu menu] numberOfItems], 0); |
| 43 } | 69 } |
| 44 | 70 |
| 45 TEST_F(MenuControllerTest, BasicCreation) { | 71 TEST_F(MenuControllerTest, BasicCreation) { |
| 46 Delegate delegate; | 72 Delegate delegate; |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 | 214 |
| 189 [menu setModel:&model]; | 215 [menu setModel:&model]; |
| 190 [menu setUseWithPopUpButtonCell:NO]; | 216 [menu setUseWithPopUpButtonCell:NO]; |
| 191 EXPECT_TRUE([menu menu]); | 217 EXPECT_TRUE([menu menu]); |
| 192 EXPECT_EQ(3, [[menu menu] numberOfItems]); | 218 EXPECT_EQ(3, [[menu menu] numberOfItems]); |
| 193 | 219 |
| 194 // Check immutability. | 220 // Check immutability. |
| 195 model.AddItem(4, ASCIIToUTF16("four")); | 221 model.AddItem(4, ASCIIToUTF16("four")); |
| 196 EXPECT_EQ(3, [[menu menu] numberOfItems]); | 222 EXPECT_EQ(3, [[menu menu] numberOfItems]); |
| 197 } | 223 } |
| 224 |
| 225 // Test that menus with dynamic labels actually get updated. |
| 226 TEST_F(MenuControllerTest, Dynamic) { |
| 227 DynamicDelegate delegate; |
| 228 |
| 229 // Create a menu containing a single item whose label is "initial" and who has |
| 230 // no icon. |
| 231 string16 initial = ASCIIToUTF16("initial"); |
| 232 delegate.SetDynamicLabel(initial); |
| 233 menus::SimpleMenuModel model(&delegate); |
| 234 model.AddItem(1, ASCIIToUTF16("foo")); |
| 235 scoped_nsobject<MenuController> menu( |
| 236 [[MenuController alloc] initWithModel:&model useWithPopUpButtonCell:NO]); |
| 237 EXPECT_EQ([[menu menu] numberOfItems], 1); |
| 238 // Validate() simulates opening the menu - the item label/icon should be |
| 239 // initialized after this so we can validate the menu contents. |
| 240 Validate(menu.get(), [menu menu]); |
| 241 NSMenuItem* item = [[menu menu] itemAtIndex:0]; |
| 242 // Item should have the "initial" label and no icon. |
| 243 EXPECT_EQ(initial, base::SysNSStringToUTF16([item title])); |
| 244 EXPECT_EQ(nil, [item image]); |
| 245 |
| 246 // Now update the item to have a label of "second" and an icon. |
| 247 string16 second = ASCIIToUTF16("second"); |
| 248 delegate.SetDynamicLabel(second); |
| 249 SkBitmap* bitmap = |
| 250 ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_THROBBER); |
| 251 delegate.SetDynamicIcon(bitmap); |
| 252 // Simulate opening the menu and validate that the item label + icon changes. |
| 253 Validate(menu.get(), [menu menu]); |
| 254 EXPECT_EQ(second, base::SysNSStringToUTF16([item title])); |
| 255 EXPECT_TRUE([item image] != nil); |
| 256 |
| 257 // Now get rid of the icon and make sure it goes away. |
| 258 delegate.SetDynamicIcon(NULL); |
| 259 Validate(menu.get(), [menu menu]); |
| 260 EXPECT_EQ(second, base::SysNSStringToUTF16([item title])); |
| 261 EXPECT_EQ(nil, [item image]); |
| 262 } |
| OLD | NEW |