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

// TODO(gspencergoog): Remove this tag once this test's state leaks/test
// dependencies have been fixed.
// https://github.com/flutter/flutter/issues/85160
// Fails with "flutter test --test-randomize-ordering-seed=123"
@Tags(<String>['no-shuffle'])

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

import 'semantics_tester.dart';

void main() {
  testWidgets('Drag and drop - control test', (WidgetTester tester) async {
    final List<int> accepted = <int>[];
    final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
    int dragStartedCount = 0;
    int moveCount = 0;

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          Draggable<int>(
            data: 1,
            feedback: const Text('Dragging'),
            onDragStarted: () {
              ++dragStartedCount;
            },
            child: const Text('Source'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const SizedBox(height: 100.0, child: Text('Target'));
            },
            onMove: (_) => moveCount++,
            onAccept: accepted.add,
            onAcceptWithDetails: acceptedDetails.add,
          ),
        ],
      ),
    ));

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(dragStartedCount, 0);
    expect(moveCount, 0);

    final Offset firstLocation = tester.getCenter(find.text('Source'));
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);
    expect(dragStartedCount, 1);
    expect(moveCount, 0);

    final Offset secondLocation = tester.getCenter(find.text('Target'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);
    expect(dragStartedCount, 1);
    expect(moveCount, 1);

    await gesture.up();
    await tester.pump();

    expect(accepted, equals(<int>[1]));
    expect(acceptedDetails, hasLength(1));
    expect(acceptedDetails.first.offset, const Offset(256.0, 74.0));
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(dragStartedCount, 1);
    expect(moveCount, 1);
  });

  // Regression test for https://github.com/flutter/flutter/issues/76825
  testWidgets('Drag and drop - onLeave callback fires correctly with generic parameter', (WidgetTester tester) async {
    final Map<String,int> leftBehind = <String,int>{
      'Target 1': 0,
      'Target 2': 0,
    };

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          const Draggable<int>(
            data: 1,
            feedback: Text('Dragging'),
            child: Text('Source'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const SizedBox(height: 100.0, child: Text('Target 1'));
            },
            onLeave: (int? data) {
              if (data != null) {
                leftBehind['Target 1'] = leftBehind['Target 1']! + data;
              }
            },
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const SizedBox(height: 100.0, child: Text('Target 2'));
            },
            onLeave: (int? data) {
              if (data != null) {
                leftBehind['Target 2'] = leftBehind['Target 2']! + data;
              }
            },
          ),
        ],
      ),
    ));

    expect(leftBehind['Target 1'], equals(0));
    expect(leftBehind['Target 2'], equals(0));

    final Offset firstLocation = tester.getCenter(find.text('Source'));
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    expect(leftBehind['Target 1'], equals(0));
    expect(leftBehind['Target 2'], equals(0));

    final Offset secondLocation = tester.getCenter(find.text('Target 1'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(leftBehind['Target 1'], equals(0));
    expect(leftBehind['Target 2'], equals(0));

    final Offset thirdLocation = tester.getCenter(find.text('Target 2'));
    await gesture.moveTo(thirdLocation);
    await tester.pump();

    expect(leftBehind['Target 1'], equals(1));
    expect(leftBehind['Target 2'], equals(0));

    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(leftBehind['Target 1'], equals(1));
    expect(leftBehind['Target 2'], equals(1));

    await gesture.up();
    await tester.pump();

    expect(leftBehind['Target 1'], equals(1));
    expect(leftBehind['Target 2'], equals(1));
  });

  testWidgets('Drag and drop - onLeave callback fires correctly', (WidgetTester tester) async {
    final Map<String,int> leftBehind = <String,int>{
      'Target 1': 0,
      'Target 2': 0,
    };

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          const Draggable<int>(
            data: 1,
            feedback: Text('Dragging'),
            child: Text('Source'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const SizedBox(height: 100.0, child: Text('Target 1'));
            },
            onLeave: (Object? data) {
              if (data is int) {
                leftBehind['Target 1'] = leftBehind['Target 1']! + data;
              }
            },
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const SizedBox(height: 100.0, child: Text('Target 2'));
            },
            onLeave: (Object? data) {
              if (data is int) {
                leftBehind['Target 2'] = leftBehind['Target 2']! + data;
              }
            },
          ),
        ],
      ),
    ));

    expect(leftBehind['Target 1'], equals(0));
    expect(leftBehind['Target 2'], equals(0));

    final Offset firstLocation = tester.getCenter(find.text('Source'));
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    expect(leftBehind['Target 1'], equals(0));
    expect(leftBehind['Target 2'], equals(0));

    final Offset secondLocation = tester.getCenter(find.text('Target 1'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(leftBehind['Target 1'], equals(0));
    expect(leftBehind['Target 2'], equals(0));

    final Offset thirdLocation = tester.getCenter(find.text('Target 2'));
    await gesture.moveTo(thirdLocation);
    await tester.pump();

    expect(leftBehind['Target 1'], equals(1));
    expect(leftBehind['Target 2'], equals(0));

    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(leftBehind['Target 1'], equals(1));
    expect(leftBehind['Target 2'], equals(1));

    await gesture.up();
    await tester.pump();

    expect(leftBehind['Target 1'], equals(1));
    expect(leftBehind['Target 2'], equals(1));
  });

  // Regression test for https://github.com/flutter/flutter/issues/76825
  testWidgets('Drag and drop - onMove callback fires correctly with generic parameter', (WidgetTester tester) async {
    final Map<String,int> targetMoveCount = <String,int>{
      'Target 1': 0,
      'Target 2': 0,
    };

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          const Draggable<int>(
            data: 1,
            feedback: Text('Dragging'),
            child: Text('Source'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const SizedBox(height: 100.0, child: Text('Target 1'));
            },
            onMove: (DragTargetDetails<int> details) {
              targetMoveCount['Target 1'] =
                  targetMoveCount['Target 1']! + details.data;
            },
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const SizedBox(height: 100.0, child: Text('Target 2'));
            },
            onMove: (DragTargetDetails<int> details) {
              targetMoveCount['Target 2'] =
                  targetMoveCount['Target 2']! + details.data;
            },
          ),
        ],
      ),
    ));

    expect(targetMoveCount['Target 1'], equals(0));
    expect(targetMoveCount['Target 2'], equals(0));

    final Offset firstLocation = tester.getCenter(find.text('Source'));
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    expect(targetMoveCount['Target 1'], equals(0));
    expect(targetMoveCount['Target 2'], equals(0));

    final Offset secondLocation = tester.getCenter(find.text('Target 1'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(targetMoveCount['Target 1'], equals(1));
    expect(targetMoveCount['Target 2'], equals(0));

    final Offset thirdLocation = tester.getCenter(find.text('Target 2'));
    await gesture.moveTo(thirdLocation);
    await tester.pump();

    expect(targetMoveCount['Target 1'], equals(1));
    expect(targetMoveCount['Target 2'], equals(1));

    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(targetMoveCount['Target 1'], equals(2));
    expect(targetMoveCount['Target 2'], equals(1));

    await gesture.up();
    await tester.pump();

    expect(targetMoveCount['Target 1'], equals(2));
    expect(targetMoveCount['Target 2'], equals(1));
  });

  testWidgets('Drag and drop - onMove callback fires correctly', (WidgetTester tester) async {
    final Map<String,int> targetMoveCount = <String,int>{
      'Target 1': 0,
      'Target 2': 0,
    };

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          const Draggable<int>(
            data: 1,
            feedback: Text('Dragging'),
            child: Text('Source'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const SizedBox(height: 100.0, child: Text('Target 1'));
            },
            onMove: (DragTargetDetails<dynamic> details) {
              if (details.data is int) {
                targetMoveCount['Target 1'] =
                    targetMoveCount['Target 1']! + (details.data as int);
              }
            },
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const SizedBox(height: 100.0, child: Text('Target 2'));
            },
            onMove: (DragTargetDetails<dynamic> details) {
              if (details.data is int) {
                targetMoveCount['Target 2'] =
                    targetMoveCount['Target 2']! + (details.data as int);
              }
            },
          ),
        ],
      ),
    ));

    expect(targetMoveCount['Target 1'], equals(0));
    expect(targetMoveCount['Target 2'], equals(0));

    final Offset firstLocation = tester.getCenter(find.text('Source'));
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    expect(targetMoveCount['Target 1'], equals(0));
    expect(targetMoveCount['Target 2'], equals(0));

    final Offset secondLocation = tester.getCenter(find.text('Target 1'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(targetMoveCount['Target 1'], equals(1));
    expect(targetMoveCount['Target 2'], equals(0));

    final Offset thirdLocation = tester.getCenter(find.text('Target 2'));
    await gesture.moveTo(thirdLocation);
    await tester.pump();

    expect(targetMoveCount['Target 1'], equals(1));
    expect(targetMoveCount['Target 2'], equals(1));

    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(targetMoveCount['Target 1'], equals(2));
    expect(targetMoveCount['Target 2'], equals(1));

    await gesture.up();
    await tester.pump();

    expect(targetMoveCount['Target 1'], equals(2));
    expect(targetMoveCount['Target 2'], equals(1));
  });

  testWidgets('Drag and drop - dragging over button', (WidgetTester tester) async {
    final List<String> events = <String>[];
    Offset firstLocation, secondLocation;

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          const Draggable<int>(
            data: 1,
            feedback: Text('Dragging'),
            child: Text('Source'),
          ),
          Stack(
            children: <Widget>[
              GestureDetector(
                behavior: HitTestBehavior.opaque,
                onTap: () {
                  events.add('tap');
                },
                child: const Text('Button'),
              ),
              DragTarget<int>(
                builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
                  return const IgnorePointer(
                    child: Text('Target'),
                  );
                },
                onAccept: (int? data) {
                  events.add('drop');
                },
                onAcceptWithDetails: (DragTargetDetails<int> _) {
                  events.add('details');
                },
              ),
            ],
          ),
        ],
      ),
    ));

    expect(events, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(find.text('Button'), findsOneWidget);

    // taps (we check both to make sure the test is consistent)

    expect(events, isEmpty);
    await tester.tap(find.text('Button'));
    expect(events, equals(<String>['tap']));
    events.clear();

    expect(events, isEmpty);
    await tester.tap(find.text('Target'), warnIfMissed: false); // (inside IgnorePointer)
    expect(events, equals(<String>['tap']));
    events.clear();

    // drag and drop

    firstLocation = tester.getCenter(find.text('Source'));
    TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    secondLocation = tester.getCenter(find.text('Target'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(events, isEmpty);
    await gesture.up();
    await tester.pump();
    expect(events, equals(<String>['drop', 'details']));
    events.clear();

    // drag and tap and drop

    firstLocation = tester.getCenter(find.text('Source'));
    gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    secondLocation = tester.getCenter(find.text('Target'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(events, isEmpty);
    await tester.tap(find.text('Button'));
    await tester.tap(find.text('Target'), warnIfMissed: false); // (inside IgnorePointer)
    await gesture.up();
    await tester.pump();
    expect(events, equals(<String>['tap', 'tap', 'drop', 'details']));
    events.clear();
  });

  testWidgets('Drag and drop - tapping button', (WidgetTester tester) async {
    final List<String> events = <String>[];
    Offset firstLocation, secondLocation;

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          Draggable<int>(
            data: 1,
            feedback: const Text('Dragging'),
            child: GestureDetector(
              behavior: HitTestBehavior.opaque,
              onTap: () {
                events.add('tap');
              },
              child: const Text('Button'),
            ),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const Text('Target');
            },
            onAccept: (int? data) {
              events.add('drop');
            },
            onAcceptWithDetails: (DragTargetDetails<int> _) {
              events.add('details');
            },
          ),
        ],
      ),
    ));

    expect(events, isEmpty);
    expect(find.text('Button'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);

    expect(events, isEmpty);
    await tester.tap(find.text('Button'));
    expect(events, equals(<String>['tap']));
    events.clear();

    firstLocation = tester.getCenter(find.text('Button'));
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    secondLocation = tester.getCenter(find.text('Target'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(events, isEmpty);
    await gesture.up();
    await tester.pump();
    expect(events, equals(<String>['drop', 'details']));
    events.clear();
  });

  testWidgets('Drag and drop - long press draggable, short press', (WidgetTester tester) async {
    final List<String> events = <String>[];
    Offset firstLocation, secondLocation;

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          const LongPressDraggable<int>(
            data: 1,
            feedback: Text('Dragging'),
            child: Text('Source'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const Text('Target');
            },
            onAccept: (int? data) {
              events.add('drop');
            },
            onAcceptWithDetails: (DragTargetDetails<int> _) {
              events.add('details');
            },
          ),
        ],
      ),
    ));

    expect(events, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);

    expect(events, isEmpty);
    await tester.tap(find.text('Source'));
    expect(events, isEmpty);

    firstLocation = tester.getCenter(find.text('Source'));
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    secondLocation = tester.getCenter(find.text('Target'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(events, isEmpty);
    await gesture.up();
    await tester.pump();
    expect(events, isEmpty);
  });

  testWidgets('Drag and drop - long press draggable, long press', (WidgetTester tester) async {
    final List<String> events = <String>[];
    Offset firstLocation, secondLocation;

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          const Draggable<int>(
            data: 1,
            feedback: Text('Dragging'),
            child: Text('Source'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const Text('Target');
            },
            onAccept: (int? data) {
              events.add('drop');
            },
            onAcceptWithDetails: (DragTargetDetails<int> _) {
              events.add('details');
            },
          ),
        ],
      ),
    ));

    expect(events, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);

    expect(events, isEmpty);
    await tester.tap(find.text('Source'));
    expect(events, isEmpty);

    firstLocation = tester.getCenter(find.text('Source'));
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    await tester.pump(const Duration(seconds: 20));

    secondLocation = tester.getCenter(find.text('Target'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(events, isEmpty);
    await gesture.up();
    await tester.pump();
    expect(events, equals(<String>['drop', 'details']));
  });

  testWidgets('Drag and drop - horizontal and vertical draggables in vertical block', (WidgetTester tester) async {
    final List<String> events = <String>[];
    Offset firstLocation, secondLocation, thirdLocation;

    await tester.pumpWidget(MaterialApp(
      home: ListView(
        dragStartBehavior: DragStartBehavior.down,
        children: <Widget>[
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const Text('Target');
            },
            onAccept: (int? data) {
              events.add('drop $data');
            },
            onAcceptWithDetails: (DragTargetDetails<int> _) {
              events.add('details');
            },
          ),
          Container(height: 400.0),
          const Draggable<int>(
            data: 1,
            feedback: Text('Dragging'),
            affinity: Axis.horizontal,
            child: Text('H'),
          ),
          const Draggable<int>(
            data: 2,
            feedback: Text('Dragging'),
            affinity: Axis.vertical,
            child: Text('V'),
          ),
          Container(height: 500.0),
          Container(height: 500.0),
          Container(height: 500.0),
          Container(height: 500.0),
        ],
      ),
    ));

    expect(events, isEmpty);
    expect(find.text('Target'), findsOneWidget);
    expect(find.text('H'), findsOneWidget);
    expect(find.text('V'), findsOneWidget);

    // vertical draggable drags vertically
    expect(events, isEmpty);
    firstLocation = tester.getCenter(find.text('V'));
    secondLocation = tester.getCenter(find.text('Target'));
    TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();
    await gesture.moveTo(secondLocation);
    await tester.pump();
    await gesture.up();
    await tester.pump();
    expect(events, equals(<String>['drop 2', 'details']));
    expect(tester.getCenter(find.text('Target')).dy, greaterThan(0.0));
    events.clear();

    // horizontal draggable drags horizontally
    expect(events, isEmpty);
    firstLocation = tester.getTopLeft(find.text('H'));
    secondLocation = tester.getTopRight(find.text('H'));
    thirdLocation = tester.getCenter(find.text('Target'));
    gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();
    await gesture.moveTo(secondLocation);
    await tester.pump();
    await gesture.moveTo(thirdLocation);
    await tester.pump();
    await gesture.up();
    await tester.pump();
    expect(events, equals(<String>['drop 1', 'details']));
    expect(tester.getCenter(find.text('Target')).dy, greaterThan(0.0));
    events.clear();

    // vertical draggable drags horizontally when there's no competition
    // from other gesture detectors
    expect(events, isEmpty);
    firstLocation = tester.getTopLeft(find.text('V'));
    secondLocation = tester.getTopRight(find.text('V'));
    thirdLocation = tester.getCenter(find.text('Target'));
    gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();
    await gesture.moveTo(secondLocation);
    await tester.pump();
    await gesture.moveTo(thirdLocation);
    await tester.pump();
    await gesture.up();
    await tester.pump();
    expect(events, equals(<String>['drop 2', 'details']));
    expect(tester.getCenter(find.text('Target')).dy, greaterThan(0.0));
    events.clear();

    // horizontal draggable doesn't drag vertically when there is competition
    // for vertical gestures
    expect(events, isEmpty);
    firstLocation = tester.getCenter(find.text('H'));
    secondLocation = tester.getCenter(find.text('Target'));
    gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();
    await gesture.moveTo(secondLocation);
    await tester.pump(); // scrolls off screen!
    await gesture.up();
    await tester.pump();
    expect(events, equals(<String>[]));
    expect(find.text('Target'), findsNothing);
    events.clear();
  });

  testWidgets('Drag and drop - horizontal and vertical draggables in horizontal block', (WidgetTester tester) async {
    final List<String> events = <String>[];
    Offset firstLocation, secondLocation, thirdLocation;

    await tester.pumpWidget(MaterialApp(
      home: ListView(
        dragStartBehavior: DragStartBehavior.down,
        scrollDirection: Axis.horizontal,
        children: <Widget>[
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const Text('Target');
            },
            onAccept: (int? data) {
              events.add('drop $data');
            },
            onAcceptWithDetails: (DragTargetDetails<int> _) {
              events.add('details');
            },
          ),
          Container(width: 400.0),
          const Draggable<int>(
            data: 1,
            feedback: Text('Dragging'),
            affinity: Axis.horizontal,
            child: Text('H'),
          ),
          const Draggable<int>(
            data: 2,
            feedback: Text('Dragging'),
            affinity: Axis.vertical,
            child: Text('V'),
          ),
          Container(width: 500.0),
          Container(width: 500.0),
          Container(width: 500.0),
          Container(width: 500.0),
        ],
      ),
    ));

    expect(events, isEmpty);
    expect(find.text('Target'), findsOneWidget);
    expect(find.text('H'), findsOneWidget);
    expect(find.text('V'), findsOneWidget);

    // horizontal draggable drags horizontally
    expect(events, isEmpty);
    firstLocation = tester.getCenter(find.text('H'));
    secondLocation = tester.getCenter(find.text('Target'));
    TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();
    await gesture.moveTo(secondLocation);
    await tester.pump();
    await gesture.up();
    await tester.pump();
    expect(events, equals(<String>['drop 1', 'details']));
    expect(tester.getCenter(find.text('Target')).dx, greaterThan(0.0));
    events.clear();

    // vertical draggable drags vertically
    expect(events, isEmpty);
    firstLocation = tester.getTopLeft(find.text('V'));
    secondLocation = tester.getBottomLeft(find.text('V'));
    thirdLocation = tester.getCenter(find.text('Target'));
    gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();
    await gesture.moveTo(secondLocation);
    await tester.pump();
    await gesture.moveTo(thirdLocation);
    await tester.pump();
    await gesture.up();
    await tester.pump();
    expect(events, equals(<String>['drop 2', 'details']));
    expect(tester.getCenter(find.text('Target')).dx, greaterThan(0.0));
    events.clear();

    // horizontal draggable drags vertically when there's no competition
    // from other gesture detectors
    expect(events, isEmpty);
    firstLocation = tester.getTopLeft(find.text('H'));
    secondLocation = tester.getBottomLeft(find.text('H'));
    thirdLocation = tester.getCenter(find.text('Target'));
    gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();
    await gesture.moveTo(secondLocation);
    await tester.pump();
    await gesture.moveTo(thirdLocation);
    await tester.pump();
    await gesture.up();
    await tester.pump();
    expect(events, equals(<String>['drop 1', 'details']));
    expect(tester.getCenter(find.text('Target')).dx, greaterThan(0.0));
    events.clear();

    // vertical draggable doesn't drag horizontally when there is competition
    // for horizontal gestures
    expect(events, isEmpty);
    firstLocation = tester.getCenter(find.text('V'));
    secondLocation = tester.getCenter(find.text('Target'));
    gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();
    await gesture.moveTo(secondLocation);
    await tester.pump(); // scrolls off screen!
    await gesture.up();
    await tester.pump();
    expect(events, equals(<String>[]));
    expect(find.text('Target'), findsNothing);
    events.clear();
  });

  group('Drag and drop - Draggables with a set axis only move along that axis', () {
    final List<String> events = <String>[];

    Widget build() {
      return MaterialApp(
        home: ListView(
          scrollDirection: Axis.horizontal,
          children: <Widget>[
            DragTarget<int>(
              builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
                return const Text('Target');
              },
              onAccept: (int? data) {
                events.add('drop $data');
              },
              onAcceptWithDetails: (DragTargetDetails<int> _) {
                events.add('details');
              },
            ),
            Container(width: 400.0),
            const Draggable<int>(
              data: 1,
              feedback: Text('H'),
              childWhenDragging: SizedBox(),
              axis: Axis.horizontal,
              child: Text('H'),
            ),
            const Draggable<int>(
              data: 2,
              feedback: Text('V'),
              childWhenDragging: SizedBox(),
              axis: Axis.vertical,
              child: Text('V'),
            ),
            const Draggable<int>(
              data: 3,
              feedback: Text('N'),
              childWhenDragging: SizedBox(),
              child: Text('N'),
            ),
            Container(width: 500.0),
            Container(width: 500.0),
            Container(width: 500.0),
            Container(width: 500.0),
          ],
        ),
      );
    }
    testWidgets('Null axis draggable moves along all axes', (WidgetTester tester) async {
      await tester.pumpWidget(build());
      final Offset firstLocation = tester.getTopLeft(find.text('N'));
      final Offset secondLocation = firstLocation + const Offset(300.0, 300.0);
      final Offset thirdLocation = firstLocation + const Offset(-300.0, -300.0);
      final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
      await tester.pump();
      await gesture.moveTo(secondLocation);
      await tester.pump();
      expect(tester.getTopLeft(find.text('N')), secondLocation);
      await gesture.moveTo(thirdLocation);
      await tester.pump();
      expect(tester.getTopLeft(find.text('N')), thirdLocation);
    });

    testWidgets('Horizontal axis draggable moves horizontally', (WidgetTester tester) async {
      await tester.pumpWidget(build());
      final Offset firstLocation = tester.getTopLeft(find.text('H'));
      final Offset secondLocation = firstLocation + const Offset(300.0, 0.0);
      final Offset thirdLocation = firstLocation + const Offset(-300.0, 0.0);
      final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
      await tester.pump();
      await gesture.moveTo(secondLocation);
      await tester.pump();
      expect(tester.getTopLeft(find.text('H')), secondLocation);
      await gesture.moveTo(thirdLocation);
      await tester.pump();
      expect(tester.getTopLeft(find.text('H')), thirdLocation);
    });

    testWidgets('Horizontal axis draggable does not move vertically', (WidgetTester tester) async {
      await tester.pumpWidget(build());
      final Offset firstLocation = tester.getTopLeft(find.text('H'));
      final Offset secondDragLocation = firstLocation + const Offset(300.0, 200.0);
      // The horizontal drag widget won't scroll vertically.
      final Offset secondWidgetLocation = firstLocation + const Offset(300.0, 0.0);
      final Offset thirdDragLocation = firstLocation + const Offset(-300.0, -200.0);
      final Offset thirdWidgetLocation = firstLocation + const Offset(-300.0, 0.0);
      final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
      await tester.pump();
      await gesture.moveTo(secondDragLocation);
      await tester.pump();
      expect(tester.getTopLeft(find.text('H')), secondWidgetLocation);
      await gesture.moveTo(thirdDragLocation);
      await tester.pump();
      expect(tester.getTopLeft(find.text('H')), thirdWidgetLocation);
    });

    testWidgets('Vertical axis draggable moves vertically', (WidgetTester tester) async {
      await tester.pumpWidget(build());
      final Offset firstLocation = tester.getTopLeft(find.text('V'));
      final Offset secondLocation = firstLocation + const Offset(0.0, 300.0);
      final Offset thirdLocation = firstLocation + const Offset(0.0, -300.0);
      final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
      await tester.pump();
      await gesture.moveTo(secondLocation);
      await tester.pump();
      expect(tester.getTopLeft(find.text('V')), secondLocation);
      await gesture.moveTo(thirdLocation);
      await tester.pump();
      expect(tester.getTopLeft(find.text('V')), thirdLocation);
    });

    testWidgets('Vertical axis draggable does not move horizontally', (WidgetTester tester) async {
      await tester.pumpWidget(build());
      final Offset firstLocation = tester.getTopLeft(find.text('V'));
      final Offset secondDragLocation = firstLocation + const Offset(200.0, 300.0);
      // The vertical drag widget won't scroll horizontally.
      final Offset secondWidgetLocation = firstLocation + const Offset(0.0, 300.0);
      final Offset thirdDragLocation = firstLocation + const Offset(-200.0, -300.0);
      final Offset thirdWidgetLocation = firstLocation + const Offset(0.0, -300.0);
      final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
      await tester.pump();
      await gesture.moveTo(secondDragLocation);
      await tester.pump();
      expect(tester.getTopLeft(find.text('V')), secondWidgetLocation);
      await gesture.moveTo(thirdDragLocation);
      await tester.pump();
      expect(tester.getTopLeft(find.text('V')), thirdWidgetLocation);
    });
  });

  group('Drag and drop - onDragUpdate called if draggable moves along a set axis', () {
    int updated = 0;
    Offset dragDelta = Offset.zero;

    setUp(() {
      updated = 0;
      dragDelta = Offset.zero;
    });

    Widget build() {
      return MaterialApp(
        home: Column(
          children: <Widget>[
            Draggable<int>(
              data: 1,
              feedback: const Text('Dragging'),
              onDragUpdate: (DragUpdateDetails details) {
                dragDelta += details.delta;
                updated++;
              },
              child: const Text('Source'),
            ),
            Draggable<int>(
              data: 2,
              feedback: const Text('Vertical Dragging'),
              onDragUpdate: (DragUpdateDetails details) {
                dragDelta += details.delta;
                updated++;
              },
              axis: Axis.vertical,
              child: const Text('Vertical Source'),
            ),
            Draggable<int>(
              data: 3,
              feedback: const Text('Horizontal Dragging'),
              onDragUpdate: (DragUpdateDetails details) {
                dragDelta += details.delta;
                updated++;
              },
              axis: Axis.horizontal,
              child: const Text('Horizontal Source'),
            ),
          ],
        ),
      );
    }

    testWidgets('Null axis onDragUpdate called only if draggable moves in any direction', (WidgetTester tester) async {
      await tester.pumpWidget(build());

      expect(updated, 0);
      expect(find.text('Source'), findsOneWidget);
      expect(find.text('Dragging'), findsNothing);

      final Offset firstLocation = tester.getCenter(find.text('Source'));
      final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
      await tester.pump();

      expect(updated, 0);
      expect(find.text('Source'), findsOneWidget);
      expect(find.text('Dragging'), findsOneWidget);

      await gesture.moveBy(const Offset(10, 10));
      await tester.pump();

      expect(updated, 1);

      await gesture.moveBy(Offset.zero);
      await tester.pump();

      expect(updated, 1);

      await gesture.up();
      await tester.pump();

      expect(updated, 1);
      expect(find.text('Source'), findsOneWidget);
      expect(find.text('Dragging'), findsNothing);
      expect(dragDelta.dx, 10);
      expect(dragDelta.dy, 10);
    });

    testWidgets('Vertical axis onDragUpdate only called if draggable moves vertical', (WidgetTester tester) async {
      await tester.pumpWidget(build());

      expect(updated, 0);
      expect(find.text('Vertical Source'), findsOneWidget);
      expect(find.text('Vertical Dragging'), findsNothing);

      final Offset firstLocation = tester.getCenter(find.text('Vertical Source'));
      final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
      await tester.pump();

      expect(updated, 0);
      expect(find.text('Vertical Source'), findsOneWidget);
      expect(find.text('Vertical Dragging'), findsOneWidget);

      await gesture.moveBy(const Offset(0, 10));
      await tester.pump();

      expect(updated, 1);

      await gesture.moveBy(const Offset(10 , 0));
      await tester.pump();

      expect(updated, 1);

      await gesture.up();
      await tester.pump();

      expect(updated, 1);
      expect(find.text('Vertical Source'), findsOneWidget);
      expect(find.text('Vertical Dragging'), findsNothing);
      expect(dragDelta.dx, 0);
      expect(dragDelta.dy, 10);
    });

    testWidgets('Horizontal axis onDragUpdate only called if draggable moves horizontal', (WidgetTester tester) async {
      await tester.pumpWidget(build());

      expect(updated, 0);
      expect(find.text('Horizontal Source'), findsOneWidget);
      expect(find.text('Horizontal Dragging'), findsNothing);

      final Offset firstLocation = tester.getCenter(find.text('Horizontal Source'));
      final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
      await tester.pump();

      expect(updated, 0);
      expect(find.text('Horizontal Source'), findsOneWidget);
      expect(find.text('Horizontal Dragging'), findsOneWidget);

      await gesture.moveBy(const Offset(0, 10));
      await tester.pump();

      expect(updated, 0);

      await gesture.moveBy(const Offset(10 , 0));
      await tester.pump();

      expect(updated, 1);

      await gesture.up();
      await tester.pump();

      expect(updated, 1);
      expect(find.text('Horizontal Source'), findsOneWidget);
      expect(find.text('Horizontal Dragging'), findsNothing);
      expect(dragDelta.dx, 10);
      expect(dragDelta.dy, 0);
    });
  });

  testWidgets('Drag and drop - onDraggableCanceled not called if dropped on accepting target', (WidgetTester tester) async {
    final List<int> accepted = <int>[];
    final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
    bool onDraggableCanceledCalled = false;

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          Draggable<int>(
            data: 1,
            feedback: const Text('Dragging'),
            onDraggableCanceled: (Velocity velocity, Offset offset) {
              onDraggableCanceledCalled = true;
            },
            child: const Text('Source'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const SizedBox(height: 100.0, child: Text('Target'));
            },
            onAccept: accepted.add,
            onAcceptWithDetails: acceptedDetails.add,
          ),
        ],
      ),
    ));

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(onDraggableCanceledCalled, isFalse);

    final Offset firstLocation = tester.getCenter(find.text('Source'));
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);
    expect(onDraggableCanceledCalled, isFalse);

    final Offset secondLocation = tester.getCenter(find.text('Target'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);
    expect(onDraggableCanceledCalled, isFalse);

    await gesture.up();
    await tester.pump();

    expect(accepted, equals(<int>[1]));
    expect(acceptedDetails, hasLength(1));
    expect(acceptedDetails.first.offset, const Offset(256.0, 74.0));
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(onDraggableCanceledCalled, isFalse);
  });

  testWidgets('Drag and drop - onDraggableCanceled called if dropped on non-accepting target', (WidgetTester tester) async {
    final List<int> accepted = <int>[];
    final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
    bool onDraggableCanceledCalled = false;
    late Velocity onDraggableCanceledVelocity;
    late Offset onDraggableCanceledOffset;

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          Draggable<int>(
            data: 1,
            feedback: const Text('Dragging'),
            onDraggableCanceled: (Velocity velocity, Offset offset) {
              onDraggableCanceledCalled = true;
              onDraggableCanceledVelocity = velocity;
              onDraggableCanceledOffset = offset;
            },
            child: const Text('Source'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const SizedBox(
                height: 100.0,
                child: Text('Target'),
              );
            },
            onWillAccept: (int? data) => false,
            onAccept: accepted.add,
            onAcceptWithDetails: acceptedDetails.add,
          ),
        ],
      ),
    ));

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(onDraggableCanceledCalled, isFalse);

    final Offset firstLocation = tester.getTopLeft(find.text('Source'));
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);
    expect(onDraggableCanceledCalled, isFalse);

    final Offset secondLocation = tester.getCenter(find.text('Target'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);
    expect(onDraggableCanceledCalled, isFalse);

    await gesture.up();
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(onDraggableCanceledCalled, isTrue);
    expect(onDraggableCanceledVelocity, equals(Velocity.zero));
    expect(onDraggableCanceledOffset, equals(Offset(secondLocation.dx, secondLocation.dy)));
  });

  testWidgets('Drag and drop - onDraggableCanceled called if dropped on non-accepting target with correct velocity', (WidgetTester tester) async {
    final List<int> accepted = <int>[];
    final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
    bool onDraggableCanceledCalled = false;
    late Velocity onDraggableCanceledVelocity;
    late Offset onDraggableCanceledOffset;

    await tester.pumpWidget(MaterialApp(
      home: Column(children: <Widget>[
        Draggable<int>(
          data: 1,
          feedback: const Text('Source'),
          onDraggableCanceled: (Velocity velocity, Offset offset) {
            onDraggableCanceledCalled = true;
            onDraggableCanceledVelocity = velocity;
            onDraggableCanceledOffset = offset;
          },
          child: const Text('Source'),
        ),
        DragTarget<int>(
          builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
            return const SizedBox(height: 100.0, child: Text('Target'));
          },
          onWillAccept: (int? data) => false,
          onAccept: accepted.add,
          onAcceptWithDetails: acceptedDetails.add,
        ),
      ]),
    ));

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(onDraggableCanceledCalled, isFalse);

    final Offset flingStart = tester.getTopLeft(find.text('Source'));
    await tester.flingFrom(flingStart, const Offset(0.0, 100.0), 1000.0);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(onDraggableCanceledCalled, isTrue);
    expect(onDraggableCanceledVelocity.pixelsPerSecond.dx.abs(), lessThan(0.0000001));
    expect((onDraggableCanceledVelocity.pixelsPerSecond.dy - 1000.0).abs(), lessThan(0.0000001));
    expect(onDraggableCanceledOffset, equals(Offset(flingStart.dx, flingStart.dy) + const Offset(0.0, 100.0)));
  });

  testWidgets('Drag and drop - onDragEnd not called if dropped on non-accepting target', (WidgetTester tester) async {
    final List<int> accepted = <int>[];
    final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
    bool onDragEndCalled = false;
    late DraggableDetails onDragEndDraggableDetails;
    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          Draggable<int>(
            data: 1,
            feedback: const Text('Dragging'),
            onDragEnd: (DraggableDetails details) {
              onDragEndCalled = true;
              onDragEndDraggableDetails = details;
            },
            child: const Text('Source'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const SizedBox(height: 100.0, child: Text('Target'));
            },
            onWillAccept: (int? data) => false,
            onAccept: accepted.add,
            onAcceptWithDetails: acceptedDetails.add,
          ),
        ],
      ),
    ));

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragEndCalled, isFalse);

    final Offset firstLocation = tester.getTopLeft(find.text('Source'));
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragEndCalled, isFalse);

    final Offset secondLocation = tester.getCenter(find.text('Target'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragEndCalled, isFalse);

    await gesture.up();
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragEndCalled, isTrue);
    expect(onDragEndDraggableDetails, isNotNull);
    expect(onDragEndDraggableDetails.wasAccepted, isFalse);
    expect(onDragEndDraggableDetails.velocity, equals(Velocity.zero));
    expect(
      onDragEndDraggableDetails.offset,
      equals(Offset(secondLocation.dx, secondLocation.dy - firstLocation.dy)),
    );
  });

  testWidgets('Drag and drop - DragTarget rebuilds with and without rejected data when a rejected draggable enters and leaves', (WidgetTester tester) async {
    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          const Draggable<int>(
            data: 1,
            feedback: Text('Dragging'),
            child: Text('Source'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return SizedBox(
                height: 100.0,
                child: rejects.isNotEmpty
                    ? const Text('Rejected')
                    : const Text('Target'),
              );
            },
            onWillAccept: (int? data) => false,
          ),
        ],
      ),
    ));

    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(find.text('Rejected'), findsNothing);

    final Offset firstLocation = tester.getTopLeft(find.text('Source'));
    final TestGesture gesture =
    await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);
    expect(find.text('Rejected'), findsNothing);

    final Offset secondLocation = tester.getCenter(find.text('Target'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsNothing);
    expect(find.text('Rejected'), findsOneWidget);

    await gesture.moveTo(firstLocation);
    await tester.pump();

    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);
    expect(find.text('Rejected'), findsNothing);
  });


  testWidgets('Drag and drop - Can drag and drop over a non-accepting target multiple times', (WidgetTester tester) async {
    int numberOfTimesOnDraggableCanceledCalled = 0;
    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          Draggable<int>(
            data: 1,
            feedback: const Text('Dragging'),
          onDraggableCanceled: (Velocity velocity, Offset offset) {
            numberOfTimesOnDraggableCanceledCalled++;
          },
            child: const Text('Source'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return SizedBox(
                height: 100.0,
                child: rejects.isNotEmpty
                    ? const Text('Rejected')
                    : const Text('Target'),
              );
            },
            onWillAccept: (int? data) => false,
          ),
        ],
      ),
    ));

    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(find.text('Rejected'), findsNothing);

    final Offset firstLocation = tester.getTopLeft(find.text('Source'));
    final TestGesture gesture =
    await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);
    expect(find.text('Rejected'), findsNothing);

    final Offset secondLocation = tester.getCenter(find.text('Target'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsNothing);
    expect(find.text('Rejected'), findsOneWidget);

    await gesture.up();
    await tester.pump();

    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(find.text('Rejected'), findsNothing);
    expect(numberOfTimesOnDraggableCanceledCalled, 1);

    // Drag and drop the Draggable onto the Target a second time.
    final TestGesture secondGesture =
    await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);
    expect(find.text('Rejected'), findsNothing);

    await secondGesture.moveTo(secondLocation);
    await tester.pump();

    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsNothing);
    expect(find.text('Rejected'), findsOneWidget);

    await secondGesture.up();
    await tester.pump();

    expect(numberOfTimesOnDraggableCanceledCalled, 2);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(find.text('Rejected'), findsNothing);
  });

  testWidgets('Drag and drop - onDragCompleted not called if dropped on non-accepting target', (WidgetTester tester) async {
    final List<int> accepted = <int>[];
    final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
    bool onDragCompletedCalled = false;

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          Draggable<int>(
            data: 1,
            feedback: const Text('Dragging'),
            onDragCompleted: () {
              onDragCompletedCalled = true;
            },
            child: const Text('Source'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const SizedBox(
                height: 100.0,
                child: Text('Target'),
              );
            },
            onWillAccept: (int? data) => false,
            onAccept: accepted.add,
            onAcceptWithDetails: acceptedDetails.add,
          ),
        ],
      ),
    ));

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragCompletedCalled, isFalse);

    final Offset firstLocation = tester.getTopLeft(find.text('Source'));
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragCompletedCalled, isFalse);

    final Offset secondLocation = tester.getCenter(find.text('Target'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragCompletedCalled, isFalse);

    await gesture.up();
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragCompletedCalled, isFalse);
  });

  testWidgets('Drag and drop - onDragEnd called if dropped on accepting target', (WidgetTester tester) async {
    final List<int> accepted = <int>[];
    final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
    bool onDragEndCalled = false;
    late DraggableDetails onDragEndDraggableDetails;
    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          Draggable<int>(
            data: 1,
            feedback: const Text('Dragging'),
            onDragEnd: (DraggableDetails details) {
              onDragEndCalled = true;
              onDragEndDraggableDetails = details;
            },
            child: const Text('Source'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const SizedBox(height: 100.0, child: Text('Target'));
            },
            onAccept: accepted.add,
            onAcceptWithDetails: acceptedDetails.add,
          ),
        ],
      ),
    ));

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragEndCalled, isFalse);

    final Offset firstLocation = tester.getCenter(find.text('Source'));
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragEndCalled, isFalse);

    final Offset secondLocation = tester.getCenter(find.text('Target'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragEndCalled, isFalse);

    await gesture.up();
    await tester.pump();

    final Offset droppedLocation = tester.getTopLeft(find.text('Target'));
    final Offset expectedDropOffset = Offset(droppedLocation.dx, secondLocation.dy - firstLocation.dy);

    expect(accepted, equals(<int>[1]));
    expect(acceptedDetails, hasLength(1));
    expect(acceptedDetails.first.offset, const Offset(256.0, 74.0));
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragEndCalled, isTrue);
    expect(onDragEndDraggableDetails, isNotNull);
    expect(onDragEndDraggableDetails.wasAccepted, isTrue);
    expect(onDragEndDraggableDetails.velocity, equals(Velocity.zero));
    expect(onDragEndDraggableDetails.offset, equals(expectedDropOffset));
  });

  testWidgets('DragTarget does not call onDragEnd when remove from the tree', (WidgetTester tester) async {
    final List<String> events = <String>[];
    Offset firstLocation, secondLocation;
    int timesOnDragEndCalled = 0;
    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          Draggable<int>(
              data: 1,
              feedback: const Text('Dragging'),
              onDragEnd: (DraggableDetails details) {
                timesOnDragEndCalled++;
              },
              child: const Text('Source'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const Text('Target');
            },
            onAccept: (int? data) {
              events.add('drop');
            },
            onAcceptWithDetails: (DragTargetDetails<int> _) {
              events.add('details');
            },
          ),
        ],
      ),
    ));

    expect(events, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);

    expect(events, isEmpty);
    await tester.tap(find.text('Source'));
    expect(events, isEmpty);

    firstLocation = tester.getCenter(find.text('Source'));
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    await tester.pump(const Duration(seconds: 20));

    secondLocation = tester.getCenter(find.text('Target'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    await tester.pumpWidget(MaterialApp(
        home: Column(
            children: const <Widget>[
              Draggable<int>(
                  data: 1,
                  feedback: Text('Dragging'),
                  child: Text('Source'),
              ),
            ],
        ),
    ));

    expect(events, isEmpty);
    expect(timesOnDragEndCalled, equals(1));
    await gesture.up();
    await tester.pump();
  });

  testWidgets('Drag and drop - onDragCompleted called if dropped on accepting target', (WidgetTester tester) async {
    final List<int> accepted = <int>[];
    final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
    bool onDragCompletedCalled = false;

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          Draggable<int>(
            data: 1,
            feedback: const Text('Dragging'),
            onDragCompleted: () {
              onDragCompletedCalled = true;
            },
            child: const Text('Source'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const SizedBox(height: 100.0, child: Text('Target'));
            },
            onAccept: accepted.add,
            onAcceptWithDetails: acceptedDetails.add,
          ),
        ],
      ),
    ));

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragCompletedCalled, isFalse);

    final Offset firstLocation = tester.getCenter(find.text('Source'));
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragCompletedCalled, isFalse);

    final Offset secondLocation = tester.getCenter(find.text('Target'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragCompletedCalled, isFalse);

    await gesture.up();
    await tester.pump();

    expect(accepted, equals(<int>[1]));
    expect(acceptedDetails, hasLength(1));
    expect(acceptedDetails.first.offset, const Offset(256.0, 74.0));
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragCompletedCalled, isTrue);
  });

  testWidgets('Drag and drop - allow pass through of unaccepted data test', (WidgetTester tester) async {
    final List<int> acceptedInts = <int>[];
    final List<DragTargetDetails<int>> acceptedIntsDetails = <DragTargetDetails<int>>[];
    final List<double> acceptedDoubles = <double>[];
    final List<DragTargetDetails<double>> acceptedDoublesDetails = <DragTargetDetails<double>>[];

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          const Draggable<int>(
            data: 1,
            feedback: Text('IntDragging'),
            child: Text('IntSource'),
          ),
          const Draggable<double>(
            data: 1.0,
            feedback: Text('DoubleDragging'),
            child: Text('DoubleSource'),
          ),
          Stack(
            children: <Widget>[
              DragTarget<int>(
                builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
                  return const IgnorePointer(
                    child: SizedBox(
                      height: 100.0,
                      child: Text('Target1'),
                    ),
                  );
                },
                onAccept: acceptedInts.add,
                onAcceptWithDetails: acceptedIntsDetails.add,
              ),
              DragTarget<double>(
                builder: (BuildContext context, List<double?> data, List<dynamic> rejects) {
                  return const IgnorePointer(
                    child: SizedBox(
                      height: 100.0,
                      child: Text('Target2'),
                    ),
                  );
                },
                onAccept: acceptedDoubles.add,
                onAcceptWithDetails: acceptedDoublesDetails.add,
              ),
            ],
          ),
        ],
      ),
    ));

    expect(acceptedInts, isEmpty);
    expect(acceptedIntsDetails, isEmpty);
    expect(acceptedDoubles, isEmpty);
    expect(acceptedDoublesDetails, isEmpty);
    expect(find.text('IntSource'), findsOneWidget);
    expect(find.text('IntDragging'), findsNothing);
    expect(find.text('DoubleSource'), findsOneWidget);
    expect(find.text('DoubleDragging'), findsNothing);
    expect(find.text('Target1'), findsOneWidget);
    expect(find.text('Target2'), findsOneWidget);

    final Offset intLocation = tester.getCenter(find.text('IntSource'));
    final Offset doubleLocation = tester.getCenter(find.text('DoubleSource'));
    final Offset targetLocation = tester.getCenter(find.text('Target1'));

    // Drag the double draggable.
    final TestGesture doubleGesture = await tester.startGesture(doubleLocation, pointer: 7);
    await tester.pump();

    expect(acceptedInts, isEmpty);
    expect(acceptedIntsDetails, isEmpty);
    expect(acceptedDoubles, isEmpty);
    expect(acceptedDoublesDetails, isEmpty);
    expect(find.text('IntDragging'), findsNothing);
    expect(find.text('DoubleDragging'), findsOneWidget);

    await doubleGesture.moveTo(targetLocation);
    await tester.pump();

    expect(acceptedInts, isEmpty);
    expect(acceptedIntsDetails, isEmpty);
    expect(acceptedDoubles, isEmpty);
    expect(acceptedDoublesDetails, isEmpty);
    expect(find.text('IntDragging'), findsNothing);
    expect(find.text('DoubleDragging'), findsOneWidget);

    await doubleGesture.up();
    await tester.pump();

    expect(acceptedInts, isEmpty);
    expect(acceptedIntsDetails, isEmpty);
    expect(acceptedDoubles, equals(<double>[1.0]));
    expect(acceptedDoublesDetails, hasLength(1));
    expect(acceptedDoublesDetails.first.offset, const Offset(112.0, 122.0));
    expect(find.text('IntDragging'), findsNothing);
    expect(find.text('DoubleDragging'), findsNothing);

    acceptedDoubles.clear();
    acceptedDoublesDetails.clear();

    // Drag the int draggable.
    final TestGesture intGesture = await tester.startGesture(intLocation, pointer: 7);
    await tester.pump();

    expect(acceptedInts, isEmpty);
    expect(acceptedIntsDetails, isEmpty);
    expect(acceptedDoubles, isEmpty);
    expect(acceptedDoublesDetails, isEmpty);
    expect(find.text('IntDragging'), findsOneWidget);
    expect(find.text('DoubleDragging'), findsNothing);

    await intGesture.moveTo(targetLocation);
    await tester.pump();

    expect(acceptedInts, isEmpty);
    expect(acceptedIntsDetails, isEmpty);
    expect(acceptedDoubles, isEmpty);
    expect(acceptedDoublesDetails, isEmpty);
    expect(find.text('IntDragging'), findsOneWidget);
    expect(find.text('DoubleDragging'), findsNothing);

    await intGesture.up();
    await tester.pump();

    expect(acceptedInts, equals(<int>[1]));
    expect(acceptedIntsDetails, hasLength(1));
    expect(acceptedIntsDetails.first.offset, const Offset(184.0, 122.0));
    expect(acceptedDoubles, isEmpty);
    expect(acceptedDoublesDetails, isEmpty);
    expect(find.text('IntDragging'), findsNothing);
    expect(find.text('DoubleDragging'), findsNothing);
  });

  testWidgets('Drag and drop - allow pass through of unaccepted data twice test', (WidgetTester tester) async {
    final List<DragTargetData> acceptedDragTargetDatas = <DragTargetData>[];
    final List<DragTargetDetails<DragTargetData>> acceptedDragTargetDataDetails = <DragTargetDetails<DragTargetData>>[];
    final List<ExtendedDragTargetData> acceptedExtendedDragTargetDatas = <ExtendedDragTargetData>[];
    final List<DragTargetDetails<ExtendedDragTargetData>> acceptedExtendedDragTargetDataDetails = <DragTargetDetails<ExtendedDragTargetData>>[];
    final DragTargetData dragTargetData = DragTargetData();
    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          Draggable<DragTargetData>(
            data: dragTargetData,
            feedback: const Text('Dragging'),
            child: const Text('Source'),
          ),
          Stack(
            children: <Widget>[
              DragTarget<DragTargetData>(
                builder: (BuildContext context, List<DragTargetData?> data, List<dynamic> rejects) {
                  return const IgnorePointer(
                    child: SizedBox(
                      height: 100.0,
                      child: Text('Target1'),
                    ),
                  );
                }, onAccept: acceptedDragTargetDatas.add,
                onAcceptWithDetails: acceptedDragTargetDataDetails.add,
              ),
              DragTarget<ExtendedDragTargetData>(
                builder: (BuildContext context, List<ExtendedDragTargetData?> data, List<dynamic> rejects) {
                  return const IgnorePointer(
                    child: SizedBox(
                      height: 100.0,
                      child: Text('Target2'),
                    ),
                  );
                },
                onAccept: acceptedExtendedDragTargetDatas.add,
                onAcceptWithDetails: acceptedExtendedDragTargetDataDetails.add,
              ),
            ],
          ),
        ],
      ),
    ));

    final Offset dragTargetLocation = tester.getCenter(find.text('Source'));
    final Offset targetLocation = tester.getCenter(find.text('Target1'));

    for (int i = 0; i < 2; i += 1) {
      final TestGesture gesture = await tester.startGesture(dragTargetLocation);
      await tester.pump();
      await gesture.moveTo(targetLocation);
      await tester.pump();
      await gesture.up();
      await tester.pump();

      expect(acceptedDragTargetDatas, equals(<DragTargetData>[dragTargetData]));
      expect(acceptedDragTargetDataDetails, hasLength(1));
      expect(acceptedDragTargetDataDetails.first.offset, const Offset(256.0, 74.0));
      expect(acceptedExtendedDragTargetDatas, isEmpty);
      expect(acceptedExtendedDragTargetDataDetails, isEmpty);

      acceptedDragTargetDatas.clear();
      acceptedDragTargetDataDetails.clear();
      await tester.pump();
    }
  });

  testWidgets('Drag and drop - maxSimultaneousDrags', (WidgetTester tester) async {
    final List<int> accepted = <int>[];
    final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];

    Widget build(int maxSimultaneousDrags) {
      return MaterialApp(
        home: Column(
          children: <Widget>[
            Draggable<int>(
              data: 1,
              maxSimultaneousDrags: maxSimultaneousDrags,
              feedback: const Text('Dragging'),
              child: const Text('Source'),
            ),
            DragTarget<int>(
              builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
                return const SizedBox(height: 100.0, child: Text('Target'));
              },
              onAccept: accepted.add,
              onAcceptWithDetails: acceptedDetails.add,
            ),
          ],
        ),
      );
    }

    await tester.pumpWidget(build(0));

    final Offset firstLocation = tester.getCenter(find.text('Source'));
    final Offset secondLocation = tester.getCenter(find.text('Target'));

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);

    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);

    await gesture.up();

    await tester.pumpWidget(build(2));

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);

    final TestGesture gesture1 = await tester.startGesture(firstLocation, pointer: 8);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);

    final TestGesture gesture2 = await tester.startGesture(firstLocation, pointer: 9);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNWidgets(2));
    expect(find.text('Target'), findsOneWidget);

    final TestGesture gesture3 = await tester.startGesture(firstLocation, pointer: 10);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNWidgets(2));
    expect(find.text('Target'), findsOneWidget);

    await gesture1.moveTo(secondLocation);
    await gesture2.moveTo(secondLocation);
    await gesture3.moveTo(secondLocation);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNWidgets(2));
    expect(find.text('Target'), findsOneWidget);

    await gesture1.up();
    await tester.pump();

    expect(accepted, equals(<int>[1]));
    expect(acceptedDetails, hasLength(1));
    expect(acceptedDetails.first.offset, const Offset(256.0, 74.0));
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);

    await gesture2.up();
    await tester.pump();

    expect(accepted, equals(<int>[1, 1]));
    expect(acceptedDetails, hasLength(2));
    expect(acceptedDetails[0].offset, const Offset(256.0, 74.0));
    expect(acceptedDetails[1].offset, const Offset(256.0, 74.0));
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);

    await gesture3.up();
    await tester.pump();

    expect(accepted, equals(<int>[1, 1]));
    expect(acceptedDetails, hasLength(2));
    expect(acceptedDetails[0].offset, const Offset(256.0, 74.0));
    expect(acceptedDetails[1].offset, const Offset(256.0, 74.0));
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
  });

  testWidgets('Draggable disposes recognizer', (WidgetTester tester) async {
    bool didTap = false;
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Overlay(
          initialEntries: <OverlayEntry>[
            OverlayEntry(
              builder: (BuildContext context) => GestureDetector(
                onTap: () {
                  didTap = true;
                },
                child: Draggable<Object>(
                  feedback: Container(
                    width: 100.0,
                    height: 100.0,
                    color: const Color(0xFFFF0000),
                  ),
                  child: Container(
                    color: const Color(0xFFFFFF00),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );

    await tester.startGesture(const Offset(10.0, 10.0));
    expect(didTap, isFalse);

    // This tears down the draggable without terminating the gesture sequence,
    // which used to trigger asserts in the multi-drag gesture recognizer.
    await tester.pumpWidget(Container(key: UniqueKey()));
    expect(didTap, isFalse);
  });

  // Regression test for https://github.com/flutter/flutter/issues/6128.
  testWidgets('Draggable plays nice with onTap', (WidgetTester tester) async {
    await tester.pumpWidget(
      Directionality(
        textDirection: TextDirection.ltr,
        child: Overlay(
          initialEntries: <OverlayEntry>[
            OverlayEntry(
              builder: (BuildContext context) => GestureDetector(
                onTap: () { /* registers a tap recognizer */ },
                child: Draggable<Object>(
                  feedback: Container(
                    width: 100.0,
                    height: 100.0,
                    color: const Color(0xFFFF0000),
                  ),
                  child: Container(
                    color: const Color(0xFFFFFF00),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );

    final TestGesture firstGesture = await tester.startGesture(const Offset(10.0, 10.0), pointer: 24);
    final TestGesture secondGesture = await tester.startGesture(const Offset(10.0, 20.0), pointer: 25);

    await firstGesture.moveBy(const Offset(100.0, 0.0));
    await secondGesture.up();
  });

  testWidgets('DragTarget does not set state when remove from the tree', (WidgetTester tester) async {
    final List<String> events = <String>[];
    Offset firstLocation, secondLocation;

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          const Draggable<int>(
            data: 1,
            feedback: Text('Dragging'),
            child: Text('Source'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const Text('Target');
            },
            onAccept: (int? data) {
              events.add('drop');
            },
            onAcceptWithDetails: (DragTargetDetails<int> _) {
              events.add('details');
            },
          ),
        ],
      ),
    ));

    expect(events, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);

    expect(events, isEmpty);
    await tester.tap(find.text('Source'));
    expect(events, isEmpty);

    firstLocation = tester.getCenter(find.text('Source'));
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    await tester.pump(const Duration(seconds: 20));

    secondLocation = tester.getCenter(find.text('Target'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: const <Widget>[
          Draggable<int>(
            data: 1,
            feedback: Text('Dragging'),
            child: Text('Source'),
          ),
        ],
      ),
    ));

    expect(events, isEmpty);
    await gesture.up();
    await tester.pump();
  });

  testWidgets('Drag and drop - remove draggable', (WidgetTester tester) async {
    final List<int> accepted = <int>[];
    final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          const Draggable<int>(
            data: 1,
            feedback: Text('Dragging'),
            child: Text('Source'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const SizedBox(height: 100.0, child: Text('Target'));
            },
            onAccept: accepted.add,
            onAcceptWithDetails: acceptedDetails.add,
          ),
        ],
      ),
    ));

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);

    final Offset firstLocation = tester.getCenter(find.text('Source'));
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const SizedBox(height: 100.0, child: Text('Target'));
            },
            onAccept: accepted.add,
            onAcceptWithDetails: acceptedDetails.add,
          ),
        ],
      ),
    ));

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsNothing);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);

    final Offset secondLocation = tester.getCenter(find.text('Target'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsNothing);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);

    await gesture.up();
    await tester.pump();

    expect(accepted, equals(<int>[1]));
    expect(acceptedDetails, hasLength(1));
    expect(acceptedDetails.first.offset, const Offset(256.0, 26.0));
    expect(find.text('Source'), findsNothing);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
  });

  testWidgets('Tap above long-press draggable works', (WidgetTester tester) async {
    final List<String> events = <String>[];

    await tester.pumpWidget(MaterialApp(
      home: Material(
        child: Center(
          child: GestureDetector(
            onTap: () {
              events.add('tap');
            },
            child: const LongPressDraggable<int>(
              feedback: Text('Feedback'),
              child: Text('X'),
            ),
          ),
        ),
      ),
    ));

    expect(events, isEmpty);
    await tester.tap(find.text('X'));
    expect(events, equals(<String>['tap']));
  });

  testWidgets('long-press draggable calls onDragEnd called if dropped on accepting target', (WidgetTester tester) async {
    final List<int> accepted = <int>[];
    final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
    bool onDragEndCalled = false;
    late DraggableDetails onDragEndDraggableDetails;

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          LongPressDraggable<int>(
            data: 1,
            feedback: const Text('Dragging'),
            onDragEnd: (DraggableDetails details) {
              onDragEndCalled = true;
              onDragEndDraggableDetails = details;
            },
            child: const Text('Source'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const SizedBox(height: 100.0, child: Text('Target'));
            },
            onAccept: accepted.add,
            onAcceptWithDetails: acceptedDetails.add,
          ),
        ],
      ),
    ));

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragEndCalled, isFalse);

    final Offset firstLocation = tester.getCenter(find.text('Source'));
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragEndCalled, isFalse);

    await tester.pump(kLongPressTimeout);

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragEndCalled, isFalse);


    final Offset secondLocation = tester.getCenter(find.text('Target'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragEndCalled, isFalse);

    await gesture.up();
    await tester.pump();

    final Offset droppedLocation = tester.getTopLeft(find.text('Target'));
    final Offset expectedDropOffset = Offset(droppedLocation.dx, secondLocation.dy - firstLocation.dy);

    expect(accepted, equals(<int>[1]));
    expect(acceptedDetails, hasLength(1));
    expect(acceptedDetails.first.offset, expectedDropOffset);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragEndCalled, isTrue);
    expect(onDragEndDraggableDetails, isNotNull);
    expect(onDragEndDraggableDetails.wasAccepted, isTrue);
    expect(onDragEndDraggableDetails.velocity, equals(Velocity.zero));
    expect(onDragEndDraggableDetails.offset, equals(expectedDropOffset));
  });

  testWidgets('long-press draggable calls onDragCompleted called if dropped on accepting target', (WidgetTester tester) async {
    final List<int> accepted = <int>[];
    final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
    bool onDragCompletedCalled = false;

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          LongPressDraggable<int>(
            data: 1,
            feedback: const Text('Dragging'),
            onDragCompleted: () {
              onDragCompletedCalled = true;
            },
            child: const Text('Source'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const SizedBox(height: 100.0, child: Text('Target'));
            },
            onAccept: accepted.add,
            onAcceptWithDetails: acceptedDetails.add,
          ),
        ],
      ),
    ));

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragCompletedCalled, isFalse);

    final Offset firstLocation = tester.getCenter(find.text('Source'));
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragCompletedCalled, isFalse);

    await tester.pump(kLongPressTimeout);

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragCompletedCalled, isFalse);

    final Offset secondLocation = tester.getCenter(find.text('Target'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(accepted, isEmpty);
    expect(acceptedDetails, isEmpty);
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragCompletedCalled, isFalse);

    await gesture.up();
    await tester.pump();

    expect(accepted, equals(<int>[1]));
    expect(acceptedDetails.first.offset, const Offset(256.0, 74.0));
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(find.text('Target'), findsOneWidget);
    expect(onDragCompletedCalled, isTrue);
  });

  testWidgets('long-press draggable calls onDragStartedCalled after long press', (WidgetTester tester) async {
    bool onDragStartedCalled = false;

    await tester.pumpWidget(MaterialApp(
      home: LongPressDraggable<int>(
        data: 1,
        feedback: const Text('Dragging'),
        onDragStarted: () {
          onDragStartedCalled = true;
        },
        child: const Text('Source'),
      ),
    ));

    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(onDragStartedCalled, isFalse);

    final Offset firstLocation = tester.getCenter(find.text('Source'));
    await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(onDragStartedCalled, isFalse);

    await tester.pump(kLongPressTimeout);

    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(onDragStartedCalled, isTrue);
  });

  testWidgets('Custom long press delay for LongPressDraggable', (WidgetTester tester) async {
    bool onDragStartedCalled = false;
    await tester.pumpWidget(MaterialApp(
      home: LongPressDraggable<int>(
        data: 1,
        delay: const Duration(seconds: 2),
        feedback: const Text('Dragging'),
        onDragStarted: () {
          onDragStartedCalled = true;
        },
        child: const Text('Source'),
      ),
    ));
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(onDragStartedCalled, isFalse);
    final Offset firstLocation = tester.getCenter(find.text('Source'));
    await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(onDragStartedCalled, isFalse);
    // Halfway into the long press duration.
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(onDragStartedCalled, isFalse);
    // Long press draggable should be showing.
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(onDragStartedCalled, isTrue);
  });

  testWidgets('Default long press delay for LongPressDraggable', (WidgetTester tester) async {
    bool onDragStartedCalled = false;
    await tester.pumpWidget(MaterialApp(
      home: LongPressDraggable<int>(
        data: 1,
        feedback: const Text('Dragging'),
        onDragStarted: () {
          onDragStartedCalled = true;
        },
        child: const Text('Source'),
      ),
    ));
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(onDragStartedCalled, isFalse);
    final Offset firstLocation = tester.getCenter(find.text('Source'));
    await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(onDragStartedCalled, isFalse);
    // Halfway into the long press duration.
    await tester.pump(const Duration(milliseconds: 250));
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsNothing);
    expect(onDragStartedCalled, isFalse);
    // Long press draggable should be showing.
    await tester.pump(const Duration(milliseconds: 250));
    expect(find.text('Source'), findsOneWidget);
    expect(find.text('Dragging'), findsOneWidget);
    expect(onDragStartedCalled, isTrue);
  });

  testWidgets('long-press draggable calls Haptic Feedback onStart', (WidgetTester tester) async {
    await _testLongPressDraggableHapticFeedback(tester: tester, hapticFeedbackOnStart: true, expectedHapticFeedbackCount: 1);
  });

  testWidgets('long-press draggable can disable Haptic Feedback', (WidgetTester tester) async {
    await _testLongPressDraggableHapticFeedback(tester: tester, hapticFeedbackOnStart: false, expectedHapticFeedbackCount: 0);
  });

  testWidgets('Drag feedback with child anchor positions correctly', (WidgetTester tester) async {
    await _testChildAnchorFeedbackPosition(tester: tester);
  });

  testWidgets('Drag feedback with child anchor within a non-global Overlay positions correctly', (WidgetTester tester) async {
    await _testChildAnchorFeedbackPosition(tester: tester, left: 100.0, top: 100.0);
  });

  testWidgets('Drag feedback is put on root overlay with [rootOverlay] flag', (WidgetTester tester) async {
      final GlobalKey<NavigatorState> rootNavigatorKey = GlobalKey<NavigatorState>();
      final GlobalKey<NavigatorState> childNavigatorKey = GlobalKey<NavigatorState>();
      // Create a [MaterialApp], with a nested [Navigator], which has the
      // [Draggable].
      await tester.pumpWidget(MaterialApp(
        navigatorKey: rootNavigatorKey,
        home: Column(
          children: <Widget>[
            SizedBox(
              height: 200.0,
              child: Navigator(
                key: childNavigatorKey,
                onGenerateRoute: (RouteSettings settings) {
                  if (settings.name == '/') {
                    return MaterialPageRoute<void>(
                      settings: settings,
                      builder: (BuildContext context) => const Draggable<int>(
                        data: 1,
                        feedback: Text('Dragging'),
                        rootOverlay: true,
                        child: Text('Source'),
                      ),
                    );
                  }
                  throw UnsupportedError('Unsupported route: $settings');
                },
              ),
            ),
            DragTarget<int>(
              builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
                return const SizedBox(
                    height: 300.0, child: Center(child: Text('Target 1')),
                );
              },
            ),
          ],
        ),
      ));

      final Offset firstLocation = tester.getCenter(find.text('Source'));
      final TestGesture gesture =
          await tester.startGesture(firstLocation, pointer: 7);
      await tester.pump();

      final Offset secondLocation = tester.getCenter(find.text('Target 1'));
      await gesture.moveTo(secondLocation);
      await tester.pump();

      // Expect that the feedback widget is a descendant of the root overlay,
      // but not a descendant of the child overlay.
      expect(
        find.descendant(
          of: find.byType(Overlay).first,
          matching: find.text('Dragging'),
        ),
        findsOneWidget,
      );
      expect(
        find.descendant(
          of: find.byType(Overlay).last,
          matching: find.text('Dragging'),
        ),
        findsNothing,
      );
    });

  // Regression test for https://github.com/flutter/flutter/issues/72483
  testWidgets('Drag and drop - DragTarget<Object> can accept Draggable<int> data', (WidgetTester tester) async {
    final List<Object> accepted = <Object>[];
    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          const Draggable<int>(
            data: 1,
            feedback: Text('Dragging'),
            child: Text('Source'),
          ),
          DragTarget<Object>(
            builder: (BuildContext context, List<Object?> data, List<dynamic> rejects) {
              return const SizedBox(height: 100.0, child: Text('Target'));
            },
            onAccept: accepted.add,
          ),
        ],
      ),
    ));

    expect(accepted, isEmpty);

    final Offset firstLocation = tester.getCenter(find.text('Source'));
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    final Offset secondLocation = tester.getCenter(find.text('Target'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    await gesture.up();
    await tester.pump();

    expect(accepted, equals(<int>[1]));
  });

  testWidgets('Drag and drop - DragTarget<int> can accept Draggable<Object> data when runtime type is int', (WidgetTester tester) async {
    final List<int> accepted = <int>[];
    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          const Draggable<Object>(
            data: 1,
            feedback: Text('Dragging'),
            child: Text('Source'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const SizedBox(height: 100.0, child: Text('Target'));
            },
            onAccept: accepted.add,
          ),
        ],
      ),
    ));

    expect(accepted, isEmpty);

    final Offset firstLocation = tester.getCenter(find.text('Source'));
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    final Offset secondLocation = tester.getCenter(find.text('Target'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    await gesture.up();
    await tester.pump();

    expect(accepted, equals(<int>[1]));
  });

  testWidgets('Drag and drop - DragTarget<int> should not accept Draggable<Object> data when runtime type null', (WidgetTester tester) async {
    final List<int> accepted = <int>[];
    bool isReceiveNullDataForCheck = false;
    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          const Draggable<Object>(
            feedback: Text('Dragging'),
            child: Text('Source'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
              return const SizedBox(height: 100.0, child: Text('Target'));
            },
            onAccept: accepted.add,
            onWillAccept: (int? data) {
              if (data == null)
                isReceiveNullDataForCheck = true;
              return data != null;
            },
          ),
        ],
      ),
    ));

    expect(accepted, isEmpty);

    final Offset firstLocation = tester.getCenter(find.text('Source'));
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();

    final Offset secondLocation = tester.getCenter(find.text('Target'));
    await gesture.moveTo(secondLocation);
    await tester.pump();

    await gesture.up();
    await tester.pump();

    expect(accepted, isEmpty);
    expect(isReceiveNullDataForCheck, true);
  });

  testWidgets('Drag and drop can contribute semantics', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);
    await tester.pumpWidget(MaterialApp(
        home: ListView(
          scrollDirection: Axis.horizontal,
          addSemanticIndexes: false,
          children: <Widget>[
            DragTarget<int>(
              builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
                return const Text('Target');
              },
            ),
            Container(width: 400.0),
            const Draggable<int>(
              data: 1,
              feedback: Text('H'),
              childWhenDragging: SizedBox(),
              axis: Axis.horizontal,
              ignoringFeedbackSemantics: false,
              child: Text('H'),
            ),
            const Draggable<int>(
              data: 2,
              feedback: Text('V'),
              childWhenDragging: SizedBox(),
              axis: Axis.vertical,
              ignoringFeedbackSemantics: false,
              child: Text('V'),
            ),
            const Draggable<int>(
              data: 3,
              feedback: Text('N'),
              childWhenDragging: SizedBox(),
              child: Text('N'),
            ),
          ],
        ),
    ));

    expect(semantics, hasSemantics(
      TestSemantics.root(
        children: <TestSemantics>[
          TestSemantics(
            id: 1,
            textDirection: TextDirection.ltr,
            children: <TestSemantics>[
              TestSemantics(
                id: 2,
                children: <TestSemantics>[
                  TestSemantics(
                    id: 3,
                    flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
                    children: <TestSemantics>[
                      TestSemantics(
                        id: 4,
                        children: <TestSemantics>[
                          TestSemantics(
                            id: 9,
                            flags: <SemanticsFlag>[SemanticsFlag.hasImplicitScrolling],
                            actions: <SemanticsAction>[SemanticsAction.scrollLeft],
                            children: <TestSemantics>[
                              TestSemantics(
                                id: 5,
                                tags: <SemanticsTag>[const SemanticsTag('RenderViewport.twoPane')],
                                label: 'Target',
                                textDirection: TextDirection.ltr,
                              ),
                              TestSemantics(
                                id: 6,
                                tags: <SemanticsTag>[const SemanticsTag('RenderViewport.twoPane')],
                                label: 'H',
                                textDirection: TextDirection.ltr,
                              ),
                              TestSemantics(
                                id: 7,
                                tags: <SemanticsTag>[const SemanticsTag('RenderViewport.twoPane')],
                                label: 'V',
                                textDirection: TextDirection.ltr,
                              ),
                              TestSemantics(
                                id: 8,
                                tags: <SemanticsTag>[const SemanticsTag('RenderViewport.twoPane')],
                                label: 'N',
                                textDirection: TextDirection.ltr,
                              ),
                            ],
                          ),
                        ],
                      ),
                    ],
                  ),
                ],
              ),
            ],
          ),
        ],
      ),
      ignoreTransform: true,
      ignoreRect: true,
    ));

    final Offset firstLocation = tester.getTopLeft(find.text('N'));
    final Offset secondLocation = firstLocation + const Offset(300.0, 300.0);
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    await tester.pump();
    await gesture.moveTo(secondLocation);
    await tester.pump();

    expect(semantics, hasSemantics(
      TestSemantics.root(
        children: <TestSemantics>[
          TestSemantics(
            id: 1,
            textDirection: TextDirection.ltr,
            children: <TestSemantics>[
              TestSemantics(
                id: 2,
                children: <TestSemantics>[
                  TestSemantics(
                    id: 3,
                    flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
                    children: <TestSemantics>[
                      TestSemantics(
                        id: 4,
                        children: <TestSemantics>[
                          TestSemantics(
                            id: 9,
                            flags: <SemanticsFlag>[SemanticsFlag.hasImplicitScrolling],
                            children: <TestSemantics>[
                              TestSemantics(
                                id: 5,
                                tags: <SemanticsTag>[const SemanticsTag('RenderViewport.twoPane')],
                                label: 'Target',
                                textDirection: TextDirection.ltr,
                              ),
                              TestSemantics(
                                id: 6,
                                tags: <SemanticsTag>[const SemanticsTag('RenderViewport.twoPane')],
                                label: 'H',
                                textDirection: TextDirection.ltr,
                              ),
                              TestSemantics(
                                id: 7,
                                tags: <SemanticsTag>[const SemanticsTag('RenderViewport.twoPane')],
                                label: 'V',
                                textDirection: TextDirection.ltr,
                              ),
                              /// N is moved offscreen.
                            ],
                          ),
                        ],
                      ),
                    ],
                  ),
                ],
              ),
            ],
          ),
        ],
      ),
      ignoreTransform: true,
      ignoreRect: true,
    ));
    semantics.dispose();
  });

  testWidgets('Drag and drop - when a dragAnchorStrategy is provided it gets called', (WidgetTester tester) async {
    bool dragAnchorStrategyCalled = false;

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          Draggable<int>(
            feedback: const Text('Feedback'),
            dragAnchorStrategy: (Draggable<Object> widget, BuildContext context, Offset position) {
              dragAnchorStrategyCalled = true;
              return Offset.zero;
            },
            child: const Text('Source'),
          ),
        ],
      ),
    ));

    final Offset location = tester.getCenter(find.text('Source'));
    await tester.startGesture(location, pointer: 7);

    expect(dragAnchorStrategyCalled, true);
  });

  testWidgets('configurable Draggable hit test behavior', (WidgetTester tester) async {
    const HitTestBehavior hitTestBehavior = HitTestBehavior.deferToChild;

    await tester.pumpWidget(
      MaterialApp(
        home: Column(
          children: const <Widget>[
            Draggable<int>(
              feedback: SizedBox(height: 50.0, child: Text('Draggable')),
              child: SizedBox(height: 50.0, child: Text('Target')),
            ),
          ],
        ),
      ),
    );

    expect(tester.widget<Listener>(find.byType(Listener).first).behavior, hitTestBehavior);
  });

  testWidgets('configurable DragTarget hit test behavior', (WidgetTester tester) async {
    const HitTestBehavior hitTestBehavior = HitTestBehavior.deferToChild;

    await tester.pumpWidget(
      MaterialApp(
        home: Column(
          children: <Widget>[
            DragTarget<int>(
              hitTestBehavior: hitTestBehavior,
              builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
                return const SizedBox(height: 100.0, child: Text('Target'));
              },
            ),
          ],
        ),
      ),
    );

    expect(tester.widget<MetaData>(find.byType(MetaData)).behavior, hitTestBehavior);
  });

  testWidgets('LongPressDraggable.dragAnchorStrategy', (WidgetTester tester) async {
    const Widget widget1 = Placeholder(key: ValueKey<int>(1));
    const Widget widget2 = Placeholder(key: ValueKey<int>(2));
    Offset dummyStrategy(Draggable<Object> draggable, BuildContext context, Offset position) => Offset.zero;
    expect(const LongPressDraggable<int>(feedback: widget2, child: widget1), isA<Draggable<int>>());
    expect(const LongPressDraggable<int>(feedback: widget2, child: widget1).child, widget1);
    expect(const LongPressDraggable<int>(feedback: widget2, child: widget1).feedback, widget2);
    expect(const LongPressDraggable<int>(feedback: widget2, child: widget1).dragAnchor, DragAnchor.child);
    expect(const LongPressDraggable<int>(feedback: widget2, dragAnchor: DragAnchor.pointer, child: widget1).dragAnchor, DragAnchor.pointer);
    expect(LongPressDraggable<int>(feedback: widget2, dragAnchorStrategy: dummyStrategy, child: widget1).dragAnchorStrategy, dummyStrategy);
  });
}

