import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mews/presentation/reader/swipe_navigator.dart'; Widget _wrap(SwipeNavigator navigator) => MaterialApp( home: Scaffold( body: Center( child: SizedBox( width: 800, height: 600, child: navigator, ), ), ), ); SwipeNavigator _navigator({ required VoidCallback onBack, required VoidCallback onForward, bool canGoBack = true, bool canGoForward = true, double? contentWidth, }) => SwipeNavigator( contentWidth: contentWidth, canGoBack: canGoBack, canGoForward: canGoForward, backTitle: 'Previous page', forwardTitle: 'Next page', background: const Color(0xfffaf8f3), onBack: onBack, onForward: onForward, child: const ColoredBox( color: Color(0xff18191b), child: SizedBox.expand(), ), ); void main() { testWidgets('dragging right reveals the previous page and commits', (tester) async { var back = 0; var forward = 0; await tester.pumpWidget(_wrap(_navigator( onBack: () => back++, onForward: () => forward++, ))); // Swipes begin at the screen edge; mid-page drags select text. final center = tester.getCenter(find.byType(SwipeNavigator)); final gesture = await tester.startGesture(Offset(20, center.dy)); await gesture.moveBy(const Offset(300, 0)); await tester.pump(); // The neighbor is peeking in with its title while the page slides away. expect(find.text('Previous page'), findsOneWidget); await gesture.up(); await tester.pumpAndSettle(); expect(back, 1); expect(forward, 0); }); testWidgets('dragging left commits forward navigation', (tester) async { var back = 0; var forward = 0; await tester.pumpWidget(_wrap(_navigator( onBack: () => back++, onForward: () => forward++, ))); final center = tester.getCenter(find.byType(SwipeNavigator)); final gesture = await tester.startGesture(Offset(780, center.dy)); await gesture.moveBy(const Offset(-300, 0)); await tester.pump(); expect(find.text('Next page'), findsOneWidget); await gesture.up(); await tester.pumpAndSettle(); expect(forward, 1); expect(back, 0); }); testWidgets('a short drag springs back without navigating', (tester) async { var back = 0; await tester.pumpWidget(_wrap(_navigator( onBack: () => back++, onForward: () {}, ))); final center = tester.getCenter(find.byType(SwipeNavigator)); final gesture = await tester.startGesture(Offset(20, center.dy)); await gesture.moveBy(const Offset(80, 0)); await tester.pump(); await gesture.up(); await tester.pumpAndSettle(); expect(back, 0); // The neighbor disappeared again. expect(find.text('Previous page'), findsNothing); }); testWidgets('swipes anywhere in the margin beside the column', (tester) async { var back = 0; await tester.pumpWidget(_wrap(_navigator( onBack: () => back++, onForward: () {}, // A 40em column leaves 200px margins on an 800px surface. contentWidth: 400, ))); final center = tester.getCenter(find.byType(SwipeNavigator)); // Deep inside the left margin, far past the base edge zone. final gesture = await tester.startGesture(Offset(180, center.dy)); await gesture.moveBy(const Offset(300, 0)); await tester.pump(); expect(find.text('Previous page'), findsOneWidget); await gesture.up(); await tester.pumpAndSettle(); expect(back, 1); }); testWidgets('drags over the content column still belong to selection', (tester) async { var back = 0; await tester.pumpWidget(_wrap(_navigator( onBack: () => back++, onForward: () {}, contentWidth: 400, ))); final center = tester.getCenter(find.byType(SwipeNavigator)); // Inside the column: no swipe, nothing peeks. final gesture = await tester.startGesture(Offset(400, center.dy)); await gesture.moveBy(const Offset(300, 0)); await tester.pump(); expect(find.text('Previous page'), findsNothing); await gesture.up(); await tester.pumpAndSettle(); expect(back, 0); }); testWidgets('directions without pages rubber-band and never commit', (tester) async { var back = 0; var forward = 0; await tester.pumpWidget(_wrap(_navigator( onBack: () => back++, onForward: () => forward++, canGoBack: false, canGoForward: false, ))); final center = tester.getCenter(find.byType(SwipeNavigator)); final gesture = await tester.startGesture(Offset(20, center.dy)); await gesture.moveBy(const Offset(400, 0)); await tester.pump(); // No neighbor title shows when there is nothing to go back to. expect(find.text('Previous page'), findsNothing); await gesture.up(); await tester.pumpAndSettle(); expect(back, 0); expect(forward, 0); }); }