1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// 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.
// @dart = 2.8
import 'package:flutter/gestures.dart';
import 'package:flutter_test/flutter_test.dart';
import 'velocity_tracker_data.dart';
bool _withinTolerance(double actual, double expected) {
const double kTolerance = 0.001; // Within .1% of expected value
final double diff = (actual - expected)/expected;
return diff.abs() < kTolerance;
}
bool _checkVelocity(Velocity actual, Offset expected) {
return (actual != null)
&& _withinTolerance(actual.pixelsPerSecond.dx, expected.dx)
&& _withinTolerance(actual.pixelsPerSecond.dy, expected.dy);
}
void main() {
const List<Offset> expected = <Offset>[
Offset(219.5762939453125, 1304.6705322265625),
Offset(355.6900939941406, 967.1700439453125),
Offset(12.651158332824707, -36.9227180480957),
Offset(714.1383056640625, -2561.540283203125),
Offset(-19.658065795898438, -2910.080322265625),
Offset(646.8700561523438, 2976.982421875),
Offset(396.6878967285156, 2106.204833984375),
Offset(298.3150634765625, -3660.821044921875),
Offset(-1.7460877895355225, -3288.16162109375),
Offset(384.6415710449219, -2645.6484375),
Offset(176.3752899169922, 2711.24609375),
Offset(396.9254455566406, 4280.640625),
Offset(-71.51288604736328, 3716.74560546875),
];
test('Velocity tracker gives expected results', () {
final VelocityTracker tracker = VelocityTracker();
int i = 0;
for (final PointerEvent event in velocityEventData) {
if (event is PointerDownEvent || event is PointerMoveEvent)
tracker.addPosition(event.timeStamp, event.position);
if (event is PointerUpEvent) {
_checkVelocity(tracker.getVelocity(), expected[i]);
i += 1;
}
}
});
test('Velocity control test', () {
const Velocity velocity1 = Velocity(pixelsPerSecond: Offset(7.0, 0.0));
const Velocity velocity2 = Velocity(pixelsPerSecond: Offset(12.0, 0.0));
expect(velocity1, equals(const Velocity(pixelsPerSecond: Offset(7.0, 0.0))));
expect(velocity1, isNot(equals(velocity2)));
expect(velocity2 - velocity1, equals(const Velocity(pixelsPerSecond: Offset(5.0, 0.0))));
expect((-velocity1).pixelsPerSecond, const Offset(-7.0, 0.0));
expect(velocity1 + velocity2, equals(const Velocity(pixelsPerSecond: Offset(19.0, 0.0))));
expect(velocity1.hashCode, isNot(equals(velocity2.hashCode)));
expect(velocity1, hasOneLineDescription);
});
test('Interrupted velocity estimation', () {
// Regression test for https://github.com/flutter/flutter/pull/7510
final VelocityTracker tracker = VelocityTracker();
for (final PointerEvent event in interruptedVelocityEventData) {
if (event is PointerDownEvent || event is PointerMoveEvent)
tracker.addPosition(event.timeStamp, event.position);
if (event is PointerUpEvent) {
_checkVelocity(tracker.getVelocity(), const Offset(649.5, 3890.3));
}
}
});
test('No data velocity estimation', () {
final VelocityTracker tracker = VelocityTracker();
expect(tracker.getVelocity(), Velocity.zero);
});
test('FreeScrollStartVelocityTracker.getVelocity throws when no points', () {
final IOSScrollViewFlingVelocityTracker tracker = IOSScrollViewFlingVelocityTracker();
AssertionError exception;
try {
tracker.getVelocity();
} on AssertionError catch (e) {
exception = e;
}
expect(exception?.toString(), contains('at least 1 point'));
});
test('FreeScrollStartVelocityTracker.getVelocity throws when the new point precedes the previous point', () {
final IOSScrollViewFlingVelocityTracker tracker = IOSScrollViewFlingVelocityTracker();
AssertionError exception;
tracker.addPosition(const Duration(hours: 1), Offset.zero);
try {
tracker.getVelocity();
tracker.addPosition(const Duration(seconds: 1), Offset.zero);
} on AssertionError catch (e) {
exception = e;
}
expect(exception?.toString(), contains('has a smaller timestamp'));
});
test('Estimate does not throw when there are more than 1 point', () {
final IOSScrollViewFlingVelocityTracker tracker = IOSScrollViewFlingVelocityTracker();
Offset position = Offset.zero;
Duration time = Duration.zero;
const Offset positionDelta = Offset(0, -1);
const Duration durationDelta = Duration(seconds: 1);
AssertionError exception;
for (int i = 0; i < 5; i+=1) {
position += positionDelta;
time += durationDelta;
tracker.addPosition(time, position);
try {
tracker.getVelocity();
} on AssertionError catch (e) {
exception = e;
}
expect(exception, isNull);
}
});
test('Makes consistent velocity estimates with consistent velocity', () {
final IOSScrollViewFlingVelocityTracker tracker = IOSScrollViewFlingVelocityTracker();
Offset position = Offset.zero;
Duration time = Duration.zero;
const Offset positionDelta = Offset(0, -1);
const Duration durationDelta = Duration(seconds: 1);
for (int i = 0; i < 10; i+=1) {
position += positionDelta;
time += durationDelta;
tracker.addPosition(time, position);
if (i >= 3) {
expect(tracker.getVelocity().pixelsPerSecond, positionDelta);
}
}
});
}