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

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: Revert a change to the unit test AutocompleteTextFieldTest.LeftDecorationMouseDown. 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 599 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 ofView:field_]; 791 ofView:field_];
783 EXPECT_FALSE([[field_ cell] showsFirstResponder]); 792 EXPECT_FALSE([[field_ cell] showsFirstResponder]);
784 EXPECT_FALSE([FieldEditor() shouldDrawInsertionPoint]); 793 EXPECT_FALSE([FieldEditor() shouldDrawInsertionPoint]);
785 794
786 [[field_ cell] setHideFocusState:NO 795 [[field_ cell] setHideFocusState:NO
787 ofView:field_]; 796 ofView:field_];
788 EXPECT_TRUE([[field_ cell] showsFirstResponder]); 797 EXPECT_TRUE([[field_ cell] showsFirstResponder]);
789 EXPECT_TRUE([FieldEditor() shouldDrawInsertionPoint]); 798 EXPECT_TRUE([FieldEditor() shouldDrawInsertionPoint]);
790 } 799 }
791 800
792 // Verify that OnSetFocus for button decorations is only sent after the 801 // Verify that clicking a decoration that accepts mouse clicks does not focus
793 // decoration is picked as the target for the subsequent -mouseDown:. Otherwise 802 // the Omnibox.
794 // hiding a ButtonDecoration in OnSetFocus will prevent a call to 803 TEST_F(AutocompleteTextFieldObserverTest,
795 // OnMousePressed, since it is already hidden at the time of mouseDown. 804 ClickingDecorationDoesNotFocusOmnibox) {
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 .WillRepeatedly(testing::Return(true));
822
823 // Ignore incidental calls. The exact frequency of these calls doesn't matter
824 // as they are auxiliary.
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 NSResponder* firstResponder = [[field_ window] firstResponder];
835 EXPECT_FALSE(
836 [base::mac::ObjCCast<NSView>(firstResponder) isDescendantOf:field_]);
826 837
827 // Execute button click event sequence. 838 // Clicking an interactive decoration doesn't change the first responder.
828 NSEvent* downEvent = Event(field_, click_location, NSLeftMouseDown); 839 SendMouseClickToDecoration(&interactive_decoration);
829 NSEvent* upEvent = Event(field_, click_location, NSLeftMouseUp); 840 EXPECT_NSEQ(firstResponder, [[field_ window] firstResponder]);
830 841
831 // Can't just use -sendEvent:, since that doesn't populate -currentEvent. 842 // Clicking a non-interactive decoration focuses the Omnibox.
832 [NSApp postEvent:downEvent atStart:YES]; 843 SendMouseClickToDecoration(&noninteractive_decoration);
833 [NSApp postEvent:upEvent atStart:NO]; 844 firstResponder = [[field_ window] firstResponder];
834 NSEvent* next_event = [NSApp nextEventMatchingMask:NSAnyEventMask 845 EXPECT_TRUE(
835 untilDate:nil 846 [base::mac::ObjCCast<NSView>(firstResponder) isDescendantOf:field_]);
836 inMode:NSDefaultRunLoopMode
837 dequeue:YES];
838 [NSApp sendEvent:next_event];
839 847
840 // Expectations check that both OnSetFocus and OnMouseDown were called. 848 // Clicking an interactive decoration doesn't change the first responder.
841 // Additionally, ensure button is hidden and field is firstResponder. 849 SendMouseClickToDecoration(&interactive_decoration);
842 EXPECT_FALSE(mock_button.IsVisible()); 850 EXPECT_NSEQ(firstResponder, [[field_ window] firstResponder]);
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 } 851 }
848 852
849 TEST_F(AutocompleteTextFieldObserverTest, SendsEditingMessages) { 853 TEST_F(AutocompleteTextFieldObserverTest, SendsEditingMessages) {
850 // Many of these methods try to change the selection. 854 // Many of these methods try to change the selection.
851 EXPECT_CALL(field_observer_, SelectionRangeForProposedRange(A<NSRange>())) 855 EXPECT_CALL(field_observer_, SelectionRangeForProposedRange(A<NSRange>()))
852 .WillRepeatedly(ReturnArg<0>()); 856 .WillRepeatedly(ReturnArg<0>());
853 857
854 EXPECT_CALL(field_observer_, OnSetFocus(false)); 858 EXPECT_CALL(field_observer_, OnSetFocus(false));
855 // Becoming first responder doesn't begin editing. 859 // Becoming first responder doesn't begin editing.
856 [test_window() makePretendKeyWindowAndSetFirstResponder:field_]; 860 [test_window() makePretendKeyWindowAndSetFirstResponder:field_];
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 base::scoped_nsobject<AutocompleteTextField> pin([field_ retain]); 899 base::scoped_nsobject<AutocompleteTextField> pin([field_ retain]);
896 [field_ removeFromSuperview]; 900 [field_ removeFromSuperview];
897 [test_window() resignKeyWindow]; 901 [test_window() resignKeyWindow];
898 902
899 [[test_window() contentView] addSubview:field_]; 903 [[test_window() contentView] addSubview:field_];
900 EXPECT_CALL(field_observer_, ClosePopup()); 904 EXPECT_CALL(field_observer_, ClosePopup());
901 [test_window() resignKeyWindow]; 905 [test_window() resignKeyWindow];
902 } 906 }
903 907
904 } // namespace 908 } // 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