summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa/styled_text_field_unittest.mm
blob: 000e77af48699fe52162b23db4733a0875c29ea7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import <Cocoa/Cocoa.h>

#import "base/cocoa_protocols_mac.h"
#include "base/scoped_nsobject.h"
#import "chrome/browser/cocoa/styled_text_field.h"
#import "chrome/browser/cocoa/styled_text_field_cell.h"
#import "chrome/browser/cocoa/styled_text_field_test_helper.h"
#import "chrome/browser/cocoa/cocoa_test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
#import "third_party/ocmock/OCMock/OCMock.h"

namespace {

// Width of the field so that we don't have to ask |field_| for it all
// the time.
static const CGFloat kWidth(300.0);

class StyledTextFieldTest : public CocoaTest {
 public:
  StyledTextFieldTest() {
    // Make sure this is wide enough to play games with the cell
    // decorations.
    NSRect frame = NSMakeRect(0, 0, kWidth, 30);

    scoped_nsobject<StyledTextFieldTestCell> cell(
        [[StyledTextFieldTestCell alloc] initTextCell:@"Testing"]);
    cell_ = cell.get();
    [cell_ setEditable:YES];
    [cell_ setBordered:YES];

    scoped_nsobject<StyledTextField> field(
        [[StyledTextField alloc] initWithFrame:frame]);
    field_ = field.get();
    [field_ setCell:cell_];

    [[test_window() contentView] addSubview:field_];
  }

  // Helper to return the field-editor frame being used w/in |field_|.
  NSRect EditorFrame() {
    EXPECT_TRUE([field_ currentEditor]);
    EXPECT_EQ([[field_ subviews] count], 1U);
    if ([[field_ subviews] count] > 0) {
      return [[[field_ subviews] objectAtIndex:0] frame];
    } else {
      // Return something which won't work so the caller can soldier
      // on.
      return NSZeroRect;
    }
  }

