Skip to content

Commit

Permalink
Fixes a bug where NavigatorState.pop does not consider any possible s…
Browse files Browse the repository at this point in the history
…… (#150014)

�tate of the popped route

fixes flutter/flutter#146938
  • Loading branch information
chunhtai authored Jun 10, 2024
1 parent 5eaeaca commit 7755edd
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 1 deletion.
2 changes: 1 addition & 1 deletion packages/flutter/lib/src/widgets/navigator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5354,7 +5354,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
}());
final _RouteEntry entry = _history.lastWhere(_RouteEntry.isPresentPredicate);
if (entry.pageBased && widget.onPopPage != null) {
if (widget.onPopPage!(entry.route, result) && entry.currentState == _RouteLifecycle.idle) {
if (widget.onPopPage!(entry.route, result) && entry.currentState.index <= _RouteLifecycle.idle.index) {
// The entry may have been disposed if the pop finishes synchronously.
assert(entry.route._popCompleter.isCompleted);
entry.currentState = _RouteLifecycle.pop;
Expand Down
61 changes: 61 additions & 0 deletions packages/flutter/test/widgets/navigator_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,67 @@ void main() {
expect(observations[0].previous, 'Page 1');
});

testWidgets('Can push, pop, and replace in sequence', (WidgetTester tester) async {
const MaterialPage<void> initial = MaterialPage<void>(key: ValueKey<String>('initial'), child: Text('initial'));
const MaterialPage<void> push = MaterialPage<void>(key: ValueKey<String>('push'), child: Text('push'));
const MaterialPage<void> replace = MaterialPage<void>(key: ValueKey<String>('replace'), child: Text('replace'));
List<Page<void>> pages = <Page<void>>[
initial
];
bool popPageCallback(Route<dynamic> route, dynamic result) {
pages.removeLast();
return route.didPop(result);
}
final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
await tester.pumpWidget(
TestDependencies(
child: Navigator(
key: navigator,
pages: pages,
onPopPage: popPageCallback,
),
),
);
expect(find.text('initial'), findsOneWidget);

// Push a new page
pages = <Page<void>>[
initial,
push
];
await tester.pumpWidget(
TestDependencies(
child: Navigator(
key: navigator,
pages: pages,
onPopPage:popPageCallback,
),
),
);
await tester.pump(const Duration(milliseconds: 100));
expect(find.text('push'), findsOneWidget);

// Pop before push finishes.
navigator.currentState!.pop();

// Replace the entire pages
// Push a new page
pages = <Page<void>>[
replace
];
await tester.pumpWidget(
TestDependencies(
child: Navigator(
key: navigator,
pages: pages,
onPopPage:popPageCallback,
),
),
);
await tester.pumpAndSettle();
expect(find.text('replace'), findsOneWidget);
});

testWidgets('Navigator.of rootNavigator finds root Navigator', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
home: Material(
Expand Down

0 comments on commit 7755edd

Please sign in to comment.