// Copyright 2013 The Flutter 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 "KeyCodeMap_Internal.h"
#import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterViewController.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h"

#import <OCMock/OCMock.h>

#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h"
#import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterEngine.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterDartProject_Internal.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEngineTestUtils.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterRenderer.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestUtils.h"
#include "flutter/shell/platform/embedder/test_utils/key_codes.g.h"
#import "flutter/testing/testing.h"

#pragma mark - Test Helper Classes

// A wrap to convert FlutterKeyEvent to a ObjC class.
@interface KeyEventWrapper : NSObject
@property(nonatomic) FlutterKeyEvent* data;
- (nonnull instancetype)initWithEvent:(const FlutterKeyEvent*)event;
@end

@implementation KeyEventWrapper
- (instancetype)initWithEvent:(const FlutterKeyEvent*)event {
  self = [super init];
  _data = new FlutterKeyEvent(*event);
  return self;
}

- (void)dealloc {
  delete _data;
}
@end

// A FlutterViewController subclass for testing that mouseDown/mouseUp get called when
// mouse events are sent to the associated view.
@interface MouseEventFlutterViewController : FlutterViewController
@property(nonatomic, assign) BOOL mouseDownCalled;
@property(nonatomic, assign) BOOL mouseUpCalled;
@end

@implementation MouseEventFlutterViewController
- (void)mouseDown:(NSEvent*)event {
  self.mouseDownCalled = YES;
}

- (void)mouseUp:(NSEvent*)event {
  self.mouseUpCalled = YES;
}
@end

@interface FlutterViewControllerTestObjC : NSObject
- (bool)testKeyEventsAreSentToFramework;
- (bool)testKeyEventsArePropagatedIfNotHandled;
- (bool)testKeyEventsAreNotPropagatedIfHandled;
- (bool)testCtrlTabKeyEventIsPropagated;
- (bool)testFlagsChangedEventsArePropagatedIfNotHandled;
- (bool)testKeyboardIsRestartedOnEngineRestart;
- (bool)testTrackpadGesturesAreSentToFramework;
- (bool)testMouseDownUpEventsSentToNextResponder;
- (bool)testModifierKeysAreSynthesizedOnMouseMove;
- (bool)testViewWillAppearCalledMultipleTimes;
- (bool)testFlutterViewIsConfigured;
- (bool)testLookupKeyAssets;
- (bool)testLookupKeyAssetsWithPackage;

+ (void)respondFalseForSendEvent:(const FlutterKeyEvent&)event
                        callback:(nullable FlutterKeyEventCallback)callback
                        userData:(nullable void*)userData;
@end

#pragma mark - Static helper functions

using namespace ::flutter::testing::keycodes;

namespace flutter::testing {

namespace {

id MockGestureEvent(NSEventType type, NSEventPhase phase, double magnification, double rotation) {
  id event = [OCMockObject mockForClass:[NSEvent class]];
  NSPoint locationInWindow = NSMakePoint(0, 0);
  CGFloat deltaX = 0;
  CGFloat deltaY = 0;
  NSTimeInterval timestamp = 1;
  NSUInteger modifierFlags = 0;
  [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(type)] type];
  [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(phase)] phase];
  [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(locationInWindow)] locationInWindow];
  [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(deltaX)] deltaX];
  [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(deltaY)] deltaY];
  [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(timestamp)] timestamp];
  [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(modifierFlags)] modifierFlags];
  [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(magnification)] magnification];
  [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(rotation)] rotation];
  return event;
}

// Allocates and returns an engine configured for the test fixture resource configuration.
FlutterEngine* CreateTestEngine() {
  NSString* fixtures = @(testing::GetFixturesPath());
  FlutterDartProject* project = [[FlutterDartProject alloc]
      initWithAssetsPath:fixtures
             ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
  return [[FlutterEngine alloc] initWithName:@"test" project:project allowHeadlessExecution:true];
}

NSResponder* mockResponder() {
  NSResponder* mock = OCMStrictClassMock([NSResponder class]);
  OCMStub([mock keyDown:[OCMArg any]]).andDo(nil);
  OCMStub([mock keyUp:[OCMArg any]]).andDo(nil);
  OCMStub([mock flagsChanged:[OCMArg any]]).andDo(nil);
  return mock;
}

NSEvent* CreateMouseEvent(NSEventModifierFlags modifierFlags) {
  return [NSEvent mouseEventWithType:NSEventTypeMouseMoved
                            location:NSZeroPoint
                       modifierFlags:modifierFlags
                           timestamp:0
                        windowNumber:0
                             context:nil
                         eventNumber:0
                          clickCount:1
                            pressure:1.0];
}

}  // namespace

#pragma mark - gtest tests

TEST(FlutterViewController, HasViewThatHidesOtherViewsInAccessibility) {
  FlutterViewController* viewControllerMock = CreateMockViewController();

  [viewControllerMock loadView];
  auto subViews = [viewControllerMock.view subviews];

  EXPECT_EQ([subViews count], 1u);
  EXPECT_EQ(subViews[0], viewControllerMock.flutterView);

  NSTextField* textField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 1, 1)];
  [viewControllerMock.view addSubview:textField];

  subViews = [viewControllerMock.view subviews];
  EXPECT_EQ([subViews count], 2u);

  auto accessibilityChildren = viewControllerMock.view.accessibilityChildren;
  // The accessibilityChildren should only contains the FlutterView.
  EXPECT_EQ([accessibilityChildren count], 1u);
  EXPECT_EQ(accessibilityChildren[0], viewControllerMock.flutterView);
}

TEST(FlutterViewController, FlutterViewAcceptsFirstMouse) {
  FlutterViewController* viewControllerMock = CreateMockViewController();
  [viewControllerMock loadView];
  EXPECT_EQ([viewControllerMock.flutterView acceptsFirstMouse:nil], YES);
}

