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
|
// Copyright (c) 2012 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>
#include "base/mac/scoped_nsobject.h"
#import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
#import "chrome/browser/ui/cocoa/styled_text_field.h"
#import "chrome/browser/ui/cocoa/styled_text_field_cell.h"
#import "chrome/browser/ui/cocoa/styled_text_field_test_helper.h"
#include "testing/gtest/include/gtest/gtest.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);
base::scoped_nsobject<StyledTextFieldTestCell> cell(
[[StyledTextFieldTestCell alloc] initTextCell:@"Testing"]);
cell_ = cell.get();
[cell_ setEditable:YES];
[cell_ setBordered:YES];
base::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
|