// 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/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  group('Horizontal', () {
    testWidgets('gets local coordinates', (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 ?? 0)),
        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 rotated 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 coordinates', (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 ?? 0)),
        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 rotated 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)
    });
  });
}
