// 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
