Home | History | Annotate | Download | only in cocoa
      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