From fc9bda40c712b9fff1ccb9cf7f71df3cab7477f2 Mon Sep 17 00:00:00 2001 From: Chun-Heng Tai Date: Tue, 15 Aug 2023 10:05:29 -0700 Subject: [PATCH 1/3] [go_router] Fixes RouteInformationParser that does not restore full RouteMatchList if the optionURLReflectsImperativeAPIs is set --- packages/go_router/CHANGELOG.md | 5 +++ packages/go_router/lib/src/parser.dart | 11 ++++-- packages/go_router/pubspec.yaml | 2 +- packages/go_router/test/parser_test.dart | 49 ++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md index 0380e7b2be1f..8d08bf65a9e4 100644 --- a/packages/go_router/CHANGELOG.md +++ b/packages/go_router/CHANGELOG.md @@ -1,3 +1,8 @@ +## 10.1.4 + +- Fixes RouteInformationParser that does not restore full RouteMatchList if + optionURLReflectsImperativeAPIs is set. + ## 10.1.3 - Fixes an issue in the documentation that was using `state.queryParameters` instead of `state.uri.queryParameters`. diff --git a/packages/go_router/lib/src/parser.dart b/packages/go_router/lib/src/parser.dart index df4d551a8bf5..cc5ca7039cb4 100644 --- a/packages/go_router/lib/src/parser.dart +++ b/packages/go_router/lib/src/parser.dart @@ -129,16 +129,21 @@ class GoRouteInformationParser extends RouteInformationParser { if (configuration.isEmpty) { return null; } + final String location; if (GoRouter.optionURLReflectsImperativeAPIs && configuration.matches.last is ImperativeRouteMatch) { - configuration = - (configuration.matches.last as ImperativeRouteMatch).matches; + location = (configuration.matches.last as ImperativeRouteMatch) + .matches + .uri + .toString(); + } else { + location = configuration.uri.toString(); } return RouteInformation( // TODO(chunhtai): remove this ignore and migrate the code // https://github.com/flutter/flutter/issues/124045. // ignore: deprecated_member_use - location: configuration.uri.toString(), + location: location, state: _routeMatchListCodec.encode(configuration), ); } diff --git a/packages/go_router/pubspec.yaml b/packages/go_router/pubspec.yaml index 0e4bb0f75f82..83bf1197a335 100644 --- a/packages/go_router/pubspec.yaml +++ b/packages/go_router/pubspec.yaml @@ -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: 10.1.3 +version: 10.1.4 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 diff --git a/packages/go_router/test/parser_test.dart b/packages/go_router/test/parser_test.dart index 67d17c28c6fd..8e5463b0cb86 100644 --- a/packages/go_router/test/parser_test.dart +++ b/packages/go_router/test/parser_test.dart @@ -6,6 +6,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:go_router/go_router.dart'; +import 'test_helpers.dart'; + RouteInformation createRouteInformation(String location, [Object? extra]) { return RouteInformation( // TODO(chunhtai): remove this ignore and migrate the code @@ -81,6 +83,53 @@ void main() { expect(matches[1].route, routes[0].routes[0]); }); + testWidgets( + 'GoRouteInformationParser can restore full route matches if optionURLReflectsImperativeAPIs is true', + (WidgetTester tester) async { + final GlobalKey navKey = GlobalKey(); + final List routes = [ + GoRoute( + path: '/', + builder: (_, __) => const Placeholder(), + routes: [ + GoRoute( + path: 'abc', + builder: (_, __) => const Placeholder(), + ), + ], + ), + ]; + GoRouter.optionURLReflectsImperativeAPIs = true; + final GoRouter router = + await createRouter(routes, tester, navigatorKey: navKey); + + // Generate RouteMatchList with imperative route match + router.go('/abc'); + await tester.pumpAndSettle(); + router.push('/'); + await tester.pumpAndSettle(); + final RouteMatchList matchList = router.routerDelegate.currentConfiguration; + expect(matchList.uri.toString(), '/abc'); + expect(matchList.matches.length, 3); + + final RouteInformation restoredRouteInformation = + router.routeInformationParser.restoreRouteInformation(matchList)!; + // URL reflects the latest push. + // TODO(chunhtai): remove this ignore and migrate the code + // https://github.com/flutter/flutter/issues/124045. + // ignore: deprecated_member_use + expect(restoredRouteInformation.location, '/'); + + // Can restore back to original RouteMatchList. + final RouteMatchList parsedRouteMatch = await router.routeInformationParser + .parseRouteInformationWithDependencies( + restoredRouteInformation, navKey.currentContext!); + expect(parsedRouteMatch.uri.toString(), '/abc'); + expect(parsedRouteMatch.matches.length, 3); + + GoRouter.optionURLReflectsImperativeAPIs = false; + }); + test('GoRouteInformationParser can retrieve route by name', () async { final List routes = [ GoRoute( From e0e841e76785bca2e20882eb327ed833854b994e Mon Sep 17 00:00:00 2001 From: Chun-Heng Tai Date: Tue, 15 Aug 2023 10:05:53 -0700 Subject: [PATCH 2/3] change list --- packages/go_router/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md index 8d08bf65a9e4..31a7b524d73d 100644 --- a/packages/go_router/CHANGELOG.md +++ b/packages/go_router/CHANGELOG.md @@ -1,7 +1,7 @@ ## 10.1.4 - Fixes RouteInformationParser that does not restore full RouteMatchList if - optionURLReflectsImperativeAPIs is set. + the optionURLReflectsImperativeAPIs is set. ## 10.1.3 From ee4f1143ebc20b69872e87d561d76915285ca8d6 Mon Sep 17 00:00:00 2001 From: Chun-Heng Tai Date: Tue, 15 Aug 2023 13:10:20 -0700 Subject: [PATCH 3/3] fix test --- packages/go_router/test/go_router_test.dart | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/go_router/test/go_router_test.dart b/packages/go_router/test/go_router_test.dart index 755b3e3b9bd6..2d670296dae3 100644 --- a/packages/go_router/test/go_router_test.dart +++ b/packages/go_router/test/go_router_test.dart @@ -1046,11 +1046,10 @@ void main() { final RouteMatchListCodec codec = RouteMatchListCodec(router.configuration); await tester.pumpAndSettle(); - final ImperativeRouteMatch match = router - .routerDelegate.currentConfiguration.last as ImperativeRouteMatch; expect(log, [ isMethodCall('selectMultiEntryHistory', arguments: null), - IsRouteUpdateCall('/settings', false, codec.encode(match.matches)), + IsRouteUpdateCall('/settings', false, + codec.encode(router.routerDelegate.currentConfiguration)), ]); GoRouter.optionURLReflectsImperativeAPIs = false; });