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

#include "flutter/shell/platform/linux/fl_scrolling_manager.h"

#include <cstring>
#include <vector>

#include "gtest/gtest.h"
namespace {
typedef std::function<void(FlutterPointerPhase phase,
                           size_t timestamp,
                           double x,
                           double y,
                           double scroll_delta_x,
                           double scroll_delta_y,
                           int64_t buttons)>
    MousePointerCallHandler;
typedef std::function<void(size_t timestamp,
                           double x,
                           double y,
                           FlutterPointerPhase phase,
                           double pan_x,
                           double pan_y,
                           double scale,
                           double rotation)>
    PointerPanZoomCallHandler;

typedef struct {
  FlutterPointerPhase phase;
  size_t timestamp;
  double x;
  double y;
  double scroll_delta_x;
  double scroll_delta_y;
  int64_t buttons;
} MousePointerEventRecord;

typedef struct {
  size_t timestamp;
  double x;
  double y;
  FlutterPointerPhase phase;
  double pan_x;
  double pan_y;
  double scale;
  double rotation;
} PointerPanZoomEventRecord;

G_BEGIN_DECLS

G_DECLARE_FINAL_TYPE(FlMockScrollingViewDelegate,
                     fl_mock_scrolling_view_delegate,
                     FL,
                     MOCK_SCROLLING_VIEW_DELEGATE,
                     GObject)

G_END_DECLS

/***** FlMockScrollingViewDelegate *****/

struct _FlMockScrollingViewDelegate {
  GObject parent_instance;

  MousePointerCallHandler mouse_handler;
  PointerPanZoomCallHandler pan_zoom_handler;
};

static void fl_mock_view_scroll_delegate_iface_init(
    FlScrollingViewDelegateInterface* iface);

G_DEFINE_TYPE_WITH_CODE(
    FlMockScrollingViewDelegate,
    fl_mock_scrolling_view_delegate,
    G_TYPE_OBJECT,
    G_IMPLEMENT_INTERFACE(fl_scrolling_view_delegate_get_type(),
                          fl_mock_view_scroll_delegate_iface_init))

static void fl_mock_scrolling_view_delegate_init(
    FlMockScrollingViewDelegate* self) {}

static void fl_mock_scrolling_view_delegate_dispose(GObject* object) {
  G_OBJECT_CLASS(fl_mock_scrolling_view_delegate_parent_class)->dispose(object);
}

static void fl_mock_scrolling_view_delegate_class_init(
    FlMockScrollingViewDelegateClass* klass) {
  G_OBJECT_CLASS(klass)->dispose = fl_mock_scrolling_view_delegate_dispose;
}

static void fl_mock_view_send_mouse_pointer_event(
    FlScrollingViewDelegate* delegate,
    FlutterPointerPhase phase,
    size_t timestamp,
    double x,
    double y,
    double scroll_delta_x,
    double scroll_delta_y,
    int64_t buttons) {
  FlMockScrollingViewDelegate* self = FL_MOCK_SCROLLING_VIEW_DELEGATE(delegate);
  self->mouse_handler(phase, timestamp, x, y, scroll_delta_x, scroll_delta_y,
                      buttons);
}

static void fl_mock_view_send_pointer_pan_zoom_event(
    FlScrollingViewDelegate* delegate,
    size_t timestamp,
    double x,
    double y,
    FlutterPointerPhase phase,
    double pan_x,
    double pan_y,
    double scale,
    double rotation) {
  FlMockScrollingViewDelegate* self = FL_MOCK_SCROLLING_VIEW_DELEGATE(delegate);
  self->pan_zoom_handler(timestamp, x, y, phase, pan_x, pan_y, scale, rotation);
}

static void fl_mock_view_scroll_delegate_iface_init(
    FlScrollingViewDelegateInterface* iface) {
  iface->send_mouse_pointer_event = fl_mock_view_send_mouse_pointer_event;
  iface->send_pointer_pan_zoom_event = fl_mock_view_send_pointer_pan_zoom_event;
}

static FlMockScrollingViewDelegate* fl_mock_scrolling_view_delegate_new() {
  FlMockScrollingViewDelegate* self = FL_MOCK_SCROLLING_VIEW_DELEGATE(
      g_object_new(fl_mock_scrolling_view_delegate_get_type(), nullptr));

  // Added to stop compiler complaining about an unused function.
  FL_IS_MOCK_SCROLLING_VIEW_DELEGATE(self);

  return self;
}

static void fl_mock_scrolling_view_set_mouse_handler(
    FlMockScrollingViewDelegate* self,
    MousePointerCallHandler handler) {
  self->mouse_handler = std::move(handler);
}

static void fl_mock_scrolling_view_set_pan_zoom_handler(
    FlMockScrollingViewDelegate* self,
    PointerPanZoomCallHandler handler) {
  self->pan_zoom_handler = std::move(handler);
}

/***** End FlMockScrollingViewDelegate *****/

class ScrollingTester {
 public:
  ScrollingTester() {
    view_ = fl_mock_scrolling_view_delegate_new();
    manager_ = fl_scrolling_manager_new(FL_SCROLLING_VIEW_DELEGATE(view_));
    fl_mock_scrolling_view_set_mouse_handler(
        view_,
        [](FlutterPointerPhase phase, size_t timestamp, double x, double y,
           double scroll_delta_x, double scroll_delta_y, int64_t buttons) {
          // do nothing
        });
    fl_mock_scrolling_view_set_pan_zoom_handler(
        view_,
        [](size_t timestamp, double x, double y, FlutterPointerPhase phase,
           double pan_x, double pan_y, double scale, double rotation) {
          // do nothing
        });
  }

