// Copyright 2014 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 "ui/views_bridge_mac/bridged_native_widget_impl.h"

#import <Cocoa/Cocoa.h>
#include <objc/runtime.h>

#include <memory>

#import "base/mac/foundation_util.h"
#import "base/mac/mac_util.h"
#import "base/mac/scoped_objc_class_swizzler.h"
#import "base/mac/sdk_forward_declarations.h"
#include "base/macros.h"
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_task_environment.h"
#import "testing/gtest_mac.h"
#import "ui/base/cocoa/window_size_constants.h"
#include "ui/base/ime/input_method.h"
#include "ui/base/material_design/material_design_controller.h"
#import "ui/base/test/cocoa_helper.h"
#include "ui/events/test/cocoa_test_event_utils.h"
#import "ui/gfx/mac/coordinate_conversion.h"
#import "ui/views/cocoa/bridged_native_widget_host_impl.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/controls/textfield/textfield_controller.h"
#include "ui/views/controls/textfield/textfield_model.h"
#include "ui/views/test/test_views_delegate.h"
#include "ui/views/view.h"
#include "ui/views/widget/native_widget_mac.h"
#include "ui/views/widget/root_view.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_observer.h"
#import "ui/views_bridge_mac/bridged_content_view.h"
#import "ui/views_bridge_mac/native_widget_mac_nswindow.h"
#import "ui/views_bridge_mac/views_nswindow_delegate.h"

using base::ASCIIToUTF16;
using base::SysNSStringToUTF8;
using base::SysNSStringToUTF16;
using base::SysUTF8ToNSString;
using base::SysUTF16ToNSString;

#define EXPECT_EQ_RANGE(a, b)        \
  EXPECT_EQ(a.location, b.location); \
  EXPECT_EQ(a.length, b.length);

// Helpers to verify an expectation against both the actual toolkit-views
// behaviour and the Cocoa behaviour.

#define EXPECT_NSEQ_3(expected_literal, expected_cocoa, actual_views) \
  EXPECT_NSEQ(expected_literal, actual_views);                        \
  EXPECT_NSEQ(expected_cocoa, actual_views);

#define EXPECT_EQ_RANGE_3(expected_literal, expected_cocoa, actual_views) \
  EXPECT_EQ_RANGE(expected_literal, actual_views);                        \
  EXPECT_EQ_RANGE(expected_cocoa, actual_views);

#define EXPECT_EQ_3(expected_literal, expected_cocoa, actual_views) \
  EXPECT_EQ(expected_literal, actual_views);                        \
  EXPECT_EQ(expected_cocoa, actual_views);

namespace {

// Implemented NSResponder action messages for use in tests.
NSArray* const kMoveActions = @[
  @"moveForward:",
  @"moveRight:",
  @"moveBackward:",
  @"moveLeft:",
  @"moveUp:",
  @"moveDown:",
  @"moveWordForward:",
  @"moveWordBackward:",
  @"moveToBeginningOfLine:",
  @"moveToEndOfLine:",
  @"moveToBeginningOfParagraph:",
  @"moveToEndOfParagraph:",
  @"moveToEndOfDocument:",
  @"moveToBeginningOfDocument:",
  @"pageDown:",
  @"pageUp:",
  @"moveWordRight:",
  @"moveWordLeft:",
  @"moveToLeftEndOfLine:",
  @"moveToRightEndOfLine:"
];

NSArray* const kSelectActions = @[
  @"moveBackwardAndModifySelection:",
  @"moveForwardAndModifySelection:",
  @"moveWordForwardAndModifySelection:",
  @"moveWordBackwardAndModifySelection:",
  @"moveUpAndModifySelection:",
  @"moveDownAndModifySelection:",
  @"moveToBeginningOfLineAndModifySelection:",
  @"moveToEndOfLineAndModifySelection:",
  @"moveToBeginningOfParagraphAndModifySelection:",
  @"moveToEndOfParagraphAndModifySelection:",
  @"moveToEndOfDocumentAndModifySelection:",
  @"moveToBeginningOfDocumentAndModifySelection:",
  @"pageDownAndModifySelection:",
  @"pageUpAndModifySelection:",
  @"moveParagraphForwardAndModifySelection:",
  @"moveParagraphBackwardAndModifySelection:",
  @"moveRightAndModifySelection:",
  @"moveLeftAndModifySelection:",
  @"moveWordRightAndModifySelection:",
  @"moveWordLeftAndModifySelection:",
  @"moveToLeftEndOfLineAndModifySelection:",
  @"moveToRightEndOfLineAndModifySelection:"
];

NSArray* const kDeleteActions = @[
  @"deleteForward:", @"deleteBackward:", @"deleteWordForward:",
  @"deleteWordBackward:", @"deleteToBeginningOfLine:", @"deleteToEndOfLine:",
  @"deleteToBeginningOfParagraph:", @"deleteToEndOfParagraph:"
];

// This omits @"insertText:":. See BridgedNativeWidgetTest.NilTextInputClient.
NSArray* const kMiscActions = @[ @"cancelOperation:", @"transpose:", @"yank:" ];

// Empty range shortcut for readibility.
NSRange EmptyRange() {
  return NSMakeRange(NSNotFound, 0);
}

// Sets |composition_text| as the composition text with caret placed at
// |caret_pos| and updates |caret_range|.
void SetCompositionText(ui::TextInputClient* client,
                        const base::string16& composition_text,
                        const int caret_pos,
                        NSRange* caret_range) {
  ui::CompositionText composition;
  composition.selection = gfx::Range(caret_pos);
  composition.text = composition_text;
  client->SetCompositionText(composition);
  if (caret_range)
    *caret_range = NSMakeRange(caret_pos, 0);
}

// Returns a zero width rectangle corresponding to current caret position.
gfx::Rect GetCaretBounds(const ui::TextInputClient* client) {
  gfx::Rect caret_bounds = client->GetCaretBounds();
  caret_bounds.set_width(0);
  return caret_bounds;
}

// Returns a zero width rectangle corresponding to caret bounds when it's placed
// at |caret_pos| and updates |caret_range|.
gfx::Rect GetCaretBoundsForPosition(ui::TextInputClient* client,
                                    const base::string16& composition_text,
                                    const int caret_pos,
                                    NSRange* caret_range) {
  SetCompositionText(client, composition_text, caret_pos, caret_range);
  return GetCaretBounds(client);
}

// Returns the expected boundary rectangle for characters of |composition_text|
// within the |query_range|.
gfx::Rect GetExpectedBoundsForRange(ui::TextInputClient* client,
                                    const base::string16& composition_text,
                                    NSRange query_range) {
  gfx::Rect left_caret = GetCaretBoundsForPosition(
      client, composition_text, query_range.location, nullptr);
  gfx::Rect right_caret = GetCaretBoundsForPosition(
      client, composition_text, query_range.location + query_range.length,
      nullptr);

  // The expected bounds correspond to the area between the left and right caret
  // positions.
  return gfx::Rect(left_caret.x(), left_caret.y(),
                   right_caret.x() - left_caret.x(), left_caret.height());
}

// Uses the NSTextInputClient protocol to extract a substring from |view|.
NSString* GetViewStringForRange(NSView<NSTextInputClient>* view,
                                NSRange range) {
  return [[view attributedSubstringForProposedRange:range actualRange:nullptr]
      string];
}

// The behavior of NSTextView for RTL strings is buggy for some move and select
// commands, but only when the command is received when there is a selection
// active. E.g. moveRight: moves a cursor right in an RTL string, but it moves
// to the left-end of a selection. See TestEditingCommands() for specifics.
// This is filed as rdar://27863290.
bool IsRTLMoveBuggy(SEL sel) {
  return sel == @selector(moveWordRight:) || sel == @selector(moveWordLeft:) ||
         sel == @selector(moveRight:) || sel == @selector(moveLeft:);
}
bool IsRTLSelectBuggy(SEL sel) {
  return sel == @selector(moveWordRightAndModifySelection:) ||
         sel == @selector(moveWordLeftAndModifySelection:) ||
         sel == @selector(moveRightAndModifySelection:) ||
         sel == @selector(moveLeftAndModifySelection:);
}

// Used by InterpretKeyEventsDonorForNSView to simulate IME behavior.
using InterpretKeyEventsCallback = base::RepeatingCallback<void(id)>;
InterpretKeyEventsCallback* g_fake_interpret_key_events = nullptr;

// Used by UpdateWindowsDonorForNSApp to hook -[NSApp updateWindows].
base::RepeatingClosure* g_update_windows_closure = nullptr;

// Used to provide a return value for +[NSTextInputContext currentInputContext].
NSTextInputContext* g_fake_current_input_context = nullptr;

}  // namespace

// Subclass of BridgedContentView with an override of interpretKeyEvents:. Note
// the size of the class must match BridgedContentView since the method table
// is swapped out at runtime. This is basically a mock, but mocks are banned
// under ui/views. Method swizzling causes these tests to flake when
// parallelized in the same process.
@interface InterpretKeyEventMockedBridgedContentView : BridgedContentView
@end

@implementation InterpretKeyEventMockedBridgedContentView

- (void)interpretKeyEvents:(NSArray<NSEvent*>*)eventArray {
  ASSERT_TRUE(g_fake_interpret_key_events);
  g_fake_interpret_key_events->Run(self);
}

@end

@interface UpdateWindowsDonorForNSApp : NSApplication
@end

@implementation UpdateWindowsDonorForNSApp

- (void)updateWindows {
  ASSERT_TRUE(g_update_windows_closure);
  g_update_windows_closure->Run();
}

@end
@interface CurrentInputContextDonorForNSTextInputContext : NSTextInputContext
@end

@implementation CurrentInputContextDonorForNSTextInputContext

+ (NSTextInputContext*)currentInputContext {
  return g_fake_current_input_context;
}

@end

