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 3 // found in the LICENSE file. 4 5 #import "chrome/browser/ui/cocoa/rwhvm_editcommand_helper.h" 6 7 #import <Cocoa/Cocoa.h> 8 9 #include "chrome/test/testing_profile.h" 10 #include "content/browser/renderer_host/mock_render_process_host.h" 11 #include "content/browser/renderer_host/render_widget_host.h" 12 #include "testing/gmock/include/gmock/gmock.h" 13 #include "testing/gtest/include/gtest/gtest.h" 14 #include "testing/platform_test.h" 15 16 class RWHVMEditCommandHelperTest : public PlatformTest { 17 }; 18 19 // Bare bones obj-c class for testing purposes. 20 @interface RWHVMEditCommandHelperTestClass : NSObject 21 @end 22 23 @implementation RWHVMEditCommandHelperTestClass 24 @end 25 26 // Class that owns a RenderWidgetHostViewMac. 27 @interface RenderWidgetHostViewMacOwner : 28 NSObject<RenderWidgetHostViewMacOwner> { 29 RenderWidgetHostViewMac* rwhvm_; 30 } 31 32 - (id) initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)rwhvm; 33 @end 34 35 @implementation RenderWidgetHostViewMacOwner 36 37 - (id)initWithRenderWidgetHostViewMac:(RenderWidgetHostViewMac*)rwhvm { 38 if ((self = [super init])) { 39 rwhvm_ = rwhvm; 40 } 41 return self; 42 } 43 44 - (RenderWidgetHostViewMac*)renderWidgetHostViewMac { 45 return rwhvm_; 46 } 47 48 @end 49 50 51 namespace { 52 // Returns true if all the edit command names in the array are present 53 // in test_obj. 54 // edit_commands is a list of NSStrings, selector names are formed by 55 // appending a trailing ':' to the string. 56 bool CheckObjectRespondsToEditCommands(NSArray* edit_commands, id test_obj) { 57 for (NSString* edit_command_name in edit_commands) { 58 NSString* sel_str = [edit_command_name stringByAppendingString:@":"]; 59 if (![test_obj respondsToSelector:NSSelectorFromString(sel_str)]) { 60 return false; 61 } 62 } 63 64 return true; 65 } 66 } // namespace 67 68 // Create a Mock RenderWidget 69 class MockRenderWidgetHostEditCommandCounter : public RenderWidgetHost { 70 public: 71 MockRenderWidgetHostEditCommandCounter(RenderProcessHost* process, 72 int routing_id) : 73 RenderWidgetHost(process, routing_id) {} 74 75 MOCK_METHOD2(ForwardEditCommand, void(const std::string&, 76 const std::string&)); 77 }; 78 79 80 // Tests that editing commands make it through the pipeline all the way to 81 // RenderWidgetHost. 82 TEST_F(RWHVMEditCommandHelperTest, TestEditingCommandDelivery) { 83 RWHVMEditCommandHelper helper; 84 NSArray* edit_command_strings = helper.GetEditSelectorNames(); 85 86 // Set up a mock render widget and set expectations. 87 MessageLoopForUI message_loop; 88 TestingProfile profile; 89 MockRenderProcessHost mock_process(&profile); 90 MockRenderWidgetHostEditCommandCounter mock_render_widget(&mock_process, 0); 91 92 size_t num_edit_commands = [edit_command_strings count]; 93 EXPECT_CALL(mock_render_widget, 94 ForwardEditCommand(testing::_, testing::_)).Times(num_edit_commands); 95 96 // TODO(jeremy): Figure this out and reenable this test. 97 // For some bizarre reason this code doesn't work, running the code in the 98 // debugger confirms that the function is called with the correct parameters 99 // however gmock appears not to be able to match up parameters correctly. 100 // Disable for now till we can figure this out. 101 #if 0 102 // Tell Mock object that we expect to recieve each edit command once. 103 std::string empty_str; 104 for (NSString* edit_command_name in edit_command_strings) { 105 std::string command([edit_command_name UTF8String]); 106 EXPECT_CALL(mock_render_widget, 107 ForwardEditCommand(command, empty_str)).Times(1); 108 } 109 #endif // 0 110 111 // RenderWidgetHostViewMac self destructs (RenderWidgetHostViewMacCocoa 112 // takes ownership) so no need to delete it ourselves. 113 RenderWidgetHostViewMac* rwhvm = new RenderWidgetHostViewMac( 114 &mock_render_widget); 115 116 RenderWidgetHostViewMacOwner* rwhwvm_owner = 117 [[[RenderWidgetHostViewMacOwner alloc] 118 initWithRenderWidgetHostViewMac:rwhvm] autorelease]; 119 120 helper.AddEditingSelectorsToClass([rwhwvm_owner class]); 121 122 for (NSString* edit_command_name in edit_command_strings) { 123 NSString* sel_str = [edit_command_name stringByAppendingString:@":"]; 124 [rwhwvm_owner performSelector:NSSelectorFromString(sel_str) withObject:nil]; 125 } 126 } 127 128 // Test RWHVMEditCommandHelper::AddEditingSelectorsToClass 129 TEST_F(RWHVMEditCommandHelperTest, TestAddEditingSelectorsToClass) { 130 RWHVMEditCommandHelper helper; 131 NSArray* edit_command_strings = helper.GetEditSelectorNames(); 132 ASSERT_GT([edit_command_strings count], 0U); 133 134 // Create a class instance and add methods to the class. 135 RWHVMEditCommandHelperTestClass* test_obj = 136 [[[RWHVMEditCommandHelperTestClass alloc] init] autorelease]; 137 138 // Check that edit commands aren't already attached to the object. 139 ASSERT_FALSE(CheckObjectRespondsToEditCommands(edit_command_strings, 140 test_obj)); 141 142 helper.AddEditingSelectorsToClass([test_obj class]); 143 144 // Check that all edit commands where added. 145 ASSERT_TRUE(CheckObjectRespondsToEditCommands(edit_command_strings, 146 test_obj)); 147 148 // AddEditingSelectorsToClass() should be idempotent. 149 helper.AddEditingSelectorsToClass([test_obj class]); 150 151 // Check that all edit commands are still there. 152 ASSERT_TRUE(CheckObjectRespondsToEditCommands(edit_command_strings, 153 test_obj)); 154 } 155 156 // Test RWHVMEditCommandHelper::IsMenuItemEnabled. 157 TEST_F(RWHVMEditCommandHelperTest, TestMenuItemEnabling) { 158 RWHVMEditCommandHelper helper; 159 RenderWidgetHostViewMacOwner* rwhvm_owner = 160 [[[RenderWidgetHostViewMacOwner alloc] init] autorelease]; 161 162 // The select all menu should always be enabled. 163 SEL select_all = NSSelectorFromString(@"selectAll:"); 164 ASSERT_TRUE(helper.IsMenuItemEnabled(select_all, rwhvm_owner)); 165 166 // Random selectors should be enabled by the function. 167 SEL garbage_selector = NSSelectorFromString(@"randomGarbageSelector:"); 168 ASSERT_FALSE(helper.IsMenuItemEnabled(garbage_selector, rwhvm_owner)); 169 170 // TODO(jeremy): Currently IsMenuItemEnabled just returns true for all edit 171 // selectors. Once we go past that we should do more extensive testing here. 172 } 173