  ~ScrollingTester() {
    g_clear_object(&view_);
    g_clear_object(&manager_);
  }

  FlScrollingManager* manager() { return manager_; }

  void recordMousePointerCallsTo(
      std::vector<MousePointerEventRecord>& storage) {
    fl_mock_scrolling_view_set_mouse_handler(
        view_, [&storage](FlutterPointerPhase phase, size_t timestamp, double x,
                          double y, double scroll_delta_x,
                          double scroll_delta_y, int64_t buttons) {
          storage.push_back(MousePointerEventRecord{
              .phase = phase,
              .timestamp = timestamp,
              .x = x,
              .y = y,
              .scroll_delta_x = scroll_delta_x,
              .scroll_delta_y = scroll_delta_y,
              .buttons = buttons,
          });
        });
  }

  void recordPointerPanZoomCallsTo(
      std::vector<PointerPanZoomEventRecord>& storage) {
    fl_mock_scrolling_view_set_pan_zoom_handler(
        view_, [&storage](size_t timestamp, double x, double y,
                          FlutterPointerPhase phase, double pan_x, double pan_y,
                          double scale, double rotation) {
          storage.push_back(PointerPanZoomEventRecord{
              .timestamp = timestamp,
              .x = x,
              .y = y,
              .phase = phase,
              .pan_x = pan_x,
              .pan_y = pan_y,
              .scale = scale,
              .rotation = rotation,
          });
        });
  }