  StyledTextField* field_;
  StyledTextFieldTestCell* cell_;
};

// Basic view tests (AddRemove, Display).
TEST_VIEW(StyledTextFieldTest, field_);

// Test that we get the same cell from -cell and
// -styledTextFieldCell.
TEST_F(StyledTextFieldTest, Cell) {
  StyledTextFieldCell* cell = [field_ styledTextFieldCell];
  EXPECT_EQ(cell, [field_ cell]);
  EXPECT_TRUE(cell != nil);
}

// Test that becoming first responder sets things up correctly.
TEST_F(StyledTextFieldTest, FirstResponder) {
  EXPECT_EQ(nil, [field_ currentEditor]);
  EXPECT_EQ([[field_ subviews] count], 0U);
  [test_window() makePretendKeyWindowAndSetFirstResponder:field_];
  EXPECT_FALSE(nil == [field_ currentEditor]);
  EXPECT_EQ([[field_ subviews] count], 1U);
  EXPECT_TRUE([[field_ currentEditor] isDescendantOf:field_]);
}

TEST_F(StyledTextFieldTest, AvailableDecorationWidth) {
  // A fudge factor to account for how much space the border takes up.
  // The test shouldn't be too dependent on the field's internals, but
  // it also shouldn't let deranged cases fall through the cracks
  // (like nothing available with no text, or everything available
  // with some text).
  const CGFloat kBorderWidth = 20.0;

  // With no contents, almost the entire width is available for
  // decorations.
  [field_ setStringValue:@""];
  CGFloat availableWidth = [field_ availableDecorationWidth];
  EXPECT_LE(availableWidth, kWidth);
  EXPECT_GT(availableWidth, kWidth - kBorderWidth);

  // With minor contents, most of the remaining width is available for
  // decorations.
  NSDictionary* attributes =
      [NSDictionary dictionaryWithObject:[field_ font]
                                  forKey:NSFontAttributeName];
  NSString* string = @"Hello world";
  const NSSize size([string sizeWithAttributes:attributes]);
  [field_ setStringValue:string];
  availableWidth = [field_ availableDecorationWidth];
  EXPECT_LE(availableWidth, kWidth - size.width);
  EXPECT_GT(availableWidth, kWidth - size.width - kBorderWidth);

  // With huge contents, nothing at all is left for decorations.
  string = @"A long string which is surely wider than field_ can hold.";
  [field_ setStringValue:string];
  availableWidth = [field_ availableDecorationWidth];
  EXPECT_LT(availableWidth, 0.0);
}

// Test drawing, mostly to ensure nothing leaks or crashes.
TEST_F(StyledTextFieldTest, Display) {
  [field_ display];

  // Test focused drawing.
  [test_window() makePretendKeyWindowAndSetFirstResponder:field_];
  [field_ display];
}

// Test that the field editor gets the same bounds when focus is delivered by
// the standard focusing machinery, or by -resetFieldEditorFrameIfNeeded.
TEST_F(StyledTextFieldTest, ResetFieldEditorBase) {
  // Capture the editor frame resulting from the standard focus machinery.
  [test_window() makePretendKeyWindowAndSetFirstResponder:field_];
  const NSRect baseEditorFrame(EditorFrame());

  // Setting a hint should result in a strictly smaller editor frame.
  EXPECT_EQ(0, [cell_ leftMargin]);
  EXPECT_EQ(0, [cell_ rightMargin]);
  [cell_ setLeftMargin:10];
  [field_ resetFieldEditorFrameIfNeeded];
  EXPECT_FALSE(NSEqualRects(baseEditorFrame, EditorFrame()));
  EXPECT_TRUE(NSContainsRect(baseEditorFrame, EditorFrame()));

  // Resetting the margin and using -resetFieldEditorFrameIfNeeded should result
  // in the same frame as the standard focus machinery.
  [cell_ setLeftMargin:0];
  [field_ resetFieldEditorFrameIfNeeded];
  EXPECT_TRUE(NSEqualRects(baseEditorFrame, EditorFrame()));
}

// Test that the field editor gets the same bounds when focus is delivered by
// the standard focusing machinery, or by -resetFieldEditorFrameIfNeeded.
TEST_F(StyledTextFieldTest, ResetFieldEditorLeftMargin) {
  const CGFloat kLeftMargin = 20;

  // Start the cell off with a non-zero left margin.
  [cell_ setLeftMargin:kLeftMargin];
  [cell_ setRightMargin:0];

  // Capture the editor frame resulting from the standard focus machinery.
  [test_window() makePretendKeyWindowAndSetFirstResponder:field_];
  const NSRect baseEditorFrame(EditorFrame());

  // Clearing the margin should result in a strictly larger editor frame.
  [cell_ setLeftMargin:0];
  [field_ resetFieldEditorFrameIfNeeded];
  EXPECT_FALSE(NSEqualRects(baseEditorFrame, EditorFrame()));
  EXPECT_TRUE(NSContainsRect(EditorFrame(), baseEditorFrame));

  // Setting the same margin and using -resetFieldEditorFrameIfNeeded should
  // result in the same frame as the standard focus machinery.
  [cell_ setLeftMargin:kLeftMargin];
  [field_ resetFieldEditorFrameIfNeeded];
  EXPECT_TRUE(NSEqualRects(baseEditorFrame, EditorFrame()));
}

// Test that the field editor gets the same bounds when focus is delivered by
// the standard focusing machinery, or by -resetFieldEditorFrameIfNeeded.
TEST_F(StyledTextFieldTest, ResetFieldEditorRightMargin) {
  const CGFloat kRightMargin = 20;

  // Start the cell off with a non-zero right margin.
  [cell_ setLeftMargin:0];
  [cell_ setRightMargin:kRightMargin];

  // Capture the editor frame resulting from the standard focus machinery.
  [test_window() makePretendKeyWindowAndSetFirstResponder:field_];
  const NSRect baseEditorFrame(EditorFrame());

  // Clearing the margin should result in a strictly larger editor frame.
  [cell_ setRightMargin:0];
  [field_ resetFieldEditorFrameIfNeeded];
  EXPECT_FALSE(NSEqualRects(baseEditorFrame, EditorFrame()));
  EXPECT_TRUE(NSContainsRect(EditorFrame(), baseEditorFrame));

  // Setting the same margin and using -resetFieldEditorFrameIfNeeded should
  // result in the same frame as the standard focus machinery.
  [cell_ setRightMargin:kRightMargin];
  [field_ resetFieldEditorFrameIfNeeded];
  EXPECT_TRUE(NSEqualRects(baseEditorFrame, EditorFrame()));
}

}  // namespace