mirror of
https://github.com/alibaba/flutter-go.git
synced 2025-07-12 16:10:10 +08:00
1811 lines
60 KiB
Dart
1811 lines
60 KiB
Dart
// 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 'dart:async';
|
|
|
|
import 'package:flutter_web_test/flutter_web_test.dart';
|
|
import 'package:flutter_web/material.dart';
|
|
import 'package:flutter_web/gestures.dart';
|
|
|
|
void main() {
|
|
testWidgets('Drag and drop - control test', (WidgetTester tester) async {
|
|
final List<int> accepted = <int>[];
|
|
int dragStartedCount = 0;
|
|
|
|
await tester.pumpWidget(new MaterialApp(
|
|
home: new Column(
|
|
children: <Widget>[
|
|
new Draggable<int>(
|
|
data: 1,
|
|
child: const Text('Source'),
|
|
feedback: const Text('Dragging'),
|
|
onDragStarted: () {
|
|
++dragStartedCount;
|
|
},
|
|
),
|
|
new DragTarget<int>(
|
|
builder:
|
|
(BuildContext context, List<int> data, List<dynamic> rejects) {
|
|
return new Container(height: 100.0, child: const Text('Target'));
|
|
},
|
|
onAccept: accepted.add,
|
|
),
|
|
],
|
|
),
|
|
));
|
|
|
|
expect(accepted, 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(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(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(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(new MaterialApp(
|
|
home: new Column(
|
|
children: <Widget>[
|
|
const Draggable<int>(
|
|
data: 1,
|
|
child: const Text('Source'),
|
|
feedback: const Text('Dragging'),
|
|
),
|
|
new DragTarget<int>(
|
|
builder:
|
|
(BuildContext context, List<int> data, List<dynamic> rejects) {
|
|
return new Container(
|
|
height: 100.0, child: const Text('Target 1'));
|
|
},
|
|
onLeave: (int data) =>
|
|
leftBehind['Target 1'] = leftBehind['Target 1'] + data,
|
|
),
|
|
new DragTarget<int>(
|
|
builder:
|
|
(BuildContext context, List<int> data, List<dynamic> rejects) {
|
|
return new Container(
|
|
height: 100.0, child: const Text('Target 2'));
|
|
},
|
|
onLeave: (int data) =>
|
|
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(new MaterialApp(
|
|
home: new Column(
|
|
children: <Widget>[
|
|
const Draggable<int>(
|
|
data: 1,
|
|
child: const Text('Source'),
|
|
feedback: const Text('Dragging'),
|
|
),
|
|
new Stack(
|
|
children: <Widget>[
|
|
new GestureDetector(
|
|
behavior: HitTestBehavior.opaque,
|
|
onTap: () {
|
|
events.add('tap');
|
|
},
|
|
child: new Container(
|
|
child: const Text('Button'),
|
|
),
|
|
),
|
|
new DragTarget<int>(builder: (BuildContext context,
|
|
List<int> data, List<dynamic> rejects) {
|
|
return new IgnorePointer(
|
|
child: new Container(child: const Text('Target')),
|
|
);
|
|
}, onAccept: (int data) {
|
|
events.add('drop');
|
|
}),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
));
|
|
|
|
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']));
|
|
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']));
|
|
events.clear();
|
|
});
|
|
|
|
testWidgets('Drag and drop - tapping button', (WidgetTester tester) async {
|
|
final List<String> events = <String>[];
|
|
Offset firstLocation, secondLocation;
|
|
|
|
await tester.pumpWidget(new MaterialApp(
|
|
home: new Column(
|
|
children: <Widget>[
|
|
new Draggable<int>(
|
|
data: 1,
|
|
child: new GestureDetector(
|
|
behavior: HitTestBehavior.opaque,
|
|
onTap: () {
|
|
events.add('tap');
|
|
},
|
|
child: new Container(child: const Text('Button')),
|
|
),
|
|
feedback: const Text('Dragging'),
|
|
),
|
|
new DragTarget<int>(
|
|
builder:
|
|
(BuildContext context, List<int> data, List<dynamic> rejects) {
|
|
return const Text('Target',
|
|
style: const TextStyle(fontSize: 24.0));
|
|
},
|
|
onAccept: (int data) {
|
|
events.add('drop');
|
|
},
|
|
),
|
|
],
|
|
),
|
|
));
|
|
|
|
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']));
|
|
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(new MaterialApp(
|
|
home: new Column(
|
|
children: <Widget>[
|
|
const LongPressDraggable<int>(
|
|
data: 1,
|
|
child: const Text('Source'),
|
|
feedback: const Text('Dragging'),
|
|
),
|
|
new DragTarget<int>(
|
|
builder:
|
|
(BuildContext context, List<int> data, List<dynamic> rejects) {
|
|
return const Text('Target');
|
|
},
|
|
onAccept: (int data) {
|
|
events.add('drop');
|
|
},
|
|
),
|
|
],
|
|
),
|
|
));
|
|
|
|
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(new MaterialApp(
|
|
home: new Column(
|
|
children: <Widget>[
|
|
const Draggable<int>(
|
|
data: 1,
|
|
child: const Text('Source'),
|
|
feedback: const Text('Dragging'),
|
|
),
|
|
new DragTarget<int>(
|
|
builder:
|
|
(BuildContext context, List<int> data, List<dynamic> rejects) {
|
|
return const Text('Target');
|
|
},
|
|
onAccept: (int data) {
|
|
events.add('drop');
|
|
},
|
|
),
|
|
],
|
|
),
|
|
));
|
|
|
|
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']));
|
|
});
|
|
|
|
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(new MaterialApp(
|
|
home: new ListView(
|
|
children: <Widget>[
|
|
new DragTarget<int>(builder:
|
|
(BuildContext context, List<int> data, List<dynamic> rejects) {
|
|
return const Text('Target');
|
|
}, onAccept: (int data) {
|
|
events.add('drop $data');
|
|
}),
|
|
new Container(height: 400.0),
|
|
const Draggable<int>(
|
|
data: 1,
|
|
child: const Text('H'),
|
|
feedback: const Text('Dragging'),
|
|
affinity: Axis.horizontal,
|
|
),
|
|
const Draggable<int>(
|
|
data: 2,
|
|
child: const Text('V'),
|
|
feedback: const Text('Dragging'),
|
|
affinity: Axis.vertical,
|
|
),
|
|
new Container(height: 500.0),
|
|
new Container(height: 500.0),
|
|
new Container(height: 500.0),
|
|
new 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']));
|
|
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']));
|
|
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']));
|
|
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
|
|
// TODO(ferhat): reenable after viewport offset is implemented in scrollable
|
|
// 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(new MaterialApp(
|
|
home: new ListView(
|
|
scrollDirection: Axis.horizontal,
|
|
children: <Widget>[
|
|
new DragTarget<int>(builder:
|
|
(BuildContext context, List<int> data, List<dynamic> rejects) {
|
|
return const Text('Target');
|
|
}, onAccept: (int data) {
|
|
events.add('drop $data');
|
|
}),
|
|
new Container(width: 400.0),
|
|
const Draggable<int>(
|
|
data: 1,
|
|
child: const Text('H'),
|
|
feedback: const Text('Dragging'),
|
|
affinity: Axis.horizontal,
|
|
),
|
|
const Draggable<int>(
|
|
data: 2,
|
|
child: const Text('V'),
|
|
feedback: const Text('Dragging'),
|
|
affinity: Axis.vertical,
|
|
),
|
|
new Container(width: 500.0),
|
|
new Container(width: 500.0),
|
|
new Container(width: 500.0),
|
|
new 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']));
|
|
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']));
|
|
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']));
|
|
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
|
|
// TODO(ferhat): reenable after viewport offset is implemented in scrollable
|
|
// 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 new MaterialApp(
|
|
home: new ListView(
|
|
scrollDirection: Axis.horizontal,
|
|
children: <Widget>[
|
|
new DragTarget<int>(builder:
|
|
(BuildContext context, List<int> data, List<dynamic> rejects) {
|
|
return const Text('Target');
|
|
}, onAccept: (int data) {
|
|
events.add('drop $data');
|
|
}),
|
|
new Container(width: 400.0),
|
|
const Draggable<int>(
|
|
data: 1,
|
|
child: const Text('H'),
|
|
feedback: const Text('H'),
|
|
childWhenDragging: SizedBox(),
|
|
axis: Axis.horizontal,
|
|
),
|
|
const Draggable<int>(
|
|
data: 2,
|
|
child: const Text('V'),
|
|
feedback: const Text('V'),
|
|
childWhenDragging: SizedBox(),
|
|
axis: Axis.vertical,
|
|
),
|
|
const Draggable<int>(
|
|
data: 3,
|
|
child: const Text('N'),
|
|
feedback: const Text('N'),
|
|
childWhenDragging: SizedBox(),
|
|
),
|
|
new Container(width: 500.0),
|
|
new Container(width: 500.0),
|
|
new Container(width: 500.0),
|
|
new 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>[];
|
|
bool onDraggableCanceledCalled = false;
|
|
|
|
await tester.pumpWidget(new MaterialApp(
|
|
home: new Column(
|
|
children: <Widget>[
|
|
new Draggable<int>(
|
|
data: 1,
|
|
child: const Text('Source'),
|
|
feedback: const Text('Dragging'),
|
|
onDraggableCanceled: (Velocity velocity, Offset offset) {
|
|
onDraggableCanceledCalled = true;
|
|
}),
|
|
new DragTarget<int>(
|
|
builder:
|
|
(BuildContext context, List<int> data, List<dynamic> rejects) {
|
|
return new Container(height: 100.0, child: const Text('Target'));
|
|
},
|
|
onAccept: accepted.add,
|
|
),
|
|
],
|
|
),
|
|
));
|
|
|
|
expect(accepted, 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(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(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(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>[];
|
|
bool onDraggableCanceledCalled = false;
|
|
Velocity onDraggableCanceledVelocity;
|
|
Offset onDraggableCanceledOffset;
|
|
|
|
await tester.pumpWidget(new MaterialApp(
|
|
home: new Column(
|
|
children: <Widget>[
|
|
new Draggable<int>(
|
|
data: 1,
|
|
child: const Text('Source'),
|
|
feedback: const Text('Dragging'),
|
|
onDraggableCanceled: (Velocity velocity, Offset offset) {
|
|
onDraggableCanceledCalled = true;
|
|
onDraggableCanceledVelocity = velocity;
|
|
onDraggableCanceledOffset = offset;
|
|
},
|
|
),
|
|
new DragTarget<int>(
|
|
builder:
|
|
(BuildContext context, List<int> data, List<dynamic> rejects) {
|
|
return new Container(height: 100.0, child: const Text('Target'));
|
|
},
|
|
onWillAccept: (int data) => false,
|
|
),
|
|
],
|
|
),
|
|
));
|
|
|
|
expect(accepted, 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(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(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(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(new 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>[];
|
|
bool onDraggableCanceledCalled = false;
|
|
Velocity onDraggableCanceledVelocity;
|
|
Offset onDraggableCanceledOffset;
|
|
|
|
await tester.pumpWidget(new MaterialApp(
|
|
home: new Column(
|
|
children: <Widget>[
|
|
new Draggable<int>(
|
|
data: 1,
|
|
child: const Text('Source'),
|
|
feedback: const Text('Source'),
|
|
onDraggableCanceled: (Velocity velocity, Offset offset) {
|
|
onDraggableCanceledCalled = true;
|
|
onDraggableCanceledVelocity = velocity;
|
|
onDraggableCanceledOffset = offset;
|
|
},
|
|
),
|
|
new DragTarget<int>(
|
|
builder: (BuildContext context, List<int> data,
|
|
List<dynamic> rejects) {
|
|
return new Container(
|
|
height: 100.0,
|
|
child: const Text('Target'),
|
|
);
|
|
},
|
|
onWillAccept: (int data) => false),
|
|
],
|
|
),
|
|
));
|
|
|
|
expect(accepted, 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(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(new Offset(flingStart.dx, flingStart.dy) +
|
|
const Offset(0.0, 100.0)));
|
|
});
|
|
|
|
testWidgets(
|
|
'Drag and drop - onDragCompleted not called if dropped on '
|
|
'non-accepting target', (WidgetTester tester) async {
|
|
final List<int> accepted = <int>[];
|
|
bool onDragCompletedCalled = false;
|
|
|
|
await tester.pumpWidget(new MaterialApp(
|
|
home: new Column(
|
|
children: <Widget>[
|
|
new Draggable<int>(
|
|
data: 1,
|
|
child: const Text('Source'),
|
|
feedback: const Text('Dragging'),
|
|
onDragCompleted: () {
|
|
onDragCompletedCalled = true;
|
|
},
|
|
),
|
|
new DragTarget<int>(
|
|
builder:
|
|
(BuildContext context, List<int> data, List<dynamic> rejects) {
|
|
return new Container(
|
|
height: 100.0,
|
|
child: const Text('Target'),
|
|
);
|
|
},
|
|
onWillAccept: (int data) => false,
|
|
),
|
|
],
|
|
),
|
|
));
|
|
|
|
expect(accepted, 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(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(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(find.text('Source'), findsOneWidget);
|
|
expect(find.text('Dragging'), findsNothing);
|
|
expect(find.text('Target'), findsOneWidget);
|
|
expect(onDragCompletedCalled, isFalse);
|
|
});
|
|
|
|
testWidgets(
|
|
'Drag and drop - onDragCompleted called if dropped on accepting target',
|
|
(WidgetTester tester) async {
|
|
final List<int> accepted = <int>[];
|
|
bool onDragCompletedCalled = false;
|
|
|
|
await tester.pumpWidget(new MaterialApp(
|
|
home: new Column(
|
|
children: <Widget>[
|
|
new Draggable<int>(
|
|
data: 1,
|
|
child: const Text('Source'),
|
|
feedback: const Text('Dragging'),
|
|
onDragCompleted: () {
|
|
onDragCompletedCalled = true;
|
|
},
|
|
),
|
|
new DragTarget<int>(
|
|
builder:
|
|
(BuildContext context, List<int> data, List<dynamic> rejects) {
|
|
return new Container(height: 100.0, child: const Text('Target'));
|
|
},
|
|
onAccept: accepted.add,
|
|
),
|
|
],
|
|
),
|
|
));
|
|
|
|
expect(accepted, 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(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(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(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<double> acceptedDoubles = <double>[];
|
|
|
|
await tester.pumpWidget(new MaterialApp(
|
|
home: new Column(
|
|
children: <Widget>[
|
|
const Draggable<int>(
|
|
data: 1,
|
|
child: const Text('IntSource'),
|
|
feedback: const Text('IntDragging'),
|
|
),
|
|
const Draggable<double>(
|
|
data: 1.0,
|
|
child: const Text('DoubleSource'),
|
|
feedback: const Text('DoubleDragging'),
|
|
),
|
|
new Stack(
|
|
children: <Widget>[
|
|
new DragTarget<int>(
|
|
builder: (BuildContext context, List<int> data,
|
|
List<dynamic> rejects) {
|
|
return new IgnorePointer(
|
|
child: new Container(
|
|
height: 100.0,
|
|
child: const Text('Target1'),
|
|
),
|
|
);
|
|
},
|
|
onAccept: acceptedInts.add,
|
|
),
|
|
new DragTarget<double>(
|
|
builder: (BuildContext context, List<double> data,
|
|
List<dynamic> rejects) {
|
|
return new IgnorePointer(
|
|
child: new Container(
|
|
height: 100.0,
|
|
child: const Text('Target2'),
|
|
),
|
|
);
|
|
},
|
|
onAccept: acceptedDoubles.add,
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
));
|
|
|
|
expect(acceptedInts, isEmpty);
|
|
expect(acceptedDoubles, 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(acceptedDoubles, isEmpty);
|
|
expect(find.text('IntDragging'), findsNothing);
|
|
expect(find.text('DoubleDragging'), findsOneWidget);
|
|
|
|
await doubleGesture.moveTo(targetLocation);
|
|
await tester.pump();
|
|
|
|
expect(acceptedInts, isEmpty);
|
|
expect(acceptedDoubles, isEmpty);
|
|
expect(find.text('IntDragging'), findsNothing);
|
|
expect(find.text('DoubleDragging'), findsOneWidget);
|
|
|
|
await doubleGesture.up();
|
|
await tester.pump();
|
|
|
|
expect(acceptedInts, isEmpty);
|
|
expect(acceptedDoubles, equals(<double>[1.0]));
|
|
expect(find.text('IntDragging'), findsNothing);
|
|
expect(find.text('DoubleDragging'), findsNothing);
|
|
|
|
acceptedDoubles.clear();
|
|
|
|
// Drag the int draggable.
|
|
final TestGesture intGesture =
|
|
await tester.startGesture(intLocation, pointer: 7);
|
|
await tester.pump();
|
|
|
|
expect(acceptedInts, isEmpty);
|
|
expect(acceptedDoubles, isEmpty);
|
|
expect(find.text('IntDragging'), findsOneWidget);
|
|
expect(find.text('DoubleDragging'), findsNothing);
|
|
|
|
await intGesture.moveTo(targetLocation);
|
|
await tester.pump();
|
|
|
|
expect(acceptedInts, isEmpty);
|
|
expect(acceptedDoubles, isEmpty);
|
|
expect(find.text('IntDragging'), findsOneWidget);
|
|
expect(find.text('DoubleDragging'), findsNothing);
|
|
|
|
await intGesture.up();
|
|
await tester.pump();
|
|
|
|
expect(acceptedInts, equals(<int>[1]));
|
|
expect(acceptedDoubles, 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<ExtendedDragTargetData> acceptedExtendedDragTargetDatas =
|
|
<ExtendedDragTargetData>[];
|
|
final DragTargetData dragTargetData = new DragTargetData();
|
|
await tester.pumpWidget(new MaterialApp(
|
|
home: new Column(
|
|
children: <Widget>[
|
|
new Draggable<DragTargetData>(
|
|
data: dragTargetData,
|
|
child: const Text('Source'),
|
|
feedback: const Text('Dragging'),
|
|
),
|
|
new Stack(
|
|
children: <Widget>[
|
|
new DragTarget<DragTargetData>(
|
|
builder: (BuildContext context, List<DragTargetData> data,
|
|
List<dynamic> rejects) {
|
|
return new IgnorePointer(
|
|
child: new Container(
|
|
height: 100.0,
|
|
child: const Text('Target1'),
|
|
),
|
|
);
|
|
},
|
|
onAccept: acceptedDragTargetDatas.add,
|
|
),
|
|
new DragTarget<ExtendedDragTargetData>(
|
|
builder: (BuildContext context,
|
|
List<ExtendedDragTargetData> data, List<dynamic> rejects) {
|
|
return new IgnorePointer(
|
|
child: new Container(
|
|
height: 100.0,
|
|
child: const Text('Target2'),
|
|
),
|
|
);
|
|
},
|
|
onAccept: acceptedExtendedDragTargetDatas.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(acceptedExtendedDragTargetDatas, isEmpty);
|
|
|
|
acceptedDragTargetDatas.clear();
|
|
await tester.pump();
|
|
}
|
|
});
|
|
|
|
testWidgets('Drag and drop - maxSimultaneousDrags',
|
|
(WidgetTester tester) async {
|
|
final List<int> accepted = <int>[];
|
|
|
|
Widget build(int maxSimultaneousDrags) {
|
|
return new MaterialApp(
|
|
home: new Column(
|
|
children: <Widget>[
|
|
new Draggable<int>(
|
|
data: 1,
|
|
maxSimultaneousDrags: maxSimultaneousDrags,
|
|
child: const Text('Source'),
|
|
feedback: const Text('Dragging'),
|
|
),
|
|
new DragTarget<int>(
|
|
builder: (BuildContext context, List<int> data,
|
|
List<dynamic> rejects) {
|
|
return new Container(
|
|
height: 100.0, child: const Text('Target'));
|
|
},
|
|
onAccept: accepted.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(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(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(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(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(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(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(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(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(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(find.text('Source'), findsOneWidget);
|
|
expect(find.text('Dragging'), findsNothing);
|
|
expect(find.text('Target'), findsOneWidget);
|
|
});
|
|
|
|
// Regression test for https://github.com/flutter/flutter/issues/6128.
|
|
testWidgets('Draggable plays nice with onTap', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
new Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: new Overlay(
|
|
initialEntries: <OverlayEntry>[
|
|
new OverlayEntry(
|
|
builder: (BuildContext context) => new GestureDetector(
|
|
onTap: () {/* registers a tap recognizer */},
|
|
child: new Draggable<dynamic>(
|
|
child: new Container(
|
|
color: const Color(0xFFFFFF00),
|
|
),
|
|
feedback: new 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(new MaterialApp(
|
|
home: new Column(
|
|
children: <Widget>[
|
|
const Draggable<int>(
|
|
data: 1,
|
|
child: const Text('Source'),
|
|
feedback: const Text('Dragging')),
|
|
new DragTarget<int>(
|
|
builder:
|
|
(BuildContext context, List<int> data, List<dynamic> rejects) {
|
|
return const Text('Target');
|
|
},
|
|
onAccept: (int data) {
|
|
events.add('drop');
|
|
},
|
|
),
|
|
],
|
|
),
|
|
));
|
|
|
|
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(new MaterialApp(
|
|
home: new Column(children: const <Widget>[
|
|
const Draggable<int>(
|
|
data: 1,
|
|
child: const Text('Source'),
|
|
feedback: const 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>[];
|
|
|
|
await tester.pumpWidget(new MaterialApp(
|
|
home: new Column(
|
|
children: <Widget>[
|
|
const Draggable<int>(
|
|
data: 1,
|
|
child: const Text('Source'),
|
|
feedback: const Text('Dragging')),
|
|
new DragTarget<int>(
|
|
builder:
|
|
(BuildContext context, List<int> data, List<dynamic> rejects) {
|
|
return new Container(height: 100.0, child: const Text('Target'));
|
|
},
|
|
onAccept: accepted.add,
|
|
),
|
|
],
|
|
),
|
|
));
|
|
|
|
expect(accepted, 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(find.text('Source'), findsOneWidget);
|
|
expect(find.text('Dragging'), findsOneWidget);
|
|
expect(find.text('Target'), findsOneWidget);
|
|
|
|
await tester.pumpWidget(new MaterialApp(
|
|
home: new Column(
|
|
children: <Widget>[
|
|
new DragTarget<int>(
|
|
builder:
|
|
(BuildContext context, List<int> data, List<dynamic> rejects) {
|
|
return new Container(height: 100.0, child: const Text('Target'));
|
|
},
|
|
onAccept: accepted.add,
|
|
),
|
|
],
|
|
),
|
|
));
|
|
|
|
expect(accepted, 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(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(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(new MaterialApp(
|
|
home: new Center(
|
|
child: new GestureDetector(
|
|
onTap: () {
|
|
events.add('tap');
|
|
},
|
|
child: const LongPressDraggable<int>(
|
|
feedback: const Text('Feedback'),
|
|
child: const Text('X'),
|
|
),
|
|
),
|
|
),
|
|
));
|
|
|
|
expect(events, isEmpty);
|
|
await tester.tap(find.text('X'));
|
|
expect(events, equals(<String>['tap']));
|
|
});
|
|
|
|
testWidgets(
|
|
'long-press draggable calls onDragCompleted called if '
|
|
'dropped on accepting target', (WidgetTester tester) async {
|
|
final List<int> accepted = <int>[];
|
|
bool onDragCompletedCalled = false;
|
|
|
|
await tester.pumpWidget(new MaterialApp(
|
|
home: new Column(
|
|
children: <Widget>[
|
|
new LongPressDraggable<int>(
|
|
data: 1,
|
|
child: const Text('Source'),
|
|
feedback: const Text('Dragging'),
|
|
onDragCompleted: () {
|
|
onDragCompletedCalled = true;
|
|
},
|
|
),
|
|
new DragTarget<int>(
|
|
builder:
|
|
(BuildContext context, List<int> data, List<dynamic> rejects) {
|
|
return new Container(height: 100.0, child: const Text('Target'));
|
|
},
|
|
onAccept: accepted.add,
|
|
),
|
|
],
|
|
),
|
|
));
|
|
|
|
expect(accepted, 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(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(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(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(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(new MaterialApp(
|
|
home: new 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('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('Draggable disposes recognizer', (WidgetTester tester) async {
|
|
bool didTap = false;
|
|
await tester.pumpWidget(
|
|
new Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: new Overlay(
|
|
initialEntries: <OverlayEntry>[
|
|
new OverlayEntry(
|
|
builder: (BuildContext context) => new GestureDetector(
|
|
onTap: () {
|
|
didTap = true;
|
|
},
|
|
child: new Draggable<dynamic>(
|
|
child: new Container(
|
|
color: const Color(0xFFFFFF00),
|
|
),
|
|
feedback: new 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(new Container(key: new UniqueKey()));
|
|
expect(didTap, isFalse);
|
|
});
|
|
}
|
|
|
|
Future<void> _testChildAnchorFeedbackPosition(
|
|
{WidgetTester tester, double top = 0.0, double left = 0.0}) async {
|
|
final List<int> accepted = <int>[];
|
|
int dragStartedCount = 0;
|
|
|
|
await tester.pumpWidget(
|
|
new Stack(
|
|
textDirection: TextDirection.ltr,
|
|
children: <Widget>[
|
|
new Positioned(
|
|
left: left,
|
|
top: top,
|
|
right: 0.0,
|
|
bottom: 0.0,
|
|
child: new MaterialApp(
|
|
home: new Column(
|
|
children: <Widget>[
|
|
new Draggable<int>(
|
|
data: 1,
|
|
child: const Text('Source'),
|
|
feedback: const Text('Dragging'),
|
|
onDragStarted: () {
|
|
++dragStartedCount;
|
|
},
|
|
),
|
|
new DragTarget<int>(
|
|
builder: (BuildContext context, List<int> data,
|
|
List<dynamic> rejects) {
|
|
return new Container(
|
|
height: 100.0, child: const Text('Target'));
|
|
},
|
|
onAccept: accepted.add,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
|
|
expect(accepted, 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(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(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 {}
|