// Class to override -[NSWindow toggleFullScreen:] to a no-op. This simulates
// NSWindow's behavior when attempting to toggle fullscreen state again, when
// the last attempt failed but Cocoa has not yet sent
// windowDidFailToEnterFullScreen:.
@interface BridgedNativeWidgetTestWindow : NativeWidgetMacNSWindow {
 @private
  BOOL ignoreToggleFullScreen_;
  int ignoredToggleFullScreenCount_;
}
@property(assign, nonatomic) BOOL ignoreToggleFullScreen;
@property(readonly, nonatomic) int ignoredToggleFullScreenCount;
@end

@implementation BridgedNativeWidgetTestWindow

@synthesize ignoreToggleFullScreen = ignoreToggleFullScreen_;
@synthesize ignoredToggleFullScreenCount = ignoredToggleFullScreenCount_;

- (void)performSelector:(SEL)aSelector
             withObject:(id)anArgument
             afterDelay:(NSTimeInterval)delay {
  // This is used in simulations without a message loop. Don't start a message
  // loop since that would expose the tests to system notifications and
  // potential flakes. Instead, just pretend the message loop is flushed here.
  if (ignoreToggleFullScreen_ && aSelector == @selector(toggleFullScreen:))
    [self toggleFullScreen:anArgument];
  else
    [super performSelector:aSelector withObject:anArgument afterDelay:delay];
}

- (void)toggleFullScreen:(id)sender {
  if (ignoreToggleFullScreen_)
    ++ignoredToggleFullScreenCount_;
  else
    [super toggleFullScreen:sender];
}

@end

namespace views {
namespace test {

// Provides the |parent| argument to construct a BridgedNativeWidgetImpl.
class MockNativeWidgetMac : public NativeWidgetMac {
 public:
  explicit MockNativeWidgetMac(internal::NativeWidgetDelegate* delegate)
      : NativeWidgetMac(delegate) {}
  using NativeWidgetMac::bridge_impl;
  using NativeWidgetMac::bridge_host;

  // internal::NativeWidgetPrivate:
  void InitNativeWidget(const Widget::InitParams& params) override {
    ownership_ = params.ownership;

    base::scoped_nsobject<NativeWidgetMacNSWindow> window(
        [[BridgedNativeWidgetTestWindow alloc]
            initWithContentRect:ui::kWindowSizeDeterminedLater
                      styleMask:NSBorderlessWindowMask
                        backing:NSBackingStoreBuffered
                          defer:NO]);
    bridge_host()->CreateLocalBridge(window);
    if (auto* parent =
            BridgedNativeWidgetHostImpl::GetFromNativeView(params.parent)) {
      bridge_host()->SetParent(parent);
    }
    bridge_host()->InitWindow(params);

    // Usually the bridge gets initialized here. It is skipped to run extra
    // checks in tests, and so that a second window isn't created.
    delegate()->OnNativeWidgetCreated(true);

    // To allow events to dispatch to a view, it needs a way to get focus.
    bridge_host()->SetFocusManager(GetWidget()->GetFocusManager());
  }

  void ReorderNativeViews() override {
    // Called via Widget::Init to set the content view. No-op in these tests.
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(MockNativeWidgetMac);
};

// Helper test base to construct a BridgedNativeWidgetImpl with a valid parent.
class BridgedNativeWidgetTestBase : public ui::CocoaTest {
 public:
  struct SkipInitialization {};

  BridgedNativeWidgetTestBase()
      : widget_(new Widget),
        native_widget_mac_(new MockNativeWidgetMac(widget_.get())) {}

  explicit BridgedNativeWidgetTestBase(SkipInitialization tag)
      : native_widget_mac_(nullptr) {}

  BridgedNativeWidgetImpl* bridge() {
    return native_widget_mac_->bridge_impl();
  }
  BridgedNativeWidgetHostImpl* bridge_host() {
    return native_widget_mac_->bridge_host();
  }

  // Generate an autoreleased KeyDown NSEvent* in |widget_| for pressing the
  // corresponding |key_code|.
  NSEvent* VkeyKeyDown(ui::KeyboardCode key_code) {
    return cocoa_test_event_utils::SynthesizeKeyEvent(
        widget_->GetNativeWindow().GetNativeNSWindow(), true /* keyDown */,
        key_code, 0);
  }

  // Generate an autoreleased KeyDown NSEvent* using the given keycode, and
  // representing the first unicode character of |chars|.
  NSEvent* UnicodeKeyDown(int key_code, NSString* chars) {
    return cocoa_test_event_utils::KeyEventWithKeyCode(
        key_code, [chars characterAtIndex:0], NSKeyDown, 0);
  }

  // Overridden from testing::Test:
  void SetUp() override {
    ui::CocoaTest::SetUp();

    ui::MaterialDesignController::Initialize();

    init_params_.native_widget = native_widget_mac_;

    // Use a frameless window, otherwise Widget will try to center the window
    // before the tests covering the Init() flow are ready to do that.
    init_params_.type = Widget::InitParams::TYPE_WINDOW_FRAMELESS;

    // To control the lifetime without an actual window that must be closed,
    // tests in this file need to use WIDGET_OWNS_NATIVE_WIDGET.
    init_params_.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;

    // Opacity defaults to "infer" which is usually updated by ViewsDelegate.
    init_params_.opacity = Widget::InitParams::OPAQUE_WINDOW;

    init_params_.bounds = gfx::Rect(100, 100, 100, 100);

    if (native_widget_mac_)
      native_widget_mac_->GetWidget()->Init(init_params_);
  }

  void TearDown() override {
    // ui::CocoaTest::TearDown will wait until all NSWindows are destroyed, so
    // be sure to destroy the widget (which will destroy its NSWindow)
    // beforehand.
    widget_.reset();
    ui::CocoaTest::TearDown();
  }

  NSWindow* bridge_window() const {
    if (native_widget_mac_->bridge_impl())
      return native_widget_mac_->bridge_impl()->ns_window();
    return nil;
  }

 protected:
  std::unique_ptr<Widget> widget_;
  MockNativeWidgetMac* native_widget_mac_;  // Weak. Owned by |widget_|.

  // Make the InitParams available to tests to cover initialization codepaths.
  Widget::InitParams init_params_;

 private:
  TestViewsDelegate test_views_delegate_;

  DISALLOW_COPY_AND_ASSIGN(BridgedNativeWidgetTestBase);
};

class BridgedNativeWidgetTest : public BridgedNativeWidgetTestBase,
                                public TextfieldController {
 public:
  using HandleKeyEventCallback =
      base::RepeatingCallback<bool(Textfield*, const ui::KeyEvent& key_event)>;

  BridgedNativeWidgetTest();
  ~BridgedNativeWidgetTest() override;

  // Install a textfield with input type |text_input_type| in the view hierarchy
  // and make it the text input client. Also initializes |dummy_text_view_|.
  Textfield* InstallTextField(
      const base::string16& text,
      ui::TextInputType text_input_type = ui::TEXT_INPUT_TYPE_TEXT);
  Textfield* InstallTextField(const std::string& text);

  // Returns the actual current text for |ns_view_|, or the selected substring.
  NSString* GetActualText();
  NSString* GetActualSelectedText();

  // Returns the expected current text from |dummy_text_view_|, or the selected
  // substring.
  NSString* GetExpectedText();
  NSString* GetExpectedSelectedText();

  // Returns the actual selection range for |ns_view_|.
  NSRange GetActualSelectionRange();

  // Returns the expected selection range from |dummy_text_view_|.
  NSRange GetExpectedSelectionRange();

  // Set the selection range for the installed textfield and |dummy_text_view_|.
  void SetSelectionRange(NSRange range);

  // Perform command |sel| on |ns_view_| and |dummy_text_view_|.
  void PerformCommand(SEL sel);

  // Make selection from |start| to |end| on installed views::Textfield and
  // |dummy_text_view_|. If |start| > |end|, extend selection to left from
  // |start|.
  void MakeSelection(int start, int end);

  // Helper method to set the private |keyDownEvent_| field on |ns_view_|.
  void SetKeyDownEvent(NSEvent* event);

  // Sets a callback to run on the next HandleKeyEvent().
  void SetHandleKeyEventCallback(HandleKeyEventCallback callback);

  // testing::Test:
  void SetUp() override;
  void TearDown() override;

  // TextfieldController:
  bool HandleKeyEvent(Textfield* sender,
                      const ui::KeyEvent& key_event) override;

 protected:
  // Test delete to beginning of line or paragraph based on |sel|. |sel| can be
  // either deleteToBeginningOfLine: or deleteToBeginningOfParagraph:.
  void TestDeleteBeginning(SEL sel);

  // Test delete to end of line or paragraph based on |sel|. |sel| can be
  // either deleteToEndOfLine: or deleteToEndOfParagraph:.
  void TestDeleteEnd(SEL sel);

  // Test editing commands in |selectors| against the expectations set by
  // |dummy_text_view_|. This is done by selecting every substring within a set
  // of test strings (both RTL and non-RTL by default) and performing every
  // selector on both the NSTextView and the BridgedContentView hosting a
  // focused views::TextField to ensure the resulting text and selection ranges
  // match. |selectors| is an NSArray of NSStrings. |cases| determines whether
  // RTL strings are to be tested.
  void TestEditingCommands(NSArray* selectors);

  std::unique_ptr<views::View> view_;

  // Weak. Owned by bridge().
  BridgedContentView* ns_view_;

  // An NSTextView which helps set the expectations for our tests.
  base::scoped_nsobject<NSTextView> dummy_text_view_;

  HandleKeyEventCallback handle_key_event_callback_;

  base::test::ScopedTaskEnvironment scoped_task_environment_;

 private:
  DISALLOW_COPY_AND_ASSIGN(BridgedNativeWidgetTest);
};

// Class that counts occurrences of a VKEY_RETURN accelerator, marking them
// processed.
class EnterAcceleratorView : public View {
 public:
  EnterAcceleratorView() { AddAccelerator({ui::VKEY_RETURN, 0}); }
  int count() const { return count_; }

  // View:
  bool AcceleratorPressed(const ui::Accelerator& accelerator) override {
    ++count_;
    return true;
  }

