From 1bb9f3f7180a28f270ecd7799acfa286fc8ac99a Mon Sep 17 00:00:00 2001 From: chunhtai <47866232+chunhtai@users.noreply.github.com> Date: Tue, 12 May 2020 07:15:03 -0700 Subject: [PATCH] =?UTF-8?q?fix=20pushAndRemoveUntil=20incorrectly=20remove?= =?UTF-8?q?s=20the=20routes=20below=20the=20first=E2=80=A6=20(#56732)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flutter/lib/src/widgets/navigator.dart | 5 ++- .../flutter/test/widgets/navigator_test.dart | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/packages/flutter/lib/src/widgets/navigator.dart b/packages/flutter/lib/src/widgets/navigator.dart index 436f3d791dc..5cf507e319d 100644 --- a/packages/flutter/lib/src/widgets/navigator.dart +++ b/packages/flutter/lib/src/widgets/navigator.dart @@ -3435,9 +3435,8 @@ class NavigatorState extends State with TickerProviderStateMixin { assert(predicate != null); int index = _history.length - 1; _history.add(_RouteEntry(newRoute, initialState: _RouteLifecycle.push)); - while (index >= 0) { - final _RouteEntry entry = _history[index]; - if (entry.isPresent && !predicate(entry.route)) + while (index >= 0 && !predicate(_history[index].route)) { + if (_history[index].isPresent) _history[index].remove(); index -= 1; } diff --git a/packages/flutter/test/widgets/navigator_test.dart b/packages/flutter/test/widgets/navigator_test.dart index d0c07cf8966..660093879ed 100644 --- a/packages/flutter/test/widgets/navigator_test.dart +++ b/packages/flutter/test/widgets/navigator_test.dart @@ -682,6 +682,42 @@ void main() { expect(find.text('B'), isOnstage); }); + testWidgets('pushAndRemoveUntil does not remove routes below the first route that pass the predicate', (WidgetTester tester) async { + // Regression https://github.com/flutter/flutter/issues/56688 + final GlobalKey navigator = GlobalKey(); + final Map routes = { + '/': (BuildContext context) => const Text('home'), + '/A': (BuildContext context) => const Text('page A'), + '/A/B': (BuildContext context) => OnTapPage( + id: 'B', + onTap: () { + Navigator.of(context).pushNamedAndRemoveUntil('/D', ModalRoute.withName('/A')); + }, + ), + '/D': (BuildContext context) => const Text('page D'), + }; + + await tester.pumpWidget( + MaterialApp( + navigatorKey: navigator, + routes: routes, + initialRoute: '/A/B', + ) + ); + await tester.pumpAndSettle(); + await tester.tap(find.text('B')); + await tester.pumpAndSettle(); + expect(find.text('page D'), isOnstage); + + navigator.currentState.pop(); + await tester.pumpAndSettle(); + expect(find.text('page A'), isOnstage); + + navigator.currentState.pop(); + await tester.pumpAndSettle(); + expect(find.text('home'), isOnstage); + }); + testWidgets('replaceNamed returned value', (WidgetTester tester) async { Future value;