// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          Draggable<int>(
            data: 1,
            child: const Text('Source'),
            feedback: const Text('Dragging'),
            onDragStarted: () {
              ++dragStartedCount;
            },
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
              return Container(height: 100.0, child: const 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.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);

    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);
  });

  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,
            child: Text('Source'),
            feedback: Text('Dragging'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
              return Container(height: 100.0, child: const 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 Container(height: 100.0, child: const 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));
  });

  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,
            child: Text('Source'),
            feedback: Text('Dragging'),
          ),
          Stack(
            children: <Widget>[
              GestureDetector(
                behavior: HitTestBehavior.opaque,
                onTap: () {
                  events.add('tap');
                },
                child: Container(
                  child: const Text('Button'),
                ),
              ),
              DragTarget<int>(
                builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
                  return IgnorePointer(
                    child: Container(child: 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('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'));
    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'));
    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,
            child: GestureDetector(
              behavior: HitTestBehavior.opaque,
              onTap: () {
                events.add('tap');
              },
              child: Container(child: const Text('Button')),
            ),
            feedback: const Text('Dragging'),
          ),
          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,
            child: Text('Source'),
            feedback: Text('Dragging'),
          ),
          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,
            child: Text('Source'),
            feedback: Text('Dragging'),
          ),
          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,
            child: Text('H'),
            feedback: Text('Dragging'),
            affinity: Axis.horizontal,
          ),
          const Draggable<int>(
            data: 2,
            child: Text('V'),
            feedback: Text('Dragging'),
            affinity: Axis.vertical,
          ),
          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,
            child: Text('H'),
            feedback: Text('Dragging'),
            affinity: Axis.horizontal,
          ),
          const Draggable<int>(
            data: 2,
            child: Text('V'),
            feedback: Text('Dragging'),
            affinity: Axis.vertical,
          ),
          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,
              child: Text('H'),
              feedback: Text('H'),
              childWhenDragging: SizedBox(),
              axis: Axis.horizontal,
            ),
            const Draggable<int>(
              data: 2,
              child: Text('V'),
              feedback: Text('V'),
              childWhenDragging: SizedBox(),
              axis: Axis.vertical,
            ),
            const Draggable<int>(
              data: 3,
              child: Text('N'),
              feedback: Text('N'),
              childWhenDragging: SizedBox(),
            ),
            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);
    });
  });


  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,
            child: const Text('Source'),
            feedback: const Text('Dragging'),
            onDraggableCanceled: (Velocity velocity, Offset offset) {
              onDraggableCanceledCalled = true;
            },
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
              return Container(height: 100.0, child: const 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;
    Velocity onDraggableCanceledVelocity;
    Offset onDraggableCanceledOffset;

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          Draggable<int>(
            data: 1,
            child: const Text('Source'),
            feedback: const Text('Dragging'),
            onDraggableCanceled: (Velocity velocity, Offset offset) {
              onDraggableCanceledCalled = true;
              onDraggableCanceledVelocity = velocity;
              onDraggableCanceledOffset = offset;
            },
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
              return Container(
                height: 100.0,
                child: const 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;
    Velocity onDraggableCanceledVelocity;
    Offset onDraggableCanceledOffset;

    await tester.pumpWidget(MaterialApp(
      home: Column(children: <Widget>[
        Draggable<int>(
          data: 1,
          child: const Text('Source'),
          feedback: const Text('Source'),
          onDraggableCanceled: (Velocity velocity, Offset offset) {
            onDraggableCanceledCalled = true;
            onDraggableCanceledVelocity = velocity;
            onDraggableCanceledOffset = offset;
          },
        ),
        DragTarget<int>(
          builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
            return Container(
              height: 100.0,
              child: const 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;
    DraggableDetails onDragEndDraggableDetails;
    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          Draggable<int>(
            data: 1,
            child: const Text('Source'),
            feedback: const Text('Dragging'),
            onDragEnd: (DraggableDetails details) {
              onDragEndCalled = true;
              onDragEndDraggableDetails = details;
            },
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
              return Container(
                height: 100.0,
                child: const 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,
            child: Text('Source'),
            feedback: Text('Dragging'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
              return Container(
                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,
            child: const Text('Source'),
            feedback: const Text('Dragging'),
          onDraggableCanceled: (Velocity velocity, Offset offset) {
            numberOfTimesOnDraggableCanceledCalled++;
          },
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
              return Container(
                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,
            child: const Text('Source'),
            feedback: const Text('Dragging'),
            onDragCompleted: () {
              onDragCompletedCalled = true;
            },
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
              return Container(
                height: 100.0,
                child: const 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;
    DraggableDetails onDragEndDraggableDetails;
    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          Draggable<int>(
            data: 1,
            child: const Text('Source'),
            feedback: const Text('Dragging'),
            onDragEnd: (DraggableDetails details) {
              onDragEndCalled = true;
              onDragEndDraggableDetails = details;
            },
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
              return Container(height: 100.0, child: const 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,
              child: const Text('Source'),
              feedback: const Text('Dragging'),
              onDragEnd: (DraggableDetails details) {
                timesOnDragEndCalled++;
              },
          ),
          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,
                  child: Text('Source'),
                  feedback: Text('Dragging'),
              ),
            ],
        ),
    ));

    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,
            child: const Text('Source'),
            feedback: const Text('Dragging'),
            onDragCompleted: () {
              onDragCompletedCalled = true;
            },
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
              return Container(height: 100.0, child: const 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 thru 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,
            child: Text('IntSource'),
            feedback: Text('IntDragging'),
          ),
          const Draggable<double>(
            data: 1.0,
            child: Text('DoubleSource'),
            feedback: Text('DoubleDragging'),
          ),
          Stack(
            children: <Widget>[
              DragTarget<int>(
                builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
                  return IgnorePointer(
                    child: Container(
                      height: 100.0,
                      child: const Text('Target1'),
                    ),
                  );
                },
                onAccept: acceptedInts.add,
                onAcceptWithDetails: acceptedIntsDetails.add,
              ),
              DragTarget<double>(
                builder: (BuildContext context, List<double> data, List<dynamic> rejects) {
                  return IgnorePointer(
                    child: Container(
                      height: 100.0,
                      child: const 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 thru 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,
            child: const Text('Source'),
            feedback: const Text('Dragging'),
          ),
          Stack(
            children: <Widget>[
              DragTarget<DragTargetData>(
                builder: (BuildContext context, List<DragTargetData> data, List<dynamic> rejects) {
                  return IgnorePointer(
                    child: Container(
                      height: 100.0,
                      child: const Text('Target1'),
                    ),
                  );
                }, onAccept: acceptedDragTargetDatas.add,
                onAcceptWithDetails: acceptedDragTargetDataDetails.add,
              ),
              DragTarget<ExtendedDragTargetData>(
                builder: (BuildContext context, List<ExtendedDragTargetData> data, List<dynamic> rejects) {
                  return IgnorePointer(
                    child: Container(
                      height: 100.0,
                      child: const 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,
              child: const Text('Source'),
              feedback: const Text('Dragging'),
            ),
            DragTarget<int>(
              builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
                return Container(height: 100.0, child: const 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<dynamic>(
                  child: Container(
                    color: const Color(0xFFFFFF00),
                  ),
                  feedback: Container(
                    width: 100.0,
                    height: 100.0,
                    color: const Color(0xFFFF0000),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );

    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<dynamic>(
                  child: Container(
                    color: const Color(0xFFFFFF00),
                  ),
                  feedback: Container(
                    width: 100.0,
                    height: 100.0,
                    color: const Color(0xFFFF0000),
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );

    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,
            child: Text('Source'),
            feedback: Text('Dragging'),
          ),
          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,
            child: Text('Source'),
            feedback: Text('Dragging'),
          ),
        ],
      ),
    ));

    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,
            child: Text('Source'),
            feedback: Text('Dragging'),
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
              return Container(height: 100.0, child: const 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 Container(height: 100.0, child: const 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;
    DraggableDetails onDragEndDraggableDetails;

    await tester.pumpWidget(MaterialApp(
      home: Column(
        children: <Widget>[
          LongPressDraggable<int>(
            data: 1,
            child: const Text('Source'),
            feedback: const Text('Dragging'),
            onDragEnd: (DraggableDetails details) {
              onDragEndCalled = true;
              onDragEndDraggableDetails = details;
            },
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
              return Container(height: 100.0, child: const 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,
            child: const Text('Source'),
            feedback: const Text('Dragging'),
            onDragCompleted: () {
              onDragCompletedCalled = true;
            },
          ),
          DragTarget<int>(
            builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
              return Container(height: 100.0, child: const 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,
        child: const Text('Source'),
        feedback: const Text('Dragging'),
        onDragStarted: () {
          onDragStartedCalled = true;
        },
      ),
    ));

    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('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 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,
              child: Text('H'),
              feedback: Text('H'),
              childWhenDragging: SizedBox(),
              axis: Axis.horizontal,
              ignoringFeedbackSemantics: false,
            ),
            const Draggable<int>(
              data: 2,
              child: Text('V'),
              feedback: Text('V'),
              childWhenDragging: SizedBox(),
              axis: Axis.vertical,
              ignoringFeedbackSemantics: false,
            ),
            const Draggable<int>(
              data: 3,
              child: Text('N'),
              feedback: Text('N'),
              childWhenDragging: SizedBox(),
            ),
          ],
        ),
    ));

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

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

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

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

  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({ 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,
                  child: const Text('Source'),
                  feedback: const Text('Dragging'),
                  onDragStarted: () {
                    ++dragStartedCount;
                  },
                ),
                DragTarget<int>(
                  builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
                    return Container(height: 100.0, child: const 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 { }
