f1b8052f77
After Ticker.stop(), elapsed resets to zero on the next start(). _now was left frozen at the old elapsed, so effects added after a drain captured a stale start time and their progress() clamped to 0 forever — ticker never stopped, second batch broken. Fix: reset _now = Duration.zero on drain. Adds @visibleForTesting getters and a regression test that catches the stale value directly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
67 lines
2.5 KiB
Dart
67 lines
2.5 KiB
Dart
import 'package:block_seasons/game/engine/game_engine.dart';
|
|
import 'package:block_seasons/ui/widgets/effects_overlay.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
PlacementResult _clearResult() => const PlacementResult(
|
|
events: [],
|
|
pointsGained: 250,
|
|
linesCleared: 1,
|
|
gemsCleared: 0,
|
|
clearedRows: [3],
|
|
clearedCols: [],
|
|
comboStreak: 2,
|
|
);
|
|
|
|
void main() {
|
|
testWidgets('second batch after drain completes within its own duration',
|
|
(tester) async {
|
|
final key = GlobalKey<EffectsOverlayState>();
|
|
await tester.pumpWidget(MaterialApp(
|
|
home:
|
|
Stack(children: [Positioned.fill(child: EffectsOverlay(key: key))]),
|
|
));
|
|
|
|
const board = Rect.fromLTWH(0, 0, 320, 320);
|
|
|
|
// ── First batch ──────────────────────────────────────────────────────────
|
|
key.currentState!.onPlacement(_clearResult(), boardRect: board);
|
|
await tester.pumpAndSettle();
|
|
|
|
// Ticker must be stopped after the first drain.
|
|
expect(
|
|
key.currentState!.ticker.isActive,
|
|
isFalse,
|
|
reason: 'ticker should be idle after first batch drains',
|
|
);
|
|
|
|
// _now must be Duration.zero after drain (regression for stale-clock bug).
|
|
// Without the fix, _now stays frozen at the elapsed value from the last
|
|
// tick of the first batch (~1000 ms).
|
|
expect(
|
|
key.currentState!.now,
|
|
Duration.zero,
|
|
reason:
|
|
'_now must be reset to zero when the list drains so the next '
|
|
'batch starts from a clean clock',
|
|
);
|
|
|
|
// ── Second batch ─────────────────────────────────────────────────────────
|
|
// With the stale-clock bug the effects get start: ~1000ms, but the
|
|
// restarted ticker delivers elapsed from 0, so progress stays 0 forever
|
|
// and they never drain. We verify the second batch completes via
|
|
// pumpAndSettle (which would time out if the ticker ran forever).
|
|
key.currentState!.onPlacement(_clearResult(), boardRect: board);
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(
|
|
tester.hasRunningAnimations,
|
|
isFalse,
|
|
reason:
|
|
'second batch must finish; stale clock would keep effects frozen '
|
|
'and the ticker running indefinitely',
|
|
);
|
|
});
|
|
}
|