 private:
  int count_ = 0;
};

BridgedNativeWidgetTest::BridgedNativeWidgetTest()
    : scoped_task_environment_(
          base::test::ScopedTaskEnvironment::MainThreadType::UI) {}

BridgedNativeWidgetTest::~BridgedNativeWidgetTest() {
}

Textfield* BridgedNativeWidgetTest::InstallTextField(
    const base::string16& text,
    ui::TextInputType text_input_type) {
  Textfield* textfield = new Textfield();
  textfield->SetText(text);
  textfield->SetTextInputType(text_input_type);
  textfield->set_controller(this);
  view_->RemoveAllChildViews(true);
  view_->AddChildView(textfield);
  textfield->SetBoundsRect(init_params_.bounds);

  // Request focus so the InputMethod can dispatch events to the RootView, and
  // have them delivered to the textfield. Note that focusing a textfield
  // schedules a task to flash the cursor, so this requires |message_loop_|.
  textfield->RequestFocus();

  [ns_view_ setTextInputClient:textfield];

  // Initialize the dummy text view. Initializing this with NSZeroRect causes
  // weird NSTextView behavior on OSX 10.9.
  dummy_text_view_.reset(
      [[NSTextView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)]);
  [dummy_text_view_ setString:SysUTF16ToNSString(text)];
  return textfield;
}

Textfield* BridgedNativeWidgetTest::InstallTextField(const std::string& text) {
  return InstallTextField(base::ASCIIToUTF16(text));
}

NSString* BridgedNativeWidgetTest::GetActualText() {
  return GetViewStringForRange(ns_view_, NSMakeRange(0, NSUIntegerMax));
}

NSString* BridgedNativeWidgetTest::GetActualSelectedText() {
  return GetViewStringForRange(ns_view_, [ns_view_ selectedRange]);
}

NSString* BridgedNativeWidgetTest::GetExpectedText() {
  return GetViewStringForRange(dummy_text_view_, NSMakeRange(0, NSUIntegerMax));
}

NSString* BridgedNativeWidgetTest::GetExpectedSelectedText() {
  return GetViewStringForRange(dummy_text_view_,
                               [dummy_text_view_ selectedRange]);
}

NSRange BridgedNativeWidgetTest::GetActualSelectionRange() {
  return [ns_view_ selectedRange];
}

NSRange BridgedNativeWidgetTest::GetExpectedSelectionRange() {
  return [dummy_text_view_ selectedRange];
}

void BridgedNativeWidgetTest::SetSelectionRange(NSRange range) {
  ui::TextInputClient* client = [ns_view_ textInputClient];
  client->SetSelectionRange(gfx::Range(range));

  [dummy_text_view_ setSelectedRange:range];
}

void BridgedNativeWidgetTest::PerformCommand(SEL sel) {
  [ns_view_ doCommandBySelector:sel];
  [dummy_text_view_ doCommandBySelector:sel];
}

void BridgedNativeWidgetTest::MakeSelection(int start, int end) {
  ui::TextInputClient* client = [ns_view_ textInputClient];
  const gfx::Range range(start, end);

  // Although a gfx::Range is directed, the underlying model will not choose an
  // affinity until the cursor is moved.
  client->SetSelectionRange(range);

  // Set the range without an affinity. The first @selector sent to the text
  // field determines the affinity. Note that Range::ToNSRange() may discard
  // the direction since NSRange has no direction.
  [dummy_text_view_ setSelectedRange:range.ToNSRange()];
}

void BridgedNativeWidgetTest::SetKeyDownEvent(NSEvent* event) {
  [ns_view_ setValue:event forKey:@"keyDownEvent_"];
}

void BridgedNativeWidgetTest::SetHandleKeyEventCallback(
    HandleKeyEventCallback callback) {
  handle_key_event_callback_ = std::move(callback);
}

void BridgedNativeWidgetTest::SetUp() {
  BridgedNativeWidgetTestBase::SetUp();

  view_.reset(new views::internal::RootView(widget_.get()));
  base::scoped_nsobject<NSWindow> window([bridge_window() retain]);

  // The delegate should exist before setting the root view.
  EXPECT_TRUE([window delegate]);
  bridge_host()->SetRootView(view_.get());
  bridge()->CreateContentView(bridge_host()->GetRootViewNSViewId(),
                              view_->bounds());
  ns_view_ = bridge()->ns_view();

  // Pretend it has been shown via NativeWidgetMac::Show().
  [window orderFront:nil];
  [window makeFirstResponder:bridge()->ns_view()];
}

void BridgedNativeWidgetTest::TearDown() {
  // Clear kill buffer so that no state persists between tests.
  TextfieldModel::ClearKillBuffer();

  if (bridge_host()) {
    bridge_host()->SetRootView(nullptr);
    bridge()->DestroyContentView();
  }
  view_.reset();
  BridgedNativeWidgetTestBase::TearDown();
}

bool BridgedNativeWidgetTest::HandleKeyEvent(Textfield* sender,
                                             const ui::KeyEvent& key_event) {
  if (handle_key_event_callback_)
    return handle_key_event_callback_.Run(sender, key_event);
  return false;
}

void BridgedNativeWidgetTest::TestDeleteBeginning(SEL sel) {
  InstallTextField("foo bar baz");
  EXPECT_EQ_RANGE_3(NSMakeRange(11, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Move the caret to the beginning of the line.
  SetSelectionRange(NSMakeRange(0, 0));
  // Verify no deletion takes place.
  PerformCommand(sel);
  EXPECT_NSEQ_3(@"foo bar baz", GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Move the caret as- "foo| bar baz".
  SetSelectionRange(NSMakeRange(3, 0));
  PerformCommand(sel);
  // Verify state is "| bar baz".
  EXPECT_NSEQ_3(@" bar baz", GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Make a selection as- " bar |baz|".
  SetSelectionRange(NSMakeRange(5, 3));
  PerformCommand(sel);
  // Verify only the selection is deleted so that the state is " bar |".
  EXPECT_NSEQ_3(@" bar ", GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange(5, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Verify yanking inserts the deleted text.
  PerformCommand(@selector(yank:));
  EXPECT_NSEQ_3(@" bar baz", GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange(8, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());
}

void BridgedNativeWidgetTest::TestDeleteEnd(SEL sel) {
  InstallTextField("foo bar baz");
  EXPECT_EQ_RANGE_3(NSMakeRange(11, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Caret is at the end of the line. Verify no deletion takes place.
  PerformCommand(sel);
  EXPECT_NSEQ_3(@"foo bar baz", GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange(11, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Move the caret as- "foo bar| baz".
  SetSelectionRange(NSMakeRange(7, 0));
  PerformCommand(sel);
  // Verify state is "foo bar|".
  EXPECT_NSEQ_3(@"foo bar", GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange(7, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Make a selection as- "|foo |bar".
  SetSelectionRange(NSMakeRange(0, 4));
  PerformCommand(sel);
  // Verify only the selection is deleted so that the state is "|bar".
  EXPECT_NSEQ_3(@"bar", GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Verify yanking inserts the deleted text.
  PerformCommand(@selector(yank:));
  EXPECT_NSEQ_3(@"foo bar", GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange(4, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());
}

void BridgedNativeWidgetTest::TestEditingCommands(NSArray* selectors) {
  struct {
    base::string16 test_string;
    bool is_rtl;
  } test_cases[] = {
      {base::WideToUTF16(L"ab c"), false},
      {base::WideToUTF16(L"\x0634\x0632 \x064A"), true},
  };

  for (const auto& test_case : test_cases) {
    for (NSString* selector_string in selectors) {
      SEL sel = NSSelectorFromString(selector_string);
      const int len = test_case.test_string.length();
      for (int i = 0; i <= len; i++) {
        for (int j = 0; j <= len; j++) {
          SCOPED_TRACE(base::StringPrintf(
              "Testing range [%d-%d] for case %s and selector %s\n", i, j,
              base::UTF16ToUTF8(test_case.test_string).c_str(),
              base::SysNSStringToUTF8(selector_string).c_str()));

          InstallTextField(test_case.test_string);
          MakeSelection(i, j);

          // Sanity checks for MakeSelection().
          EXPECT_NSEQ(GetExpectedSelectedText(), GetActualSelectedText());
          EXPECT_EQ_RANGE_3(NSMakeRange(std::min(i, j), std::abs(i - j)),
                            GetExpectedSelectionRange(),
                            GetActualSelectionRange());

          // Bail out early for selection-modifying commands that are buggy in
          // Cocoa, since the selected text will not match.
          if (test_case.is_rtl && i != j && IsRTLSelectBuggy(sel))
            continue;

          PerformCommand(sel);
          EXPECT_NSEQ(GetExpectedSelectedText(), GetActualSelectedText());
          EXPECT_NSEQ(GetExpectedText(), GetActualText());

          // Spot-check some Cocoa RTL bugs. These only manifest when there is a
          // selection (i != j), not for regular cursor moves.
          if (test_case.is_rtl && i != j && IsRTLMoveBuggy(sel)) {
            if (sel == @selector(moveRight:)) {
              // Surely moving right with an rtl string moves to the start of a
              // range (i.e. min). But Cocoa moves to the end.
              EXPECT_EQ_RANGE(NSMakeRange(std::max(i, j), 0),
                              GetExpectedSelectionRange());
              EXPECT_EQ_RANGE(NSMakeRange(std::min(i, j), 0),
                              GetActualSelectionRange());
            } else if (sel == @selector(moveLeft:)) {
              EXPECT_EQ_RANGE(NSMakeRange(std::min(i, j), 0),
                              GetExpectedSelectionRange());
              EXPECT_EQ_RANGE(NSMakeRange(std::max(i, j), 0),
                              GetActualSelectionRange());
            }
            continue;
          }

          EXPECT_EQ_RANGE(GetExpectedSelectionRange(),
                          GetActualSelectionRange());
        }
      }
    }
  }
}

// The TEST_VIEW macro expects the view it's testing to have a superview. In
// these tests, the NSView bridge is a contentView, at the root. These mimic
// what TEST_VIEW usually does.
TEST_F(BridgedNativeWidgetTest, BridgedNativeWidgetTest_TestViewAddRemove) {
  base::scoped_nsobject<BridgedContentView> view([bridge()->ns_view() retain]);
  base::scoped_nsobject<NSWindow> window([bridge_window() retain]);
  EXPECT_NSEQ([window contentView], view);
  EXPECT_NSEQ(window, [view window]);

  // The superview of a contentView is an NSNextStepFrame.
  EXPECT_TRUE([view superview]);
  EXPECT_TRUE([view bridge]);

  // Ensure the tracking area to propagate mouseMoved: events to the RootView is
  // installed.
  EXPECT_EQ(1u, [[view trackingAreas] count]);

  // Closing the window should tear down the C++ bridge, remove references to
  // any C++ objects in the ObjectiveC object, and remove it from the hierarchy.
  [window close];
  EXPECT_FALSE([view bridge]);
  EXPECT_FALSE([view superview]);
  EXPECT_FALSE([view window]);
  EXPECT_EQ(0u, [[view trackingAreas] count]);
  EXPECT_FALSE([window contentView]);
  EXPECT_FALSE([window delegate]);
}

TEST_F(BridgedNativeWidgetTest, BridgedNativeWidgetTest_TestViewDisplay) {
  [bridge()->ns_view() display];
}

// Test that resizing the window resizes the root view appropriately.
TEST_F(BridgedNativeWidgetTest, ViewSizeTracksWindow) {
  const int kTestNewWidth = 400;
  const int kTestNewHeight = 300;

  // |bridge_window()| is borderless, so these should align.
  NSSize window_size = [bridge_window() frame].size;
  EXPECT_EQ(view_->width(), static_cast<int>(window_size.width));
  EXPECT_EQ(view_->height(), static_cast<int>(window_size.height));

  // Make sure a resize actually occurs.
  EXPECT_NE(kTestNewWidth, view_->width());
  EXPECT_NE(kTestNewHeight, view_->height());

  [bridge_window() setFrame:NSMakeRect(0, 0, kTestNewWidth, kTestNewHeight)
                    display:NO];
  EXPECT_EQ(kTestNewWidth, view_->width());
  EXPECT_EQ(kTestNewHeight, view_->height());
}

TEST_F(BridgedNativeWidgetTest, GetInputMethodShouldNotReturnNull) {
  EXPECT_TRUE(bridge_host()->GetInputMethod());
}

// A simpler test harness for testing initialization flows.
class BridgedNativeWidgetInitTest : public BridgedNativeWidgetTestBase {
 public:
  BridgedNativeWidgetInitTest()
      : BridgedNativeWidgetTestBase(SkipInitialization()) {}

  // Prepares a new |window_| and |widget_| for a call to PerformInit().
  void CreateNewWidgetToInit() {
    widget_.reset(new Widget);
    native_widget_mac_ = new MockNativeWidgetMac(widget_.get());
    init_params_.native_widget = native_widget_mac_;
  }

  void PerformInit() {
    widget_->Init(init_params_);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(BridgedNativeWidgetInitTest);
};

// Test that BridgedNativeWidgetImpl remains sane if Init() is never called.
TEST_F(BridgedNativeWidgetInitTest, InitNotCalled) {
  // Don't use a Widget* as the delegate. ~Widget() checks for Widget::
  // |native_widget_destroyed_| being set to true. That can only happen with a
  // non-null WidgetDelegate, which is only set in Widget::Init(). Then, since
  // neither Widget nor NativeWidget take ownership, use a unique_ptr.
  std::unique_ptr<MockNativeWidgetMac> native_widget(
      new MockNativeWidgetMac(nullptr));
  native_widget_mac_ = native_widget.get();
  EXPECT_FALSE(bridge());
  EXPECT_FALSE(bridge_host()->GetLocalNSWindow());
}

// Tests the shadow type given in InitParams.
TEST_F(BridgedNativeWidgetInitTest, ShadowType) {
  // Verify Widget::InitParam defaults and arguments added from SetUp().
  EXPECT_EQ(Widget::InitParams::TYPE_WINDOW_FRAMELESS, init_params_.type);
  EXPECT_EQ(Widget::InitParams::OPAQUE_WINDOW, init_params_.opacity);
  EXPECT_EQ(Widget::InitParams::SHADOW_TYPE_DEFAULT, init_params_.shadow_type);

  CreateNewWidgetToInit();
  EXPECT_FALSE(
      [bridge_window() hasShadow]);  // Default for NSBorderlessWindowMask.
  PerformInit();

  // Borderless is 0, so isn't really a mask. Check that nothing is set.
  EXPECT_EQ(NSBorderlessWindowMask, [bridge_window() styleMask]);
  EXPECT_TRUE(
      [bridge_window() hasShadow]);  // SHADOW_TYPE_DEFAULT means a shadow.

  CreateNewWidgetToInit();
  init_params_.shadow_type = Widget::InitParams::SHADOW_TYPE_NONE;
  PerformInit();
  EXPECT_FALSE([bridge_window() hasShadow]);  // Preserves lack of shadow.

  // Default for Widget::InitParams::TYPE_WINDOW.
  CreateNewWidgetToInit();
  PerformInit();
  EXPECT_FALSE(
      [bridge_window() hasShadow]);  // SHADOW_TYPE_NONE removes shadow.

  init_params_.shadow_type = Widget::InitParams::SHADOW_TYPE_DEFAULT;
  CreateNewWidgetToInit();
  PerformInit();
  EXPECT_TRUE([bridge_window() hasShadow]);  // Preserves shadow.

  widget_.reset();
}

// Ensure a nil NSTextInputContext is returned when the ui::TextInputClient is
// not editable, a password field, or unset.
TEST_F(BridgedNativeWidgetTest, InputContext) {
  const base::string16 test_string = base::ASCIIToUTF16("test_str");
  InstallTextField(test_string, ui::TEXT_INPUT_TYPE_PASSWORD);
  EXPECT_FALSE([ns_view_ inputContext]);
  InstallTextField(test_string, ui::TEXT_INPUT_TYPE_TEXT);
  EXPECT_TRUE([ns_view_ inputContext]);
  [ns_view_ setTextInputClient:nil];
  EXPECT_FALSE([ns_view_ inputContext]);
  InstallTextField(test_string, ui::TEXT_INPUT_TYPE_NONE);
  EXPECT_FALSE([ns_view_ inputContext]);
}

// Test getting complete string using text input protocol.
TEST_F(BridgedNativeWidgetTest, TextInput_GetCompleteString) {
  const std::string test_string = "foo bar baz";
  InstallTextField(test_string);

  NSRange range = NSMakeRange(0, test_string.size());
  NSRange actual_range;

  NSAttributedString* actual_text =
      [ns_view_ attributedSubstringForProposedRange:range
                                        actualRange:&actual_range];

  NSRange expected_range;
  NSAttributedString* expected_text =
      [dummy_text_view_ attributedSubstringForProposedRange:range
                                                actualRange:&expected_range];

  EXPECT_NSEQ_3(@"foo bar baz", [expected_text string], [actual_text string]);
  EXPECT_EQ_RANGE_3(range, expected_range, actual_range);
}

// Test getting middle substring using text input protocol.
TEST_F(BridgedNativeWidgetTest, TextInput_GetMiddleSubstring) {
  const std::string test_string = "foo bar baz";
  InstallTextField(test_string);

  NSRange range = NSMakeRange(4, 3);
  NSRange actual_range;
  NSAttributedString* actual_text =
      [ns_view_ attributedSubstringForProposedRange:range
                                        actualRange:&actual_range];

  NSRange expected_range;
  NSAttributedString* expected_text =
      [dummy_text_view_ attributedSubstringForProposedRange:range
                                                actualRange:&expected_range];

  EXPECT_NSEQ_3(@"bar", [expected_text string], [actual_text string]);
  EXPECT_EQ_RANGE_3(range, expected_range, actual_range);
}

// Test getting ending substring using text input protocol.
TEST_F(BridgedNativeWidgetTest, TextInput_GetEndingSubstring) {
  const std::string test_string = "foo bar baz";
  InstallTextField(test_string);

  NSRange range = NSMakeRange(8, 100);
  NSRange actual_range;
  NSAttributedString* actual_text =
      [ns_view_ attributedSubstringForProposedRange:range
                                        actualRange:&actual_range];
  NSRange expected_range;
  NSAttributedString* expected_text =
      [dummy_text_view_ attributedSubstringForProposedRange:range
                                                actualRange:&expected_range];

  EXPECT_NSEQ_3(@"baz", [expected_text string], [actual_text string]);
  EXPECT_EQ_RANGE_3(NSMakeRange(8, 3), expected_range, actual_range);
}

// Test getting empty substring using text input protocol.
TEST_F(BridgedNativeWidgetTest, TextInput_GetEmptySubstring) {
  const std::string test_string = "foo bar baz";
  InstallTextField(test_string);

  // Try with EmptyRange(). This behaves specially and should return the
  // complete string and the corresponding text range.
  NSRange range = EmptyRange();
  NSRange actual_range = EmptyRange();
  NSRange expected_range = EmptyRange();
  NSAttributedString* actual_text =
      [ns_view_ attributedSubstringForProposedRange:range
                                        actualRange:&actual_range];
  NSAttributedString* expected_text =
      [dummy_text_view_ attributedSubstringForProposedRange:range
                                                actualRange:&expected_range];
  EXPECT_NSEQ_3(@"foo bar baz", [expected_text string], [actual_text string]);
  EXPECT_EQ_RANGE_3(NSMakeRange(0, test_string.length()), expected_range,
                    actual_range);

  // Try with a valid empty range.
  range = NSMakeRange(2, 0);
  actual_range = EmptyRange();
  expected_range = EmptyRange();
  actual_text = [ns_view_ attributedSubstringForProposedRange:range
                                                  actualRange:&actual_range];
  expected_text =
      [dummy_text_view_ attributedSubstringForProposedRange:range
                                                actualRange:&expected_range];
  EXPECT_NSEQ_3(nil, [expected_text string], [actual_text string]);
  EXPECT_EQ_RANGE_3(range, expected_range, actual_range);

  // Try with an out of bounds empty range.
  range = NSMakeRange(20, 0);
  actual_range = EmptyRange();
  expected_range = EmptyRange();
  actual_text = [ns_view_ attributedSubstringForProposedRange:range
                                                  actualRange:&actual_range];
  expected_text =
      [dummy_text_view_ attributedSubstringForProposedRange:range
                                                actualRange:&expected_range];

  EXPECT_NSEQ_3(nil, [expected_text string], [actual_text string]);
  EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), expected_range, actual_range);
}

// Test inserting text using text input protocol.
TEST_F(BridgedNativeWidgetTest, TextInput_InsertText) {
  const std::string test_string = "foo";
  InstallTextField(test_string);

  [ns_view_ insertText:SysUTF8ToNSString(test_string)
      replacementRange:EmptyRange()];
  [dummy_text_view_ insertText:SysUTF8ToNSString(test_string)
              replacementRange:EmptyRange()];

  EXPECT_NSEQ_3(@"foofoo", GetExpectedText(), GetActualText());
}

// Test replacing text using text input protocol.
TEST_F(BridgedNativeWidgetTest, TextInput_ReplaceText) {
  const std::string test_string = "foo bar";
  InstallTextField(test_string);

  [ns_view_ insertText:@"baz" replacementRange:NSMakeRange(4, 3)];
  [dummy_text_view_ insertText:@"baz" replacementRange:NSMakeRange(4, 3)];

  EXPECT_NSEQ_3(@"foo baz", GetExpectedText(), GetActualText());
}

// Test IME composition using text input protocol.
TEST_F(BridgedNativeWidgetTest, TextInput_Compose) {
  const std::string test_string = "foo ";
  InstallTextField(test_string);

  EXPECT_EQ_3(NO, [dummy_text_view_ hasMarkedText], [ns_view_ hasMarkedText]);

  // As per NSTextInputClient documentation, markedRange should return
  // {NSNotFound, 0} iff hasMarked returns false. However, NSTextView returns
  // {text_length, text_length} for this case. We maintain consistency with the
  // documentation, hence the EXPECT_FALSE check.
  EXPECT_FALSE(
      NSEqualRanges([dummy_text_view_ markedRange], [ns_view_ markedRange]));
  EXPECT_EQ_RANGE(EmptyRange(), [ns_view_ markedRange]);

  // Start composition.
  NSString* compositionText = @"bar";
  NSUInteger compositionLength = [compositionText length];
  [ns_view_ setMarkedText:compositionText
            selectedRange:NSMakeRange(0, 2)
         replacementRange:EmptyRange()];
  [dummy_text_view_ setMarkedText:compositionText
                    selectedRange:NSMakeRange(0, 2)
                 replacementRange:EmptyRange()];
  EXPECT_EQ_3(YES, [dummy_text_view_ hasMarkedText], [ns_view_ hasMarkedText]);
  EXPECT_EQ_RANGE_3(NSMakeRange(test_string.size(), compositionLength),
                    [dummy_text_view_ markedRange], [ns_view_ markedRange]);
  EXPECT_EQ_RANGE_3(NSMakeRange(test_string.size(), 2),
                    GetExpectedSelectionRange(), GetActualSelectionRange());

  // Confirm composition.
  [ns_view_ unmarkText];
  [dummy_text_view_ unmarkText];

  EXPECT_EQ_3(NO, [dummy_text_view_ hasMarkedText], [ns_view_ hasMarkedText]);
  EXPECT_FALSE(
      NSEqualRanges([dummy_text_view_ markedRange], [ns_view_ markedRange]));
  EXPECT_EQ_RANGE(EmptyRange(), [ns_view_ markedRange]);
  EXPECT_NSEQ_3(@"foo bar", GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange([GetActualText() length], 0),
                    GetExpectedSelectionRange(), GetActualSelectionRange());
}

// Test IME composition for accented characters.
TEST_F(BridgedNativeWidgetTest, TextInput_AccentedCharacter) {
  InstallTextField("abc");

  // Simulate action messages generated when the key 'a' is pressed repeatedly
  // and leads to the showing of an IME candidate window. To simulate an event,
  // set the private keyDownEvent field on the BridgedContentView.

  // First an insertText: message with key 'a' is generated.
  SetKeyDownEvent(cocoa_test_event_utils::SynthesizeKeyEvent(
      widget_->GetNativeWindow().GetNativeNSWindow(), true, ui::VKEY_A, 0));
  [ns_view_ insertText:@"a" replacementRange:EmptyRange()];
  [dummy_text_view_ insertText:@"a" replacementRange:EmptyRange()];
  SetKeyDownEvent(nil);
  EXPECT_EQ_3(NO, [dummy_text_view_ hasMarkedText], [ns_view_ hasMarkedText]);
  EXPECT_NSEQ_3(@"abca", GetExpectedText(), GetActualText());

  // Next the IME popup appears. On selecting the accented character using arrow
  // keys, setMarkedText action message is generated which replaces the earlier
  // inserted 'a'.
  SetKeyDownEvent(cocoa_test_event_utils::SynthesizeKeyEvent(
      widget_->GetNativeWindow().GetNativeNSWindow(), true, ui::VKEY_RIGHT, 0));
  [ns_view_ setMarkedText:@"à"
            selectedRange:NSMakeRange(0, 1)
         replacementRange:NSMakeRange(3, 1)];
  [dummy_text_view_ setMarkedText:@"à"
                    selectedRange:NSMakeRange(0, 1)
                 replacementRange:NSMakeRange(3, 1)];
  SetKeyDownEvent(nil);
  EXPECT_EQ_3(YES, [dummy_text_view_ hasMarkedText], [ns_view_ hasMarkedText]);
  EXPECT_EQ_RANGE_3(NSMakeRange(3, 1), [dummy_text_view_ markedRange],
                    [ns_view_ markedRange]);
  EXPECT_EQ_RANGE_3(NSMakeRange(3, 1), GetExpectedSelectionRange(),
                    GetActualSelectionRange());
  EXPECT_NSEQ_3(@"abcà", GetExpectedText(), GetActualText());

  // On pressing enter, the marked text is confirmed.
  SetKeyDownEvent(cocoa_test_event_utils::SynthesizeKeyEvent(
      widget_->GetNativeWindow().GetNativeNSWindow(), true, ui::VKEY_RETURN,
      0));
  [ns_view_ insertText:@"à" replacementRange:EmptyRange()];
  [dummy_text_view_ insertText:@"à" replacementRange:EmptyRange()];
  SetKeyDownEvent(nil);
  EXPECT_EQ_3(NO, [dummy_text_view_ hasMarkedText], [ns_view_ hasMarkedText]);
  EXPECT_EQ_RANGE_3(NSMakeRange(4, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());
  EXPECT_NSEQ_3(@"abcà", GetExpectedText(), GetActualText());
}

// Test moving the caret left and right using text input protocol.
TEST_F(BridgedNativeWidgetTest, TextInput_MoveLeftRight) {
  InstallTextField("foo");
  EXPECT_EQ_RANGE_3(NSMakeRange(3, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Move right not allowed, out of range.
  PerformCommand(@selector(moveRight:));
  EXPECT_EQ_RANGE_3(NSMakeRange(3, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Move left.
  PerformCommand(@selector(moveLeft:));
  EXPECT_EQ_RANGE_3(NSMakeRange(2, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Move right.
  PerformCommand(@selector(moveRight:));
  EXPECT_EQ_RANGE_3(NSMakeRange(3, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());
}

// Test backward delete using text input protocol.
TEST_F(BridgedNativeWidgetTest, TextInput_DeleteBackward) {
  InstallTextField("a");
  EXPECT_EQ_RANGE_3(NSMakeRange(1, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Delete one character.
  PerformCommand(@selector(deleteBackward:));
  EXPECT_NSEQ_3(nil, GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Verify that deletion did not modify the kill buffer.
  PerformCommand(@selector(yank:));
  EXPECT_NSEQ_3(nil, GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Try to delete again on an empty string.
  PerformCommand(@selector(deleteBackward:));
  EXPECT_NSEQ_3(nil, GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());
}

// Test forward delete using text input protocol.
TEST_F(BridgedNativeWidgetTest, TextInput_DeleteForward) {
  InstallTextField("a");
  EXPECT_EQ_RANGE_3(NSMakeRange(1, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // At the end of the string, can't delete forward.
  PerformCommand(@selector(deleteForward:));
  EXPECT_NSEQ_3(@"a", GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange(1, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Should succeed after moving left first.
  PerformCommand(@selector(moveLeft:));
  PerformCommand(@selector(deleteForward:));
  EXPECT_NSEQ_3(nil, GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Verify that deletion did not modify the kill buffer.
  PerformCommand(@selector(yank:));
  EXPECT_NSEQ_3(nil, GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());
}

// Test forward word deletion using text input protocol.
TEST_F(BridgedNativeWidgetTest, TextInput_DeleteWordForward) {
  InstallTextField("foo bar baz");
  EXPECT_EQ_RANGE_3(NSMakeRange(11, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Caret is at the end of the line. Verify no deletion takes place.
  PerformCommand(@selector(deleteWordForward:));
  EXPECT_NSEQ_3(@"foo bar baz", GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange(11, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Move the caret as- "foo b|ar baz".
  SetSelectionRange(NSMakeRange(5, 0));
  PerformCommand(@selector(deleteWordForward:));
  // Verify state is "foo b| baz"
  EXPECT_NSEQ_3(@"foo b baz", GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange(5, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Make a selection as- "|fo|o b baz".
  SetSelectionRange(NSMakeRange(0, 2));
  PerformCommand(@selector(deleteWordForward:));
  // Verify only the selection is deleted and state is "|o b baz".
  EXPECT_NSEQ_3(@"o b baz", GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Verify that deletion did not modify the kill buffer.
  PerformCommand(@selector(yank:));
  EXPECT_NSEQ_3(@"o b baz", GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());
}

// Test backward word deletion using text input protocol.
TEST_F(BridgedNativeWidgetTest, TextInput_DeleteWordBackward) {
  InstallTextField("foo bar baz");
  EXPECT_EQ_RANGE_3(NSMakeRange(11, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Move the caret to the beginning of the line.
  SetSelectionRange(NSMakeRange(0, 0));
  // Verify no deletion takes place.
  PerformCommand(@selector(deleteWordBackward:));
  EXPECT_NSEQ_3(@"foo bar baz", GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange(0, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Move the caret as- "foo ba|r baz".
  SetSelectionRange(NSMakeRange(6, 0));
  PerformCommand(@selector(deleteWordBackward:));
  // Verify state is "foo |r baz".
  EXPECT_NSEQ_3(@"foo r baz", GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange(4, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Make a selection as- "f|oo r b|az".
  SetSelectionRange(NSMakeRange(1, 6));
  PerformCommand(@selector(deleteWordBackward:));
  // Verify only the selection is deleted and state is "f|az"
  EXPECT_NSEQ_3(@"faz", GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange(1, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());

  // Verify that deletion did not modify the kill buffer.
  PerformCommand(@selector(yank:));
  EXPECT_NSEQ_3(@"faz", GetExpectedText(), GetActualText());
  EXPECT_EQ_RANGE_3(NSMakeRange(1, 0), GetExpectedSelectionRange(),
                    GetActualSelectionRange());
}

// Test deleting to beginning/end of line/paragraph using text input protocol.

TEST_F(BridgedNativeWidgetTest, TextInput_DeleteToBeginningOfLine) {
  TestDeleteBeginning(@selector(deleteToBeginningOfLine:));
}

TEST_F(BridgedNativeWidgetTest, TextInput_DeleteToEndOfLine) {
  TestDeleteEnd(@selector(deleteToEndOfLine:));
}

TEST_F(BridgedNativeWidgetTest, TextInput_DeleteToBeginningOfParagraph) {
  TestDeleteBeginning(@selector(deleteToBeginningOfParagraph:));
}

TEST_F(BridgedNativeWidgetTest, TextInput_DeleteToEndOfParagraph) {
  TestDeleteEnd(@selector(deleteToEndOfParagraph:));
}

// Test move commands against expectations set by |dummy_text_view_|.
TEST_F(BridgedNativeWidgetTest, TextInput_MoveEditingCommands) {
  TestEditingCommands(kMoveActions);
}

// Test move and select commands against expectations set by |dummy_text_view_|.
TEST_F(BridgedNativeWidgetTest, TextInput_MoveAndSelectEditingCommands) {
  TestEditingCommands(kSelectActions);
}

// Test delete commands against expectations set by |dummy_text_view_|.
TEST_F(BridgedNativeWidgetTest, TextInput_DeleteCommands) {
  TestEditingCommands(kDeleteActions);
}

// Test that we don't crash during an action message even if the TextInputClient
// is nil. Regression test for crbug.com/615745.
TEST_F(BridgedNativeWidgetTest, NilTextInputClient) {
  [ns_view_ setTextInputClient:nil];
  NSMutableArray* selectors = [NSMutableArray array];
  [selectors addObjectsFromArray:kMoveActions];
  [selectors addObjectsFromArray:kSelectActions];
  [selectors addObjectsFromArray:kDeleteActions];

  // -insertText: is omitted from this list to avoid a DCHECK in
  // doCommandBySelector:. AppKit never passes -insertText: to
  // doCommandBySelector: (it calls -insertText: directly instead).
  [selectors addObjectsFromArray:kMiscActions];

  for (NSString* selector in selectors)
    [ns_view_ doCommandBySelector:NSSelectorFromString(selector)];

  [ns_view_ insertText:@""];
}

// Test transpose command against expectations set by |dummy_text_view_|.
TEST_F(BridgedNativeWidgetTest, TextInput_Transpose) {
  TestEditingCommands(@[ @"transpose:" ]);
}

// Test firstRectForCharacterRange:actualRange for cases where query range is
// empty or outside composition range.
TEST_F(BridgedNativeWidgetTest, TextInput_FirstRectForCharacterRange_Caret) {
  InstallTextField("");
  ui::TextInputClient* client = [ns_view_ textInputClient];

  // No composition. Ensure bounds and range corresponding to the current caret
  // position are returned.
  // Initially selection range will be [0, 0].
  NSRange caret_range = NSMakeRange(0, 0);
  NSRange query_range = NSMakeRange(1, 1);
  NSRange actual_range;
  NSRect rect = [ns_view_ firstRectForCharacterRange:query_range
                                         actualRange:&actual_range];
  EXPECT_EQ(GetCaretBounds(client), gfx::ScreenRectFromNSRect(rect));
  EXPECT_EQ_RANGE(caret_range, actual_range);

  // Set composition with caret before second character ('e').
  const base::string16 test_string = base::ASCIIToUTF16("test_str");
  const size_t kTextLength = 8;
  SetCompositionText(client, test_string, 1, &caret_range);

  // Test bounds returned for empty ranges within composition range. As per
  // Apple's documentation for firstRectForCharacterRange:actualRange:, for an
  // empty query range, the returned rectangle should coincide with the
  // insertion point and have zero width. However in our implementation, if the
  // empty query range lies within the composition range, we return a zero width
  // rectangle corresponding to the query range location.

  // Test bounds returned for empty range before second character ('e') are same
  // as caret bounds when placed before second character.
  query_range = NSMakeRange(1, 0);
  rect = [ns_view_ firstRectForCharacterRange:query_range
                                  actualRange:&actual_range];
  EXPECT_EQ(GetCaretBoundsForPosition(client, test_string, 1, &caret_range),
            gfx::ScreenRectFromNSRect(rect));
  EXPECT_EQ_RANGE(query_range, actual_range);

  // Test bounds returned for empty range after the composition text are same as
  // caret bounds when placed after the composition text.
  query_range = NSMakeRange(kTextLength, 0);
  rect = [ns_view_ firstRectForCharacterRange:query_range
                                  actualRange:&actual_range];
  EXPECT_NE(GetCaretBoundsForPosition(client, test_string, 1, &caret_range),
            gfx::ScreenRectFromNSRect(rect));
  EXPECT_EQ(
      GetCaretBoundsForPosition(client, test_string, kTextLength, &caret_range),
      gfx::ScreenRectFromNSRect(rect));
  EXPECT_EQ_RANGE(query_range, actual_range);

  // Query outside composition range. Ensure bounds and range corresponding to
  // the current caret position are returned.
  query_range = NSMakeRange(kTextLength + 1, 0);
  rect = [ns_view_ firstRectForCharacterRange:query_range
                                  actualRange:&actual_range];
  EXPECT_EQ(GetCaretBounds(client), gfx::ScreenRectFromNSRect(rect));
  EXPECT_EQ_RANGE(caret_range, actual_range);

  // Make sure not crashing by passing null pointer instead of actualRange.
  rect = [ns_view_ firstRectForCharacterRange:query_range actualRange:nullptr];
}

// Test firstRectForCharacterRange:actualRange for non-empty query ranges within
// the composition range.
TEST_F(BridgedNativeWidgetTest, TextInput_FirstRectForCharacterRange) {
  InstallTextField("");
  ui::TextInputClient* client = [ns_view_ textInputClient];

  const base::string16 test_string = base::ASCIIToUTF16("test_str");
  const size_t kTextLength = 8;
  SetCompositionText(client, test_string, 1, nullptr);

  // Query bounds for the whole composition string.
  NSRange query_range = NSMakeRange(0, kTextLength);
  NSRange actual_range;
  NSRect rect = [ns_view_ firstRectForCharacterRange:query_range
                                         actualRange:&actual_range];
  EXPECT_EQ(GetExpectedBoundsForRange(client, test_string, query_range),
            gfx::ScreenRectFromNSRect(rect));
  EXPECT_EQ_RANGE(query_range, actual_range);

  // Query bounds for the substring "est_".
  query_range = NSMakeRange(1, 4);
  rect = [ns_view_ firstRectForCharacterRange:query_range
                                  actualRange:&actual_range];
  EXPECT_EQ(GetExpectedBoundsForRange(client, test_string, query_range),
            gfx::ScreenRectFromNSRect(rect));
  EXPECT_EQ_RANGE(query_range, actual_range);
}

// Test simulated codepaths for IMEs that do not always "mark" text. E.g.
// phonetic languages such as Korean and Vietnamese.
TEST_F(BridgedNativeWidgetTest, TextInput_SimulatePhoneticIme) {
  Textfield* textfield = InstallTextField("");
  EXPECT_TRUE([ns_view_ textInputClient]);

  object_setClass(ns_view_, [InterpretKeyEventMockedBridgedContentView class]);

  // Sequence of calls (and corresponding keyDown events) obtained via tracing
  // with 2-Set Korean IME and pressing q, o, then Enter on the keyboard.
  NSEvent* q_in_ime = UnicodeKeyDown(12, @"ㅂ");
  InterpretKeyEventsCallback handle_q_in_ime = base::BindRepeating([](id view) {
    [view insertText:@"ㅂ" replacementRange:NSMakeRange(NSNotFound, 0)];
  });

  NSEvent* o_in_ime = UnicodeKeyDown(31, @"ㅐ");
  InterpretKeyEventsCallback handle_o_in_ime = base::BindRepeating([](id view) {
    [view insertText:@"배" replacementRange:NSMakeRange(0, 1)];
  });

  InterpretKeyEventsCallback handle_return_in_ime =
      base::BindRepeating([](id view) {
        // When confirming the composition, AppKit repeats itself.
        [view insertText:@"배" replacementRange:NSMakeRange(0, 1)];
        [view insertText:@"배" replacementRange:NSMakeRange(0, 1)];
        [view doCommandBySelector:@selector(insertNewLine:)];
      });

  // Add a hook for the KeyEvent being received by the TextfieldController. E.g.
  // this is where the Omnibox would start to search when Return is pressed.
  bool saw_vkey_return = false;
  SetHandleKeyEventCallback(base::BindRepeating(
      [](bool* saw_return, Textfield* textfield, const ui::KeyEvent& event) {
        if (event.key_code() == ui::VKEY_RETURN) {
          EXPECT_FALSE(*saw_return);
          *saw_return = true;
          EXPECT_EQ(base::SysNSStringToUTF16(@"배"), textfield->text());
        }
        return false;
      },
      &saw_vkey_return));

  EXPECT_EQ(base::UTF8ToUTF16(""), textfield->text());

  g_fake_interpret_key_events = &handle_q_in_ime;
  [ns_view_ keyDown:q_in_ime];
  EXPECT_EQ(base::SysNSStringToUTF16(@"ㅂ"), textfield->text());
  EXPECT_FALSE(saw_vkey_return);

  g_fake_interpret_key_events = &handle_o_in_ime;
  [ns_view_ keyDown:o_in_ime];
  EXPECT_EQ(base::SysNSStringToUTF16(@"배"), textfield->text());
  EXPECT_FALSE(saw_vkey_return);

  // Note the "Enter" should not replace the replacement range, even though a
  // replacement range was set.
  g_fake_interpret_key_events = &handle_return_in_ime;
  [ns_view_ keyDown:VkeyKeyDown(ui::VKEY_RETURN)];
  EXPECT_EQ(base::SysNSStringToUTF16(@"배"), textfield->text());

  // VKEY_RETURN should be seen by via the unhandled key event handler (but not
  // via -insertText:.
  EXPECT_TRUE(saw_vkey_return);

  g_fake_interpret_key_events = nullptr;
}

// Test simulated codepaths for typing 'm', 'o', 'o', Enter in the Telex IME.
// This IME does not mark text, but, unlike 2-set Korean, it re-inserts the
// entire word on each keypress, even though only the last character in the word
// can be modified. This prevents the keypress being treated as a "character"
// event (which is unavoidably unfortunate for the Undo buffer), but also led to
// a codepath that suppressed a VKEY_RETURN when it should not, since there is
// no candidate IME window to dismiss for this IME.
TEST_F(BridgedNativeWidgetTest, TextInput_SimulateTelexMoo) {
  Textfield* textfield = InstallTextField("");
  EXPECT_TRUE([ns_view_ textInputClient]);

  EnterAcceleratorView* enter_view = new EnterAcceleratorView();
  textfield->parent()->AddChildView(enter_view);

  // Sequence of calls (and corresponding keyDown events) obtained via tracing
  // with Telex IME and pressing 'm', 'o', 'o', then Enter on the keyboard.
  // Note that without the leading 'm', only one character changes, which could
  // allow the keypress to be treated as a character event, which would not
  // produce the bug.
  NSEvent* m_in_ime = UnicodeKeyDown(46, @"m");
  InterpretKeyEventsCallback handle_m_in_ime = base::BindRepeating([](id view) {
    [view insertText:@"m" replacementRange:NSMakeRange(NSNotFound, 0)];
  });

  // Note that (unlike Korean IME), Telex generates a latin "o" for both events:
  // it doesn't associate a unicode character on the second NSEvent.
  NSEvent* o_in_ime = UnicodeKeyDown(31, @"o");
  InterpretKeyEventsCallback handle_first_o_in_ime =
      base::BindRepeating([](id view) {
        // Note the whole word is replaced, not just the last character.
        [view insertText:@"mo" replacementRange:NSMakeRange(0, 1)];
      });
  InterpretKeyEventsCallback handle_second_o_in_ime =
      base::BindRepeating([](id view) {
        [view insertText:@"mô" replacementRange:NSMakeRange(0, 2)];
      });

  InterpretKeyEventsCallback handle_return_in_ime =
      base::BindRepeating([](id view) {
        // Note the previous -insertText: repeats, even though it is unchanged.
        // But the IME also follows with an -insertNewLine:.
        [view insertText:@"mô" replacementRange:NSMakeRange(0, 2)];
        [view doCommandBySelector:@selector(insertNewLine:)];
      });

  EXPECT_EQ(base::UTF8ToUTF16(""), textfield->text());
  EXPECT_EQ(0, enter_view->count());

  object_setClass(ns_view_, [InterpretKeyEventMockedBridgedContentView class]);
  g_fake_interpret_key_events = &handle_m_in_ime;
  [ns_view_ keyDown:m_in_ime];
  EXPECT_EQ(base::SysNSStringToUTF16(@"m"), textfield->text());
  EXPECT_EQ(0, enter_view->count());

  g_fake_interpret_key_events = &handle_first_o_in_ime;
  [ns_view_ keyDown:o_in_ime];
  EXPECT_EQ(base::SysNSStringToUTF16(@"mo"), textfield->text());
  EXPECT_EQ(0, enter_view->count());

  g_fake_interpret_key_events = &handle_second_o_in_ime;
  [ns_view_ keyDown:o_in_ime];
  EXPECT_EQ(base::SysNSStringToUTF16(@"mô"), textfield->text());
  EXPECT_EQ(0, enter_view->count());

  g_fake_interpret_key_events = &handle_return_in_ime;
  [ns_view_ keyDown:VkeyKeyDown(ui::VKEY_RETURN)];
  EXPECT_EQ(base::SysNSStringToUTF16(@"mô"), textfield->text());  // No change.
  EXPECT_EQ(1, enter_view->count());  // Now we see the accelerator.
}

// Simulate 'a', Enter in Hiragana. This should just insert "あ", suppressing
// accelerators.
TEST_F(BridgedNativeWidgetTest, TextInput_NoAcceleratorEnterComposition) {
  Textfield* textfield = InstallTextField("");
  EXPECT_TRUE([ns_view_ textInputClient]);

  EnterAcceleratorView* enter_view = new EnterAcceleratorView();
  textfield->parent()->AddChildView(enter_view);

  // Sequence of calls (and corresponding keyDown events) obtained via tracing
  // with Hiragana IME and pressing 'a', then Enter on the keyboard.
  // Note 0 is the actual keyCode for 'a', not a placeholder.
  NSEvent* a_in_ime = UnicodeKeyDown(0, @"a");
  InterpretKeyEventsCallback handle_a_in_ime = base::BindRepeating([](id view) {
    // TODO(crbug/612675): |text| should be an NSAttributedString.
    [view setMarkedText:@"あ"
           selectedRange:NSMakeRange(1, 0)
        replacementRange:NSMakeRange(NSNotFound, 0)];
  });

  InterpretKeyEventsCallback handle_first_return_in_ime =
      base::BindRepeating([](id view) {
        [view insertText:@"あ" replacementRange:NSMakeRange(NSNotFound, 0)];
        // Note there is no call to -insertNewLine: here.
      });
  InterpretKeyEventsCallback handle_second_return_in_ime = base::BindRepeating(
      [](id view) { [view doCommandBySelector:@selector(insertNewLine:)]; });

  EXPECT_EQ(base::UTF8ToUTF16(""), textfield->text());
  EXPECT_EQ(0, enter_view->count());

  object_setClass(ns_view_, [InterpretKeyEventMockedBridgedContentView class]);
  g_fake_interpret_key_events = &handle_a_in_ime;
  [ns_view_ keyDown:a_in_ime];
  EXPECT_EQ(base::SysNSStringToUTF16(@"あ"), textfield->text());
  EXPECT_EQ(0, enter_view->count());

  g_fake_interpret_key_events = &handle_first_return_in_ime;
  [ns_view_ keyDown:VkeyKeyDown(ui::VKEY_RETURN)];
  EXPECT_EQ(base::SysNSStringToUTF16(@"あ"), textfield->text());
  EXPECT_EQ(0, enter_view->count());  // Not seen as an accelerator.

  g_fake_interpret_key_events = &handle_second_return_in_ime;
  [ns_view_
      keyDown:VkeyKeyDown(ui::VKEY_RETURN)];  // Sanity check: send Enter again.
  EXPECT_EQ(base::SysNSStringToUTF16(@"あ"), textfield->text());  // No change.
  EXPECT_EQ(1, enter_view->count());  // Now we see the accelerator.
}

// Simulate 'a', Tab, Enter, Enter in Hiragana. This should just insert "a",
// suppressing accelerators.
TEST_F(BridgedNativeWidgetTest, TextInput_NoAcceleratorTabEnterComposition) {
  Textfield* textfield = InstallTextField("");
  EXPECT_TRUE([ns_view_ textInputClient]);

  EnterAcceleratorView* enter_view = new EnterAcceleratorView();
  textfield->parent()->AddChildView(enter_view);

  // Sequence of calls (and corresponding keyDown events) obtained via tracing
  // with Hiragana IME and pressing 'a', Tab, then Enter on the keyboard.
  NSEvent* a_in_ime = UnicodeKeyDown(0, @"a");
  InterpretKeyEventsCallback handle_a_in_ime = base::BindRepeating([](id view) {
    // TODO(crbug/612675): |text| should have an underline.
    [view setMarkedText:@"あ"
           selectedRange:NSMakeRange(1, 0)
        replacementRange:NSMakeRange(NSNotFound, 0)];
  });

  InterpretKeyEventsCallback handle_tab_in_ime =
      base::BindRepeating([](id view) {
        // TODO(crbug/612675): |text| should be an NSAttributedString (now with
        // a different underline color).
        [view setMarkedText:@"a"
               selectedRange:NSMakeRange(0, 1)
            replacementRange:NSMakeRange(NSNotFound, 0)];
        // Note there is no -insertTab: generated.
      });

  InterpretKeyEventsCallback handle_first_return_in_ime =
      base::BindRepeating([](id view) {
        // Do *nothing*. Enter does not confirm nor change the composition, it
        // just dismisses the IME window, leaving the text marked.
      });
  InterpretKeyEventsCallback handle_second_return_in_ime =
      base::BindRepeating([](id view) {
        // The second return will confirm the composition.
        [view insertText:@"a" replacementRange:NSMakeRange(NSNotFound, 0)];
      });
  InterpretKeyEventsCallback handle_third_return_in_ime =
      base::BindRepeating([](id view) {
        // Only the third return will generate -insertNewLine:.
        [view doCommandBySelector:@selector(insertNewLine:)];
      });

  EXPECT_EQ(base::UTF8ToUTF16(""), textfield->text());
  EXPECT_EQ(0, enter_view->count());

  object_setClass(ns_view_, [InterpretKeyEventMockedBridgedContentView class]);
  g_fake_interpret_key_events = &handle_a_in_ime;
  [ns_view_ keyDown:a_in_ime];
  EXPECT_EQ(base::SysNSStringToUTF16(@"あ"), textfield->text());
  EXPECT_EQ(0, enter_view->count());

  g_fake_interpret_key_events = &handle_tab_in_ime;
  [ns_view_ keyDown:VkeyKeyDown(ui::VKEY_TAB)];
  // Tab will switch to a Romanji (Latin) character.
  EXPECT_EQ(base::SysNSStringToUTF16(@"a"), textfield->text());
  EXPECT_EQ(0, enter_view->count());

  g_fake_interpret_key_events = &handle_first_return_in_ime;
  [ns_view_ keyDown:VkeyKeyDown(ui::VKEY_RETURN)];
  // Enter just dismisses the IME window. The composition is still active.
  EXPECT_EQ(base::SysNSStringToUTF16(@"a"), textfield->text());
  EXPECT_EQ(0, enter_view->count());  // Not seen as an accelerator.

  g_fake_interpret_key_events = &handle_second_return_in_ime;
  [ns_view_ keyDown:VkeyKeyDown(ui::VKEY_RETURN)];
  // Enter now confirms the composition (unmarks text). Note there is still no
  // IME window visible but, since there is marked text, IME is still active.
  EXPECT_EQ(base::SysNSStringToUTF16(@"a"), textfield->text());
  EXPECT_EQ(0, enter_view->count());  // Not seen as an accelerator.

  g_fake_interpret_key_events = &handle_third_return_in_ime;
  [ns_view_ keyDown:VkeyKeyDown(ui::VKEY_RETURN)];  // Send Enter a third time.
  EXPECT_EQ(base::SysNSStringToUTF16(@"a"), textfield->text());  // No change.
  EXPECT_EQ(1, enter_view->count());  // Now we see the accelerator.
}

// Test a codepath that could hypothetically cause [NSApp updateWindows] to be
// called recursively due to IME dismissal during teardown triggering a focus
// change. Twice.
TEST_F(BridgedNativeWidgetTest, TextInput_RecursiveUpdateWindows) {
  Textfield* textfield = InstallTextField("");
  EXPECT_TRUE([ns_view_ textInputClient]);

  object_setClass(ns_view_, [InterpretKeyEventMockedBridgedContentView class]);
  base::mac::ScopedObjCClassSwizzler update_windows_swizzler(
      [NSApplication class], [UpdateWindowsDonorForNSApp class],
      @selector(updateWindows));
  base::mac::ScopedObjCClassSwizzler current_input_context_swizzler(
      [NSTextInputContext class],
      [CurrentInputContextDonorForNSTextInputContext class],
      @selector(currentInputContext));

  int vkey_return_count = 0;

  // Everything happens with this one event.
  NSEvent* return_with_fake_ime = cocoa_test_event_utils::SynthesizeKeyEvent(
      widget_->GetNativeWindow().GetNativeNSWindow(), true, ui::VKEY_RETURN, 0);

  InterpretKeyEventsCallback generate_return_and_fake_ime = base::BindRepeating(
      [](int* saw_return_count, id view) {
        EXPECT_EQ(0, *saw_return_count);
        // First generate the return to simulate an input context change.
        [view insertText:@"\r" replacementRange:NSMakeRange(NSNotFound, 0)];

        EXPECT_EQ(1, *saw_return_count);
      },
      &vkey_return_count);

  bool saw_update_windows = false;
  base::RepeatingClosure update_windows_closure = base::BindRepeating(
      [](bool* saw_update_windows, BridgedContentView* view,
         Textfield* textfield) {
        // Ensure updateWindows is not invoked recursively.
        EXPECT_FALSE(*saw_update_windows);
        *saw_update_windows = true;

        // Inside updateWindows, assume the IME got dismissed and wants to
        // insert its last bit of text for the old input context.
        [view insertText:@"배" replacementRange:NSMakeRange(0, 1)];

        // This is triggered by the setTextInputClient:nullptr in
        // SetHandleKeyEventCallback(), so -inputContext should also be nil.
        EXPECT_FALSE([view inputContext]);

        // Ensure we can't recursively call updateWindows. A TextInputClient
        // reacting to InsertChar could theoretically do this, but toolkit-views
        // DCHECKs if there is recursive event dispatch, so call
        // setTextInputClient directly.
        [view setTextInputClient:textfield];

        // Finally simulate what -[NSApp updateWindows] should _actually_ do,
        // which is to update the input context (from the first responder).
        g_fake_current_input_context = [view inputContext];

        // Now, the |textfield| set above should have been set again.
        EXPECT_TRUE(g_fake_current_input_context);
      },
      &saw_update_windows, ns_view_, textfield);

  SetHandleKeyEventCallback(base::BindRepeating(
      [](int* saw_return_count, BridgedContentView* view, Textfield* textfield,
         const ui::KeyEvent& event) {
        if (event.key_code() == ui::VKEY_RETURN) {
          *saw_return_count += 1;
          // Simulate Textfield::OnBlur() by clearing the input method.
          // Textfield needs to be in a Widget to do this normally.
          [view setTextInputClient:nullptr];
        }
        return false;
      },
      &vkey_return_count, ns_view_));

  // Starting text (just insert it).
  [ns_view_ insertText:@"ㅂ" replacementRange:NSMakeRange(NSNotFound, 0)];

  EXPECT_EQ(base::SysNSStringToUTF16(@"ㅂ"), textfield->text());

  g_fake_interpret_key_events = &generate_return_and_fake_ime;
  g_update_windows_closure = &update_windows_closure;
  g_fake_current_input_context = [ns_view_ inputContext];
  EXPECT_TRUE(g_fake_current_input_context);
  [ns_view_ keyDown:return_with_fake_ime];

  // We should see one VKEY_RETURNs and one updateWindows. In particular, note
  // that there is not a second VKEY_RETURN seen generated by keyDown: thinking
  // the event has been unhandled. This is because it was handled when the fake
  // IME sent \r.
  EXPECT_TRUE(saw_update_windows);
  EXPECT_EQ(1, vkey_return_count);

  // The text inserted during updateWindows should have been inserted, even
  // though we were trying to change the input context.
  EXPECT_EQ(base::SysNSStringToUTF16(@"배"), textfield->text());

  EXPECT_TRUE(g_fake_current_input_context);

  g_fake_current_input_context = nullptr;
  g_fake_interpret_key_events = nullptr;
  g_update_windows_closure = nullptr;
}

typedef BridgedNativeWidgetTestBase BridgedNativeWidgetSimulateFullscreenTest;

// Simulate the notifications that AppKit would send out if a fullscreen
// operation begins, and then fails and must abort. This notification sequence
// was determined by posting delayed tasks to toggle fullscreen state and then
// mashing Ctrl+Left/Right to keep OSX in a transition between Spaces to cause
// the fullscreen transition to fail.
TEST_F(BridgedNativeWidgetSimulateFullscreenTest, FailToEnterAndExit) {
  BridgedNativeWidgetTestWindow* window =
      base::mac::ObjCCastStrict<BridgedNativeWidgetTestWindow>(
          widget_->GetNativeWindow().GetNativeNSWindow());
  [window setIgnoreToggleFullScreen:YES];
  widget_->Show();

  NSNotificationCenter* center = [NSNotificationCenter defaultCenter];

  EXPECT_FALSE(bridge()->target_fullscreen_state());

  // Simulate an initial toggleFullScreen: (user- or Widget-initiated).
  [center postNotificationName:NSWindowWillEnterFullScreenNotification
                        object:window];

  // On a failure, Cocoa starts by sending an unexpected *exit* fullscreen, and
  // BridgedNativeWidgetImpl will think it's just a delayed transition and try
  // to go back into fullscreen but get ignored by Cocoa.
  EXPECT_EQ(0, [window ignoredToggleFullScreenCount]);
  EXPECT_TRUE(bridge()->target_fullscreen_state());
  [center postNotificationName:NSWindowDidExitFullScreenNotification
                        object:window];
  EXPECT_EQ(1, [window ignoredToggleFullScreenCount]);
  EXPECT_FALSE(bridge()->target_fullscreen_state());

  // Cocoa follows up with a failure message sent to the NSWindowDelegate (there
  // is no equivalent notification for failure).
  ViewsNSWindowDelegate* window_delegate =
      base::mac::ObjCCast<ViewsNSWindowDelegate>([window delegate]);
  [window_delegate windowDidFailToEnterFullScreen:window];
  EXPECT_FALSE(bridge()->target_fullscreen_state());

  // Now perform a successful fullscreen operation.
  [center postNotificationName:NSWindowWillEnterFullScreenNotification
                        object:window];
  EXPECT_TRUE(bridge()->target_fullscreen_state());
  [center postNotificationName:NSWindowDidEnterFullScreenNotification
                        object:window];
  EXPECT_TRUE(bridge()->target_fullscreen_state());

  // And try to get out.
  [center postNotificationName:NSWindowWillExitFullScreenNotification
                        object:window];
  EXPECT_FALSE(bridge()->target_fullscreen_state());

  // On a failure, Cocoa sends a failure message, but then just dumps the window
  // out of fullscreen anyway (in that order).
  [window_delegate windowDidFailToExitFullScreen:window];
  EXPECT_FALSE(bridge()->target_fullscreen_state());
  [center postNotificationName:NSWindowDidExitFullScreenNotification
                        object:window];
  EXPECT_EQ(1, [window ignoredToggleFullScreenCount]);  // No change.
  EXPECT_FALSE(bridge()->target_fullscreen_state());

  widget_->CloseNow();
}

}  // namespace test
}  // namespace views
