Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(726)

Side by Side Diff: chrome/browser/cocoa/autocomplete_text_field_unittest.mm

Issue 173194: [Mac] Omnibox keyword, keyword hint, and search hint support.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Name: svn:eol-style
+ LF
OLDNEW
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/scoped_nsobject.h" 7 #include "base/scoped_nsobject.h"
8 #import "chrome/browser/cocoa/autocomplete_text_field.h" 8 #import "chrome/browser/cocoa/autocomplete_text_field.h"
9 #import "chrome/browser/cocoa/autocomplete_text_field_cell.h" 9 #import "chrome/browser/cocoa/autocomplete_text_field_cell.h"
10 #import "chrome/browser/cocoa/autocomplete_text_field_editor.h" 10 #import "chrome/browser/cocoa/autocomplete_text_field_editor.h"
11 #import "chrome/browser/cocoa/cocoa_test_helper.h" 11 #import "chrome/browser/cocoa/cocoa_test_helper.h"
12 #include "testing/gtest/include/gtest/gtest.h" 12 #include "testing/gtest/include/gtest/gtest.h"
13 13
14 @interface AutocompleteTextFieldTestDelegate : NSObject { 14 @interface AutocompleteTextFieldTestDelegate : NSObject {
15 BOOL textShouldPaste_; 15 BOOL textShouldPaste_;
16 BOOL receivedTextShouldPaste_; 16 BOOL receivedTextShouldPaste_;
17 BOOL receivedFlagsChanged_; 17 BOOL receivedFlagsChanged_;
18 BOOL receivedControlTextDidBeginEditing_;
19 BOOL receivedControlTextShouldEndEditing_;
18 } 20 }
19 - initWithTextShouldPaste:(BOOL)flag; 21 - initWithTextShouldPaste:(BOOL)flag;
20 - (BOOL)receivedTextShouldPaste; 22 - (BOOL)receivedTextShouldPaste;
21 - (BOOL)receivedFlagsChanged; 23 - (BOOL)receivedFlagsChanged;
24 - (BOOL)receivedControlTextDidBeginEditing;
25 - (BOOL)receivedControlTextShouldEndEditing;
26 @end
27
28 @interface AutocompleteTextFieldWindowTestDelegate : NSObject {
29 scoped_nsobject<AutocompleteTextFieldEditor> editor_;
30 }
31 - (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)anObject;
22 @end 32 @end
23 33
24 namespace { 34 namespace {
25 35
26 class AutocompleteTextFieldTest : public testing::Test { 36 class AutocompleteTextFieldTest : public testing::Test {
27 public: 37 public:
28 AutocompleteTextFieldTest() { 38 AutocompleteTextFieldTest() {
29 NSRect frame = NSMakeRect(0, 0, 50, 30); 39 // Make sure this is wide enough to play games with the cell
40 // decorations.
41 NSRect frame = NSMakeRect(0, 0, 300, 30);
30 field_.reset([[AutocompleteTextField alloc] initWithFrame:frame]); 42 field_.reset([[AutocompleteTextField alloc] initWithFrame:frame]);
31 [field_ setStringValue:@"Testing"]; 43 [field_ setStringValue:@"Testing"];
32 [cocoa_helper_.contentView() addSubview:field_.get()]; 44 [cocoa_helper_.contentView() addSubview:field_.get()];
45
46 window_delegate_.reset(
47 [[AutocompleteTextFieldWindowTestDelegate alloc] init]);
48 [cocoa_helper_.window() setDelegate:window_delegate_];
49 }
50
51 // The removeFromSuperview call is needed to prevent crashes in later tests.
52 ~AutocompleteTextFieldTest() {
53 [cocoa_helper_.window() setDelegate:nil];
54 [field_ removeFromSuperview];
33 } 55 }
34 56
35 CocoaTestHelper cocoa_helper_; // Inits Cocoa, creates window, etc... 57 CocoaTestHelper cocoa_helper_; // Inits Cocoa, creates window, etc...
36 scoped_nsobject<AutocompleteTextField> field_; 58 scoped_nsobject<AutocompleteTextField> field_;
59 scoped_nsobject<AutocompleteTextFieldWindowTestDelegate> window_delegate_;
37 }; 60 };
38 61
39 // Test that we have the right cell class. 62 // Test that we have the right cell class.
40 TEST_F(AutocompleteTextFieldTest, CellClass) { 63 TEST_F(AutocompleteTextFieldTest, CellClass) {
41 EXPECT_TRUE([[field_ cell] isKindOfClass:[AutocompleteTextFieldCell class]]); 64 EXPECT_TRUE([[field_ cell] isKindOfClass:[AutocompleteTextFieldCell class]]);
42 } 65 }
43 66
44 // Test adding/removing from the view hierarchy, mostly to ensure nothing 67 // Test adding/removing from the view hierarchy, mostly to ensure nothing
45 // leaks or crashes. 68 // leaks or crashes.
46 TEST_F(AutocompleteTextFieldTest, AddRemove) { 69 TEST_F(AutocompleteTextFieldTest, AddRemove) {
47 EXPECT_EQ(cocoa_helper_.contentView(), [field_ superview]); 70 EXPECT_EQ(cocoa_helper_.contentView(), [field_ superview]);
48 [field_.get() removeFromSuperview]; 71 [field_.get() removeFromSuperview];
49 EXPECT_FALSE([field_ superview]); 72 EXPECT_FALSE([field_ superview]);
50 } 73 }
51 74
75 // Test that we get the same cell from -cell and
76 // -autocompleteTextFieldCell.
77 TEST_F(AutocompleteTextFieldTest, Cell) {
78 AutocompleteTextFieldCell* cell = [field_ autocompleteTextFieldCell];
79 EXPECT_EQ(cell, [field_ cell]);
80 EXPECT_TRUE(cell != nil);
81 }
82
52 // Test drawing, mostly to ensure nothing leaks or crashes. 83 // Test drawing, mostly to ensure nothing leaks or crashes.
53 TEST_F(AutocompleteTextFieldTest, Display) { 84 TEST_F(AutocompleteTextFieldTest, Display) {
54 [field_ display]; 85 [field_ display];
86
87 // Test display of various cell configurations.
88 AutocompleteTextFieldCell* cell = [field_ autocompleteTextFieldCell];
89
90 [cell setSearchHintString:@"Type to search"];
91 [field_ display];
92
93 NSImage* image = [NSImage imageNamed:@"NSApplicationIcon"];
94 [cell setKeywordHintPrefix:@"prefix" image:image suffix:@"suffix"];
95 [field_ display];
96
97 [cell setKeywordString:@"Search Engine:"];
98 [field_ display];
99
100 [cell clearKeywordAndHint];
101 [field_ display];
55 } 102 }
56 103
57 // Test that -textShouldPaste: properly queries the delegate. 104 // Test that -textShouldPaste: properly queries the delegate.
58 TEST_F(AutocompleteTextFieldTest, TextShouldPaste) { 105 TEST_F(AutocompleteTextFieldTest, TextShouldPaste) {
59 EXPECT_TRUE(![field_ delegate]); 106 EXPECT_TRUE(![field_ delegate]);
60 EXPECT_TRUE([field_ textShouldPaste:nil]); 107 EXPECT_TRUE([field_ textShouldPaste:nil]);
61 108
62 scoped_nsobject<AutocompleteTextFieldTestDelegate> shouldPaste( 109 scoped_nsobject<AutocompleteTextFieldTestDelegate> shouldPaste(
63 [[AutocompleteTextFieldTestDelegate alloc] initWithTextShouldPaste:YES]); 110 [[AutocompleteTextFieldTestDelegate alloc] initWithTextShouldPaste:YES]);
64 [field_ setDelegate:shouldPaste]; 111 [field_ setDelegate:shouldPaste];
65 EXPECT_FALSE([shouldPaste receivedTextShouldPaste]); 112 EXPECT_FALSE([shouldPaste receivedTextShouldPaste]);
66 EXPECT_TRUE([field_ textShouldPaste:nil]); 113 EXPECT_TRUE([field_ textShouldPaste:nil]);
67 EXPECT_TRUE([shouldPaste receivedTextShouldPaste]); 114 EXPECT_TRUE([shouldPaste receivedTextShouldPaste]);
68 115
69 scoped_nsobject<AutocompleteTextFieldTestDelegate> shouldNotPaste( 116 scoped_nsobject<AutocompleteTextFieldTestDelegate> shouldNotPaste(
70 [[AutocompleteTextFieldTestDelegate alloc] initWithTextShouldPaste:NO]); 117 [[AutocompleteTextFieldTestDelegate alloc] initWithTextShouldPaste:NO]);
71 [field_ setDelegate:shouldNotPaste]; 118 [field_ setDelegate:shouldNotPaste];
72 EXPECT_FALSE([shouldNotPaste receivedTextShouldPaste]); 119 EXPECT_FALSE([shouldNotPaste receivedTextShouldPaste]);
73 EXPECT_FALSE([field_ textShouldPaste:nil]); 120 EXPECT_FALSE([field_ textShouldPaste:nil]);
74 EXPECT_TRUE([shouldNotPaste receivedTextShouldPaste]); 121 EXPECT_TRUE([shouldNotPaste receivedTextShouldPaste]);
122 [field_ setDelegate:nil];
75 } 123 }
76 124
77 // Test that -control:flagsChanged: properly reaches the delegate. 125 // Test that -control:flagsChanged: properly reaches the delegate.
78 TEST_F(AutocompleteTextFieldTest, FlagsChanged) { 126 TEST_F(AutocompleteTextFieldTest, FlagsChanged) {
79 EXPECT_TRUE(![field_ delegate]); 127 EXPECT_TRUE(![field_ delegate]);
80 128
81 // This shouldn't crash, at least. 129 // This shouldn't crash, at least.
82 [field_ flagsChanged:nil]; 130 [field_ flagsChanged:nil];
83 131
84 scoped_nsobject<AutocompleteTextFieldTestDelegate> delegate( 132 scoped_nsobject<AutocompleteTextFieldTestDelegate> delegate(
85 [[AutocompleteTextFieldTestDelegate alloc] initWithTextShouldPaste:NO]); 133 [[AutocompleteTextFieldTestDelegate alloc] initWithTextShouldPaste:NO]);
86 [field_ setDelegate:delegate]; 134 [field_ setDelegate:delegate];
87 EXPECT_FALSE([delegate receivedFlagsChanged]); 135 EXPECT_FALSE([delegate receivedFlagsChanged]);
88 [field_ flagsChanged:nil]; 136 [field_ flagsChanged:nil];
89 EXPECT_TRUE([delegate receivedFlagsChanged]); 137 EXPECT_TRUE([delegate receivedFlagsChanged]);
138 [field_ setDelegate:nil];
90 } 139 }
91 140
92 // Test that -control:flagsChanged: properly reaches the delegate when 141 // Test that -control:flagsChanged: properly reaches the delegate when
93 // the -flagsChanged: message goes to the editor. In that case it is 142 // the -flagsChanged: message goes to the editor. In that case it is
94 // forwarded via the responder chain. 143 // forwarded via the responder chain.
95 TEST_F(AutocompleteTextFieldTest, FieldEditorFlagsChanged) { 144 TEST_F(AutocompleteTextFieldTest, FieldEditorFlagsChanged) {
96 EXPECT_TRUE(![field_ delegate]); 145 EXPECT_TRUE(![field_ delegate]);
97 146
98 scoped_nsobject<AutocompleteTextFieldTestDelegate> delegate( 147 scoped_nsobject<AutocompleteTextFieldTestDelegate> delegate(
99 [[AutocompleteTextFieldTestDelegate alloc] initWithTextShouldPaste:NO]); 148 [[AutocompleteTextFieldTestDelegate alloc] initWithTextShouldPaste:NO]);
100 149
101 // Setup a field editor for |field_|. 150 // Setup a field editor for |field_|.
102 scoped_nsobject<AutocompleteTextFieldEditor> editor( 151 scoped_nsobject<AutocompleteTextFieldEditor> editor(
103 [[AutocompleteTextFieldEditor alloc] init]); 152 [[AutocompleteTextFieldEditor alloc] init]);
104 [field_ setDelegate:delegate]; 153 [field_ setDelegate:delegate];
105 154
106 [editor setFieldEditor:YES]; 155 [editor setFieldEditor:YES];
107 [[field_ cell] setUpFieldEditorAttributes:editor]; 156 [[field_ cell] setUpFieldEditorAttributes:editor];
108 [[field_ cell] editWithFrame:[field_ bounds] 157 [[field_ cell] editWithFrame:[field_ bounds]
109 inView:field_ 158 inView:field_
110 editor:editor 159 editor:editor
111 delegate:[field_ delegate] 160 delegate:[field_ delegate]
112 event:nil]; 161 event:nil];
113 EXPECT_FALSE([delegate receivedFlagsChanged]); 162 EXPECT_FALSE([delegate receivedFlagsChanged]);
114 [editor flagsChanged:nil]; 163 [editor flagsChanged:nil];
115 EXPECT_TRUE([delegate receivedFlagsChanged]); 164 EXPECT_TRUE([delegate receivedFlagsChanged]);
165 [field_ setDelegate:nil];
166 }
167
168 // Test that the field editor is reset correctly when search keyword
169 // or hints change.
170 TEST_F(AutocompleteTextFieldTest, ResetFieldEditor) {
171 EXPECT_EQ(nil, [field_ currentEditor]);
172 EXPECT_EQ([[field_ subviews] count], 0U);
173 [[field_ window] makeFirstResponder:field_];
174 EXPECT_FALSE(nil == [field_ currentEditor]);
175 EXPECT_EQ([[field_ subviews] count], 1U);
176
177 // Check that the window delegate is working right.
178 {
179 Class c = [AutocompleteTextFieldEditor class];
180 EXPECT_TRUE([[field_ currentEditor] isKindOfClass:c]);
181 }
182
183 // The field editor may not be an immediate subview of |field_|, it
184 // may be a subview of a clipping view (for purposes of scrolling).
185 // So just look at the immediate subview.
186 EXPECT_EQ([[field_ subviews] count], 1U);
187 const NSRect baseEditorFrame([[[field_ subviews] objectAtIndex:0] frame]);
188
189 AutocompleteTextFieldCell* cell = [field_ autocompleteTextFieldCell];
190 EXPECT_FALSE([cell fieldEditorNeedsReset]);
191
192 // Asking the cell to add a search hint should leave the field
193 // editor alone until -resetFieldEditorFrameIfNeeded is called.
194 // Then the field editor should be moved to a smaller region with
195 // the same left-hand side.
196 [cell setSearchHintString:@"Type to search"];
197 EXPECT_TRUE([cell fieldEditorNeedsReset]);
198 NSRect r = [[[field_ subviews] objectAtIndex:0] frame];
199 EXPECT_TRUE(NSEqualRects(r, baseEditorFrame));
200 [field_ resetFieldEditorFrameIfNeeded];
201 r = [[[field_ subviews] objectAtIndex:0] frame];
202 EXPECT_FALSE([cell fieldEditorNeedsReset]);
203 EXPECT_FALSE(NSEqualRects(r, baseEditorFrame));
204 EXPECT_TRUE(NSContainsRect(baseEditorFrame, r));
205 EXPECT_EQ(NSMinX(r), NSMinX(baseEditorFrame));
206 EXPECT_LT(NSWidth(r), NSWidth(baseEditorFrame));
207
208 // Save the search-hint editor frame for later.
209 const NSRect searchHintEditorFrame(r);
210
211 // Asking the cell to change to keyword mode should leave the field
212 // editor alone until -resetFieldEditorFrameIfNeeded is called.
213 // Then the field editor should be moved to a smaller region with
214 // the same right-hand side.
215 [cell setKeywordString:@"Search Engine:"];
216 EXPECT_TRUE([cell fieldEditorNeedsReset]);
217 r = [[[field_ subviews] objectAtIndex:0] frame];
218 EXPECT_TRUE(NSEqualRects(r, searchHintEditorFrame));
219 [field_ resetFieldEditorFrameIfNeeded];
220 r = [[[field_ subviews] objectAtIndex:0] frame];
221 EXPECT_FALSE([cell fieldEditorNeedsReset]);
222 EXPECT_FALSE(NSEqualRects(r, baseEditorFrame));
223 EXPECT_FALSE(NSEqualRects(r, searchHintEditorFrame));
224 EXPECT_TRUE(NSContainsRect(baseEditorFrame, r));
225 EXPECT_EQ(NSMaxX(r), NSMaxX(baseEditorFrame));
226 EXPECT_LT(NSWidth(r), NSWidth(baseEditorFrame));
227
228 // Asking the cell to clear everything should leave the field editor
229 // alone until -resetFieldEditorFrameIfNeeded is called. Then the
230 // field editor should be back to baseEditorFrame.
231 [cell clearKeywordAndHint];
232 EXPECT_TRUE([cell fieldEditorNeedsReset]);
233 [field_ resetFieldEditorFrameIfNeeded];
234 r = [[[field_ subviews] objectAtIndex:0] frame];
235 EXPECT_FALSE([cell fieldEditorNeedsReset]);
236 EXPECT_TRUE(NSEqualRects(r, baseEditorFrame));
237 }
238
239 // Test that the field editor is reset correctly when search keyword
240 // or hints change.
241 TEST_F(AutocompleteTextFieldTest, ResetFieldEditorBlocksEndEditing) {
242 [[field_ window] makeFirstResponder:field_];
243
244 // First, test that -makeFirstResponder: sends
245 // -controlTextDidBeginEditing: and -control:textShouldEndEditing at
246 // the expected times.
247 {
248 scoped_nsobject<AutocompleteTextFieldTestDelegate> delegate(
249 [[AutocompleteTextFieldTestDelegate alloc] initWithTextShouldPaste:NO]);
250 EXPECT_FALSE([delegate receivedControlTextDidBeginEditing]);
251 EXPECT_FALSE([delegate receivedControlTextShouldEndEditing]);
252
253 [field_ setDelegate:delegate];
254 [[field_ window] makeFirstResponder:field_];
255 NSTextView* editor = static_cast<NSTextView*>([field_ currentEditor]);
256 EXPECT_TRUE(nil != editor);
257 EXPECT_FALSE([delegate receivedControlTextDidBeginEditing]);
258 EXPECT_FALSE([delegate receivedControlTextShouldEndEditing]);
259
260 // This should start the begin/end editing state.
261 [editor shouldChangeTextInRange:NSMakeRange(0, 0) replacementString:@""];
262 EXPECT_TRUE([delegate receivedControlTextDidBeginEditing]);
263 EXPECT_FALSE([delegate receivedControlTextShouldEndEditing]);
264
265 // This should send the end-editing message.
266 [[field_ window] makeFirstResponder:field_];
267 EXPECT_TRUE([delegate receivedControlTextShouldEndEditing]);
268 [field_ setDelegate:nil];
269 }
270
271 // Then test that -resetFieldEditorFrameIfNeeded manages without
272 // sending that message.
273 {
274 scoped_nsobject<AutocompleteTextFieldTestDelegate> delegate(
275 [[AutocompleteTextFieldTestDelegate alloc] initWithTextShouldPaste:NO]);
276 [field_ setDelegate:delegate];
277 EXPECT_FALSE([delegate receivedControlTextDidBeginEditing]);
278 EXPECT_FALSE([delegate receivedControlTextShouldEndEditing]);
279
280 AutocompleteTextFieldCell* cell = [field_ autocompleteTextFieldCell];
281 EXPECT_FALSE([cell fieldEditorNeedsReset]);
282 [cell setSearchHintString:@"Type to search"];
283 EXPECT_TRUE([cell fieldEditorNeedsReset]);
284 EXPECT_FALSE([delegate receivedControlTextShouldEndEditing]);
285 [field_ resetFieldEditorFrameIfNeeded];
286 EXPECT_FALSE([delegate receivedControlTextShouldEndEditing]);
287 EXPECT_TRUE([delegate receivedControlTextDidBeginEditing]);
288 [field_ setDelegate:nil];
289 }
116 } 290 }
117 291
118 } // namespace 292 } // namespace
119 293
120 @implementation AutocompleteTextFieldTestDelegate 294 @implementation AutocompleteTextFieldTestDelegate
121 295
122 - initWithTextShouldPaste:(BOOL)flag { 296 - initWithTextShouldPaste:(BOOL)flag {
123 self = [super init]; 297 self = [super init];
124 if (self) { 298 if (self) {
125 textShouldPaste_ = flag; 299 textShouldPaste_ = flag;
126 receivedTextShouldPaste_ = NO; 300 receivedTextShouldPaste_ = NO;
127 receivedFlagsChanged_ = NO; 301 receivedFlagsChanged_ = NO;
302 receivedControlTextDidBeginEditing_ = NO;
303 receivedControlTextShouldEndEditing_ = NO;
128 } 304 }
129 return self; 305 return self;
130 } 306 }
131 307
132 - (BOOL)receivedTextShouldPaste { 308 - (BOOL)receivedTextShouldPaste {
133 return receivedTextShouldPaste_; 309 return receivedTextShouldPaste_;
134 } 310 }
135 311
136 - (BOOL)receivedFlagsChanged { 312 - (BOOL)receivedFlagsChanged {
137 return receivedFlagsChanged_; 313 return receivedFlagsChanged_;
138 } 314 }
139 315
316 - (BOOL)receivedControlTextDidBeginEditing {
317 return receivedControlTextDidBeginEditing_;
318 }
319
320 - (BOOL)receivedControlTextShouldEndEditing {
321 return receivedControlTextShouldEndEditing_;
322 }
323
140 - (BOOL)control:(NSControl*)control textShouldPaste:(NSText*)fieldEditor { 324 - (BOOL)control:(NSControl*)control textShouldPaste:(NSText*)fieldEditor {
141 receivedTextShouldPaste_ = YES; 325 receivedTextShouldPaste_ = YES;
142 return textShouldPaste_; 326 return textShouldPaste_;
143 } 327 }
144 328
145 - (void)control:(id)control flagsChanged:(NSEvent*)theEvent { 329 - (void)control:(id)control flagsChanged:(NSEvent*)theEvent {
146 receivedFlagsChanged_ = YES; 330 receivedFlagsChanged_ = YES;
147 } 331 }
148 332
333 - (void)controlTextDidBeginEditing:(NSNotification*)aNotification {
334 receivedControlTextDidBeginEditing_ = YES;
335 }
336
337 - (BOOL)control:(NSControl*)control textShouldEndEditing:(NSText*)fieldEditor {
338 receivedControlTextShouldEndEditing_ = YES;
339 return YES;
340 }
341
149 @end 342 @end
343
344 @implementation AutocompleteTextFieldWindowTestDelegate
345
346 - (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)anObject {
347 EXPECT_TRUE([anObject isKindOfClass:[AutocompleteTextField class]]);
348
349 if (editor_ == nil) {
350 editor_.reset([[AutocompleteTextFieldEditor alloc] init]);
351 }
352 EXPECT_TRUE(editor_ != nil);
353
354 // This needs to be called every time, otherwise notifications
355 // aren't sent correctly.
356 [editor_ setFieldEditor:YES];
357 return editor_;
358 }
359
360 @end
OLDNEW
« no previous file with comments | « chrome/browser/cocoa/autocomplete_text_field_editor.h ('k') | chrome/browser/cocoa/location_bar_view_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698