107 lines
3.5 KiB
Dart
107 lines
3.5 KiB
Dart
// Author: fruit.com.cn
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:fruitshorts/pages/player/widgets/player_double_tap_hearts.dart';
|
|
|
|
void main() {
|
|
testWidgets('heart pixels start at origin and move upward', (tester) async {
|
|
tester.view.physicalSize = const Size(400, 800);
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.resetPhysicalSize);
|
|
addTearDown(tester.view.resetDevicePixelRatio);
|
|
|
|
var completedCalls = 0;
|
|
const origin = Offset(300, 546);
|
|
final clock = _HeartClock();
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: TickerMode(
|
|
enabled: false,
|
|
child: Scaffold(
|
|
body: Stack(
|
|
fit: StackFit.expand,
|
|
clipBehavior: Clip.none,
|
|
children: [
|
|
Positioned.fill(
|
|
child: PlayerDoubleTapHeartBurst(
|
|
burstId: 91,
|
|
origin: origin,
|
|
now: clock.now,
|
|
onCompleted: () => completedCalls++,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
final firstHeart = find.byKey(const Key('double-tap-heart-0'));
|
|
expect(firstHeart, findsOneWidget);
|
|
final firstSize = tester.getSize(firstHeart);
|
|
final initialCenter = tester.getCenter(firstHeart);
|
|
debugPrint(
|
|
'[heart-pixels] initial size=${firstSize.width}x${firstSize.height} '
|
|
'center=${initialCenter.dx},${initialCenter.dy}',
|
|
);
|
|
expect(firstSize.width, closeTo(48, 1));
|
|
expect(firstSize.height, closeTo(48, 1));
|
|
expect(firstSize.width, greaterThan(20));
|
|
expect((initialCenter - origin).distance, lessThanOrEqualTo(1));
|
|
|
|
await _pumpHeartTime(tester, clock, const Duration(milliseconds: 300));
|
|
final center300 = tester.getCenter(firstHeart);
|
|
debugPrint('[heart-pixels] t=300 center=${center300.dx},${center300.dy}');
|
|
expect(center300.dy, lessThan(initialCenter.dy));
|
|
expect((center300.dx - origin.dx).abs(), lessThanOrEqualTo(30));
|
|
|
|
await _pumpHeartTime(tester, clock, const Duration(milliseconds: 300));
|
|
final center600 = tester.getCenter(firstHeart);
|
|
debugPrint('[heart-pixels] t=600 center=${center600.dx},${center600.dy}');
|
|
expect(center600.dy, lessThan(center300.dy));
|
|
expect((center600.dx - origin.dx).abs(), lessThanOrEqualTo(30));
|
|
|
|
await _pumpHeartTime(tester, clock, const Duration(milliseconds: 300));
|
|
final center900 = tester.getCenter(firstHeart);
|
|
debugPrint('[heart-pixels] t=900 center=${center900.dx},${center900.dy}');
|
|
expect(center900.dy, lessThan(center600.dy));
|
|
expect((center900.dx - origin.dx).abs(), lessThanOrEqualTo(30));
|
|
expect({
|
|
initialCenter.dy,
|
|
center300.dy,
|
|
center600.dy,
|
|
center900.dy,
|
|
}, hasLength(4));
|
|
|
|
await _pumpHeartTime(tester, clock, const Duration(milliseconds: 700));
|
|
expect(completedCalls, 1);
|
|
});
|
|
}
|
|
|
|
Future<void> _pumpHeartTime(
|
|
WidgetTester tester,
|
|
_HeartClock clock,
|
|
Duration duration,
|
|
) async {
|
|
const frameMs = 16;
|
|
var remainingMs = duration.inMilliseconds;
|
|
while (remainingMs > 0) {
|
|
final stepMs = remainingMs >= frameMs ? frameMs : remainingMs;
|
|
clock.advance(Duration(milliseconds: stepMs));
|
|
await tester.pump(const Duration(milliseconds: frameMs));
|
|
remainingMs -= stepMs;
|
|
}
|
|
}
|
|
|
|
class _HeartClock {
|
|
DateTime _now = DateTime(2026, 10, 26, 12);
|
|
|
|
DateTime now() => _now;
|
|
|
|
void advance(Duration duration) {
|
|
_now = _now.add(duration);
|
|
}
|
|
}
|