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
3 // found in the LICENSE file.
5 #import <Cocoa/Cocoa.h>
7 #include "base/mac/scoped_nsobject.h"
8 #import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
9 #import "chrome/browser/ui/cocoa/styled_text_field.h"
10 #import "chrome/browser/ui/cocoa/styled_text_field_cell.h"
11 #import "chrome/browser/ui/cocoa/styled_text_field_test_helper.h"
12 #include "testing/gtest/include/gtest/gtest.h"
16 // Width of the field so that we don't have to ask |field_| for it all
18 static const CGFloat kWidth(300.0);
20 class StyledTextFieldTest : public CocoaTest {
22 StyledTextFieldTest() {
23 // Make sure this is wide enough to play games with the cell
25 NSRect frame = NSMakeRect(0, 0, kWidth, 30);
27 base::scoped_nsobject<StyledTextFieldTestCell> cell(
28 [[StyledTextFieldTestCell alloc] initTextCell:@"Testing"]);
30 [cell_ setEditable:YES];
31 [cell_ setBordered:YES];
33 base::scoped_nsobject<StyledTextField> field(
34 [[StyledTextField alloc] initWithFrame:frame]);
36 [field_ setCell:cell_];
38 [[test_window() contentView] addSubview:field_];
41 // Helper to return the field-editor frame being used w/in |field_|.
42 NSRect EditorFrame() {
43 EXPECT_TRUE([field_ currentEditor]);
44 EXPECT_EQ([[field_ subviews] count], 1U);
45 if ([[field_ subviews] count] > 0) {
46 return [[[field_ subviews] objectAtIndex:0] frame];
48 // Return something which won't work so the caller can soldier
54 StyledTextField* field_;
55 StyledTextFieldTestCell* cell_;
58 // Basic view tests (AddRemove, Display).
59 TEST_VIEW(StyledTextFieldTest, field_);
61 // Test that we get the same cell from -cell and
62 // -styledTextFieldCell.
63 TEST_F(StyledTextFieldTest, Cell) {
64 StyledTextFieldCell* cell = [field_ styledTextFieldCell];
65 EXPECT_EQ(cell, [field_ cell]);
66 EXPECT_TRUE(cell != nil);
69 // Test that becoming first responder sets things up correctly.
70 TEST_F(StyledTextFieldTest, FirstResponder) {
71 EXPECT_EQ(nil, [field_ currentEditor]);
72 EXPECT_EQ([[field_ subviews] count], 0U);
73 [test_window() makePretendKeyWindowAndSetFirstResponder:field_];
74 EXPECT_FALSE(nil == [field_ currentEditor]);
75 EXPECT_EQ([[field_ subviews] count], 1U);
76 EXPECT_TRUE([[field_ currentEditor] isDescendantOf:field_]);
79 TEST_F(StyledTextFieldTest, AvailableDecorationWidth) {
80 // A fudge factor to account for how much space the border takes up.
81 // The test shouldn't be too dependent on the field's internals, but
82 // it also shouldn't let deranged cases fall through the cracks
83 // (like nothing available with no text, or everything available
85 const CGFloat kBorderWidth = 20.0;
87 // With no contents, almost the entire width is available for
89 [field_ setStringValue:@""];
90 CGFloat availableWidth = [field_ availableDecorationWidth];
91 EXPECT_LE(availableWidth, kWidth);
92 EXPECT_GT(availableWidth, kWidth - kBorderWidth);
94 // With minor contents, most of the remaining width is available for
96 NSDictionary* attributes =
97 [NSDictionary dictionaryWithObject:[field_ font]
98 forKey:NSFontAttributeName];
99 NSString* string = @"Hello world";
100 const NSSize size([string sizeWithAttributes:attributes]);
101 [field_ setStringValue:string];
102 availableWidth = [field_ availableDecorationWidth];
103 EXPECT_LE(availableWidth, kWidth - size.width);
104 EXPECT_GT(availableWidth, kWidth - size.width - kBorderWidth);
106 // With huge contents, nothing at all is left for decorations.
107 string = @"A long string which is surely wider than field_ can hold.";
108 [field_ setStringValue:string];
109 availableWidth = [field_ availableDecorationWidth];
110 EXPECT_LT(availableWidth, 0.0);
113 // Test drawing, mostly to ensure nothing leaks or crashes.
114 TEST_F(StyledTextFieldTest, Display) {
117 // Test focused drawing.
118 [test_window() makePretendKeyWindowAndSetFirstResponder:field_];
122 // Test that the field editor gets the same bounds when focus is delivered by
123 // the standard focusing machinery, or by -resetFieldEditorFrameIfNeeded.
124 TEST_F(StyledTextFieldTest, ResetFieldEditorBase) {
125 // Capture the editor frame resulting from the standard focus machinery.
126 [test_window() makePretendKeyWindowAndSetFirstResponder:field_];
127 const NSRect baseEditorFrame(EditorFrame());
129 // Setting a hint should result in a strictly smaller editor frame.
130 EXPECT_EQ(0, [cell_ leftMargin]);
131 EXPECT_EQ(0, [cell_ rightMargin]);
132 [cell_ setLeftMargin:10];
133 [field_ resetFieldEditorFrameIfNeeded];
134 EXPECT_FALSE(NSEqualRects(baseEditorFrame, EditorFrame()));
135 EXPECT_TRUE(NSContainsRect(baseEditorFrame, EditorFrame()));
137 // Resetting the margin and using -resetFieldEditorFrameIfNeeded should result
138 // in the same frame as the standard focus machinery.
139 [cell_ setLeftMargin:0];
140 [field_ resetFieldEditorFrameIfNeeded];
141 EXPECT_TRUE(NSEqualRects(baseEditorFrame, EditorFrame()));
144 // Test that the field editor gets the same bounds when focus is delivered by
145 // the standard focusing machinery, or by -resetFieldEditorFrameIfNeeded.
146 TEST_F(StyledTextFieldTest, ResetFieldEditorLeftMargin) {
147 const CGFloat kLeftMargin = 20;
149 // Start the cell off with a non-zero left margin.
150 [cell_ setLeftMargin:kLeftMargin];
151 [cell_ setRightMargin:0];
153 // Capture the editor frame resulting from the standard focus machinery.
154 [test_window() makePretendKeyWindowAndSetFirstResponder:field_];
155 const NSRect baseEditorFrame(EditorFrame());
157 // Clearing the margin should result in a strictly larger editor frame.
158 [cell_ setLeftMargin:0];
159 [field_ resetFieldEditorFrameIfNeeded];
160 EXPECT_FALSE(NSEqualRects(baseEditorFrame, EditorFrame()));
161 EXPECT_TRUE(NSContainsRect(EditorFrame(), baseEditorFrame));
163 // Setting the same margin and using -resetFieldEditorFrameIfNeeded should
164 // result in the same frame as the standard focus machinery.
165 [cell_ setLeftMargin:kLeftMargin];
166 [field_ resetFieldEditorFrameIfNeeded];
167 EXPECT_TRUE(NSEqualRects(baseEditorFrame, EditorFrame()));
170 // Test that the field editor gets the same bounds when focus is delivered by
171 // the standard focusing machinery, or by -resetFieldEditorFrameIfNeeded.
172 TEST_F(StyledTextFieldTest, ResetFieldEditorRightMargin) {
173 const CGFloat kRightMargin = 20;
175 // Start the cell off with a non-zero right margin.
176 [cell_ setLeftMargin:0];
177 [cell_ setRightMargin:kRightMargin];
179 // Capture the editor frame resulting from the standard focus machinery.
180 [test_window() makePretendKeyWindowAndSetFirstResponder:field_];
181 const NSRect baseEditorFrame(EditorFrame());
183 // Clearing the margin should result in a strictly larger editor frame.
184 [cell_ setRightMargin:0];
185 [field_ resetFieldEditorFrameIfNeeded];
186 EXPECT_FALSE(NSEqualRects(baseEditorFrame, EditorFrame()));
187 EXPECT_TRUE(NSContainsRect(EditorFrame(), baseEditorFrame));
189 // Setting the same margin and using -resetFieldEditorFrameIfNeeded should
190 // result in the same frame as the standard focus machinery.
191 [cell_ setRightMargin:kRightMargin];
192 [field_ resetFieldEditorFrameIfNeeded];
193 EXPECT_TRUE(NSEqualRects(baseEditorFrame, EditorFrame()));