blob: 8cde52f2f182412cf6f01800217faaeae86b59b2 [file] [log] [blame]
// 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/gestures.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'gesture_tester.dart';
class TestDrag extends Drag { }
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
testGesture('MultiDrag: moving before delay rejects', (GestureTester tester) {
final DelayedMultiDragGestureRecognizer drag = DelayedMultiDragGestureRecognizer();
bool didStartDrag = false;
drag.onStart = (Offset position) {
didStartDrag = true;
return TestDrag();
};
final TestPointer pointer = TestPointer(5);
final PointerDownEvent down = pointer.down(const Offset(10.0, 10.0));
drag.addPointer(down);
tester.closeArena(5);
expect(didStartDrag, isFalse);
tester.async.flushMicrotasks();
expect(didStartDrag, isFalse);
tester.route(pointer.move(const Offset(20.0, 60.0))); // move more than touch slop before delay expires
expect(didStartDrag, isFalse);
tester.async.elapse(kLongPressTimeout * 2); // expire delay
expect(didStartDrag, isFalse);
tester.route(pointer.move(const Offset(30.0, 120.0))); // move some more after delay expires
expect(didStartDrag, isFalse);
drag.dispose();
});
testGesture('MultiDrag: delay triggers', (GestureTester tester) {
final DelayedMultiDragGestureRecognizer drag = DelayedMultiDragGestureRecognizer();
bool didStartDrag = false;
drag.onStart = (Offset position) {
didStartDrag = true;
return TestDrag();
};
final TestPointer pointer = TestPointer(5);
final PointerDownEvent down = pointer.down(const Offset(10.0, 10.0));
drag.addPointer(down);
tester.closeArena(5);
expect(didStartDrag, isFalse);
tester.async.flushMicrotasks();
expect(didStartDrag, isFalse);
tester.route(pointer.move(const Offset(20.0, 20.0))); // move less than touch slop before delay expires
expect(didStartDrag, isFalse);
tester.async.elapse(kLongPressTimeout * 2); // expire delay
expect(didStartDrag, isTrue);
tester.route(pointer.move(const Offset(30.0, 70.0))); // move more than touch slop after delay expires
expect(didStartDrag, isTrue);
drag.dispose();
});
testGesture('MultiDrag: can filter based on device kind', (GestureTester tester) {
final DelayedMultiDragGestureRecognizer drag = DelayedMultiDragGestureRecognizer(
supportedDevices: <PointerDeviceKind>{ PointerDeviceKind.touch },
);
bool didStartDrag = false;
drag.onStart = (Offset position) {
didStartDrag = true;
return TestDrag();
};
final TestPointer mousePointer = TestPointer(5, PointerDeviceKind.mouse);
final PointerDownEvent down = mousePointer.down(const Offset(10.0, 10.0));
drag.addPointer(down);
tester.closeArena(5);
expect(didStartDrag, isFalse);
tester.async.flushMicrotasks();
expect(didStartDrag, isFalse);
tester.route(mousePointer.move(const Offset(20.0, 20.0))); // move less than touch slop before delay expires
expect(didStartDrag, isFalse);
tester.async.elapse(kLongPressTimeout * 2); // expire delay
// Still false because it shouldn't recognize mouse events.
expect(didStartDrag, isFalse);
tester.route(mousePointer.move(const Offset(30.0, 70.0))); // move more than touch slop after delay expires
// And still false.
expect(didStartDrag, isFalse);
drag.dispose();
});
test('allowedButtonsFilter should work the same when null or not specified', () {
// Regression test for https://github.com/flutter/flutter/pull/122227
final ImmediateMultiDragGestureRecognizer recognizer1 = ImmediateMultiDragGestureRecognizer();
// ignore: avoid_redundant_argument_values
final ImmediateMultiDragGestureRecognizer recognizer2 = ImmediateMultiDragGestureRecognizer(allowedButtonsFilter: null);
// We want to test _allowedButtonsFilter, which is called in this method.
const PointerDownEvent allowedPointer = PointerDownEvent(timeStamp: Duration(days: 10));
// ignore: invalid_use_of_protected_member
expect(recognizer1.isPointerAllowed(allowedPointer), true);
// ignore: invalid_use_of_protected_member
expect(recognizer2.isPointerAllowed(allowedPointer), true);
const PointerDownEvent rejectedPointer = PointerDownEvent(timeStamp: Duration(days: 10), buttons: kMiddleMouseButton);
// ignore: invalid_use_of_protected_member
expect(recognizer1.isPointerAllowed(rejectedPointer), false);
// ignore: invalid_use_of_protected_member
expect(recognizer2.isPointerAllowed(rejectedPointer), false);
});
test('$MultiDragPointerState dispatches memory events', () async {
await expectLater(
await memoryEvents(
() => _MultiDragPointerState(
Offset.zero,
PointerDeviceKind.touch,
null,
).dispose(),
_MultiDragPointerState,
),
areCreateAndDispose,
);
});
}
class _MultiDragPointerState extends MultiDragPointerState {
_MultiDragPointerState(
super.initialPosition,
super.kind,
super.gestureSettings,
);
@override
void accepted(GestureMultiDragStartCallback starter) {}
@override
void dispose() {
super.dispose();
}
}