Skip to content

Commit

Permalink
[go_router] Use the correct configuration to build the state passed t…
Browse files Browse the repository at this point in the history
…o the `onExit` (#6623)

While working on #6614, I notice some issues with the state that is given to the `onExit` (see the run https://github.com/flutter/packages/pull/6614/checks?check_run_id=24284539541)

This PR uses the correct configuration to build the state and pass it to the `onExit`
  • Loading branch information
ValentinVignal committed May 14, 2024
1 parent 1412041 commit fd714bd
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 7 deletions.
4 changes: 4 additions & 0 deletions packages/go_router/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 14.1.1

- Fixes correctness of the state provided in the `onExit`.

## 14.1.0

- Adds route redirect to ShellRoutes
Expand Down
6 changes: 1 addition & 5 deletions packages/go_router/lib/src/delegate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,6 @@ class GoRouterDelegate extends RouterDelegate<RouteMatchList>
exitingMatches.length - 1,
context: navigatorContext,
matches: exitingMatches,
configuration: configuration,
).then<void>((bool exit) {
if (!exit) {
return SynchronousFuture<void>(null);
Expand All @@ -254,7 +253,6 @@ class GoRouterDelegate extends RouterDelegate<RouteMatchList>
int index, {
required BuildContext context,
required List<RouteMatch> matches,
required RouteMatchList configuration,
}) {
if (index < 0) {
return SynchronousFuture<bool>(true);
Expand All @@ -266,7 +264,6 @@ class GoRouterDelegate extends RouterDelegate<RouteMatchList>
index - 1,
context: context,
matches: matches,
configuration: configuration,
);
}

Expand All @@ -276,15 +273,14 @@ class GoRouterDelegate extends RouterDelegate<RouteMatchList>
index - 1,
context: context,
matches: matches,
configuration: configuration,
);
}
return SynchronousFuture<bool>(false);
}

final FutureOr<bool> exitFuture = goRoute.onExit!(
context,
match.buildState(_configuration, configuration),
match.buildState(_configuration, currentConfiguration),
);
if (exitFuture is bool) {
return handleOnExitResult(exitFuture);
Expand Down
2 changes: 1 addition & 1 deletion packages/go_router/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: go_router
description: A declarative router for Flutter based on Navigation 2 supporting
deep linking, data-driven routes and more
version: 14.1.0
version: 14.1.1
repository: https://github.com/flutter/packages/tree/main/packages/go_router
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+go_router%22

Expand Down
159 changes: 158 additions & 1 deletion packages/go_router/test/on_exit_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ void main() {
expect(await router.routerDelegate.popRoute(), false);
});