TEST(FlutterViewController, ReparentsPluginWhenAccessibilityDisabled) {
  FlutterEngine* engine = CreateTestEngine();
  FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
                                                                                nibName:nil
                                                                                 bundle:nil];
  [viewController loadView];
  [engine setViewController:viewController];
  // Creates a NSWindow so that sub view can be first responder.
  NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
                                                 styleMask:NSBorderlessWindowMask
                                                   backing:NSBackingStoreBuffered
                                                     defer:NO];
  window.contentView = viewController.view;
  NSView* dummyView = [[NSView alloc] initWithFrame:CGRectZero];
  [viewController.view addSubview:dummyView];
  // Attaches FlutterTextInputPlugin to the view;
  [dummyView addSubview:viewController.textInputPlugin];
  // Makes sure the textInputPlugin can be the first responder.
  EXPECT_TRUE([window makeFirstResponder:viewController.textInputPlugin]);
  EXPECT_EQ([window firstResponder], viewController.textInputPlugin);
  EXPECT_FALSE(viewController.textInputPlugin.superview == viewController.view);
  [viewController onAccessibilityStatusChanged:NO];
  // FlutterView becomes child of view controller
  EXPECT_TRUE(viewController.textInputPlugin.superview == viewController.view);
}

TEST(FlutterViewController, CanSetMouseTrackingModeBeforeViewLoaded) {
  NSString* fixtures = @(testing::GetFixturesPath());
  FlutterDartProject* project = [[FlutterDartProject alloc]
      initWithAssetsPath:fixtures
             ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
  FlutterViewController* viewController = [[FlutterViewController alloc] initWithProject:project];
  viewController.mouseTrackingMode = FlutterMouseTrackingModeInActiveApp;
  ASSERT_EQ(viewController.mouseTrackingMode, FlutterMouseTrackingModeInActiveApp);
}

TEST(FlutterViewControllerTest, TestKeyEventsAreSentToFramework) {
  ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testKeyEventsAreSentToFramework]);
}

TEST(FlutterViewControllerTest, TestKeyEventsArePropagatedIfNotHandled) {
  ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testKeyEventsArePropagatedIfNotHandled]);
}

TEST(FlutterViewControllerTest, TestKeyEventsAreNotPropagatedIfHandled) {
  ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testKeyEventsAreNotPropagatedIfHandled]);
}

TEST(FlutterViewControllerTest, TestCtrlTabKeyEventIsPropagated) {
  ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testCtrlTabKeyEventIsPropagated]);
}

TEST(FlutterViewControllerTest, TestFlagsChangedEventsArePropagatedIfNotHandled) {
  ASSERT_TRUE(
      [[FlutterViewControllerTestObjC alloc] testFlagsChangedEventsArePropagatedIfNotHandled]);
}

TEST(FlutterViewControllerTest, TestKeyboardIsRestartedOnEngineRestart) {
  ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testKeyboardIsRestartedOnEngineRestart]);
}

TEST(FlutterViewControllerTest, TestTrackpadGesturesAreSentToFramework) {
  ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testTrackpadGesturesAreSentToFramework]);
}

TEST(FlutterViewControllerTest, TestMouseDownUpEventsSentToNextResponder) {
  ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testMouseDownUpEventsSentToNextResponder]);
}

TEST(FlutterViewControllerTest, TestModifierKeysAreSynthesizedOnMouseMove) {
  ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testModifierKeysAreSynthesizedOnMouseMove]);
}

TEST(FlutterViewControllerTest, testViewWillAppearCalledMultipleTimes) {
  ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testViewWillAppearCalledMultipleTimes]);
}

TEST(FlutterViewControllerTest, testFlutterViewIsConfigured) {
  ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testFlutterViewIsConfigured]);
}

TEST(FlutterViewControllerTest, testLookupKeyAssets) {
  ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testLookupKeyAssets]);
}

TEST(FlutterViewControllerTest, testLookupKeyAssetsWithPackage) {
  ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testLookupKeyAssetsWithPackage]);
}

}  // namespace flutter::testing

#pragma mark - FlutterViewControllerTestObjC

@implementation FlutterViewControllerTestObjC

- (bool)testKeyEventsAreSentToFramework {
  id engineMock = flutter::testing::CreateMockFlutterEngine(@"");
  id binaryMessengerMock = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
  OCMStub(  // NOLINT(google-objc-avoid-throwing-exception)
      [engineMock binaryMessenger])
      .andReturn(binaryMessengerMock);
  OCMStub([[engineMock ignoringNonObjectArgs] sendKeyEvent:FlutterKeyEvent {}
                                                  callback:nil
                                                  userData:nil])
      .andCall([FlutterViewControllerTestObjC class],
               @selector(respondFalseForSendEvent:callback:userData:));
  FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engineMock
                                                                                nibName:@""
                                                                                 bundle:nil];
  NSDictionary* expectedEvent = @{
    @"keymap" : @"macos",
    @"type" : @"keydown",
    @"keyCode" : @(65),
    @"modifiers" : @(538968064),
    @"characters" : @".",
    @"charactersIgnoringModifiers" : @".",
  };
  NSData* encodedKeyEvent = [[FlutterJSONMessageCodec sharedInstance] encode:expectedEvent];
  CGEventRef cgEvent = CGEventCreateKeyboardEvent(NULL, 65, TRUE);
  NSEvent* event = [NSEvent eventWithCGEvent:cgEvent];
  [viewController viewWillAppear];  // Initializes the event channel.
  [viewController keyDown:event];
  @try {
    OCMVerify(  // NOLINT(google-objc-avoid-throwing-exception)
        [binaryMessengerMock sendOnChannel:@"flutter/keyevent"
                                   message:encodedKeyEvent
                               binaryReply:[OCMArg any]]);
  } @catch (...) {
    return false;
  }
  return true;
}