 private:
  FlMockScrollingViewDelegate* view_;
  FlScrollingManager* manager_;
};

// Disgusting hack but could not find any way to create a GdkDevice
struct _FakeGdkDevice {
  GObject parent_instance;
  gchar* name;
  GdkInputSource source;
};
GdkDevice* makeFakeDevice(GdkInputSource source) {
  _FakeGdkDevice* device = (_FakeGdkDevice*)g_malloc0(sizeof(_FakeGdkDevice));
  device->source = source;
  // Bully the type checker
  ((GTypeInstance*)device)->g_class =
      (GTypeClass*)g_malloc0(sizeof(GTypeClass));
  ((GTypeInstance*)device)->g_class->g_type = GDK_TYPE_DEVICE;
  return (GdkDevice*)device;
}

TEST(FlScrollingManagerTest, DiscreteDirectionional) {
  ScrollingTester tester;
  std::vector<MousePointerEventRecord> mouse_records;
  std::vector<PointerPanZoomEventRecord> pan_zoom_records;
  tester.recordMousePointerCallsTo(mouse_records);
  tester.recordPointerPanZoomCallsTo(pan_zoom_records);
  GdkDevice* mouse = makeFakeDevice(GDK_SOURCE_MOUSE);
  GdkEventScroll* event = (GdkEventScroll*)gdk_event_new(GDK_SCROLL);
  event->time = 1;
  event->x = 4.0;
  event->y = 8.0;
  event->device = mouse;
  event->direction = GDK_SCROLL_UP;
  fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
  EXPECT_EQ(pan_zoom_records.size(), 0u);
  EXPECT_EQ(mouse_records.size(), 1u);
  EXPECT_EQ(mouse_records[0].x, 4.0);
  EXPECT_EQ(mouse_records[0].y, 8.0);
  EXPECT_EQ(mouse_records[0].timestamp,
            1000lu);  // Milliseconds -> Microseconds
  EXPECT_EQ(mouse_records[0].scroll_delta_x, 0);
  EXPECT_EQ(mouse_records[0].scroll_delta_y, 53 * -1.0);
  event->direction = GDK_SCROLL_DOWN;
  fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
  EXPECT_EQ(pan_zoom_records.size(), 0u);
  EXPECT_EQ(mouse_records.size(), 2u);
  EXPECT_EQ(mouse_records[1].x, 4.0);
  EXPECT_EQ(mouse_records[1].y, 8.0);
  EXPECT_EQ(mouse_records[1].timestamp,
            1000lu);  // Milliseconds -> Microseconds
  EXPECT_EQ(mouse_records[1].scroll_delta_x, 0);
  EXPECT_EQ(mouse_records[1].scroll_delta_y, 53 * 1.0);
  event->direction = GDK_SCROLL_LEFT;
  fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
  EXPECT_EQ(pan_zoom_records.size(), 0u);
  EXPECT_EQ(mouse_records.size(), 3u);
  EXPECT_EQ(mouse_records[2].x, 4.0);
  EXPECT_EQ(mouse_records[2].y, 8.0);
  EXPECT_EQ(mouse_records[2].timestamp,
            1000lu);  // Milliseconds -> Microseconds
  EXPECT_EQ(mouse_records[2].scroll_delta_x, 53 * -1.0);
  EXPECT_EQ(mouse_records[2].scroll_delta_y, 0);
  event->direction = GDK_SCROLL_RIGHT;
  fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
  EXPECT_EQ(pan_zoom_records.size(), 0u);
  EXPECT_EQ(mouse_records.size(), 4u);
  EXPECT_EQ(mouse_records[3].x, 4.0);
  EXPECT_EQ(mouse_records[3].y, 8.0);
  EXPECT_EQ(mouse_records[3].timestamp,
            1000lu);  // Milliseconds -> Microseconds
  EXPECT_EQ(mouse_records[3].scroll_delta_x, 53 * 1.0);
  EXPECT_EQ(mouse_records[3].scroll_delta_y, 0);
}

TEST(FlScrollingManagerTest, DiscreteScrolling) {
  ScrollingTester tester;
  std::vector<MousePointerEventRecord> mouse_records;
  std::vector<PointerPanZoomEventRecord> pan_zoom_records;
  tester.recordMousePointerCallsTo(mouse_records);
  tester.recordPointerPanZoomCallsTo(pan_zoom_records);
  GdkDevice* mouse = makeFakeDevice(GDK_SOURCE_MOUSE);
  GdkEventScroll* event = (GdkEventScroll*)gdk_event_new(GDK_SCROLL);
  event->time = 1;
  event->x = 4.0;
  event->y = 8.0;
  event->delta_x = 1.0;
  event->delta_y = 2.0;
  event->device = mouse;
  event->direction = GDK_SCROLL_SMOOTH;
  fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
  EXPECT_EQ(pan_zoom_records.size(), 0u);
  EXPECT_EQ(mouse_records.size(), 1u);
  EXPECT_EQ(mouse_records[0].x, 4.0);
  EXPECT_EQ(mouse_records[0].y, 8.0);
  EXPECT_EQ(mouse_records[0].timestamp,
            1000lu);  // Milliseconds -> Microseconds
  EXPECT_EQ(mouse_records[0].scroll_delta_x, 53 * 1.0);
  EXPECT_EQ(mouse_records[0].scroll_delta_y, 53 * 2.0);
}

TEST(FlScrollingManagerTest, Panning) {
  ScrollingTester tester;
  std::vector<MousePointerEventRecord> mouse_records;
  std::vector<PointerPanZoomEventRecord> pan_zoom_records;
  tester.recordMousePointerCallsTo(mouse_records);
  tester.recordPointerPanZoomCallsTo(pan_zoom_records);
  GdkDevice* touchpad = makeFakeDevice(GDK_SOURCE_TOUCHPAD);
  GdkEventScroll* event = (GdkEventScroll*)gdk_event_new(GDK_SCROLL);
  event->time = 1;
  event->x = 4.0;
  event->y = 8.0;
  event->delta_x = 1.0;
  event->delta_y = 2.0;
  event->device = touchpad;
  event->direction = GDK_SCROLL_SMOOTH;
  fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
  EXPECT_EQ(pan_zoom_records.size(), 2u);
  EXPECT_EQ(mouse_records.size(), 0u);
  EXPECT_EQ(pan_zoom_records[0].x, 4.0);
  EXPECT_EQ(pan_zoom_records[0].y, 8.0);
  EXPECT_EQ(pan_zoom_records[0].timestamp,
            1000lu);  // Milliseconds -> Microseconds
  EXPECT_EQ(pan_zoom_records[0].phase, kPanZoomStart);
  EXPECT_EQ(pan_zoom_records[1].x, 4.0);
  EXPECT_EQ(pan_zoom_records[1].y, 8.0);
  EXPECT_EQ(pan_zoom_records[1].timestamp,
            1000lu);  // Milliseconds -> Microseconds
  EXPECT_EQ(pan_zoom_records[1].phase, kPanZoomUpdate);
  EXPECT_EQ(pan_zoom_records[1].pan_x, 53 * -1.0);  // directions get swapped
  EXPECT_EQ(pan_zoom_records[1].pan_y, 53 * -2.0);
  EXPECT_EQ(pan_zoom_records[1].scale, 1.0);
  EXPECT_EQ(pan_zoom_records[1].rotation, 0.0);
  fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
  EXPECT_EQ(pan_zoom_records.size(), 3u);
  EXPECT_EQ(mouse_records.size(), 0u);
  EXPECT_EQ(pan_zoom_records[2].x, 4.0);
  EXPECT_EQ(pan_zoom_records[2].y, 8.0);
  EXPECT_EQ(pan_zoom_records[2].timestamp,
            1000lu);  // Milliseconds -> Microseconds
  EXPECT_EQ(pan_zoom_records[2].phase, kPanZoomUpdate);
  EXPECT_EQ(pan_zoom_records[2].pan_x, 53 * -2.0);  // directions get swapped
  EXPECT_EQ(pan_zoom_records[2].pan_y, 53 * -4.0);
  EXPECT_EQ(pan_zoom_records[2].scale, 1.0);
  EXPECT_EQ(pan_zoom_records[2].rotation, 0.0);
  event->is_stop = true;
  fl_scrolling_manager_handle_scroll_event(tester.manager(), event, 1.0);
  EXPECT_EQ(pan_zoom_records.size(), 4u);
  EXPECT_EQ(mouse_records.size(), 0u);
  EXPECT_EQ(pan_zoom_records[3].x, 4.0);
  EXPECT_EQ(pan_zoom_records[3].y, 8.0);
  EXPECT_EQ(pan_zoom_records[3].timestamp,
            1000lu);  // Milliseconds -> Microseconds
  EXPECT_EQ(pan_zoom_records[3].phase, kPanZoomEnd);
}

TEST(FlScrollingManagerTest, Zooming) {
  ScrollingTester tester;
  std::vector<MousePointerEventRecord> mouse_records;
  std::vector<PointerPanZoomEventRecord> pan_zoom_records;
  tester.recordMousePointerCallsTo(mouse_records);
  tester.recordPointerPanZoomCallsTo(pan_zoom_records);
  size_t time_start = g_get_real_time();
  fl_scrolling_manager_handle_zoom_begin(tester.manager());
  EXPECT_EQ(pan_zoom_records.size(), 1u);
  EXPECT_EQ(mouse_records.size(), 0u);
  EXPECT_EQ(pan_zoom_records[0].x, 0);
  EXPECT_EQ(pan_zoom_records[0].y, 0);
  EXPECT_EQ(pan_zoom_records[0].phase, kPanZoomStart);
  EXPECT_GE(pan_zoom_records[0].timestamp, time_start);
  fl_scrolling_manager_handle_zoom_update(tester.manager(), 1.1);
  EXPECT_EQ(pan_zoom_records.size(), 2u);
  EXPECT_EQ(mouse_records.size(), 0u);
  EXPECT_EQ(pan_zoom_records[1].x, 0);
  EXPECT_EQ(pan_zoom_records[1].y, 0);
  EXPECT_EQ(pan_zoom_records[1].phase, kPanZoomUpdate);
  EXPECT_GE(pan_zoom_records[1].timestamp, pan_zoom_records[0].timestamp);
  EXPECT_EQ(pan_zoom_records[1].pan_x, 0);
  EXPECT_EQ(pan_zoom_records[1].pan_y, 0);
  EXPECT_EQ(pan_zoom_records[1].scale, 1.1);
  EXPECT_EQ(pan_zoom_records[1].rotation, 0);
  fl_scrolling_manager_handle_zoom_end(tester.manager());
  EXPECT_EQ(pan_zoom_records.size(), 3u);
  EXPECT_EQ(mouse_records.size(), 0u);
  EXPECT_EQ(pan_zoom_records[2].x, 0);
  EXPECT_EQ(pan_zoom_records[2].y, 0);
  EXPECT_EQ(pan_zoom_records[2].phase, kPanZoomEnd);
  EXPECT_GE(pan_zoom_records[2].timestamp, pan_zoom_records[1].timestamp);
}

TEST(FlScrollingManagerTest, Rotating) {
  ScrollingTester tester;
  std::vector<MousePointerEventRecord> mouse_records;
  std::vector<PointerPanZoomEventRecord> pan_zoom_records;
  tester.recordMousePointerCallsTo(mouse_records);
  tester.recordPointerPanZoomCallsTo(pan_zoom_records);
  size_t time_start = g_get_real_time();
  fl_scrolling_manager_handle_rotation_begin(tester.manager());
  EXPECT_EQ(pan_zoom_records.size(), 1u);
  EXPECT_EQ(mouse_records.size(), 0u);
  EXPECT_EQ(pan_zoom_records[0].x, 0);
  EXPECT_EQ(pan_zoom_records[0].y, 0);
  EXPECT_EQ(pan_zoom_records[0].phase, kPanZoomStart);
  EXPECT_GE(pan_zoom_records[0].timestamp, time_start);
  fl_scrolling_manager_handle_rotation_update(tester.manager(), 0.5);
  EXPECT_EQ(pan_zoom_records.size(), 2u);
  EXPECT_EQ(mouse_records.size(), 0u);
  EXPECT_EQ(pan_zoom_records[1].x, 0);
  EXPECT_EQ(pan_zoom_records[1].y, 0);
  EXPECT_EQ(pan_zoom_records[1].phase, kPanZoomUpdate);
  EXPECT_GE(pan_zoom_records[1].timestamp, pan_zoom_records[0].timestamp);
  EXPECT_EQ(pan_zoom_records[1].pan_x, 0);
  EXPECT_EQ(pan_zoom_records[1].pan_y, 0);
  EXPECT_EQ(pan_zoom_records[1].scale, 1.0);
  EXPECT_EQ(pan_zoom_records[1].rotation, 0.5);
  fl_scrolling_manager_handle_rotation_end(tester.manager());
  EXPECT_EQ(pan_zoom_records.size(), 3u);
  EXPECT_EQ(mouse_records.size(), 0u);
  EXPECT_EQ(pan_zoom_records[2].x, 0);
  EXPECT_EQ(pan_zoom_records[2].y, 0);
  EXPECT_EQ(pan_zoom_records[2].phase, kPanZoomEnd);
  EXPECT_GE(pan_zoom_records[2].timestamp, pan_zoom_records[1].timestamp);
}

TEST(FlScrollingManagerTest, SynchronizedZoomingAndRotating) {
  ScrollingTester tester;
  std::vector<MousePointerEventRecord> mouse_records;
  std::vector<PointerPanZoomEventRecord> pan_zoom_records;
  tester.recordMousePointerCallsTo(mouse_records);
  tester.recordPointerPanZoomCallsTo(pan_zoom_records);
  size_t time_start = g_get_real_time();
  fl_scrolling_manager_handle_zoom_begin(tester.manager());
  EXPECT_EQ(pan_zoom_records.size(), 1u);
  EXPECT_EQ(mouse_records.size(), 0u);
  EXPECT_EQ(pan_zoom_records[0].x, 0);
  EXPECT_EQ(pan_zoom_records[0].y, 0);
  EXPECT_EQ(pan_zoom_records[0].phase, kPanZoomStart);
  EXPECT_GE(pan_zoom_records[0].timestamp, time_start);
  fl_scrolling_manager_handle_zoom_update(tester.manager(), 1.1);
  EXPECT_EQ(pan_zoom_records.size(), 2u);
  EXPECT_EQ(mouse_records.size(), 0u);
  EXPECT_EQ(pan_zoom_records[1].x, 0);
  EXPECT_EQ(pan_zoom_records[1].y, 0);
  EXPECT_EQ(pan_zoom_records[1].phase, kPanZoomUpdate);
  EXPECT_GE(pan_zoom_records[1].timestamp, pan_zoom_records[0].timestamp);
  EXPECT_EQ(pan_zoom_records[1].pan_x, 0);
  EXPECT_EQ(pan_zoom_records[1].pan_y, 0);
  EXPECT_EQ(pan_zoom_records[1].scale, 1.1);
  EXPECT_EQ(pan_zoom_records[1].rotation, 0);
  fl_scrolling_manager_handle_rotation_begin(tester.manager());
  EXPECT_EQ(pan_zoom_records.size(), 2u);
  EXPECT_EQ(mouse_records.size(), 0u);
  fl_scrolling_manager_handle_rotation_update(tester.manager(), 0.5);
  EXPECT_EQ(pan_zoom_records.size(), 3u);
  EXPECT_EQ(pan_zoom_records[2].x, 0);
  EXPECT_EQ(pan_zoom_records[2].y, 0);
  EXPECT_EQ(pan_zoom_records[2].phase, kPanZoomUpdate);
  EXPECT_GE(pan_zoom_records[2].timestamp, pan_zoom_records[1].timestamp);
  EXPECT_EQ(pan_zoom_records[2].pan_x, 0);
  EXPECT_EQ(pan_zoom_records[2].pan_y, 0);
  EXPECT_EQ(pan_zoom_records[2].scale, 1.1);
  EXPECT_EQ(pan_zoom_records[2].rotation, 0.5);
  fl_scrolling_manager_handle_zoom_end(tester.manager());
  // End event should only be sent after both zoom and rotate complete.
  EXPECT_EQ(pan_zoom_records.size(), 3u);
  fl_scrolling_manager_handle_rotation_end(tester.manager());
  EXPECT_EQ(pan_zoom_records.size(), 4u);
  EXPECT_EQ(mouse_records.size(), 0u);
  EXPECT_EQ(pan_zoom_records[3].x, 0);
  EXPECT_EQ(pan_zoom_records[3].y, 0);
  EXPECT_EQ(pan_zoom_records[3].phase, kPanZoomEnd);
  EXPECT_GE(pan_zoom_records[3].timestamp, pan_zoom_records[2].timestamp);
}

// Make sure that zoom and rotate sequences which don't end at the same time
// don't cause any problems.
TEST(FlScrollingManagerTest, UnsynchronizedZoomingAndRotating) {
  ScrollingTester tester;
  std::vector<MousePointerEventRecord> mouse_records;
  std::vector<PointerPanZoomEventRecord> pan_zoom_records;
  tester.recordMousePointerCallsTo(mouse_records);
  tester.recordPointerPanZoomCallsTo(pan_zoom_records);
  size_t time_start = g_get_real_time();
  fl_scrolling_manager_handle_zoom_begin(tester.manager());
  EXPECT_EQ(pan_zoom_records.size(), 1u);
  EXPECT_EQ(mouse_records.size(), 0u);
  EXPECT_EQ(pan_zoom_records[0].x, 0);
  EXPECT_EQ(pan_zoom_records[0].y, 0);
  EXPECT_EQ(pan_zoom_records[0].phase, kPanZoomStart);
  EXPECT_GE(pan_zoom_records[0].timestamp, time_start);
  fl_scrolling_manager_handle_zoom_update(tester.manager(), 1.1);
  EXPECT_EQ(pan_zoom_records.size(), 2u);
  EXPECT_EQ(mouse_records.size(), 0u);
  EXPECT_EQ(pan_zoom_records[1].x, 0);
  EXPECT_EQ(pan_zoom_records[1].y, 0);
  EXPECT_EQ(pan_zoom_records[1].phase, kPanZoomUpdate);
  EXPECT_GE(pan_zoom_records[1].timestamp, pan_zoom_records[0].timestamp);
  EXPECT_EQ(pan_zoom_records[1].pan_x, 0);
  EXPECT_EQ(pan_zoom_records[1].pan_y, 0);
  EXPECT_EQ(pan_zoom_records[1].scale, 1.1);
  EXPECT_EQ(pan_zoom_records[1].rotation, 0);
  fl_scrolling_manager_handle_rotation_begin(tester.manager());
  EXPECT_EQ(pan_zoom_records.size(), 2u);
  EXPECT_EQ(mouse_records.size(), 0u);
  fl_scrolling_manager_handle_rotation_update(tester.manager(), 0.5);
  EXPECT_EQ(pan_zoom_records.size(), 3u);
  EXPECT_EQ(pan_zoom_records[2].x, 0);
  EXPECT_EQ(pan_zoom_records[2].y, 0);
  EXPECT_EQ(pan_zoom_records[2].phase, kPanZoomUpdate);
  EXPECT_GE(pan_zoom_records[2].timestamp, pan_zoom_records[1].timestamp);
  EXPECT_EQ(pan_zoom_records[2].pan_x, 0);
  EXPECT_EQ(pan_zoom_records[2].pan_y, 0);
  EXPECT_EQ(pan_zoom_records[2].scale, 1.1);
  EXPECT_EQ(pan_zoom_records[2].rotation, 0.5);
  fl_scrolling_manager_handle_zoom_end(tester.manager());
  EXPECT_EQ(pan_zoom_records.size(), 3u);
  fl_scrolling_manager_handle_rotation_update(tester.manager(), 1.0);
  EXPECT_EQ(pan_zoom_records.size(), 4u);
  EXPECT_EQ(mouse_records.size(), 0u);
  EXPECT_EQ(pan_zoom_records[3].x, 0);
  EXPECT_EQ(pan_zoom_records[3].y, 0);
  EXPECT_EQ(pan_zoom_records[3].phase, kPanZoomUpdate);
  EXPECT_GE(pan_zoom_records[3].timestamp, pan_zoom_records[2].timestamp);
  EXPECT_EQ(pan_zoom_records[3].pan_x, 0);
  EXPECT_EQ(pan_zoom_records[3].pan_y, 0);
  EXPECT_EQ(pan_zoom_records[3].scale, 1.1);
  EXPECT_EQ(pan_zoom_records[3].rotation, 1.0);
  fl_scrolling_manager_handle_rotation_end(tester.manager());
  EXPECT_EQ(pan_zoom_records.size(), 5u);
  EXPECT_EQ(mouse_records.size(), 0u);
  EXPECT_EQ(pan_zoom_records[4].x, 0);
  EXPECT_EQ(pan_zoom_records[4].y, 0);
  EXPECT_EQ(pan_zoom_records[4].phase, kPanZoomEnd);
  EXPECT_GE(pan_zoom_records[4].timestamp, pan_zoom_records[3].timestamp);
}

}  // namespace
