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

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

Issue 1011943002: Mac: Clicking an omnibox decoration should not highlight the omnibox. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comments from shess. Created 5 years, 7 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
« no previous file with comments | « chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.mm ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <ApplicationServices/ApplicationServices.h> 5 #import <ApplicationServices/ApplicationServices.h>
6 #import <Cocoa/Cocoa.h> 6 #import <Cocoa/Cocoa.h>
7 7
8 #include "base/mac/foundation_util.h" 8 #include "base/mac/foundation_util.h"
9 #include "base/mac/scoped_nsobject.h" 9 #include "base/mac/scoped_nsobject.h"
10 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h" 10 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
(...skipping 21 matching lines...) Expand all
32 class MockDecoration : public LocationBarDecoration { 32 class MockDecoration : public LocationBarDecoration {
33 public: 33 public:
34 virtual CGFloat GetWidthForSpace(CGFloat width) { return 20.0; } 34 virtual CGFloat GetWidthForSpace(CGFloat width) { return 20.0; }
35 35
36 virtual void DrawInFrame(NSRect frame, NSView* control_view) { ; } 36 virtual void DrawInFrame(NSRect frame, NSView* control_view) { ; }
37 MOCK_METHOD0(AcceptsMousePress, bool()); 37 MOCK_METHOD0(AcceptsMousePress, bool());
38 MOCK_METHOD2(OnMousePressed, bool(NSRect frame, NSPoint location)); 38 MOCK_METHOD2(OnMousePressed, bool(NSRect frame, NSPoint location));
39 MOCK_METHOD0(GetMenu, NSMenu*()); 39 MOCK_METHOD0(GetMenu, NSMenu*());
40 }; 40 };
41 41
42 class MockButtonDecoration : public ButtonDecoration {
43 public:
44 // Note: It does not matter which images are used here - but ButtonDecoration
45 // needs _some_ images to work properly.
46 MockButtonDecoration()
47 : ButtonDecoration(IMAGE_GRID(IDR_OMNIBOX_EV_BUBBLE),
48 IDR_OMNIBOX_EV_BUBBLE_CENTER,
49 IMAGE_GRID(IDR_OMNIBOX_EV_BUBBLE),
50 IDR_OMNIBOX_EV_BUBBLE_CENTER,
51 IMAGE_GRID(IDR_OMNIBOX_EV_BUBBLE),
52 IDR_OMNIBOX_EV_BUBBLE_CENTER,
53 3) {}
54 void Hide() { SetVisible(false); }
55 MOCK_METHOD2(OnMousePressed, bool(NSRect frame, NSPoint location));
56 };
57
58 // Mock up an incrementing event number. 42 // Mock up an incrementing event number.
59 NSUInteger eventNumber = 0; 43 NSUInteger eventNumber = 0;
60 44
61 // Create an event of the indicated |type| at |point| within |view|. 45 // Create an event of the indicated |type| at |point| within |view|.
62 // TODO(shess): Would be nice to have a MockApplication which provided 46 // TODO(shess): Would be nice to have a MockApplication which provided
63 // nifty accessors to create these things and inject them. It could 47 // nifty accessors to create these things and inject them. It could
64 // even provide functions for "Click and drag mouse from point A to 48 // even provide functions for "Click and drag mouse from point A to
65 // point B". 49 // point B".
66 // TODO(groby): This is very similar to cocoa_testing_utils - unify. 50 // TODO(groby): This is very similar to cocoa_testing_utils - unify.
67 NSEvent* Event(NSView* view, const NSPoint point, const NSEventType type, 51 NSEvent* Event(NSView* view, const NSPoint point, const NSEventType type,
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 147
164 virtual void TearDown() { 148 virtual void TearDown() {
165 // Clear the observer so that we don't show output for 149 // Clear the observer so that we don't show output for
166 // uninteresting messages to the mock (for instance, if |field_| has 150 // uninteresting messages to the mock (for instance, if |field_| has
167 // focus at the end of the test). 151 // focus at the end of the test).
168 [field_ setObserver:NULL]; 152 [field_ setObserver:NULL];
169 153
170 AutocompleteTextFieldTest::TearDown(); 154 AutocompleteTextFieldTest::TearDown();
171 } 155 }
172 156
157 // Returns the center point of the decoration.
158 NSPoint ClickLocationForDecoration(LocationBarDecoration* decoration) {
159 AutocompleteTextFieldCell* cell = [field_ cell];
160 NSRect decoration_rect =
161 [cell frameForDecoration:decoration inFrame:[field_ bounds]];
162 EXPECT_FALSE(NSIsEmptyRect(decoration_rect));
163 return NSMakePoint(NSMidX(decoration_rect), NSMidY(decoration_rect));
164 }
165
166 void SendMouseClickToDecoration(LocationBarDecoration* decoration) {
167 NSPoint point = ClickLocationForDecoration(decoration);
168 NSEvent* downEvent = Event(field_, point, NSLeftMouseDown);
169 NSEvent* upEvent = Event(field_, point, NSLeftMouseUp);
170
171 // Can't just use -sendEvent:, since that doesn't populate -currentEvent.
172 [NSApp postEvent:downEvent atStart:YES];
173 [NSApp postEvent:upEvent atStart:NO];
174
175 NSEvent* next_event = [NSApp nextEventMatchingMask:NSAnyEventMask
176 untilDate:nil
177 inMode:NSDefaultRunLoopMode
178 dequeue:YES];
179 [NSApp sendEvent:next_event];
180 }
181
173 StrictMock<MockAutocompleteTextFieldObserver> field_observer_; 182 StrictMock<MockAutocompleteTextFieldObserver> field_observer_;
174 }; 183 };
175 184
176 // Test that we have the right cell class. 185 // Test that we have the right cell class.
177 TEST_F(AutocompleteTextFieldTest, CellClass) { 186 TEST_F(AutocompleteTextFieldTest, CellClass) {
178 EXPECT_TRUE([[field_ cell] isKindOfClass:[AutocompleteTextFieldCell class]]); 187 EXPECT_TRUE([[field_ cell] isKindOfClass:[AutocompleteTextFieldCell class]]);
179 } 188 }
180 189
181 // Test that becoming first responder sets things up correctly. 190 // Test that becoming first responder sets things up correctly.
182 TEST_F(AutocompleteTextFieldTest, FirstResponder) { 191 TEST_F(AutocompleteTextFieldTest, FirstResponder) {
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 EXPECT_TRUE(NSEqualRanges(allRange, [[field_ currentEditor] selectedRange])); 596 EXPECT_TRUE(NSEqualRanges(allRange, [[field_ currentEditor] selectedRange]));
588 597
589 // Generate another click on the decoration. 598 // Generate another click on the decoration.
590 downEvent = Event(field_, location, NSLeftMouseDown, 1); 599 downEvent = Event(field_, location, NSLeftMouseDown, 1);
591 upEvent = Event(field_, location, NSLeftMouseUp, 1); 600 upEvent = Event(field_, location, NSLeftMouseUp, 1);
592 [NSApp postEvent:upEvent atStart:YES]; 601 [NSApp postEvent:upEvent atStart:YES];
593 EXPECT_CALL(mock_left_decoration_, OnMousePressed(_, _)) 602 EXPECT_CALL(mock_left_decoration_, OnMousePressed(_, _))
594 .WillOnce(Return(true)); 603 .WillOnce(Return(true));
595 [field_ mouseDown:downEvent]; 604 [field_ mouseDown:downEvent];
596 605
606 // The text field should no longer be first responder.
597 // The selection should not have changed. 607 // The selection should not have changed.
Scott Hess - ex-Googler 2015/05/08 20:34:29 Without first responder the selection is ill-defin
erikchen 2015/05/09 01:09:38 Fixed.
598 EXPECT_TRUE(NSEqualRanges(allRange, [[field_ currentEditor] selectedRange])); 608 EXPECT_FALSE([base::mac::ObjCCast<NSView>([[field_ window] firstResponder])
609 isDescendantOf:field_]);
599 610
600 // TODO(shess): Test that mouse drags are initiated if the next 611 // TODO(shess): Test that mouse drags are initiated if the next
601 // event is a drag, or if the mouse-up takes too long to arrive. 612 // event is a drag, or if the mouse-up takes too long to arrive.
602 // IDEA: mock decoration to return a pasteboard which a mock 613 // IDEA: mock decoration to return a pasteboard which a mock
603 // AutocompleteTextField notes in -dragImage:*. 614 // AutocompleteTextField notes in -dragImage:*.
604 } 615 }
605 616
606 // Clicking a decoration should call decoration's OnMousePressed. 617 // Clicking a decoration should call decoration's OnMousePressed.
607 TEST_F(AutocompleteTextFieldTest, RightDecorationMouseDown) { 618 TEST_F(AutocompleteTextFieldTest, RightDecorationMouseDown) {
608 // At this point, not focussed. 619 // At this point, not focussed.
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 ofView:field_]; 793 ofView:field_];
783 EXPECT_FALSE([[field_ cell] showsFirstResponder]); 794 EXPECT_FALSE([[field_ cell] showsFirstResponder]);
784 EXPECT_FALSE([FieldEditor() shouldDrawInsertionPoint]); 795 EXPECT_FALSE([FieldEditor() shouldDrawInsertionPoint]);
785 796
786 [[field_ cell] setHideFocusState:NO 797 [[field_ cell] setHideFocusState:NO
787 ofView:field_]; 798 ofView:field_];
788 EXPECT_TRUE([[field_ cell] showsFirstResponder]); 799 EXPECT_TRUE([[field_ cell] showsFirstResponder]);
789 EXPECT_TRUE([FieldEditor() shouldDrawInsertionPoint]); 800 EXPECT_TRUE([FieldEditor() shouldDrawInsertionPoint]);
790 } 801 }
791 802
792 // Verify that OnSetFocus for button decorations is only sent after the 803 // Verify that clicking decorations defocuses the omnibox.
793 // decoration is picked as the target for the subsequent -mouseDown:. Otherwise 804 TEST_F(AutocompleteTextFieldObserverTest, ClickingDecorationDefocusesOmnibox) {
794 // hiding a ButtonDecoration in OnSetFocus will prevent a call to
795 // OnMousePressed, since it is already hidden at the time of mouseDown.
796 TEST_F(AutocompleteTextFieldObserverTest, ButtonDecorationFocus) {
797 // Add the mock button.
798 MockButtonDecoration mock_button;
799 mock_button.SetVisible(true);
800 AutocompleteTextFieldCell* cell = [field_ cell]; 805 AutocompleteTextFieldCell* cell = [field_ cell];
801 [cell addLeftDecoration:&mock_button];
802 806
803 // Ensure button is hidden when OnSetFocus() is called. 807 // Set up a non-interactive decoration.
804 EXPECT_CALL(field_observer_, OnSetFocus(false)).WillOnce( 808 MockDecoration noninteractive_decoration;
805 testing::InvokeWithoutArgs(&mock_button, &MockButtonDecoration::Hide)); 809 noninteractive_decoration.SetVisible(true);
810 EXPECT_CALL(noninteractive_decoration, AcceptsMousePress())
811 .WillRepeatedly(testing::Return(false));
812 [cell addLeftDecoration:&noninteractive_decoration];
806 813
807 // Ignore incidental calls. 814 // Set up an interactive decoration.
815 MockDecoration interactive_decoration;
816 EXPECT_CALL(interactive_decoration, AcceptsMousePress())
817 .WillRepeatedly(testing::Return(true));
818 interactive_decoration.SetVisible(true);
819 [cell addLeftDecoration:&interactive_decoration];
820 EXPECT_CALL(interactive_decoration, OnMousePressed(_, _))
821 .WillOnce(testing::Return(true));
822
823 // Ignore incidental calls. The exact frequency of these calls doesn't matter
824 // as they auxiliary.
Scott Hess - ex-Googler 2015/05/08 20:34:29 I think it still needs an "are" in there somewhere
erikchen 2015/05/09 01:09:37 Yup, fixed.
808 EXPECT_CALL(field_observer_, SelectionRangeForProposedRange(_)) 825 EXPECT_CALL(field_observer_, SelectionRangeForProposedRange(_))
809 .WillRepeatedly(testing::Return(NSMakeRange(0, 0))); 826 .WillRepeatedly(testing::Return(NSMakeRange(0, 0)));
810 EXPECT_CALL(field_observer_, OnMouseDown(_)); 827 EXPECT_CALL(field_observer_, OnMouseDown(_)).Times(testing::AnyNumber());
811 828 EXPECT_CALL(field_observer_, OnSetFocus(false)).Times(testing::AnyNumber());
812 // Still expect an OnMousePressed on the button. 829 EXPECT_CALL(field_observer_, OnKillFocus()).Times(testing::AnyNumber());
813 EXPECT_CALL(mock_button, OnMousePressed(_, _)) 830 EXPECT_CALL(field_observer_, OnDidEndEditing()).Times(testing::AnyNumber());
814 .WillOnce(testing::Return(true));
815
816 // Get click point for button decoration.
817 NSRect button_rect =
818 [cell frameForDecoration:&mock_button inFrame:[field_ bounds]];
819 EXPECT_FALSE(NSIsEmptyRect(button_rect));
820 NSPoint click_location =
821 NSMakePoint(NSMidX(button_rect), NSMidY(button_rect));
822 831
823 // Ensure the field is currently not first responder. 832 // Ensure the field is currently not first responder.
824 [test_window() makePretendKeyWindowAndSetFirstResponder:nil]; 833 [test_window() makePretendKeyWindowAndSetFirstResponder:nil];
825 EXPECT_NSNE([[field_ window] firstResponder], field_); 834 EXPECT_FALSE([base::mac::ObjCCast<NSView>([[field_ window] firstResponder])
835 isDescendantOf:field_]);
826 836
827 // Execute button click event sequence. 837 SendMouseClickToDecoration(&noninteractive_decoration);
828 NSEvent* downEvent = Event(field_, click_location, NSLeftMouseDown); 838 EXPECT_TRUE([base::mac::ObjCCast<NSView>([[field_ window] firstResponder])
829 NSEvent* upEvent = Event(field_, click_location, NSLeftMouseUp); 839 isDescendantOf:field_]);
830 840
831 // Can't just use -sendEvent:, since that doesn't populate -currentEvent. 841 SendMouseClickToDecoration(&interactive_decoration);
832 [NSApp postEvent:downEvent atStart:YES]; 842 EXPECT_FALSE([base::mac::ObjCCast<NSView>([[field_ window] firstResponder])
833 [NSApp postEvent:upEvent atStart:NO]; 843 isDescendantOf:field_]);
834 NSEvent* next_event = [NSApp nextEventMatchingMask:NSAnyEventMask
835 untilDate:nil
836 inMode:NSDefaultRunLoopMode
837 dequeue:YES];
838 [NSApp sendEvent:next_event];
839 844
840 // Expectations check that both OnSetFocus and OnMouseDown were called. 845 SendMouseClickToDecoration(&noninteractive_decoration);
841 // Additionally, ensure button is hidden and field is firstResponder. 846 EXPECT_TRUE([base::mac::ObjCCast<NSView>([[field_ window] firstResponder])
842 EXPECT_FALSE(mock_button.IsVisible()); 847 isDescendantOf:field_]);
843 EXPECT_TRUE(NSIsEmptyRect([cell frameForDecoration:&mock_left_decoration_
844 inFrame:[field_ bounds]]));
845 EXPECT_TRUE([base::mac::ObjCCastStrict<NSView>(
846 [[field_ window] firstResponder]) isDescendantOf:field_]);
847 } 848 }
848 849
849 TEST_F(AutocompleteTextFieldObserverTest, SendsEditingMessages) { 850 TEST_F(AutocompleteTextFieldObserverTest, SendsEditingMessages) {
850 // Many of these methods try to change the selection. 851 // Many of these methods try to change the selection.
851 EXPECT_CALL(field_observer_, SelectionRangeForProposedRange(A<NSRange>())) 852 EXPECT_CALL(field_observer_, SelectionRangeForProposedRange(A<NSRange>()))
852 .WillRepeatedly(ReturnArg<0>()); 853 .WillRepeatedly(ReturnArg<0>());
853 854
854 EXPECT_CALL(field_observer_, OnSetFocus(false)); 855 EXPECT_CALL(field_observer_, OnSetFocus(false));
855 // Becoming first responder doesn't begin editing. 856 // Becoming first responder doesn't begin editing.
856 [test_window() makePretendKeyWindowAndSetFirstResponder:field_]; 857 [test_window() makePretendKeyWindowAndSetFirstResponder:field_];
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 base::scoped_nsobject<AutocompleteTextField> pin([field_ retain]); 896 base::scoped_nsobject<AutocompleteTextField> pin([field_ retain]);
896 [field_ removeFromSuperview]; 897 [field_ removeFromSuperview];
897 [test_window() resignKeyWindow]; 898 [test_window() resignKeyWindow];
898 899
899 [[test_window() contentView] addSubview:field_]; 900 [[test_window() contentView] addSubview:field_];
900 EXPECT_CALL(field_observer_, ClosePopup()); 901 EXPECT_CALL(field_observer_, ClosePopup());
901 [test_window() resignKeyWindow]; 902 [test_window() resignKeyWindow];
902 } 903 }
903 904
904 } // namespace 905 } // namespace
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/location_bar/autocomplete_text_field.mm ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698