// Regression test for https://github.com/flutter/flutter/issues/122084.
- (bool)testCtrlTabKeyEventIsPropagated {
  id engineMock = flutter::testing::CreateMockFlutterEngine(@"");
  __block bool called = false;
  __block FlutterKeyEvent last_event;
  OCMStub([[engineMock ignoringNonObjectArgs] sendKeyEvent:FlutterKeyEvent {}
                                                  callback:nil
                                                  userData:nil])
      .andDo((^(NSInvocation* invocation) {
        FlutterKeyEvent* event;
        [invocation getArgument:&event atIndex:2];
        called = true;
        last_event = *event;
      }));
  FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engineMock
                                                                                nibName:@""
                                                                                 bundle:nil];
  // Ctrl+tab
  NSEvent* event = [NSEvent keyEventWithType:NSEventTypeKeyDown
                                    location:NSZeroPoint
                               modifierFlags:0x40101
                                   timestamp:0
                                windowNumber:0
                                     context:nil
                                  characters:@""
                 charactersIgnoringModifiers:@""
                                   isARepeat:NO
                                     keyCode:48];
  const uint64_t kPhysicalKeyTab = 0x7002b;

  [viewController viewWillAppear];  // Initializes the event channel.
  [viewController.view performKeyEquivalent:event];

  EXPECT_TRUE(called);
  EXPECT_EQ(last_event.type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(last_event.physical, kPhysicalKeyTab);
  return true;
}

- (bool)testKeyEventsArePropagatedIfNotHandled {
  id engineMock = flutter::testing::CreateMockFlutterEngine(@"");
  id binaryMessengerMock = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
  OCMStub(  // NOLINT(google-objc-avoid-throwing-exception)
      [engineMock binaryMessenger])
      .andReturn(binaryMessengerMock);
  OCMStub([[engineMock ignoringNonObjectArgs] sendKeyEvent:FlutterKeyEvent {}
                                                  callback:nil
                                                  userData:nil])
      .andCall([FlutterViewControllerTestObjC class],
               @selector(respondFalseForSendEvent:callback:userData:));
  FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engineMock
                                                                                nibName:@""
                                                                                 bundle:nil];
  id responderMock = flutter::testing::mockResponder();
  viewController.nextResponder = responderMock;
  NSDictionary* expectedEvent = @{
    @"keymap" : @"macos",
    @"type" : @"keydown",
    @"keyCode" : @(65),
    @"modifiers" : @(538968064),
    @"characters" : @".",
    @"charactersIgnoringModifiers" : @".",
  };
  NSData* encodedKeyEvent = [[FlutterJSONMessageCodec sharedInstance] encode:expectedEvent];
  CGEventRef cgEvent = CGEventCreateKeyboardEvent(NULL, 65, TRUE);
  NSEvent* event = [NSEvent eventWithCGEvent:cgEvent];
  OCMExpect(  // NOLINT(google-objc-avoid-throwing-exception)
      [binaryMessengerMock sendOnChannel:@"flutter/keyevent"
                                 message:encodedKeyEvent
                             binaryReply:[OCMArg any]])
      .andDo((^(NSInvocation* invocation) {
        FlutterBinaryReply handler;
        [invocation getArgument:&handler atIndex:4];
        NSDictionary* reply = @{
          @"handled" : @(false),
        };
        NSData* encodedReply = [[FlutterJSONMessageCodec sharedInstance] encode:reply];
        handler(encodedReply);
      }));
  [viewController viewWillAppear];  // Initializes the event channel.
  [viewController keyDown:event];
  @try {
    OCMVerify(  // NOLINT(google-objc-avoid-throwing-exception)
        [responderMock keyDown:[OCMArg any]]);
    OCMVerify(  // NOLINT(google-objc-avoid-throwing-exception)
        [binaryMessengerMock sendOnChannel:@"flutter/keyevent"
                                   message:encodedKeyEvent
                               binaryReply:[OCMArg any]]);
  } @catch (...) {
    return false;
  }
  return true;
}

- (bool)testFlutterViewIsConfigured {
  id engineMock = flutter::testing::CreateMockFlutterEngine(@"");

  FlutterRenderer* renderer_ = [[FlutterRenderer alloc] initWithFlutterEngine:engineMock];
  OCMStub([engineMock renderer]).andReturn(renderer_);

  FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engineMock
                                                                                nibName:@""
                                                                                 bundle:nil];
  [viewController loadView];

  @try {
    // Make sure "renderer" was called during "loadView", which means "flutterView" is created
    OCMVerify([engineMock renderer]);
  } @catch (...) {
    return false;
  }

  return true;
}