Future<void> _testLongPressDraggableHapticFeedback({ required WidgetTester tester, required bool hapticFeedbackOnStart, required int expectedHapticFeedbackCount }) async {
  bool onDragStartedCalled = false;

  int hapticFeedbackCalls = 0;
  tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
    if (methodCall.method == 'HapticFeedback.vibrate') {
      hapticFeedbackCalls++;
    }
  });

  await tester.pumpWidget(MaterialApp(
    home: LongPressDraggable<int>(
      data: 1,
      feedback: const Text('Dragging'),
      hapticFeedbackOnStart: hapticFeedbackOnStart,
      onDragStarted: () {
        onDragStartedCalled = true;
      },
      child: const Text('Source'),
    ),
  ));

  expect(find.text('Source'), findsOneWidget);
  expect(find.text('Dragging'), findsNothing);
  expect(onDragStartedCalled, isFalse);

  final Offset firstLocation = tester.getCenter(find.text('Source'));
  await tester.startGesture(firstLocation, pointer: 7);
  await tester.pump();

  expect(find.text('Source'), findsOneWidget);
  expect(find.text('Dragging'), findsNothing);
  expect(onDragStartedCalled, isFalse);

  await tester.pump(kLongPressTimeout);

  expect(find.text('Source'), findsOneWidget);
  expect(find.text('Dragging'), findsOneWidget);
  expect(onDragStartedCalled, isTrue);
  expect(hapticFeedbackCalls, expectedHapticFeedbackCount);
}