testWidgets('It should provide the correct state to the onExit callback',
testWidgets('It should provide the correct uri to the onExit callback',
(WidgetTester tester) async {
final UniqueKey home = UniqueKey();
final UniqueKey page1 = UniqueKey();
Expand Down Expand Up @@ -314,4 +314,161 @@ void main() {
expect(find.byKey(home), findsOneWidget);
expect(onExitState1.uri.toString(), '/1');
});

testWidgets(
'It should provide the correct path parameters to the onExit callback',
(WidgetTester tester) async {
final UniqueKey page0 = UniqueKey();
final UniqueKey page1 = UniqueKey();
final UniqueKey page2 = UniqueKey();
final UniqueKey page3 = UniqueKey();
late final GoRouterState onExitState1;
late final GoRouterState onExitState2;
late final GoRouterState onExitState3;
final List<GoRoute> routes = <GoRoute>[
GoRoute(
path: '/route-0/:id0',
builder: (BuildContext context, GoRouterState state) =>
DummyScreen(key: page0),
),
GoRoute(
path: '/route-1/:id1',
builder: (BuildContext context, GoRouterState state) =>
DummyScreen(key: page1),
onExit: (BuildContext context, GoRouterState state) {
onExitState1 = state;
return true;
},
),
GoRoute(
path: '/route-2/:id2',
builder: (BuildContext context, GoRouterState state) =>
DummyScreen(key: page2),
onExit: (BuildContext context, GoRouterState state) {
onExitState2 = state;
return true;
},
),
GoRoute(
path: '/route-3/:id3',
builder: (BuildContext context, GoRouterState state) {
return DummyScreen(key: page3);
},
onExit: (BuildContext context, GoRouterState state) {
onExitState3 = state;
return true;
},
),
];

final GoRouter router = await createRouter(
routes,
tester,
initialLocation: '/route-0/0?param0=0',
);
unawaited(router.push('/route-1/1?param1=1'));
unawaited(router.push('/route-2/2?param2=2'));
unawaited(router.push('/route-3/3?param3=3'));

await tester.pumpAndSettle();
expect(find.byKey(page3), findsOne);

router.pop();
await tester.pumpAndSettle();
expect(find.byKey(page2), findsOne);
expect(onExitState3.uri.toString(), '/route-3/3?param3=3');
expect(onExitState3.pathParameters, const <String, String>{'id3': '3'});
expect(onExitState3.fullPath, '/route-3/:id3');

router.pop();
await tester.pumpAndSettle();
expect(find.byKey(page1), findsOne);
expect(onExitState2.uri.toString(), '/route-2/2?param2=2');
expect(onExitState2.pathParameters, const <String, String>{'id2': '2'});
expect(onExitState2.fullPath, '/route-2/:id2');

router.pop();
await tester.pumpAndSettle();
expect(find.byKey(page0), findsOne);
expect(onExitState1.uri.toString(), '/route-1/1?param1=1');
expect(onExitState1.pathParameters, const <String, String>{'id1': '1'});
expect(onExitState1.fullPath, '/route-1/:id1');
},
);

testWidgets(
'It should provide the correct path parameters to the onExit callback during a go',
(WidgetTester tester) async {
final UniqueKey page0 = UniqueKey();
final UniqueKey page1 = UniqueKey();
final UniqueKey page2 = UniqueKey();
final UniqueKey page3 = UniqueKey();
late final GoRouterState onExitState0;
late final GoRouterState onExitState1;
late final GoRouterState onExitState2;
final List<GoRoute> routes = <GoRoute>[
GoRoute(
path: '/route-0/:id0',
builder: (BuildContext context, GoRouterState state) =>
DummyScreen(key: page0),
onExit: (BuildContext context, GoRouterState state) {
onExitState0 = state;
return true;
},
),
GoRoute(
path: '/route-1/:id1',
builder: (BuildContext context, GoRouterState state) =>
DummyScreen(key: page1),
onExit: (BuildContext context, GoRouterState state) {
onExitState1 = state;
return true;
},
),
GoRoute(
path: '/route-2/:id2',
builder: (BuildContext context, GoRouterState state) =>
DummyScreen(key: page2),
onExit: (BuildContext context, GoRouterState state) {
onExitState2 = state;
return true;
},
),
GoRoute(
path: '/route-3/:id3',
builder: (BuildContext context, GoRouterState state) {
return DummyScreen(key: page3);
},
),
];

final GoRouter router = await createRouter(
routes,
tester,
initialLocation: '/route-0/0?param0=0',
);
expect(find.byKey(page0), findsOne);

router.go('/route-1/1?param1=1');
await tester.pumpAndSettle();
expect(find.byKey(page1), findsOne);
expect(onExitState0.uri.toString(), '/route-0/0?param0=0');
expect(onExitState0.pathParameters, const <String, String>{'id0': '0'});
expect(onExitState0.fullPath, '/route-0/:id0');

router.go('/route-2/2?param2=2');
await tester.pumpAndSettle();
expect(find.byKey(page2), findsOne);
expect(onExitState1.uri.toString(), '/route-1/1?param1=1');
expect(onExitState1.pathParameters, const <String, String>{'id1': '1'});
expect(onExitState1.fullPath, '/route-1/:id1');

router.go('/route-3/3?param3=3');
await tester.pumpAndSettle();
expect(find.byKey(page3), findsOne);
expect(onExitState2.uri.toString(), '/route-2/2?param2=2');
expect(onExitState2.pathParameters, const <String, String>{'id2': '2'});
expect(onExitState2.fullPath, '/route-2/:id2');
},
);
}

0 comments on commit fd714bd

Please sign in to comment.