- (bool)testFlagsChangedEventsArePropagatedIfNotHandled {
  id engineMock = flutter::testing::CreateMockFlutterEngine(@"");
  id binaryMessengerMock = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
  OCMStub(  // NOLINT(google-objc-avoid-throwing-exception)
      [engineMock binaryMessenger])
      .andReturn(binaryMessengerMock);
  OCMStub([[engineMock ignoringNonObjectArgs] sendKeyEvent:FlutterKeyEvent {}
                                                  callback:nil
                                                  userData:nil])
      .andCall([FlutterViewControllerTestObjC class],
               @selector(respondFalseForSendEvent:callback:userData:));
  FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engineMock
                                                                                nibName:@""
                                                                                 bundle:nil];
  id responderMock = flutter::testing::mockResponder();
  viewController.nextResponder = responderMock;
  NSDictionary* expectedEvent = @{
    @"keymap" : @"macos",
    @"type" : @"keydown",
    @"keyCode" : @(56),  // SHIFT key
    @"modifiers" : @(537001986),
  };
  NSData* encodedKeyEvent = [[FlutterJSONMessageCodec sharedInstance] encode:expectedEvent];
  CGEventRef cgEvent = CGEventCreateKeyboardEvent(NULL, 56, TRUE);  // SHIFT key
  CGEventSetType(cgEvent, kCGEventFlagsChanged);
  NSEvent* event = [NSEvent eventWithCGEvent:cgEvent];
  OCMExpect(  // NOLINT(google-objc-avoid-throwing-exception)
      [binaryMessengerMock sendOnChannel:@"flutter/keyevent"
                                 message:encodedKeyEvent
                             binaryReply:[OCMArg any]])
      .andDo((^(NSInvocation* invocation) {
        FlutterBinaryReply handler;
        [invocation getArgument:&handler atIndex:4];
        NSDictionary* reply = @{
          @"handled" : @(false),
        };
        NSData* encodedReply = [[FlutterJSONMessageCodec sharedInstance] encode:reply];
        handler(encodedReply);
      }));
  [viewController viewWillAppear];  // Initializes the event channel.
  [viewController flagsChanged:event];
  @try {
    OCMVerify(  // NOLINT(google-objc-avoid-throwing-exception)
        [binaryMessengerMock sendOnChannel:@"flutter/keyevent"
                                   message:encodedKeyEvent
                               binaryReply:[OCMArg any]]);
  } @catch (NSException* e) {
    NSLog(@"%@", e.reason);
    return false;
  }
  return true;
}

- (bool)testKeyEventsAreNotPropagatedIfHandled {
  id engineMock = flutter::testing::CreateMockFlutterEngine(@"");
  id binaryMessengerMock = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
  OCMStub(  // NOLINT(google-objc-avoid-throwing-exception)
      [engineMock binaryMessenger])
      .andReturn(binaryMessengerMock);
  OCMStub([[engineMock ignoringNonObjectArgs] sendKeyEvent:FlutterKeyEvent {}
                                                  callback:nil
                                                  userData:nil])
      .andCall([FlutterViewControllerTestObjC class],
               @selector(respondFalseForSendEvent:callback:userData:));
  FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engineMock
                                                                                nibName:@""
                                                                                 bundle:nil];
  id responderMock = flutter::testing::mockResponder();
  viewController.nextResponder = responderMock;
  NSDictionary* expectedEvent = @{
    @"keymap" : @"macos",
    @"type" : @"keydown",
    @"keyCode" : @(65),
    @"modifiers" : @(538968064),
    @"characters" : @".",
    @"charactersIgnoringModifiers" : @".",
  };
  NSData* encodedKeyEvent = [[FlutterJSONMessageCodec sharedInstance] encode:expectedEvent];
  CGEventRef cgEvent = CGEventCreateKeyboardEvent(NULL, 65, TRUE);
  NSEvent* event = [NSEvent eventWithCGEvent:cgEvent];
  OCMExpect(  // NOLINT(google-objc-avoid-throwing-exception)
      [binaryMessengerMock sendOnChannel:@"flutter/keyevent"
                                 message:encodedKeyEvent
                             binaryReply:[OCMArg any]])
      .andDo((^(NSInvocation* invocation) {
        FlutterBinaryReply handler;
        [invocation getArgument:&handler atIndex:4];
        NSDictionary* reply = @{
          @"handled" : @(true),
        };
        NSData* encodedReply = [[FlutterJSONMessageCodec sharedInstance] encode:reply];
        handler(encodedReply);
      }));
  [viewController viewWillAppear];  // Initializes the event channel.
  [viewController keyDown:event];
  @try {
    OCMVerify(  // NOLINT(google-objc-avoid-throwing-exception)
        never(), [responderMock keyDown:[OCMArg any]]);
    OCMVerify(  // NOLINT(google-objc-avoid-throwing-exception)
        [binaryMessengerMock sendOnChannel:@"flutter/keyevent"
                                   message:encodedKeyEvent
                               binaryReply:[OCMArg any]]);
  } @catch (...) {
    return false;
  }
  return true;
}