Future<void> _testChildAnchorFeedbackPosition({ required WidgetTester tester, double top = 0.0, double left = 0.0 }) async {
  final List<int> accepted = <int>[];
  final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
  int dragStartedCount = 0;

  await tester.pumpWidget(
    Stack(
      textDirection: TextDirection.ltr,
      children: <Widget>[
        Positioned(
          left: left,
          top: top,
          right: 0.0,
          bottom: 0.0,
          child: MaterialApp(
            home: Column(
              children: <Widget>[
                Draggable<int>(
                  data: 1,
                  feedback: const Text('Dragging'),
                  onDragStarted: () {
                    ++dragStartedCount;
                  },
                  child: const Text('Source'),
                ),
                DragTarget<int>(
                  builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
                    return const SizedBox(height: 100.0, child: Text('Target'));
                  },
                  onAccept: accepted.add,
                  onAcceptWithDetails: acceptedDetails.add,
                ),
              ],
            ),
          ),
        ),
      ],
    ),
  );

  expect(accepted, isEmpty);
  expect(acceptedDetails, isEmpty);
  expect(find.text('Source'), findsOneWidget);
  expect(find.text('Dragging'), findsNothing);
  expect(find.text('Target'), findsOneWidget);
  expect(dragStartedCount, 0);

  final Offset firstLocation = tester.getCenter(find.text('Source'));
  final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
  await tester.pump();

  expect(accepted, isEmpty);
  expect(acceptedDetails, isEmpty);
  expect(find.text('Source'), findsOneWidget);
  expect(find.text('Dragging'), findsOneWidget);
  expect(find.text('Target'), findsOneWidget);
  expect(dragStartedCount, 1);


  final Offset secondLocation = tester.getBottomRight(find.text('Target'));
  await gesture.moveTo(secondLocation);
  await tester.pump();

  expect(accepted, isEmpty);
  expect(acceptedDetails, isEmpty);
  expect(find.text('Source'), findsOneWidget);
  expect(find.text('Dragging'), findsOneWidget);
  expect(find.text('Target'), findsOneWidget);
  expect(dragStartedCount, 1);

  final Offset feedbackTopLeft = tester.getTopLeft(find.text('Dragging'));
  final Offset sourceTopLeft = tester.getTopLeft(find.text('Source'));
  final Offset dragOffset = secondLocation - firstLocation;
  expect(feedbackTopLeft, equals(sourceTopLeft + dragOffset));
}

class DragTargetData { }

class ExtendedDragTargetData extends DragTargetData { }
