diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md index 0380e7b2be1f3..31a7b524d73d5 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 + the 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 df4d551a8bf5d..cc5ca7039cb48 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 0e4bb0f75f82d..83bf1197a3355 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/go_router_test.dart b/packages/go_router/test/go_router_test.dart index 755b3e3b9bd69..2d670296dae3f 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; }); diff --git a/packages/go_router/test/parser_test.dart b/packages/go_router/test/parser_test.dart index 67d17c28c6fd7..8e5463b0cb86d 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(