Files
flutter-go/packages/flutter_web/test/widgets/text_selection_test.dart
2019-08-13 20:38:46 +08:00

458 lines
14 KiB
Dart

// Copyright 2018 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.
// Synced 2019-05-30T14:20:57.784247.
import 'package:flutter_web_test/flutter_web_test.dart';
import 'package:flutter_web/gestures.dart' show PointerDeviceKind;
import 'package:flutter_web/widgets.dart';
void main() {
int tapCount;
int singleTapUpCount;
int singleTapCancelCount;
int singleLongTapStartCount;
int doubleTapDownCount;
int forcePressStartCount;
int forcePressEndCount;
int dragStartCount;
int dragUpdateCount;
int dragEndCount;
const Offset forcePressOffset = Offset(400.0, 50.0);
void _handleTapDown(TapDownDetails details) {
tapCount++;
}
void _handleSingleTapUp(TapUpDetails details) {
singleTapUpCount++;
}
void _handleSingleTapCancel() {
singleTapCancelCount++;
}
void _handleSingleLongTapStart(LongPressStartDetails details) {
singleLongTapStartCount++;
}
void _handleDoubleTapDown(TapDownDetails details) {
doubleTapDownCount++;
}
void _handleForcePressStart(ForcePressDetails details) {
forcePressStartCount++;
}
void _handleForcePressEnd(ForcePressDetails details) {
forcePressEndCount++;
}
void _handleDragSelectionStart(DragStartDetails details) {
dragStartCount++;
}
void _handleDragSelectionUpdate(
DragStartDetails _, DragUpdateDetails details) {
dragUpdateCount++;
}
void _handleDragSelectionEnd(DragEndDetails details) {
dragEndCount++;
}
setUp(() {
tapCount = 0;
singleTapUpCount = 0;
singleTapCancelCount = 0;
singleLongTapStartCount = 0;
doubleTapDownCount = 0;
forcePressStartCount = 0;
forcePressEndCount = 0;
dragStartCount = 0;
dragUpdateCount = 0;
dragEndCount = 0;
});
Future<void> pumpGestureDetector(WidgetTester tester) async {
await tester.pumpWidget(
TextSelectionGestureDetector(
behavior: HitTestBehavior.opaque,
onTapDown: _handleTapDown,
onSingleTapUp: _handleSingleTapUp,
onSingleTapCancel: _handleSingleTapCancel,
onSingleLongTapStart: _handleSingleLongTapStart,
onDoubleTapDown: _handleDoubleTapDown,
onForcePressStart: _handleForcePressStart,
onForcePressEnd: _handleForcePressEnd,
onDragSelectionStart: _handleDragSelectionStart,
onDragSelectionUpdate: _handleDragSelectionUpdate,
onDragSelectionEnd: _handleDragSelectionEnd,
child: Container(),
),
);
}
testWidgets('a series of taps all call onTaps', (WidgetTester tester) async {
await pumpGestureDetector(tester);
await tester.tapAt(const Offset(200, 200));
await tester.pump(const Duration(milliseconds: 150));
await tester.tapAt(const Offset(200, 200));
await tester.pump(const Duration(milliseconds: 150));
await tester.tapAt(const Offset(200, 200));
await tester.pump(const Duration(milliseconds: 150));
await tester.tapAt(const Offset(200, 200));
await tester.pump(const Duration(milliseconds: 150));
await tester.tapAt(const Offset(200, 200));
await tester.pump(const Duration(milliseconds: 150));
await tester.tapAt(const Offset(200, 200));
expect(tapCount, 6);
});
testWidgets(
'in a series of rapid taps, onTapDown and onDoubleTapDown alternate',
(WidgetTester tester) async {
await pumpGestureDetector(tester);
await tester.tapAt(const Offset(200, 200));
await tester.pump(const Duration(milliseconds: 50));
expect(singleTapUpCount, 1);
await tester.tapAt(const Offset(200, 200));
await tester.pump(const Duration(milliseconds: 50));
expect(singleTapUpCount, 1);
expect(doubleTapDownCount, 1);
await tester.tapAt(const Offset(200, 200));
await tester.pump(const Duration(milliseconds: 50));
expect(singleTapUpCount, 2);
expect(doubleTapDownCount, 1);
await tester.tapAt(const Offset(200, 200));
await tester.pump(const Duration(milliseconds: 50));
expect(singleTapUpCount, 2);
expect(doubleTapDownCount, 2);
await tester.tapAt(const Offset(200, 200));
await tester.pump(const Duration(milliseconds: 50));
expect(singleTapUpCount, 3);
expect(doubleTapDownCount, 2);
await tester.tapAt(const Offset(200, 200));
expect(singleTapUpCount, 3);
expect(doubleTapDownCount, 3);
expect(tapCount, 6);
});
testWidgets('quick tap-tap-hold is a double tap down',
(WidgetTester tester) async {
await pumpGestureDetector(tester);
await tester.tapAt(const Offset(200, 200));
await tester.pump(const Duration(milliseconds: 50));
expect(singleTapUpCount, 1);
final TestGesture gesture =
await tester.startGesture(const Offset(200, 200));
await tester.pump(const Duration(milliseconds: 200));
expect(singleTapUpCount, 1);
// Every down is counted.
expect(tapCount, 2);
// No cancels because the second tap of the double tap is a second successful
// single tap behind the scene.
expect(singleTapCancelCount, 0);
expect(doubleTapDownCount, 1);
// The double tap down hold supersedes the single tap down.
expect(singleLongTapStartCount, 0);
await gesture.up();
// Nothing else happens on up.
expect(singleTapUpCount, 1);
expect(tapCount, 2);
expect(singleTapCancelCount, 0);
expect(doubleTapDownCount, 1);
expect(singleLongTapStartCount, 0);
});
testWidgets('a very quick swipe is ignored', (WidgetTester tester) async {
await pumpGestureDetector(tester);
final TestGesture gesture =
await tester.startGesture(const Offset(200, 200));
await tester.pump(const Duration(milliseconds: 20));
await gesture.moveBy(const Offset(100, 100));
await tester.pump();
expect(singleTapUpCount, 0);
expect(tapCount, 0);
expect(singleTapCancelCount, 0);
expect(doubleTapDownCount, 0);
expect(singleLongTapStartCount, 0);
await gesture.up();
// Nothing else happens on up.
expect(singleTapUpCount, 0);
expect(tapCount, 0);
expect(singleTapCancelCount, 0);
expect(doubleTapDownCount, 0);
expect(singleLongTapStartCount, 0);
});
testWidgets('a slower swipe has a tap down and a canceled tap',
(WidgetTester tester) async {
await pumpGestureDetector(tester);
final TestGesture gesture =
await tester.startGesture(const Offset(200, 200));
await tester.pump(const Duration(milliseconds: 120));
await gesture.moveBy(const Offset(100, 100));
await tester.pump();
expect(singleTapUpCount, 0);
expect(tapCount, 1);
expect(singleTapCancelCount, 1);
expect(doubleTapDownCount, 0);
expect(singleLongTapStartCount, 0);
});
testWidgets('a force press intiates a force press',
(WidgetTester tester) async {
await pumpGestureDetector(tester);
const int pointerValue = 1;
final TestGesture gesture = await tester.createGesture();
await gesture.downWithCustomEvent(
forcePressOffset,
const PointerDownEvent(
pointer: pointerValue,
position: forcePressOffset,
pressure: 0.0,
pressureMax: 6.0,
pressureMin: 0.0,
),
);
await gesture.updateWithCustomEvent(const PointerMoveEvent(
pointer: pointerValue,
position: Offset(0.0, 0.0),
pressure: 0.5,
pressureMin: 0,
pressureMax: 1));
await gesture.up();
await tester.pumpAndSettle();
await gesture.downWithCustomEvent(
forcePressOffset,
const PointerDownEvent(
pointer: pointerValue,
position: forcePressOffset,
pressure: 0.0,
pressureMax: 6.0,
pressureMin: 0.0,
),
);
await gesture.updateWithCustomEvent(const PointerMoveEvent(
pointer: pointerValue,
position: Offset(0.0, 0.0),
pressure: 0.5,
pressureMin: 0,
pressureMax: 1));
await gesture.up();
await tester.pump(const Duration(milliseconds: 20));
await gesture.downWithCustomEvent(
forcePressOffset,
const PointerDownEvent(
pointer: pointerValue,
position: forcePressOffset,
pressure: 0.0,
pressureMax: 6.0,
pressureMin: 0.0,
),
);
await gesture.updateWithCustomEvent(const PointerMoveEvent(
pointer: pointerValue,
position: Offset(0.0, 0.0),
pressure: 0.5,
pressureMin: 0,
pressureMax: 1));
await gesture.up();
await tester.pump(const Duration(milliseconds: 20));
await gesture.downWithCustomEvent(
forcePressOffset,
const PointerDownEvent(
pointer: pointerValue,
position: forcePressOffset,
pressure: 0.0,
pressureMax: 6.0,
pressureMin: 0.0,
),
);
await gesture.updateWithCustomEvent(const PointerMoveEvent(
pointer: pointerValue,
position: Offset(0.0, 0.0),
pressure: 0.5,
pressureMin: 0,
pressureMax: 1));
await gesture.up();
expect(forcePressStartCount, 4);
});
testWidgets(
'a tap and then force press intiates a force press and not a double tap',
(WidgetTester tester) async {
await pumpGestureDetector(tester);
const int pointerValue = 1;
final TestGesture gesture = await tester.createGesture();
await gesture.downWithCustomEvent(
forcePressOffset,
const PointerDownEvent(
pointer: pointerValue,
position: forcePressOffset,
pressure: 0.0,
pressureMax: 6.0,
pressureMin: 0.0,
),
);
// Initiate a quick tap.
await gesture.updateWithCustomEvent(const PointerMoveEvent(
pointer: pointerValue,
position: Offset(0.0, 0.0),
pressure: 0.0,
pressureMin: 0,
pressureMax: 1,
));
await tester.pump(const Duration(milliseconds: 50));
await gesture.up();
// Initiate a force tap.
await gesture.downWithCustomEvent(
forcePressOffset,
const PointerDownEvent(
pointer: pointerValue,
position: forcePressOffset,
pressure: 0.0,
pressureMax: 6.0,
pressureMin: 0.0,
),
);
await gesture.updateWithCustomEvent(const PointerMoveEvent(
pointer: pointerValue,
position: Offset(0.0, 0.0),
pressure: 0.5,
pressureMin: 0,
pressureMax: 1,
));
expect(forcePressStartCount, 1);
await tester.pump(const Duration(milliseconds: 50));
await gesture.up();
await tester.pumpAndSettle();
expect(forcePressEndCount, 1);
expect(doubleTapDownCount, 0);
});
testWidgets(
'a long press from a touch device is recognized as a long single tap',
(WidgetTester tester) async {
await pumpGestureDetector(tester);
const int pointerValue = 1;
final TestGesture gesture = await tester.startGesture(
const Offset(200.0, 200.0),
pointer: pointerValue,
kind: PointerDeviceKind.touch);
await tester.pump(const Duration(seconds: 2));
await gesture.up();
await tester.pumpAndSettle();
expect(tapCount, 1);
expect(singleTapUpCount, 0);
expect(singleLongTapStartCount, 1);
});
testWidgets('a long press from a mouse is just a tap',
(WidgetTester tester) async {
await pumpGestureDetector(tester);
const int pointerValue = 1;
final TestGesture gesture = await tester.startGesture(
const Offset(200.0, 200.0),
pointer: pointerValue,
kind: PointerDeviceKind.mouse);
await tester.pump(const Duration(seconds: 2));
await gesture.up();
await tester.pumpAndSettle();
expect(tapCount, 1);
expect(singleTapUpCount, 1);
expect(singleLongTapStartCount, 0);
await gesture.removePointer();
});
testWidgets('a touch drag is not recognized for text selection',
(WidgetTester tester) async {
await pumpGestureDetector(tester);
const int pointerValue = 1;
final TestGesture gesture = await tester.startGesture(
const Offset(200.0, 200.0),
pointer: pointerValue,
kind: PointerDeviceKind.touch);
await tester.pump();
await gesture.moveBy(const Offset(210.0, 200.0));
await tester.pump();
await gesture.up();
await tester.pumpAndSettle();
expect(tapCount, 0);
expect(singleTapUpCount, 0);
expect(dragStartCount, 0);
expect(dragUpdateCount, 0);
expect(dragEndCount, 0);
await gesture.removePointer();
});
testWidgets('a mouse drag is recognized for text selection',
(WidgetTester tester) async {
await pumpGestureDetector(tester);
const int pointerValue = 1;
final TestGesture gesture = await tester.startGesture(
const Offset(200.0, 200.0),
pointer: pointerValue,
kind: PointerDeviceKind.mouse);
await tester.pump();
await gesture.moveBy(const Offset(210.0, 200.0));
await tester.pump();
await gesture.up();
await tester.pumpAndSettle();
expect(tapCount, 0);
expect(singleTapUpCount, 0);
expect(dragStartCount, 1);
expect(dragUpdateCount, 1);
expect(dragEndCount, 1);
await gesture.removePointer();
});
testWidgets('a slow mouse drag is still recognized for text selection',
(WidgetTester tester) async {
await pumpGestureDetector(tester);
const int pointerValue = 1;
final TestGesture gesture = await tester.startGesture(
const Offset(200.0, 200.0),
pointer: pointerValue,
kind: PointerDeviceKind.mouse);
await tester.pump(const Duration(seconds: 2));
await gesture.moveBy(const Offset(210.0, 200.0));
await tester.pump();
await gesture.up();
await tester.pumpAndSettle();
expect(dragStartCount, 1);
expect(dragUpdateCount, 1);
expect(dragEndCount, 1);
await gesture.removePointer();
});
}