import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:qlyra/core/utils/route_settle.dart'; class _GatedPage extends StatefulWidget { const _GatedPage({required this.onSettled}); final VoidCallback onSettled; @override State<_GatedPage> createState() => _GatedPageState(); } class _GatedPageState extends State<_GatedPage> { late final RouteSettle _settle = RouteSettle(isMounted: () => mounted); bool _queued = false; @override void didChangeDependencies() { super.didChangeDependencies(); _settle.bind(context); if (!_queued) { _queued = true; _settle.run(widget.onSettled); } } @override void dispose() { _settle.dispose(); super.dispose(); } @override Widget build(BuildContext context) => const SizedBox.shrink(); } void main() { testWidgets('queued work waits for the push transition to finish', ( tester, ) async { final navigator = GlobalKey(); var ran = 0; await tester.pumpWidget( MaterialApp(navigatorKey: navigator, home: const SizedBox.shrink()), ); navigator.currentState!.push( MaterialPageRoute( builder: (_) => _GatedPage(onSettled: () => ran++), ), ); await tester.pump(); expect(ran, 0); await tester.pump(const Duration(milliseconds: 100)); expect(ran, 0); await tester.pumpAndSettle(); expect(ran, 1); }); testWidgets('a route that is already in place does not hold work back', ( tester, ) async { var ran = 0; await tester.pumpWidget( MaterialApp(home: _GatedPage(onSettled: () => ran++)), ); expect(ran, 1); }); testWidgets('work runs immediately once the gate is open', (tester) async { final settle = RouteSettle(isMounted: () => true); settle.settleNow(); var ran = 0; settle.run(() => ran++); expect(ran, 1); settle.dispose(); }); testWidgets('queued work is dropped when the owner is gone', (tester) async { var alive = true; final settle = RouteSettle(isMounted: () => alive); var ran = 0; settle.run(() => ran++); expect(ran, 0); alive = false; settle.settleNow(); expect(ran, 0); settle.dispose(); }); }