- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / styled_text_field_unittest.mm
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.
4
5 #import <Cocoa/Cocoa.h>
6
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"
13
14 namespace {
15
16 // Width of the field so that we don't have to ask |field_| for it all
17 // the time.
18 static const CGFloat kWidth(300.0);
19
20 class StyledTextFieldTest : public CocoaTest {
21  public:
22   StyledTextFieldTest() {
23     // Make sure this is wide enough to play games with the cell
24     // decorations.
25     NSRect frame = NSMakeRect(0, 0, kWidth, 30);
26
27     base::scoped_nsobject<StyledTextFieldTestCell> cell(
28         [[StyledTextFieldTestCell alloc] initTextCell:@"Testing"]);
29     cell_ = cell.get();
30     [cell_ setEditable:YES];
31     [cell_ setBordered:YES];
32
33     base::scoped_nsobject<StyledTextField> field(
34         [[StyledTextField alloc] initWithFrame:frame]);
35     field_ = field.get();
36     [field_ setCell:cell_];
37
38     [[test_window() contentView] addSubview:field_];
39   }
40
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];
47     } else {
48       // Return something which won't work so the caller can soldier
49       // on.
50       return NSZeroRect;
51     }
52   }
53
54   StyledTextField* field_;
55   StyledTextFieldTestCell* cell_;
56 };
57
58 // Basic view tests (AddRemove, Display).
59 TEST_VIEW(StyledTextFieldTest, field_);
60
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);
67 }
68
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_]);
77 }
78
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
84   // with some text).
85   const CGFloat kBorderWidth = 20.0;
86
87   // With no contents, almost the entire width is available for
88   // decorations.
89   [field_ setStringValue:@""];
90   CGFloat availableWidth = [field_ availableDecorationWidth];
91   EXPECT_LE(availableWidth, kWidth);
92   EXPECT_GT(availableWidth, kWidth - kBorderWidth);
93
94   // With minor contents, most of the remaining width is available for
95   // decorations.
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);
105
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);
111 }
112
113 // Test drawing, mostly to ensure nothing leaks or crashes.
114 TEST_F(StyledTextFieldTest, Display) {
115   [field_ display];
116
117   // Test focused drawing.
118   [test_window() makePretendKeyWindowAndSetFirstResponder:field_];
119   [field_ display];
120 }
121
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());
128
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()));
136
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()));
142 }
143
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;
148
149   // Start the cell off with a non-zero left margin.
150   [cell_ setLeftMargin:kLeftMargin];
151   [cell_ setRightMargin:0];
152
153   // Capture the editor frame resulting from the standard focus machinery.
154   [test_window() makePretendKeyWindowAndSetFirstResponder:field_];
155   const NSRect baseEditorFrame(EditorFrame());
156
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));
162
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()));
168 }
169
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;
174
175   // Start the cell off with a non-zero right margin.
176   [cell_ setLeftMargin:0];
177   [cell_ setRightMargin:kRightMargin];
178
179   // Capture the editor frame resulting from the standard focus machinery.
180   [test_window() makePretendKeyWindowAndSetFirstResponder:field_];
181   const NSRect baseEditorFrame(EditorFrame());
182
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));
188
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()));
194 }
195
196 }  // namespace