// Copyright 2014 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 'dart:math' as math;

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/gestures.dart';

void main() {
  group('Horizontal', () {
    testWidgets('gets local corrdinates', (WidgetTester tester) async {
      int dragCancelCount = 0;
      final List<DragDownDetails> downDetails = <DragDownDetails>[];
      final List<DragEndDetails> endDetails = <DragEndDetails>[];
      final List<DragStartDetails> startDetails = <DragStartDetails>[];
      final List<DragUpdateDetails> updateDetails = <DragUpdateDetails>[];

      final Key redContainer = UniqueKey();
      await tester.pumpWidget(
        Center(
          child: GestureDetector(
            onHorizontalDragCancel: () {
              dragCancelCount++;
            },
            onHorizontalDragDown: (DragDownDetails details) {
              downDetails.add(details);
            },
            onHorizontalDragEnd: (DragEndDetails details) {
              endDetails.add(details);
            },
            onHorizontalDragStart: (DragStartDetails details) {
              startDetails.add(details);
            },
            onHorizontalDragUpdate: (DragUpdateDetails details) {
              updateDetails.add(details);
            },
            child: Container(
              key: redContainer,
              width: 100,
              height: 150,
              color: Colors.red,
            ),
          ),
        ),
      );

      await tester.drag(find.byKey(redContainer), const Offset(100, 0));
      expect(dragCancelCount, 0);
      expect(downDetails.single.localPosition, const Offset(50, 75));
      expect(downDetails.single.globalPosition, const Offset(400, 300));
      expect(endDetails, hasLength(1));
      expect(startDetails.single.localPosition, const Offset(50, 75));
      expect(startDetails.single.globalPosition, const Offset(400, 300));
      expect(updateDetails.last.localPosition, const Offset(50 + 100.0, 75));
      expect(updateDetails.last.globalPosition, const Offset(400 + 100.0, 300));
      expect(
        updateDetails.fold(Offset.zero, (Offset offset, DragUpdateDetails details) => offset + details.delta),
        const Offset(100, 0),
      );
      expect(
        updateDetails.fold(0.0, (double offset, DragUpdateDetails details) => offset + details.primaryDelta),
        100.0,
      );
    });

    testWidgets('kTouchSlop is evaluated in the global coordinate space when scaled up', (WidgetTester tester) async {
      int dragCancelCount = 0;
      final List<DragDownDetails> downDetails = <DragDownDetails>[];
      final List<DragEndDetails> endDetails = <DragEndDetails>[];
      final List<DragStartDetails> startDetails = <DragStartDetails>[];
      final List<DragUpdateDetails> updateDetails = <DragUpdateDetails>[];

      final Key redContainer = UniqueKey();
      await tester.pumpWidget(
        Center(
          child: Transform.scale(
            scale: 2.0,
            child: GestureDetector(
              onHorizontalDragCancel: () {
                dragCancelCount++;
              },
              onHorizontalDragDown: (DragDownDetails details) {
                downDetails.add(details);
              },
              onHorizontalDragEnd: (DragEndDetails details) {
                endDetails.add(details);
              },
              onHorizontalDragStart: (DragStartDetails details) {
                startDetails.add(details);
              },
              onHorizontalDragUpdate: (DragUpdateDetails details) {
                updateDetails.add(details);
              },
              onTap: () {
                // Competing gesture detector.
              },
              child: Container(
                key: redContainer,
                width: 100,
                height: 150,
                color: Colors.red,
              ),
            ),
          ),
        ),
      );

      // Move just above kTouchSlop should recognize drag.
      await tester.drag(find.byKey(redContainer), const Offset(kTouchSlop + 1, 0));

      expect(dragCancelCount, 0);
      expect(downDetails.single.localPosition, const Offset(50, 75));
      expect(downDetails.single.globalPosition, const Offset(400, 300));
      expect(endDetails, hasLength(1));
      expect(startDetails.single.localPosition, const Offset(50 + (kTouchSlop + 1) / 2, 75));
      expect(startDetails.single.globalPosition, const Offset(400 + (kTouchSlop + 1), 300));
      expect(updateDetails, isEmpty);

      dragCancelCount = 0;
      downDetails.clear();
      endDetails.clear();
      startDetails.clear();
      updateDetails.clear();

      // Move just below kTouchSlop does not recognize drag.
      await tester.drag(find.byKey(redContainer), const Offset(kTouchSlop - 1, 0));
      expect(dragCancelCount, 1);
      expect(downDetails.single.localPosition, const Offset(50, 75));
      expect(downDetails.single.globalPosition, const Offset(400, 300));
      expect(endDetails, isEmpty);
      expect(startDetails, isEmpty);
      expect(updateDetails, isEmpty);

      dragCancelCount = 0;
      downDetails.clear();
      endDetails.clear();
      startDetails.clear();
      updateDetails.clear();

      // Move in two separate movements
      final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byKey(redContainer)));
      await gesture.moveBy(const Offset(kTouchSlop + 1, 30));
      await gesture.moveBy(const Offset(100, 10));
      await gesture.up();

      expect(dragCancelCount, 0);
      expect(downDetails.single.localPosition, const Offset(50, 75));
      expect(downDetails.single.globalPosition, const Offset(400, 300));
      expect(endDetails, hasLength(1));
      expect(startDetails.single.localPosition, const Offset(50 + (kTouchSlop + 1) / 2, 75.0 + 30.0 / 2));
      expect(startDetails.single.globalPosition, const Offset(400 + (kTouchSlop + 1), 300 + 30.0));
      expect(updateDetails.single.localPosition, startDetails.single.localPosition + const Offset(100.0 / 2, 10 / 2));
      expect(updateDetails.single.globalPosition, startDetails.single.globalPosition + const Offset(100.0, 10.0));
      expect(updateDetails.single.delta, const Offset(100.0 / 2, 0.0));
      expect(updateDetails.single.primaryDelta, 100.0 / 2);

      dragCancelCount = 0;
      downDetails.clear();
      endDetails.clear();
      startDetails.clear();
      updateDetails.clear();
    });

    testWidgets('kTouchSlop is evaluated in the global coordinate space when scaled down', (WidgetTester tester) async {
      int dragCancelCount = 0;
      final List<DragDownDetails> downDetails = <DragDownDetails>[];
      final List<DragEndDetails> endDetails = <DragEndDetails>[];
      final List<DragStartDetails> startDetails = <DragStartDetails>[];
      final List<DragUpdateDetails> updateDetails = <DragUpdateDetails>[];

      final Key redContainer = UniqueKey();
      await tester.pumpWidget(
        Center(
          child: Transform.scale(
            scale: 0.5,
            child: GestureDetector(
              onHorizontalDragCancel: () {
                dragCancelCount++;
              },
              onHorizontalDragDown: (DragDownDetails details) {
                downDetails.add(details);
              },
              onHorizontalDragEnd: (DragEndDetails details) {
                endDetails.add(details);
              },
              onHorizontalDragStart: (DragStartDetails details) {
                startDetails.add(details);
              },
              onHorizontalDragUpdate: (DragUpdateDetails details) {
                updateDetails.add(details);
              },
              onTap: () {
                // Competing gesture detector.
              },
              child: Container(
                key: redContainer,
                width: 100,
                height: 150,
                color: Colors.red,
              ),
            ),
          ),
        ),
      );

      // Move just above kTouchSlop should recognize drag.
      await tester.drag(find.byKey(redContainer), const Offset(kTouchSlop + 1, 0));

      expect(dragCancelCount, 0);
      expect(downDetails.single.localPosition, const Offset(50, 75));
      expect(downDetails.single.globalPosition, const Offset(400, 300));
      expect(endDetails, hasLength(1));
      expect(startDetails.single.localPosition, const Offset(50 + (kTouchSlop + 1) * 2, 75));
      expect(startDetails.single.globalPosition, const Offset(400 + (kTouchSlop + 1), 300));
      expect(updateDetails, isEmpty);

      dragCancelCount = 0;
      downDetails.clear();
      endDetails.clear();
      startDetails.clear();
      updateDetails.clear();

      // Move just below kTouchSlop does not recognize drag.
      await tester.drag(find.byKey(redContainer), const Offset(kTouchSlop - 1, 0));
      expect(dragCancelCount, 1);
      expect(downDetails.single.localPosition, const Offset(50, 75));
      expect(downDetails.single.globalPosition, const Offset(400, 300));
      expect(endDetails, isEmpty);
      expect(startDetails, isEmpty);
      expect(updateDetails, isEmpty);

      dragCancelCount = 0;
      downDetails.clear();
      endDetails.clear();
      startDetails.clear();
      updateDetails.clear();

      // Move in two separate movements
      final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byKey(redContainer)));
      await gesture.moveBy(const Offset(kTouchSlop + 1, 30));
      await gesture.moveBy(const Offset(100, 10));
      await gesture.up();

      expect(dragCancelCount, 0);
      expect(downDetails.single.localPosition, const Offset(50, 75));
      expect(downDetails.single.globalPosition, const Offset(400, 300));
      expect(endDetails, hasLength(1));
      expect(startDetails.single.localPosition, const Offset(50 + (kTouchSlop + 1) * 2, 75.0 + 30.0 * 2));
      expect(startDetails.single.globalPosition, const Offset(400 + (kTouchSlop + 1), 300 + 30.0));
      expect(updateDetails.single.localPosition, startDetails.single.localPosition + const Offset(100.0 * 2, 10.0 * 2.0));
      expect(updateDetails.single.globalPosition, startDetails.single.globalPosition + const Offset(100.0, 10.0));
      expect(updateDetails.single.delta, const Offset(100.0 * 2.0, 0.0));
      expect(updateDetails.single.primaryDelta, 100.0 * 2);

      dragCancelCount = 0;
      downDetails.clear();
      endDetails.clear();
      startDetails.clear();
      updateDetails.clear();
    });

    testWidgets('kTouchSlop is evaluated in the global coordinate space when roateted 45 degrees', (WidgetTester tester) async {
      int dragCancelCount = 0;
      final List<DragDownDetails> downDetails = <DragDownDetails>[];
      final List<DragEndDetails> endDetails = <DragEndDetails>[];
      final List<DragStartDetails> startDetails = <DragStartDetails>[];
      final List<DragUpdateDetails> updateDetails = <DragUpdateDetails>[];

      final Key redContainer = UniqueKey();
      await tester.pumpWidget(
        Center(
          child: Transform.rotate(
            angle: math.pi / 4,
            child: GestureDetector(
              onHorizontalDragCancel: () {
                dragCancelCount++;
              },
              onHorizontalDragDown: (DragDownDetails details) {
                downDetails.add(details);
              },
              onHorizontalDragEnd: (DragEndDetails details) {
                endDetails.add(details);
              },
              onHorizontalDragStart: (DragStartDetails details) {
                startDetails.add(details);
              },
              onHorizontalDragUpdate: (DragUpdateDetails details) {
                updateDetails.add(details);
              },
              onTap: () {
                // Competing gesture detector.
              },
              child: Container(
                key: redContainer,
                width: 100,
                height: 150,
                color: Colors.red,
              ),
            ),
          ),
        ),
      );

      // Move just below kTouchSlop should not recognize drag.
      const Offset moveBy1 = Offset(kTouchSlop/ 2, kTouchSlop / 2);
      expect(moveBy1.distance, lessThan(kTouchSlop));
      await tester.drag(find.byKey(redContainer), moveBy1);
      expect(dragCancelCount, 1);
      expect(downDetails.single.localPosition, within(distance: 0.0001, from: const Offset(50, 75)));
      expect(downDetails.single.globalPosition, within(distance: 0.0001, from: const Offset(400, 300)));
      expect(endDetails, isEmpty);
      expect(startDetails, isEmpty);
      expect(updateDetails, isEmpty);

      dragCancelCount = 0;
      downDetails.clear();
      endDetails.clear();
      startDetails.clear();
      updateDetails.clear();

      // Move above kTouchSlop recognizes drag.
      final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byKey(redContainer)));
      await gesture.moveBy(const Offset(kTouchSlop, kTouchSlop));
      await gesture.moveBy(const Offset(3, 4));
      await gesture.up();

      expect(dragCancelCount, 0);
      expect(downDetails.single.localPosition,  within(distance: 0.0001, from: const Offset(50, 75)));
      expect(downDetails.single.globalPosition,  within(distance: 0.0001, from: const Offset(400, 300)));
      expect(endDetails, hasLength(1));
      expect(startDetails, hasLength(1));
      expect(updateDetails.single.globalPosition, within(distance: 0.0001, from: const Offset(400 + kTouchSlop + 3, 300 + kTouchSlop + 4)));
      expect(updateDetails.single.delta, within(distance: 0.1, from: const Offset(5, 0.0))); // sqrt(3^2 + 4^2)
      expect(updateDetails.single.primaryDelta, within<double>(distance: 0.1, from: 5.0)); // sqrt(3^2 + 4^2)
    });
  });

  group('Vertical', () {
    testWidgets('gets local corrdinates', (WidgetTester tester) async {
      int dragCancelCount = 0;
      final List<DragDownDetails> downDetails = <DragDownDetails>[];
      final List<DragEndDetails> endDetails = <DragEndDetails>[];
      final List<DragStartDetails> startDetails = <DragStartDetails>[];
      final List<DragUpdateDetails> updateDetails = <DragUpdateDetails>[];

      final Key redContainer = UniqueKey();
      await tester.pumpWidget(
        Center(
          child: GestureDetector(
            onVerticalDragCancel: () {
              dragCancelCount++;
            },
            onVerticalDragDown: (DragDownDetails details) {
              downDetails.add(details);
            },
            onVerticalDragEnd: (DragEndDetails details) {
              endDetails.add(details);
            },
            onVerticalDragStart: (DragStartDetails details) {
              startDetails.add(details);
            },
            onVerticalDragUpdate: (DragUpdateDetails details) {
              updateDetails.add(details);
            },
            child: Container(
              key: redContainer,
              width: 100,
              height: 150,
              color: Colors.red,
            ),
          ),
        ),
      );

      await tester.drag(find.byKey(redContainer), const Offset(0, 100));
      expect(dragCancelCount, 0);
      expect(downDetails.single.localPosition, const Offset(50, 75));
      expect(downDetails.single.globalPosition, const Offset(400, 300));
      expect(endDetails, hasLength(1));
      expect(startDetails.single.localPosition, const Offset(50, 75));
      expect(startDetails.single.globalPosition, const Offset(400, 300));
      expect(updateDetails.last.localPosition, const Offset(50, 75 + 100.0));
      expect(updateDetails.last.globalPosition, const Offset(400, 300 + 100.0));
      expect(
        updateDetails.fold(Offset.zero, (Offset offset, DragUpdateDetails details) => offset + details.delta),
        const Offset(0, 100),
      );
      expect(
        updateDetails.fold(0.0, (double offset, DragUpdateDetails details) => offset + details.primaryDelta),
        100.0,
      );
    });

    testWidgets('kTouchSlop is evaluated in the global coordinate space when scaled up', (WidgetTester tester) async {
      int dragCancelCount = 0;
      final List<DragDownDetails> downDetails = <DragDownDetails>[];
      final List<DragEndDetails> endDetails = <DragEndDetails>[];
      final List<DragStartDetails> startDetails = <DragStartDetails>[];
      final List<DragUpdateDetails> updateDetails = <DragUpdateDetails>[];

      final Key redContainer = UniqueKey();
      await tester.pumpWidget(
        Center(
          child: Transform.scale(
            scale: 2.0,
            child: GestureDetector(
              onVerticalDragCancel: () {
                dragCancelCount++;
              },
              onVerticalDragDown: (DragDownDetails details) {
                downDetails.add(details);
              },
              onVerticalDragEnd: (DragEndDetails details) {
                endDetails.add(details);
              },
              onVerticalDragStart: (DragStartDetails details) {
                startDetails.add(details);
              },
              onVerticalDragUpdate: (DragUpdateDetails details) {
                updateDetails.add(details);
              },
              onTap: () {
                // Competing gesture detector.
              },
              child: Container(
                key: redContainer,
                width: 100,
                height: 150,
                color: Colors.red,
              ),
            ),
          ),
        ),
      );

      // Move just above kTouchSlop should recognize drag.
      await tester.drag(find.byKey(redContainer), const Offset(0, kTouchSlop + 1));

      expect(dragCancelCount, 0);
      expect(downDetails.single.localPosition, const Offset(50, 75));
      expect(downDetails.single.globalPosition, const Offset(400, 300));
      expect(endDetails, hasLength(1));
      expect(startDetails.single.localPosition, const Offset(50, 75 + (kTouchSlop + 1) / 2));
      expect(startDetails.single.globalPosition, const Offset(400, 300 + (kTouchSlop + 1)));
      expect(updateDetails, isEmpty);

      dragCancelCount = 0;
      downDetails.clear();
      endDetails.clear();
      startDetails.clear();
      updateDetails.clear();

      // Move just below kTouchSlop does not recognize drag.
      await tester.drag(find.byKey(redContainer), const Offset(0, kTouchSlop - 1));
      expect(dragCancelCount, 1);
      expect(downDetails.single.localPosition, const Offset(50, 75));
      expect(downDetails.single.globalPosition, const Offset(400, 300));
      expect(endDetails, isEmpty);
      expect(startDetails, isEmpty);
      expect(updateDetails, isEmpty);

      dragCancelCount = 0;
      downDetails.clear();
      endDetails.clear();
      startDetails.clear();
      updateDetails.clear();

      // Move in two separate movements
      final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byKey(redContainer)));
      await gesture.moveBy(const Offset(30, kTouchSlop + 1));
      await gesture.moveBy(const Offset(10, 100));
      await gesture.up();

      expect(dragCancelCount, 0);
      expect(downDetails.single.localPosition, const Offset(50, 75));
      expect(downDetails.single.globalPosition, const Offset(400, 300));
      expect(endDetails, hasLength(1));
      expect(startDetails.single.localPosition, const Offset(50 + 30.0 / 2, 75.0 + (kTouchSlop + 1) / 2));
      expect(startDetails.single.globalPosition, const Offset(400 + 30.0, 300 + (kTouchSlop + 1)));
      expect(updateDetails.single.localPosition, startDetails.single.localPosition + const Offset(10.0 / 2, 100.0 / 2));
      expect(updateDetails.single.globalPosition, startDetails.single.globalPosition + const Offset(10.0, 100.0));
      expect(updateDetails.single.delta, const Offset(0.0, 100.0 / 2));
      expect(updateDetails.single.primaryDelta, 100.0 / 2);

      dragCancelCount = 0;
      downDetails.clear();
      endDetails.clear();
      startDetails.clear();
      updateDetails.clear();
    });

    testWidgets('kTouchSlop is evaluated in the global coordinate space when scaled down', (WidgetTester tester) async {
      int dragCancelCount = 0;
      final List<DragDownDetails> downDetails = <DragDownDetails>[];
      final List<DragEndDetails> endDetails = <DragEndDetails>[];
      final List<DragStartDetails> startDetails = <DragStartDetails>[];
      final List<DragUpdateDetails> updateDetails = <DragUpdateDetails>[];

      final Key redContainer = UniqueKey();
      await tester.pumpWidget(
        Center(
          child: Transform.scale(
            scale: 0.5,
            child: GestureDetector(
              onVerticalDragCancel: () {
                dragCancelCount++;
              },
              onVerticalDragDown: (DragDownDetails details) {
                downDetails.add(details);
              },
              onVerticalDragEnd: (DragEndDetails details) {
                endDetails.add(details);
              },
              onVerticalDragStart: (DragStartDetails details) {
                startDetails.add(details);
              },
              onVerticalDragUpdate: (DragUpdateDetails details) {
                updateDetails.add(details);
              },
              onTap: () {
                // Competing gesture detector.
              },
              child: Container(
                key: redContainer,
                width: 100,
                height: 150,
                color: Colors.red,
              ),
            ),
          ),
        ),
      );

      // Move just above kTouchSlop should recognize drag.
      await tester.drag(find.byKey(redContainer), const Offset(0, kTouchSlop + 1));

      expect(dragCancelCount, 0);
      expect(downDetails.single.localPosition, const Offset(50, 75));
      expect(downDetails.single.globalPosition, const Offset(400, 300));
      expect(endDetails, hasLength(1));
      expect(startDetails.single.localPosition, const Offset(50, 75 + (kTouchSlop + 1) * 2));
      expect(startDetails.single.globalPosition, const Offset(400, 300 + (kTouchSlop + 1)));
      expect(updateDetails, isEmpty);

      dragCancelCount = 0;
      downDetails.clear();
      endDetails.clear();
      startDetails.clear();
      updateDetails.clear();

      // Move just below kTouchSlop does not recognize drag.
      await tester.drag(find.byKey(redContainer), const Offset(0, kTouchSlop - 1));
      expect(dragCancelCount, 1);
      expect(downDetails.single.localPosition, const Offset(50, 75));
      expect(downDetails.single.globalPosition, const Offset(400, 300));
      expect(endDetails, isEmpty);
      expect(startDetails, isEmpty);
      expect(updateDetails, isEmpty);

      dragCancelCount = 0;
      downDetails.clear();
      endDetails.clear();
      startDetails.clear();
      updateDetails.clear();

      // Move in two separate movements
      final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byKey(redContainer)));
      await gesture.moveBy(const Offset(30, kTouchSlop + 1));
      await gesture.moveBy(const Offset(10, 100));
      await gesture.up();

      expect(dragCancelCount, 0);
      expect(downDetails.single.localPosition, const Offset(50, 75));
      expect(downDetails.single.globalPosition, const Offset(400, 300));
      expect(endDetails, hasLength(1));
      expect(startDetails.single.localPosition, const Offset(50 + 30.0 * 2, 75.0 + (kTouchSlop + 1) * 2));
      expect(startDetails.single.globalPosition, const Offset(400 + 30.0, 300 + (kTouchSlop + 1)));
      expect(updateDetails.single.localPosition, startDetails.single.localPosition + const Offset(10.0 * 2, 100.0 * 2.0));
      expect(updateDetails.single.globalPosition, startDetails.single.globalPosition + const Offset(10.0, 100.0));
      expect(updateDetails.single.delta, const Offset(0.0, 100.0 * 2.0));
      expect(updateDetails.single.primaryDelta, 100.0 * 2);

      dragCancelCount = 0;
      downDetails.clear();
      endDetails.clear();
      startDetails.clear();
      updateDetails.clear();
    });

    testWidgets('kTouchSlop is evaluated in the global coordinate space when roateted 45 degrees', (WidgetTester tester) async {
      int dragCancelCount = 0;
      final List<DragDownDetails> downDetails = <DragDownDetails>[];
      final List<DragEndDetails> endDetails = <DragEndDetails>[];
      final List<DragStartDetails> startDetails = <DragStartDetails>[];
      final List<DragUpdateDetails> updateDetails = <DragUpdateDetails>[];

      final Key redContainer = UniqueKey();
      await tester.pumpWidget(
        Center(
          child: Transform.rotate(
            angle: math.pi / 4,
            child: GestureDetector(
              onVerticalDragCancel: () {
                dragCancelCount++;
              },
              onVerticalDragDown: (DragDownDetails details) {
                downDetails.add(details);
              },
              onVerticalDragEnd: (DragEndDetails details) {
                endDetails.add(details);
              },
              onVerticalDragStart: (DragStartDetails details) {
                startDetails.add(details);
              },
              onVerticalDragUpdate: (DragUpdateDetails details) {
                updateDetails.add(details);
              },
              onTap: () {
                // Competing gesture detector.
              },
              child: Container(
                key: redContainer,
                width: 100,
                height: 150,
                color: Colors.red,
              ),
            ),
          ),
        ),
      );

      // Move just below kTouchSlop should not recognize drag.
      const Offset moveBy1 = Offset(kTouchSlop/ 2, kTouchSlop / 2);
      expect(moveBy1.distance, lessThan(kTouchSlop));
      await tester.drag(find.byKey(redContainer), moveBy1);
      expect(dragCancelCount, 1);
      expect(downDetails.single.localPosition, within(distance: 0.0001, from: const Offset(50, 75)));
      expect(downDetails.single.globalPosition, within(distance: 0.0001, from: const Offset(400, 300)));
      expect(endDetails, isEmpty);
      expect(startDetails, isEmpty);
      expect(updateDetails, isEmpty);

      dragCancelCount = 0;
      downDetails.clear();
      endDetails.clear();
      startDetails.clear();
      updateDetails.clear();

      // Move above kTouchSlop recognizes drag.
      final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byKey(redContainer)));
      await gesture.moveBy(const Offset(kTouchSlop, kTouchSlop));
      await gesture.moveBy(const Offset(-4, 3));
      await gesture.up();

      expect(dragCancelCount, 0);
      expect(downDetails.single.localPosition,  within(distance: 0.0001, from: const Offset(50, 75)));
      expect(downDetails.single.globalPosition,  within(distance: 0.0001, from: const Offset(400, 300)));
      expect(endDetails, hasLength(1));
      expect(startDetails, hasLength(1));
      expect(updateDetails.single.globalPosition, within(distance: 0.0001, from: const Offset(400 + kTouchSlop - 4, 300 + kTouchSlop + 3)));
      expect(updateDetails.single.delta, within(distance: 0.1, from: const Offset(0.0, 5.0))); // sqrt(3^2 + 4^2)
      expect(updateDetails.single.primaryDelta, within<double>(distance: 0.1, from: 5.0)); // sqrt(3^2 + 4^2)
    });
  });
}
