| 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 "chrome/browser/cocoa/autocomplete_text_field_editor.h" | 5 #import "chrome/browser/cocoa/autocomplete_text_field_editor.h" |
| 6 | 6 |
| 7 #include "base/scoped_nsobject.h" | 7 #include "base/scoped_nsobject.h" |
| 8 #include "base/scoped_ptr.h" | 8 #include "base/scoped_ptr.h" |
| 9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "chrome/app/chrome_dll_resource.h" // IDC_* | 10 #include "chrome/app/chrome_dll_resource.h" // IDC_* |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 } | 33 } |
| 34 | 34 |
| 35 bool ClipboardContainsText(NSPasteboard* pb, NSString* cmp) { | 35 bool ClipboardContainsText(NSPasteboard* pb, NSString* cmp) { |
| 36 NSString* clipboard_text = [pb stringForType:NSStringPboardType]; | 36 NSString* clipboard_text = [pb stringForType:NSStringPboardType]; |
| 37 return [clipboard_text isEqualToString:cmp]; | 37 return [clipboard_text isEqualToString:cmp]; |
| 38 } | 38 } |
| 39 | 39 |
| 40 // TODO(shess): Very similar to AutocompleteTextFieldTest. Maybe | 40 // TODO(shess): Very similar to AutocompleteTextFieldTest. Maybe |
| 41 // those can be shared. | 41 // those can be shared. |
| 42 | 42 |
| 43 class AutocompleteTextFieldEditorTest : public PlatformTest { | 43 class AutocompleteTextFieldEditorTest : public CocoaTest { |
| 44 public: | 44 public: |
| 45 AutocompleteTextFieldEditorTest() | 45 AutocompleteTextFieldEditorTest() |
| 46 : pb_([NSPasteboard pasteboardWithUniqueName]) { | 46 : pb_([NSPasteboard pasteboardWithUniqueName]) { |
| 47 } |
| 48 |
| 49 virtual void SetUp() { |
| 50 CocoaTest::SetUp(); |
| 47 NSRect frame = NSMakeRect(0, 0, 50, 30); | 51 NSRect frame = NSMakeRect(0, 0, 50, 30); |
| 48 field_.reset([[AutocompleteTextField alloc] initWithFrame:frame]); | 52 scoped_nsobject<AutocompleteTextField> field( |
| 53 [[AutocompleteTextField alloc] initWithFrame:frame]); |
| 54 field_ = field.get(); |
| 49 [field_ setStringValue:@"Testing"]; | 55 [field_ setStringValue:@"Testing"]; |
| 50 [field_ setObserver:&field_observer_]; | 56 [field_ setObserver:&field_observer_]; |
| 51 [cocoa_helper_.contentView() addSubview:field_.get()]; | 57 [[test_window() contentView] addSubview:field_]; |
| 52 | 58 |
| 53 // Arrange for |field_| to get the right field editor. | 59 // Arrange for |field_| to get the right field editor. |
| 54 window_delegate_.reset( | 60 window_delegate_.reset( |
| 55 [[AutocompleteTextFieldWindowTestDelegate alloc] init]); | 61 [[AutocompleteTextFieldWindowTestDelegate alloc] init]); |
| 56 [cocoa_helper_.window() setDelegate:window_delegate_.get()]; | 62 [test_window() setDelegate:window_delegate_.get()]; |
| 57 | 63 |
| 58 // Get the field editor setup. | 64 // Get the field editor setup. |
| 59 cocoa_helper_.makeFirstResponder(field_); | 65 [test_window() makePretendKeyWindowAndSetFirstResponder:field_]; |
| 60 id editor = [field_.get() currentEditor]; | 66 editor_ = static_cast<AutocompleteTextFieldEditor*>([field_ currentEditor]); |
| 61 editor_.reset([static_cast<AutocompleteTextFieldEditor*>(editor) retain]); | 67 |
| 68 EXPECT_TRUE(editor_); |
| 69 EXPECT_TRUE([editor_ isKindOfClass:[AutocompleteTextFieldEditor class]]); |
| 62 } | 70 } |
| 63 | 71 |
| 64 virtual void SetUp() { | |
| 65 EXPECT_TRUE(editor_.get() != nil); | |
| 66 EXPECT_TRUE( | |
| 67 [editor_.get() isKindOfClass:[AutocompleteTextFieldEditor class]]); | |
| 68 } | |
| 69 | |
| 70 // The removeFromSuperview call is needed to prevent crashes in | |
| 71 // later tests. | |
| 72 // TODO(shess): -removeromSuperview should not be necessary. Fix | |
| 73 // it. Also in autocomplete_text_field_unittest.mm. | |
| 74 virtual ~AutocompleteTextFieldEditorTest() { | 72 virtual ~AutocompleteTextFieldEditorTest() { |
| 75 [cocoa_helper_.window() setDelegate:nil]; | |
| 76 [field_ removeFromSuperview]; | |
| 77 [pb_ releaseGlobally]; | 73 [pb_ releaseGlobally]; |
| 78 } | 74 } |
| 79 | 75 |
| 80 NSPasteboard *clipboard() { | 76 NSPasteboard *clipboard() { |
| 81 DCHECK(pb_); | 77 DCHECK(pb_); |
| 82 return pb_; | 78 return pb_; |
| 83 } | 79 } |
| 84 | 80 |
| 85 CocoaTestHelper cocoa_helper_; // Inits Cocoa, creates window, etc... | 81 AutocompleteTextFieldEditor* editor_; |
| 86 scoped_nsobject<AutocompleteTextFieldEditor> editor_; | 82 AutocompleteTextField* field_; |
| 87 scoped_nsobject<AutocompleteTextField> field_; | |
| 88 MockAutocompleteTextFieldObserver field_observer_; | 83 MockAutocompleteTextFieldObserver field_observer_; |
| 89 scoped_nsobject<AutocompleteTextFieldWindowTestDelegate> window_delegate_; | 84 scoped_nsobject<AutocompleteTextFieldWindowTestDelegate> window_delegate_; |
| 90 | 85 |
| 91 private: | 86 private: |
| 92 NSPasteboard *pb_; | 87 NSPasteboard* pb_; |
| 93 }; | 88 }; |
| 94 | 89 |
| 90 TEST_VIEW(AutocompleteTextFieldEditorTest, field_); |
| 91 |
| 95 // Test that the field editor is linked in correctly. | 92 // Test that the field editor is linked in correctly. |
| 96 TEST_F(AutocompleteTextFieldEditorTest, FirstResponder) { | 93 TEST_F(AutocompleteTextFieldEditorTest, FirstResponder) { |
| 97 EXPECT_EQ(editor_.get(), [field_ currentEditor]); | 94 EXPECT_EQ(editor_, [field_ currentEditor]); |
| 98 EXPECT_TRUE([editor_.get() isDescendantOf:field_.get()]); | 95 EXPECT_TRUE([editor_ isDescendantOf:field_]); |
| 99 EXPECT_EQ([editor_.get() delegate], field_.get()); | 96 EXPECT_EQ([editor_ delegate], field_); |
| 100 EXPECT_EQ([editor_.get() observer], [field_.get() observer]); | 97 EXPECT_EQ([editor_ observer], [field_ observer]); |
| 101 } | 98 } |
| 102 | 99 |
| 103 TEST_F(AutocompleteTextFieldEditorTest, CutCopyTest) { | 100 TEST_F(AutocompleteTextFieldEditorTest, CutCopyTest) { |
| 104 // Make sure pasteboard is empty before we start. | 101 // Make sure pasteboard is empty before we start. |
| 105 ASSERT_EQ(NumTypesOnPasteboard(clipboard()), 0); | 102 ASSERT_EQ(NumTypesOnPasteboard(clipboard()), 0); |
| 106 | 103 |
| 107 NSString* test_string_1 = @"astring"; | 104 NSString* test_string_1 = @"astring"; |
| 108 NSString* test_string_2 = @"another string"; | 105 NSString* test_string_2 = @"another string"; |
| 109 | 106 |
| 110 [editor_.get() setRichText:YES]; | 107 [editor_ setRichText:YES]; |
| 111 | 108 |
| 112 // Put some text on the clipboard. | 109 // Put some text on the clipboard. |
| 113 [editor_.get() setString:test_string_1]; | 110 [editor_ setString:test_string_1]; |
| 114 [editor_.get() selectAll:nil]; | 111 [editor_ selectAll:nil]; |
| 115 [editor_.get() alignRight:nil]; // Add a rich text attribute. | 112 [editor_ alignRight:nil]; // Add a rich text attribute. |
| 116 ASSERT_TRUE(NoRichTextOnClipboard(clipboard())); | 113 ASSERT_TRUE(NoRichTextOnClipboard(clipboard())); |
| 117 | 114 |
| 118 // Check that copying it works and we only get plain text. | 115 // Check that copying it works and we only get plain text. |
| 119 [editor_.get() performCopy:clipboard()]; | 116 [editor_ performCopy:clipboard()]; |
| 120 ASSERT_TRUE(NoRichTextOnClipboard(clipboard())); | 117 ASSERT_TRUE(NoRichTextOnClipboard(clipboard())); |
| 121 ASSERT_TRUE(ClipboardContainsText(clipboard(), test_string_1)); | 118 ASSERT_TRUE(ClipboardContainsText(clipboard(), test_string_1)); |
| 122 | 119 |
| 123 // Check that cutting it works and we only get plain text. | 120 // Check that cutting it works and we only get plain text. |
| 124 [editor_.get() setString:test_string_2]; | 121 [editor_ setString:test_string_2]; |
| 125 [editor_.get() selectAll:nil]; | 122 [editor_ selectAll:nil]; |
| 126 [editor_.get() alignLeft:nil]; // Add a rich text attribute. | 123 [editor_ alignLeft:nil]; // Add a rich text attribute. |
| 127 [editor_.get() performCut:clipboard()]; | 124 [editor_ performCut:clipboard()]; |
| 128 ASSERT_TRUE(NoRichTextOnClipboard(clipboard())); | 125 ASSERT_TRUE(NoRichTextOnClipboard(clipboard())); |
| 129 ASSERT_TRUE(ClipboardContainsText(clipboard(), test_string_2)); | 126 ASSERT_TRUE(ClipboardContainsText(clipboard(), test_string_2)); |
| 130 ASSERT_EQ([[editor_.get() textStorage] length], 0U); | 127 ASSERT_EQ([[editor_ textStorage] length], 0U); |
| 131 } | |
| 132 | |
| 133 // Test adding/removing from the view hierarchy, mostly to ensure nothing | |
| 134 // leaks or crashes. | |
| 135 TEST_F(AutocompleteTextFieldEditorTest, AddRemove) { | |
| 136 EXPECT_EQ(cocoa_helper_.contentView(), [field_ superview]); | |
| 137 | |
| 138 // TODO(shess): For some reason, -removeFromSuperview while |field_| | |
| 139 // is first-responder causes AutocompleteTextFieldWindowTestDelegate | |
| 140 // -windowWillReturnFieldEditor:toObject: to be passed an object of | |
| 141 // class AutocompleteTextFieldEditor. Which is weird. Changing | |
| 142 // first responder will remove the field editor. | |
| 143 cocoa_helper_.makeFirstResponder(nil); | |
| 144 EXPECT_FALSE([field_.get() currentEditor]); | |
| 145 EXPECT_FALSE([editor_.get() superview]); | |
| 146 | |
| 147 [field_.get() removeFromSuperview]; | |
| 148 EXPECT_FALSE([field_.get() superview]); | |
| 149 } | 128 } |
| 150 | 129 |
| 151 // Test drawing, mostly to ensure nothing leaks or crashes. | 130 // Test drawing, mostly to ensure nothing leaks or crashes. |
| 152 TEST_F(AutocompleteTextFieldEditorTest, Display) { | 131 TEST_F(AutocompleteTextFieldEditorTest, Display) { |
| 153 [field_ display]; | 132 [field_ display]; |
| 154 [editor_ display]; | 133 [editor_ display]; |
| 155 } | 134 } |
| 156 | 135 |
| 157 // Test that -paste: is correctly delegated to the observer. | 136 // Test that -paste: is correctly delegated to the observer. |
| 158 TEST_F(AutocompleteTextFieldEditorTest, Paste) { | 137 TEST_F(AutocompleteTextFieldEditorTest, Paste) { |
| 159 EXPECT_CALL(field_observer_, OnPaste()); | 138 EXPECT_CALL(field_observer_, OnPaste()); |
| 160 [editor_.get() paste:nil]; | 139 [editor_ paste:nil]; |
| 161 } | 140 } |
| 162 | 141 |
| 163 // Test that -pasteAndGo: is correctly delegated to the observer. | 142 // Test that -pasteAndGo: is correctly delegated to the observer. |
| 164 TEST_F(AutocompleteTextFieldEditorTest, PasteAndGo) { | 143 TEST_F(AutocompleteTextFieldEditorTest, PasteAndGo) { |
| 165 EXPECT_CALL(field_observer_, OnPasteAndGo()); | 144 EXPECT_CALL(field_observer_, OnPasteAndGo()); |
| 166 [editor_.get() pasteAndGo:nil]; | 145 [editor_ pasteAndGo:nil]; |
| 167 } | 146 } |
| 168 | 147 |
| 169 // Test that the menu is constructed correctly when CanPasteAndGo(). | 148 // Test that the menu is constructed correctly when CanPasteAndGo(). |
| 170 TEST_F(AutocompleteTextFieldEditorTest, CanPasteAndGoMenu) { | 149 TEST_F(AutocompleteTextFieldEditorTest, CanPasteAndGoMenu) { |
| 171 EXPECT_CALL(field_observer_, CanPasteAndGo()) | 150 EXPECT_CALL(field_observer_, CanPasteAndGo()) |
| 172 .WillOnce(Return(true)); | 151 .WillOnce(Return(true)); |
| 173 EXPECT_CALL(field_observer_, GetPasteActionStringId()) | 152 EXPECT_CALL(field_observer_, GetPasteActionStringId()) |
| 174 .WillOnce(Return(IDS_PASTE_AND_GO)); | 153 .WillOnce(Return(IDS_PASTE_AND_GO)); |
| 175 | 154 |
| 176 NSMenu* menu = [editor_.get() menuForEvent:nil]; | 155 NSMenu* menu = [editor_ menuForEvent:nil]; |
| 177 NSArray* items = [menu itemArray]; | 156 NSArray* items = [menu itemArray]; |
| 178 ASSERT_EQ([items count], 6U); | 157 ASSERT_EQ([items count], 6U); |
| 179 // TODO(shess): Check the titles, too? | 158 // TODO(shess): Check the titles, too? |
| 180 NSUInteger i = 0; // Use an index to make future changes easier. | 159 NSUInteger i = 0; // Use an index to make future changes easier. |
| 181 EXPECT_EQ([[items objectAtIndex:i++] action], @selector(cut:)); | 160 EXPECT_EQ([[items objectAtIndex:i++] action], @selector(cut:)); |
| 182 EXPECT_EQ([[items objectAtIndex:i++] action], @selector(copy:)); | 161 EXPECT_EQ([[items objectAtIndex:i++] action], @selector(copy:)); |
| 183 EXPECT_EQ([[items objectAtIndex:i++] action], @selector(paste:)); | 162 EXPECT_EQ([[items objectAtIndex:i++] action], @selector(paste:)); |
| 184 EXPECT_EQ([[items objectAtIndex:i++] action], @selector(pasteAndGo:)); | 163 EXPECT_EQ([[items objectAtIndex:i++] action], @selector(pasteAndGo:)); |
| 185 EXPECT_TRUE([[items objectAtIndex:i++] isSeparatorItem]); | 164 EXPECT_TRUE([[items objectAtIndex:i++] isSeparatorItem]); |
| 186 | 165 |
| 187 EXPECT_EQ([[items objectAtIndex:i] action], @selector(commandDispatch:)); | 166 EXPECT_EQ([[items objectAtIndex:i] action], @selector(commandDispatch:)); |
| 188 EXPECT_EQ([[items objectAtIndex:i] tag], IDC_EDIT_SEARCH_ENGINES); | 167 EXPECT_EQ([[items objectAtIndex:i] tag], IDC_EDIT_SEARCH_ENGINES); |
| 189 i++; | 168 i++; |
| 190 } | 169 } |
| 191 | 170 |
| 192 // Test that the menu is constructed correctly when !CanPasteAndGo(). | 171 // Test that the menu is constructed correctly when !CanPasteAndGo(). |
| 193 TEST_F(AutocompleteTextFieldEditorTest, CannotPasteAndGoMenu) { | 172 TEST_F(AutocompleteTextFieldEditorTest, CannotPasteAndGoMenu) { |
| 194 EXPECT_CALL(field_observer_, CanPasteAndGo()) | 173 EXPECT_CALL(field_observer_, CanPasteAndGo()) |
| 195 .WillOnce(Return(false)); | 174 .WillOnce(Return(false)); |
| 196 | 175 |
| 197 NSMenu* menu = [editor_.get() menuForEvent:nil]; | 176 NSMenu* menu = [editor_ menuForEvent:nil]; |
| 198 NSArray* items = [menu itemArray]; | 177 NSArray* items = [menu itemArray]; |
| 199 ASSERT_EQ([items count], 5U); | 178 ASSERT_EQ([items count], 5U); |
| 200 // TODO(shess): Check the titles, too? | 179 // TODO(shess): Check the titles, too? |
| 201 NSUInteger i = 0; // Use an index to make future changes easier. | 180 NSUInteger i = 0; // Use an index to make future changes easier. |
| 202 EXPECT_EQ([[items objectAtIndex:i++] action], @selector(cut:)); | 181 EXPECT_EQ([[items objectAtIndex:i++] action], @selector(cut:)); |
| 203 EXPECT_EQ([[items objectAtIndex:i++] action], @selector(copy:)); | 182 EXPECT_EQ([[items objectAtIndex:i++] action], @selector(copy:)); |
| 204 EXPECT_EQ([[items objectAtIndex:i++] action], @selector(paste:)); | 183 EXPECT_EQ([[items objectAtIndex:i++] action], @selector(paste:)); |
| 205 EXPECT_TRUE([[items objectAtIndex:i++] isSeparatorItem]); | 184 EXPECT_TRUE([[items objectAtIndex:i++] isSeparatorItem]); |
| 206 | 185 |
| 207 EXPECT_EQ([[items objectAtIndex:i] action], @selector(commandDispatch:)); | 186 EXPECT_EQ([[items objectAtIndex:i] action], @selector(commandDispatch:)); |
| 208 EXPECT_EQ([[items objectAtIndex:i] tag], IDC_EDIT_SEARCH_ENGINES); | 187 EXPECT_EQ([[items objectAtIndex:i] tag], IDC_EDIT_SEARCH_ENGINES); |
| 209 i++; | 188 i++; |
| 210 } | 189 } |
| 211 | 190 |
| 212 // Test that the menu is constructed correctly when field isn't | 191 // Test that the menu is constructed correctly when field isn't |
| 213 // editable. | 192 // editable. |
| 214 TEST_F(AutocompleteTextFieldEditorTest, CanPasteAndGoMenuNotEditable) { | 193 TEST_F(AutocompleteTextFieldEditorTest, CanPasteAndGoMenuNotEditable) { |
| 215 [field_.get() setEditable:NO]; | 194 [field_ setEditable:NO]; |
| 216 [editor_.get() setEditable:NO]; | 195 [editor_ setEditable:NO]; |
| 217 | 196 |
| 218 // Never call these when not editable. | 197 // Never call these when not editable. |
| 219 EXPECT_CALL(field_observer_, CanPasteAndGo()) | 198 EXPECT_CALL(field_observer_, CanPasteAndGo()) |
| 220 .Times(0); | 199 .Times(0); |
| 221 EXPECT_CALL(field_observer_, GetPasteActionStringId()) | 200 EXPECT_CALL(field_observer_, GetPasteActionStringId()) |
| 222 .Times(0); | 201 .Times(0); |
| 223 | 202 |
| 224 NSMenu* menu = [editor_.get() menuForEvent:nil]; | 203 NSMenu* menu = [editor_ menuForEvent:nil]; |
| 225 NSArray* items = [menu itemArray]; | 204 NSArray* items = [menu itemArray]; |
| 226 ASSERT_EQ([items count], 3U); | 205 ASSERT_EQ([items count], 3U); |
| 227 // TODO(shess): Check the titles, too? | 206 // TODO(shess): Check the titles, too? |
| 228 NSUInteger i = 0; // Use an index to make future changes easier. | 207 NSUInteger i = 0; // Use an index to make future changes easier. |
| 229 EXPECT_EQ([[items objectAtIndex:i++] action], @selector(cut:)); | 208 EXPECT_EQ([[items objectAtIndex:i++] action], @selector(cut:)); |
| 230 EXPECT_EQ([[items objectAtIndex:i++] action], @selector(copy:)); | 209 EXPECT_EQ([[items objectAtIndex:i++] action], @selector(copy:)); |
| 231 EXPECT_EQ([[items objectAtIndex:i++] action], @selector(paste:)); | 210 EXPECT_EQ([[items objectAtIndex:i++] action], @selector(paste:)); |
| 232 } | 211 } |
| 233 | 212 |
| 234 } // namespace | 213 } // namespace |
| OLD | NEW |