- (bool)testKeyboardIsRestartedOnEngineRestart {
  id engineMock = flutter::testing::CreateMockFlutterEngine(@"");
  id binaryMessengerMock = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
  OCMStub(  // NOLINT(google-objc-avoid-throwing-exception)
      [engineMock binaryMessenger])
      .andReturn(binaryMessengerMock);
  __block bool called = false;
  __block FlutterKeyEvent last_event;
  OCMStub([[engineMock ignoringNonObjectArgs] sendKeyEvent:FlutterKeyEvent {}
                                                  callback:nil
                                                  userData:nil])
      .andDo((^(NSInvocation* invocation) {
        FlutterKeyEvent* event;
        [invocation getArgument:&event atIndex:2];
        called = true;
        last_event = *event;
      }));

  FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engineMock
                                                                                nibName:@""
                                                                                 bundle:nil];
  [viewController viewWillAppear];
  NSEvent* keyADown = [NSEvent keyEventWithType:NSEventTypeKeyDown
                                       location:NSZeroPoint
                                  modifierFlags:0x100
                                      timestamp:0
                                   windowNumber:0
                                        context:nil
                                     characters:@"a"
                    charactersIgnoringModifiers:@"a"
                                      isARepeat:FALSE
                                        keyCode:0];
  const uint64_t kPhysicalKeyA = 0x70004;

  // Send KeyA key down event twice. Without restarting the keyboard during
  // onPreEngineRestart, the second event received will be an empty event with
  // physical key 0x0 because duplicate key down events are ignored.

  called = false;
  [viewController keyDown:keyADown];
  EXPECT_TRUE(called);
  EXPECT_EQ(last_event.type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(last_event.physical, kPhysicalKeyA);

  [viewController onPreEngineRestart];

  called = false;
  [viewController keyDown:keyADown];
  EXPECT_TRUE(called);
  EXPECT_EQ(last_event.type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(last_event.physical, kPhysicalKeyA);
  return true;
}

+ (void)respondFalseForSendEvent:(const FlutterKeyEvent&)event
                        callback:(nullable FlutterKeyEventCallback)callback
                        userData:(nullable void*)userData {
  if (callback != nullptr) {
    callback(false, userData);
  }
}

- (bool)testTrackpadGesturesAreSentToFramework {
  id engineMock = flutter::testing::CreateMockFlutterEngine(@"");
  // Need to return a real renderer to allow view controller to load.
  FlutterRenderer* renderer_ = [[FlutterRenderer alloc] initWithFlutterEngine:engineMock];
  OCMStub([engineMock renderer]).andReturn(renderer_);
  __block bool called = false;
  __block FlutterPointerEvent last_event;
  OCMStub([[engineMock ignoringNonObjectArgs] sendPointerEvent:FlutterPointerEvent{}])
      .andDo((^(NSInvocation* invocation) {
        FlutterPointerEvent* event;
        [invocation getArgument:&event atIndex:2];
        called = true;
        last_event = *event;
      }));

  FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engineMock
                                                                                nibName:@""
                                                                                 bundle:nil];
  [viewController loadView];

  // Test for pan events.
  // Start gesture.
  CGEventRef cgEventStart = CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitPixel, 1, 0);
  CGEventSetType(cgEventStart, kCGEventScrollWheel);
  CGEventSetIntegerValueField(cgEventStart, kCGScrollWheelEventScrollPhase, kCGScrollPhaseBegan);
  CGEventSetIntegerValueField(cgEventStart, kCGScrollWheelEventIsContinuous, 1);

  called = false;
  [viewController scrollWheel:[NSEvent eventWithCGEvent:cgEventStart]];
  EXPECT_TRUE(called);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);
  EXPECT_EQ(last_event.phase, kPanZoomStart);
  EXPECT_EQ(last_event.device_kind, kFlutterPointerDeviceKindTrackpad);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);

  // Update gesture.
  CGEventRef cgEventUpdate = CGEventCreateCopy(cgEventStart);
  CGEventSetIntegerValueField(cgEventUpdate, kCGScrollWheelEventScrollPhase, kCGScrollPhaseChanged);
  CGEventSetIntegerValueField(cgEventUpdate, kCGScrollWheelEventDeltaAxis2, 1);  // pan_x
  CGEventSetIntegerValueField(cgEventUpdate, kCGScrollWheelEventDeltaAxis1, 2);  // pan_y

  called = false;
  [viewController scrollWheel:[NSEvent eventWithCGEvent:cgEventUpdate]];
  EXPECT_TRUE(called);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);
  EXPECT_EQ(last_event.phase, kPanZoomUpdate);
  EXPECT_EQ(last_event.device_kind, kFlutterPointerDeviceKindTrackpad);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);
  EXPECT_EQ(last_event.pan_x, 8 * viewController.flutterView.layer.contentsScale);
  EXPECT_EQ(last_event.pan_y, 16 * viewController.flutterView.layer.contentsScale);

  // Make sure the pan values accumulate.
  called = false;
  [viewController scrollWheel:[NSEvent eventWithCGEvent:cgEventUpdate]];
  EXPECT_TRUE(called);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);
  EXPECT_EQ(last_event.phase, kPanZoomUpdate);
  EXPECT_EQ(last_event.device_kind, kFlutterPointerDeviceKindTrackpad);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);
  EXPECT_EQ(last_event.pan_x, 16 * viewController.flutterView.layer.contentsScale);
  EXPECT_EQ(last_event.pan_y, 32 * viewController.flutterView.layer.contentsScale);

  // End gesture.
  CGEventRef cgEventEnd = CGEventCreateCopy(cgEventStart);
  CGEventSetIntegerValueField(cgEventEnd, kCGScrollWheelEventScrollPhase, kCGScrollPhaseEnded);

  called = false;
  [viewController scrollWheel:[NSEvent eventWithCGEvent:cgEventEnd]];
  EXPECT_TRUE(called);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);
  EXPECT_EQ(last_event.phase, kPanZoomEnd);
  EXPECT_EQ(last_event.device_kind, kFlutterPointerDeviceKindTrackpad);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);

  // Start system momentum.
  CGEventRef cgEventMomentumStart = CGEventCreateCopy(cgEventStart);
  CGEventSetIntegerValueField(cgEventMomentumStart, kCGScrollWheelEventScrollPhase, 0);
  CGEventSetIntegerValueField(cgEventMomentumStart, kCGScrollWheelEventMomentumPhase,
                              kCGMomentumScrollPhaseBegin);

  called = false;
  [viewController scrollWheel:[NSEvent eventWithCGEvent:cgEventMomentumStart]];
  EXPECT_FALSE(called);

  // Advance system momentum.
  CGEventRef cgEventMomentumUpdate = CGEventCreateCopy(cgEventStart);
  CGEventSetIntegerValueField(cgEventMomentumUpdate, kCGScrollWheelEventScrollPhase, 0);
  CGEventSetIntegerValueField(cgEventMomentumUpdate, kCGScrollWheelEventMomentumPhase,
                              kCGMomentumScrollPhaseContinue);

  called = false;
  [viewController scrollWheel:[NSEvent eventWithCGEvent:cgEventMomentumUpdate]];
  EXPECT_FALSE(called);

  // Mock a touch on the trackpad.
  id touchMock = OCMClassMock([NSTouch class]);
  NSSet* touchSet = [NSSet setWithObject:touchMock];
  id touchEventMock1 = OCMClassMock([NSEvent class]);
  OCMStub([touchEventMock1 allTouches]).andReturn(touchSet);
  CGPoint touchLocation = {0, 0};
  OCMStub([touchEventMock1 locationInWindow]).andReturn(touchLocation);
  OCMStub([(NSEvent*)touchEventMock1 timestamp]).andReturn(0.150);  // 150 milliseconds.

  // Scroll inertia cancel event should not be issued (timestamp too far in the future).
  called = false;
  [viewController touchesBeganWithEvent:touchEventMock1];
  EXPECT_FALSE(called);

  // Mock another touch on the trackpad.
  id touchEventMock2 = OCMClassMock([NSEvent class]);
  OCMStub([touchEventMock2 allTouches]).andReturn(touchSet);
  OCMStub([touchEventMock2 locationInWindow]).andReturn(touchLocation);
  OCMStub([(NSEvent*)touchEventMock2 timestamp]).andReturn(0.005);  // 5 milliseconds.

  // Scroll inertia cancel event should be issued.
  called = false;
  [viewController touchesBeganWithEvent:touchEventMock2];
  EXPECT_TRUE(called);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindScrollInertiaCancel);
  EXPECT_EQ(last_event.device_kind, kFlutterPointerDeviceKindTrackpad);

  // End system momentum.
  CGEventRef cgEventMomentumEnd = CGEventCreateCopy(cgEventStart);
  CGEventSetIntegerValueField(cgEventMomentumEnd, kCGScrollWheelEventScrollPhase, 0);
  CGEventSetIntegerValueField(cgEventMomentumEnd, kCGScrollWheelEventMomentumPhase,
                              kCGMomentumScrollPhaseEnd);

  called = false;
  [viewController scrollWheel:[NSEvent eventWithCGEvent:cgEventMomentumEnd]];
  EXPECT_FALSE(called);

  // May-begin and cancel are used while macOS determines which type of gesture to choose.
  CGEventRef cgEventMayBegin = CGEventCreateCopy(cgEventStart);
  CGEventSetIntegerValueField(cgEventMayBegin, kCGScrollWheelEventScrollPhase,
                              kCGScrollPhaseMayBegin);

  called = false;
  [viewController scrollWheel:[NSEvent eventWithCGEvent:cgEventMayBegin]];
  EXPECT_TRUE(called);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);
  EXPECT_EQ(last_event.phase, kPanZoomStart);
  EXPECT_EQ(last_event.device_kind, kFlutterPointerDeviceKindTrackpad);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);

  // Cancel gesture.
  CGEventRef cgEventCancel = CGEventCreateCopy(cgEventStart);
  CGEventSetIntegerValueField(cgEventCancel, kCGScrollWheelEventScrollPhase,
                              kCGScrollPhaseCancelled);

  called = false;
  [viewController scrollWheel:[NSEvent eventWithCGEvent:cgEventCancel]];
  EXPECT_TRUE(called);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);
  EXPECT_EQ(last_event.phase, kPanZoomEnd);
  EXPECT_EQ(last_event.device_kind, kFlutterPointerDeviceKindTrackpad);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);

  // A discrete scroll event should use the PointerSignal system.
  CGEventRef cgEventDiscrete = CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitPixel, 1, 0);
  CGEventSetType(cgEventDiscrete, kCGEventScrollWheel);
  CGEventSetIntegerValueField(cgEventDiscrete, kCGScrollWheelEventIsContinuous, 0);
  CGEventSetIntegerValueField(cgEventDiscrete, kCGScrollWheelEventDeltaAxis2, 1);  // scroll_delta_x
  CGEventSetIntegerValueField(cgEventDiscrete, kCGScrollWheelEventDeltaAxis1, 2);  // scroll_delta_y

  called = false;
  [viewController scrollWheel:[NSEvent eventWithCGEvent:cgEventDiscrete]];
  EXPECT_TRUE(called);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindScroll);
  // pixelsPerLine is 40.0 and direction is reversed.
  EXPECT_EQ(last_event.scroll_delta_x, -40 * viewController.flutterView.layer.contentsScale);
  EXPECT_EQ(last_event.scroll_delta_y, -80 * viewController.flutterView.layer.contentsScale);

  // A discrete scroll event should use the PointerSignal system, and flip the
  // direction when shift is pressed.
  CGEventRef cgEventDiscreteShift =
      CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitPixel, 1, 0);
  CGEventSetType(cgEventDiscreteShift, kCGEventScrollWheel);
  CGEventSetFlags(cgEventDiscreteShift, kCGEventFlagMaskShift);
  CGEventSetIntegerValueField(cgEventDiscreteShift, kCGScrollWheelEventIsContinuous, 0);
  CGEventSetIntegerValueField(cgEventDiscreteShift, kCGScrollWheelEventDeltaAxis2,
                              0);  // scroll_delta_x
  CGEventSetIntegerValueField(cgEventDiscreteShift, kCGScrollWheelEventDeltaAxis1,
                              2);  // scroll_delta_y

  called = false;
  [viewController scrollWheel:[NSEvent eventWithCGEvent:cgEventDiscreteShift]];
  EXPECT_TRUE(called);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindScroll);
  // pixelsPerLine is 40.0, direction is reversed and axes have been flipped back.
  EXPECT_FLOAT_EQ(last_event.scroll_delta_x, 0.0 * viewController.flutterView.layer.contentsScale);
  EXPECT_FLOAT_EQ(last_event.scroll_delta_y,
                  -80.0 * viewController.flutterView.layer.contentsScale);

  // Test for scale events.
  // Start gesture.
  called = false;
  [viewController magnifyWithEvent:flutter::testing::MockGestureEvent(NSEventTypeMagnify,
                                                                      NSEventPhaseBegan, 1, 0)];
  EXPECT_TRUE(called);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);
  EXPECT_EQ(last_event.phase, kPanZoomStart);
  EXPECT_EQ(last_event.device_kind, kFlutterPointerDeviceKindTrackpad);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);

  // Update gesture.
  called = false;
  [viewController magnifyWithEvent:flutter::testing::MockGestureEvent(NSEventTypeMagnify,
                                                                      NSEventPhaseChanged, 1, 0)];
  EXPECT_TRUE(called);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);
  EXPECT_EQ(last_event.phase, kPanZoomUpdate);
  EXPECT_EQ(last_event.device_kind, kFlutterPointerDeviceKindTrackpad);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);
  EXPECT_EQ(last_event.pan_x, 0);
  EXPECT_EQ(last_event.pan_y, 0);
  EXPECT_EQ(last_event.scale, 2);  // macOS uses logarithmic scaling values, the linear value for
                                   // flutter here should be 2^1 = 2.
  EXPECT_EQ(last_event.rotation, 0);

  // Make sure the scale values accumulate.
  called = false;
  [viewController magnifyWithEvent:flutter::testing::MockGestureEvent(NSEventTypeMagnify,
                                                                      NSEventPhaseChanged, 1, 0)];
  EXPECT_TRUE(called);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);
  EXPECT_EQ(last_event.phase, kPanZoomUpdate);
  EXPECT_EQ(last_event.device_kind, kFlutterPointerDeviceKindTrackpad);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);
  EXPECT_EQ(last_event.pan_x, 0);
  EXPECT_EQ(last_event.pan_y, 0);
  EXPECT_EQ(last_event.scale, 4);  // macOS uses logarithmic scaling values, the linear value for
                                   // flutter here should be 2^(1+1) = 2.
  EXPECT_EQ(last_event.rotation, 0);

  // End gesture.
  called = false;
  [viewController magnifyWithEvent:flutter::testing::MockGestureEvent(NSEventTypeMagnify,
                                                                      NSEventPhaseEnded, 0, 0)];
  EXPECT_TRUE(called);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);
  EXPECT_EQ(last_event.phase, kPanZoomEnd);
  EXPECT_EQ(last_event.device_kind, kFlutterPointerDeviceKindTrackpad);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);

  // Test for rotation events.
  // Start gesture.
  called = false;
  [viewController rotateWithEvent:flutter::testing::MockGestureEvent(NSEventTypeRotate,
                                                                     NSEventPhaseBegan, 1, 0)];
  EXPECT_TRUE(called);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);
  EXPECT_EQ(last_event.phase, kPanZoomStart);
  EXPECT_EQ(last_event.device_kind, kFlutterPointerDeviceKindTrackpad);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);

  // Update gesture.
  called = false;
  [viewController rotateWithEvent:flutter::testing::MockGestureEvent(
                                      NSEventTypeRotate, NSEventPhaseChanged, 0, -180)];  // degrees
  EXPECT_TRUE(called);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);
  EXPECT_EQ(last_event.phase, kPanZoomUpdate);
  EXPECT_EQ(last_event.device_kind, kFlutterPointerDeviceKindTrackpad);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);
  EXPECT_EQ(last_event.pan_x, 0);
  EXPECT_EQ(last_event.pan_y, 0);
  EXPECT_EQ(last_event.scale, 1);
  EXPECT_EQ(last_event.rotation, M_PI);  // radians

  // Make sure the rotation values accumulate.
  called = false;
  [viewController rotateWithEvent:flutter::testing::MockGestureEvent(
                                      NSEventTypeRotate, NSEventPhaseChanged, 0, -360)];  // degrees
  EXPECT_TRUE(called);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);
  EXPECT_EQ(last_event.phase, kPanZoomUpdate);
  EXPECT_EQ(last_event.device_kind, kFlutterPointerDeviceKindTrackpad);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);
  EXPECT_EQ(last_event.pan_x, 0);
  EXPECT_EQ(last_event.pan_y, 0);
  EXPECT_EQ(last_event.scale, 1);
  EXPECT_EQ(last_event.rotation, 3 * M_PI);  // radians

  // End gesture.
  called = false;
  [viewController rotateWithEvent:flutter::testing::MockGestureEvent(NSEventTypeRotate,
                                                                     NSEventPhaseEnded, 0, 0)];
  EXPECT_TRUE(called);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);
  EXPECT_EQ(last_event.phase, kPanZoomEnd);
  EXPECT_EQ(last_event.device_kind, kFlutterPointerDeviceKindTrackpad);
  EXPECT_EQ(last_event.signal_kind, kFlutterPointerSignalKindNone);

  return true;
}

