// Copyright 2015 The Chromium 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_test/flutter_test.dart'; import 'package:flutter/material.dart'; import 'package:test/test.dart'; void main() { test('Drag and drop - control test', () { testWidgets((WidgetTester tester) { List<dynamic> accepted = <dynamic>[]; tester.pumpWidget(new MaterialApp( routes: <String, WidgetBuilder>{ '/': (BuildContext context) { return new Column( children: <Widget>[ new Draggable<int>( data: 1, child: new Text('Source'), feedback: new Text('Dragging') ), new DragTarget<int>( builder: (BuildContext context, List<int> data, List<dynamic> rejects) { return new Container( height: 100.0, child: new Text('Target') ); }, onAccept: (int data) { accepted.add(data); } ), ]); }, } )); expect(accepted, isEmpty); expect(tester.findText('Source'), isNotNull); expect(tester.findText('Dragging'), isNull); expect(tester.findText('Target'), isNotNull); Point firstLocation = tester.getCenter(tester.findText('Source')); TestGesture gesture = tester.startGesture(firstLocation, pointer: 7); tester.pump(); expect(accepted, isEmpty); expect(tester.findText('Source'), isNotNull); expect(tester.findText('Dragging'), isNotNull); expect(tester.findText('Target'), isNotNull); Point secondLocation = tester.getCenter(tester.findText('Target')); gesture.moveTo(secondLocation); tester.pump(); expect(accepted, isEmpty); expect(tester.findText('Source'), isNotNull); expect(tester.findText('Dragging'), isNotNull); expect(tester.findText('Target'), isNotNull); gesture.up(); tester.pump(); expect(accepted, equals([1])); expect(tester.findText('Source'), isNotNull); expect(tester.findText('Dragging'), isNull); expect(tester.findText('Target'), isNotNull); }); }); test('Drag and drop - dragging over button', () { testWidgets((WidgetTester tester) { List<String> events = <String>[]; Point firstLocation, secondLocation; tester.pumpWidget(new MaterialApp( routes: <String, WidgetBuilder>{ '/': (BuildContext context) { return new Column( children: <Widget>[ new Draggable<int>( data: 1, child: new Text('Source'), feedback: new Text('Dragging') ), new Stack( children: <Widget>[ new GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { events.add('tap'); }, child: new Container( child: new Text('Button') ) ), new DragTarget<int>( builder: (BuildContext context, List<int> data, List<dynamic> rejects) { return new IgnorePointer( child: new Container( child: new Text('Target') ) ); }, onAccept: (int data) { events.add('drop'); } ), ] ), ]); }, } )); expect(events, isEmpty); expect(tester.findText('Source'), isNotNull); expect(tester.findText('Dragging'), isNull); expect(tester.findText('Target'), isNotNull); expect(tester.findText('Button'), isNotNull); // taps (we check both to make sure the test is consistent) expect(events, isEmpty); tester.tap(tester.findText('Button')); expect(events, equals(<String>['tap'])); events.clear(); expect(events, isEmpty); tester.tap(tester.findText('Target')); expect(events, equals(<String>['tap'])); events.clear(); // drag and drop firstLocation = tester.getCenter(tester.findText('Source')); TestGesture gesture = tester.startGesture(firstLocation, pointer: 7); tester.pump(); secondLocation = tester.getCenter(tester.findText('Target')); gesture.moveTo(secondLocation); tester.pump(); expect(events, isEmpty); gesture.up(); tester.pump(); expect(events, equals(<String>['drop'])); events.clear(); // drag and tap and drop firstLocation = tester.getCenter(tester.findText('Source')); gesture = tester.startGesture(firstLocation, pointer: 7); tester.pump(); secondLocation = tester.getCenter(tester.findText('Target')); gesture.moveTo(secondLocation); tester.pump(); expect(events, isEmpty); tester.tap(tester.findText('Button')); tester.tap(tester.findText('Target')); gesture.up(); tester.pump(); expect(events, equals(<String>['tap', 'tap', 'drop'])); events.clear(); }); }); test('Drag and drop - tapping button', () { testWidgets((WidgetTester tester) { List<String> events = <String>[]; Point firstLocation, secondLocation; tester.pumpWidget(new MaterialApp( routes: <String, WidgetBuilder>{ '/': (BuildContext context) { return new Column( children: <Widget>[ new Draggable<int>( data: 1, child: new GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { events.add('tap'); }, child: new Container( child: new Text('Button') ) ), feedback: new Text('Dragging') ), new DragTarget<int>( builder: (BuildContext context, List<int> data, List<dynamic> rejects) { return new Text('Target'); }, onAccept: (int data) { events.add('drop'); } ), ]); }, } )); expect(events, isEmpty); expect(tester.findText('Button'), isNotNull); expect(tester.findText('Target'), isNotNull); expect(events, isEmpty); tester.tap(tester.findText('Button')); expect(events, equals(<String>['tap'])); events.clear(); firstLocation = tester.getCenter(tester.findText('Button')); TestGesture gesture = tester.startGesture(firstLocation, pointer: 7); tester.pump(); secondLocation = tester.getCenter(tester.findText('Target')); gesture.moveTo(secondLocation); tester.pump(); expect(events, isEmpty); gesture.up(); tester.pump(); expect(events, equals(<String>['drop'])); events.clear(); }); }); test('Drag and drop - long press draggable, short press', () { testWidgets((WidgetTester tester) { List<String> events = <String>[]; Point firstLocation, secondLocation; tester.pumpWidget(new MaterialApp( routes: <String, WidgetBuilder>{ '/': (BuildContext context) { return new Column( children: <Widget>[ new LongPressDraggable<int>( data: 1, child: new Text('Source'), feedback: new Text('Dragging') ), new DragTarget<int>( builder: (BuildContext context, List<int> data, List<dynamic> rejects) { return new Text('Target'); }, onAccept: (int data) { events.add('drop'); } ), ]); }, } )); expect(events, isEmpty); expect(tester.findText('Source'), isNotNull); expect(tester.findText('Target'), isNotNull); expect(events, isEmpty); tester.tap(tester.findText('Source')); expect(events, isEmpty); firstLocation = tester.getCenter(tester.findText('Source')); TestGesture gesture = tester.startGesture(firstLocation, pointer: 7); tester.pump(); secondLocation = tester.getCenter(tester.findText('Target')); gesture.moveTo(secondLocation); tester.pump(); expect(events, isEmpty); gesture.up(); tester.pump(); expect(events, isEmpty); }); }); test('Drag and drop - long press draggable, long press', () { testWidgets((WidgetTester tester) { List<String> events = <String>[]; Point firstLocation, secondLocation; tester.pumpWidget(new MaterialApp( routes: <String, WidgetBuilder>{ '/': (BuildContext context) { return new Column( children: <Widget>[ new Draggable<int>( data: 1, child: new Text('Source'), feedback: new Text('Dragging') ), new DragTarget<int>( builder: (BuildContext context, List<int> data, List<dynamic> rejects) { return new Text('Target'); }, onAccept: (int data) { events.add('drop'); } ), ]); }, } )); expect(events, isEmpty); expect(tester.findText('Source'), isNotNull); expect(tester.findText('Target'), isNotNull); expect(events, isEmpty); tester.tap(tester.findText('Source')); expect(events, isEmpty); firstLocation = tester.getCenter(tester.findText('Source')); TestGesture gesture = tester.startGesture(firstLocation, pointer: 7); tester.pump(); tester.pump(const Duration(seconds: 20)); secondLocation = tester.getCenter(tester.findText('Target')); gesture.moveTo(secondLocation); tester.pump(); expect(events, isEmpty); gesture.up(); tester.pump(); expect(events, equals(<String>['drop'])); }); }); test('Drag and drop - horizontal and vertical draggables in vertical block', () { testWidgets((WidgetTester tester) { List<String> events = <String>[]; Point firstLocation, secondLocation, thirdLocation; tester.pumpWidget(new MaterialApp( routes: <String, WidgetBuilder>{ '/': (BuildContext context) { return new Block( children: <Widget>[ new DragTarget<int>( builder: (BuildContext context, List<int> data, List<dynamic> rejects) { return new Text('Target'); }, onAccept: (int data) { events.add('drop $data'); } ), new Container(height: 400.0), new HorizontalDraggable<int>( data: 1, child: new Text('H'), feedback: new Text('Dragging') ), new VerticalDraggable<int>( data: 2, child: new Text('V'), feedback: new Text('Dragging') ), new Container(height: 500.0), new Container(height: 500.0), new Container(height: 500.0), new Container(height: 500.0), ] ); }, } )); expect(events, isEmpty); expect(tester.findText('Target'), isNotNull); expect(tester.findText('H'), isNotNull); expect(tester.findText('V'), isNotNull); // vertical draggable drags vertically expect(events, isEmpty); firstLocation = tester.getCenter(tester.findText('V')); secondLocation = tester.getCenter(tester.findText('Target')); TestGesture gesture = tester.startGesture(firstLocation, pointer: 7); tester.pump(); gesture.moveTo(secondLocation); tester.pump(); gesture.up(); tester.pump(); expect(events, equals(<String>['drop 2'])); expect(tester.getCenter(tester.findText('Target')).y, greaterThan(0.0)); events.clear(); // horizontal draggable drags horizontally expect(events, isEmpty); firstLocation = tester.getTopLeft(tester.findText('H')); secondLocation = tester.getTopRight(tester.findText('H')); thirdLocation = tester.getCenter(tester.findText('Target')); gesture = tester.startGesture(firstLocation, pointer: 7); tester.pump(); gesture.moveTo(secondLocation); tester.pump(); gesture.moveTo(thirdLocation); tester.pump(); gesture.up(); tester.pump(); expect(events, equals(<String>['drop 1'])); expect(tester.getCenter(tester.findText('Target')).y, greaterThan(0.0)); events.clear(); // vertical draggable drags horizontally when there's no competition // from other gesture detectors expect(events, isEmpty); firstLocation = tester.getTopLeft(tester.findText('V')); secondLocation = tester.getTopRight(tester.findText('V')); thirdLocation = tester.getCenter(tester.findText('Target')); gesture = tester.startGesture(firstLocation, pointer: 7); tester.pump(); gesture.moveTo(secondLocation); tester.pump(); gesture.moveTo(thirdLocation); tester.pump(); gesture.up(); tester.pump(); expect(events, equals(<String>['drop 2'])); expect(tester.getCenter(tester.findText('Target')).y, greaterThan(0.0)); events.clear(); // horizontal draggable doesn't drag vertically when there is competition // for vertical gestures expect(events, isEmpty); firstLocation = tester.getCenter(tester.findText('H')); secondLocation = tester.getCenter(tester.findText('Target')); gesture = tester.startGesture(firstLocation, pointer: 7); tester.pump(); gesture.moveTo(secondLocation); tester.pump(); // scrolls off screen! gesture.up(); tester.pump(); expect(events, equals(<String>[])); expect(tester.getCenter(tester.findText('Target')).y, lessThan(0.0)); events.clear(); }); }); test('Drag and drop - horizontal and vertical draggables in horizontal block', () { testWidgets((WidgetTester tester) { List<String> events = <String>[]; Point firstLocation, secondLocation, thirdLocation; tester.pumpWidget(new MaterialApp( routes: <String, WidgetBuilder>{ '/': (BuildContext context) { return new Block( scrollDirection: Axis.horizontal, children: <Widget>[ new DragTarget<int>( builder: (BuildContext context, List<int> data, List<dynamic> rejects) { return new Text('Target'); }, onAccept: (int data) { events.add('drop $data'); } ), new Container(width: 400.0), new HorizontalDraggable<int>( data: 1, child: new Text('H'), feedback: new Text('Dragging') ), new VerticalDraggable<int>( data: 2, child: new Text('V'), feedback: new Text('Dragging') ), new Container(width: 500.0), new Container(width: 500.0), new Container(width: 500.0), new Container(width: 500.0), ] ); }, } )); expect(events, isEmpty); expect(tester.findText('Target'), isNotNull); expect(tester.findText('H'), isNotNull); expect(tester.findText('V'), isNotNull); // horizontal draggable drags horizontally expect(events, isEmpty); firstLocation = tester.getCenter(tester.findText('H')); secondLocation = tester.getCenter(tester.findText('Target')); TestGesture gesture = tester.startGesture(firstLocation, pointer: 7); tester.pump(); gesture.moveTo(secondLocation); tester.pump(); gesture.up(); tester.pump(); expect(events, equals(<String>['drop 1'])); expect(tester.getCenter(tester.findText('Target')).x, greaterThan(0.0)); events.clear(); // vertical draggable drags vertically expect(events, isEmpty); firstLocation = tester.getTopLeft(tester.findText('V')); secondLocation = tester.getBottomLeft(tester.findText('V')); thirdLocation = tester.getCenter(tester.findText('Target')); gesture = tester.startGesture(firstLocation, pointer: 7); tester.pump(); gesture.moveTo(secondLocation); tester.pump(); gesture.moveTo(thirdLocation); tester.pump(); gesture.up(); tester.pump(); expect(events, equals(<String>['drop 2'])); expect(tester.getCenter(tester.findText('Target')).x, greaterThan(0.0)); events.clear(); // horizontal draggable drags vertically when there's no competition // from other gesture detectors expect(events, isEmpty); firstLocation = tester.getTopLeft(tester.findText('H')); secondLocation = tester.getBottomLeft(tester.findText('H')); thirdLocation = tester.getCenter(tester.findText('Target')); gesture = tester.startGesture(firstLocation, pointer: 7); tester.pump(); gesture.moveTo(secondLocation); tester.pump(); gesture.moveTo(thirdLocation); tester.pump(); gesture.up(); tester.pump(); expect(events, equals(<String>['drop 1'])); expect(tester.getCenter(tester.findText('Target')).x, greaterThan(0.0)); events.clear(); // vertical draggable doesn't drag horizontally when there is competition // for horizontal gestures expect(events, isEmpty); firstLocation = tester.getCenter(tester.findText('V')); secondLocation = tester.getCenter(tester.findText('Target')); gesture = tester.startGesture(firstLocation, pointer: 7); tester.pump(); gesture.moveTo(secondLocation); tester.pump(); // scrolls off screen! gesture.up(); tester.pump(); expect(events, equals(<String>[])); expect(tester.getCenter(tester.findText('Target')).x, lessThan(0.0)); events.clear(); }); }); }