- (bool)testViewWillAppearCalledMultipleTimes {
  id engineMock = flutter::testing::CreateMockFlutterEngine(@"");
  FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engineMock
                                                                                nibName:@""
                                                                                 bundle:nil];
  [viewController viewWillAppear];
  [viewController viewWillAppear];
  return true;
}

- (bool)testLookupKeyAssets {
  FlutterViewController* viewController = [[FlutterViewController alloc] initWithProject:nil];
  NSString* key = [viewController lookupKeyForAsset:@"test.png"];
  EXPECT_TRUE(
      [key isEqualToString:@"Contents/Frameworks/App.framework/Resources/flutter_assets/test.png"]);
  return true;
}

- (bool)testLookupKeyAssetsWithPackage {
  FlutterViewController* viewController = [[FlutterViewController alloc] initWithProject:nil];

  NSString* packageKey = [viewController lookupKeyForAsset:@"test.png" fromPackage:@"test"];
  EXPECT_TRUE([packageKey
      isEqualToString:
          @"Contents/Frameworks/App.framework/Resources/flutter_assets/packages/test/test.png"]);
  return true;
}

static void SwizzledNoop(id self, SEL _cmd) {}

// Verify workaround an AppKit bug where mouseDown/mouseUp are not called on the view controller if
// the view is the content view of an NSPopover AND macOS's Reduced Transparency accessibility
// setting is enabled.
//
// See: https://github.com/flutter/flutter/issues/115015
// See: http://www.openradar.me/FB12050037
// See: https://developer.apple.com/documentation/appkit/nsresponder/1524634-mousedown
- (bool)testMouseDownUpEventsSentToNextResponder {
  // The root cause of the above bug is NSResponder mouseDown/mouseUp methods that don't correctly
  // walk the responder chain calling the appropriate method on the next responder under certain
  // conditions. Simulate this by swizzling out the default implementations and replacing them with
  // no-ops.
  Method mouseDown = class_getInstanceMethod([NSResponder class], @selector(mouseDown:));
  Method mouseUp = class_getInstanceMethod([NSResponder class], @selector(mouseUp:));
  IMP noopImp = (IMP)SwizzledNoop;
  IMP origMouseDown = method_setImplementation(mouseDown, noopImp);
  IMP origMouseUp = method_setImplementation(mouseUp, noopImp);

  // Verify that mouseDown/mouseUp trigger mouseDown/mouseUp calls on FlutterViewController.
  id engineMock = flutter::testing::CreateMockFlutterEngine(@"");
  MouseEventFlutterViewController* viewController =
      [[MouseEventFlutterViewController alloc] initWithEngine:engineMock nibName:@"" bundle:nil];
  FlutterView* view = (FlutterView*)[viewController view];

  EXPECT_FALSE(viewController.mouseDownCalled);
  EXPECT_FALSE(viewController.mouseUpCalled);

  NSEvent* mouseEvent = flutter::testing::CreateMouseEvent(0x00);
  [view mouseDown:mouseEvent];
  EXPECT_TRUE(viewController.mouseDownCalled);
  EXPECT_FALSE(viewController.mouseUpCalled);

  viewController.mouseDownCalled = NO;
  [view mouseUp:mouseEvent];
  EXPECT_FALSE(viewController.mouseDownCalled);
  EXPECT_TRUE(viewController.mouseUpCalled);

  // Restore the original NSResponder mouseDown/mouseUp implementations.
  method_setImplementation(mouseDown, origMouseDown);
  method_setImplementation(mouseUp, origMouseUp);

  return true;
}

- (bool)testModifierKeysAreSynthesizedOnMouseMove {
  id engineMock = flutter::testing::CreateMockFlutterEngine(@"");
  // Need to return a real renderer to allow view controller to load.
  FlutterRenderer* renderer_ = [[FlutterRenderer alloc] initWithFlutterEngine:engineMock];
  OCMStub([engineMock renderer]).andReturn(renderer_);

  // Capture calls to sendKeyEvent
  __block NSMutableArray<KeyEventWrapper*>* events =
      [[NSMutableArray<KeyEventWrapper*> alloc] init];
  OCMStub([[engineMock ignoringNonObjectArgs] sendKeyEvent:FlutterKeyEvent {}
                                                  callback:nil
                                                  userData:nil])
      .andDo((^(NSInvocation* invocation) {
        FlutterKeyEvent* event;
        [invocation getArgument:&event atIndex:2];
        [events addObject:[[KeyEventWrapper alloc] initWithEvent:event]];
      }));

  FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engineMock
                                                                                nibName:@""
                                                                                 bundle:nil];
  [viewController loadView];
  [viewController viewWillAppear];

  // Zeroed modifier flag should not synthesize events.
  NSEvent* mouseEvent = flutter::testing::CreateMouseEvent(0x00);
  [viewController mouseMoved:mouseEvent];
  EXPECT_EQ([events count], 0u);

  // For each modifier key, check that key events are synthesized.
  for (NSNumber* keyCode in flutter::keyCodeToModifierFlag) {
    FlutterKeyEvent* event;
    NSNumber* logicalKey;
    NSNumber* physicalKey;
    NSNumber* flag = flutter::keyCodeToModifierFlag[keyCode];

    // Should synthesize down event.
    NSEvent* mouseEvent = flutter::testing::CreateMouseEvent([flag unsignedLongValue]);
    [viewController mouseMoved:mouseEvent];
    EXPECT_EQ([events count], 1u);
    event = events[0].data;
    logicalKey = [flutter::keyCodeToLogicalKey objectForKey:keyCode];
    physicalKey = [flutter::keyCodeToPhysicalKey objectForKey:keyCode];
    EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
    EXPECT_EQ(event->logical, logicalKey.unsignedLongLongValue);
    EXPECT_EQ(event->physical, physicalKey.unsignedLongLongValue);
    EXPECT_EQ(event->synthesized, true);

    // Should synthesize up event.
    mouseEvent = flutter::testing::CreateMouseEvent(0x00);
    [viewController mouseMoved:mouseEvent];
    EXPECT_EQ([events count], 2u);
    event = events[1].data;
    logicalKey = [flutter::keyCodeToLogicalKey objectForKey:keyCode];
    physicalKey = [flutter::keyCodeToPhysicalKey objectForKey:keyCode];
    EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
    EXPECT_EQ(event->logical, logicalKey.unsignedLongLongValue);
    EXPECT_EQ(event->physical, physicalKey.unsignedLongLongValue);
    EXPECT_EQ(event->synthesized, true);

    [events removeAllObjects];
  };

  return true;
}

@end
