Unverified Commit 3b4ac4d5 authored by chunhtai's avatar chunhtai Committed by GitHub

Implement url support for RouteInformation and didPushRouteInformation (#119968)

Related https://github.com/flutter/flutter/issues/100624

The goal is to make sure the engine can send a location string in either the existing format or a complete uri string to the framework, and the framework will still work as usual.
parent 034adb66
...@@ -80,14 +80,21 @@ abstract final class SystemNavigator { ...@@ -80,14 +80,21 @@ abstract final class SystemNavigator {
/// ///
/// The `replace` flag defaults to false. /// The `replace` flag defaults to false.
static Future<void> routeInformationUpdated({ static Future<void> routeInformationUpdated({
required String location, @Deprecated(
'Pass Uri.parse(location) to uri parameter instead. '
'This feature was deprecated after v3.8.0-3.0.pre.'
)
String? location,
Uri? uri,
Object? state, Object? state,
bool replace = false, bool replace = false,
}) { }) {
assert((location != null) != (uri != null), 'One of uri or location must be provided, but not both.');
uri ??= Uri.parse(location!);
return SystemChannels.navigation.invokeMethod<void>( return SystemChannels.navigation.invokeMethod<void>(
'routeInformationUpdated', 'routeInformationUpdated',
<String, dynamic>{ <String, dynamic>{
'location': location, 'uri': uri.toString(),
'state': state, 'state': state,
'replace': replace, 'replace': replace,
}, },
......
...@@ -1362,7 +1362,7 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver { ...@@ -1362,7 +1362,7 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver {
if (widget.routeInformationProvider == null && widget.routeInformationParser != null) { if (widget.routeInformationProvider == null && widget.routeInformationParser != null) {
_defaultRouteInformationProvider ??= PlatformRouteInformationProvider( _defaultRouteInformationProvider ??= PlatformRouteInformationProvider(
initialRouteInformation: RouteInformation( initialRouteInformation: RouteInformation(
location: _initialRouteName, uri: Uri.parse(_initialRouteName),
), ),
); );
} else { } else {
...@@ -1484,7 +1484,7 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver { ...@@ -1484,7 +1484,7 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver {
} }
@override @override
Future<bool> didPushRoute(String route) async { Future<bool> didPushRouteInformation(RouteInformation routeInformation) async {
assert(mounted); assert(mounted);
// The route name provider should handle the push route if we uses a // The route name provider should handle the push route if we uses a
// router. // router.
...@@ -1496,7 +1496,16 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver { ...@@ -1496,7 +1496,16 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver {
if (navigator == null) { if (navigator == null) {
return false; return false;
} }
navigator.pushNamed(route); final Uri uri = routeInformation.uri;
navigator.pushNamed(
Uri.decodeComponent(
Uri(
path: uri.path.isEmpty ? '/' : uri.path,
queryParameters: uri.queryParametersAll.isEmpty ? null : uri.queryParametersAll,
fragment: uri.fragment.isEmpty ? null : uri.fragment,
).toString(),
),
);
return true; return true;
} }
......
...@@ -72,6 +72,10 @@ abstract mixin class WidgetsBindingObserver { ...@@ -72,6 +72,10 @@ abstract mixin class WidgetsBindingObserver {
/// ///
/// This method exposes the `pushRoute` notification from /// This method exposes the `pushRoute` notification from
/// [SystemChannels.navigation]. /// [SystemChannels.navigation].
@Deprecated(
'Use didPushRouteInformation instead. '
'This feature was deprecated after v3.8.0-14.0.pre.'
)
Future<bool> didPushRoute(String route) => Future<bool>.value(false); Future<bool> didPushRoute(String route) => Future<bool>.value(false);
/// Called when the host tells the application to push a new /// Called when the host tells the application to push a new
...@@ -85,9 +89,20 @@ abstract mixin class WidgetsBindingObserver { ...@@ -85,9 +89,20 @@ abstract mixin class WidgetsBindingObserver {
/// [SystemChannels.navigation]. /// [SystemChannels.navigation].
/// ///
/// The default implementation is to call the [didPushRoute] directly with the /// The default implementation is to call the [didPushRoute] directly with the
/// [RouteInformation.location]. /// string constructed from [RouteInformation.uri]'s path and query parameters.
// TODO(chunhtai): remove the default implementation once `didPushRoute` is
// removed.
Future<bool> didPushRouteInformation(RouteInformation routeInformation) { Future<bool> didPushRouteInformation(RouteInformation routeInformation) {
return didPushRoute(routeInformation.location!); final Uri uri = routeInformation.uri;
return didPushRoute(
Uri.decodeComponent(
Uri(
path: uri.path.isEmpty ? '/' : uri.path,
queryParameters: uri.queryParametersAll.isEmpty ? null : uri.queryParametersAll,
fragment: uri.fragment.isEmpty ? null : uri.fragment,
).toString(),
),
);
} }
/// Called when the application's dimensions change. For example, /// Called when the application's dimensions change. For example,
...@@ -672,23 +687,21 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB ...@@ -672,23 +687,21 @@ mixin WidgetsBinding on BindingBase, ServicesBinding, SchedulerBinding, GestureB
@protected @protected
@mustCallSuper @mustCallSuper
Future<void> handlePushRoute(String route) async { Future<void> handlePushRoute(String route) async {
final RouteInformation routeInformation = RouteInformation(uri: Uri.parse(route));
for (final WidgetsBindingObserver observer in List<WidgetsBindingObserver>.of(_observers)) { for (final WidgetsBindingObserver observer in List<WidgetsBindingObserver>.of(_observers)) {
if (await observer.didPushRoute(route)) { if (await observer.didPushRouteInformation(routeInformation)) {
return; return;
} }
} }
} }
Future<void> _handlePushRouteInformation(Map<dynamic, dynamic> routeArguments) async { Future<void> _handlePushRouteInformation(Map<dynamic, dynamic> routeArguments) async {
final RouteInformation routeInformation = RouteInformation(
uri: Uri.parse(routeArguments['location'] as String),
state: routeArguments['state'] as Object?,
);
for (final WidgetsBindingObserver observer in List<WidgetsBindingObserver>.of(_observers)) { for (final WidgetsBindingObserver observer in List<WidgetsBindingObserver>.of(_observers)) {
if ( if (await observer.didPushRouteInformation(routeInformation)) {
await observer.didPushRouteInformation(
RouteInformation(
location: routeArguments['location'] as String,
state: routeArguments['state'] as Object?,
),
)
) {
return; return;
} }
} }
......
...@@ -4050,7 +4050,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res ...@@ -4050,7 +4050,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
); );
final String? routeName = lastEntry?.route.settings.name; final String? routeName = lastEntry?.route.settings.name;
if (routeName != null && routeName != _lastAnnouncedRouteName) { if (routeName != null && routeName != _lastAnnouncedRouteName) {
SystemNavigator.routeInformationUpdated(location: routeName); SystemNavigator.routeInformationUpdated(uri: Uri.parse(routeName));
_lastAnnouncedRouteName = routeName; _lastAnnouncedRouteName = routeName;
} }
} }
......
...@@ -41,18 +41,57 @@ import 'restoration_properties.dart'; ...@@ -41,18 +41,57 @@ import 'restoration_properties.dart';
class RouteInformation { class RouteInformation {
/// Creates a route information object. /// Creates a route information object.
/// ///
/// The arguments may be null. /// Either location or uri must not be null.
const RouteInformation({this.location, this.state}); const RouteInformation({
@Deprecated(
'Pass Uri.parse(location) to uri parameter instead. '
'This feature was deprecated after v3.8.0-3.0.pre.'
)
String? location,
Uri? uri,
this.state,
}) : _location = location,
_uri = uri,
assert((location != null) != (uri != null));
/// The location of the application. /// The location of the application.
/// ///
/// The string is usually in the format of multiple string identifiers with /// The string is usually in the format of multiple string identifiers with
/// slashes in between. ex: `/`, `/path`, `/path/to/the/app`. /// slashes in between. ex: `/`, `/path`, `/path/to/the/app`.
@Deprecated(
'Use uri instead. '
'This feature was deprecated after v3.8.0-3.0.pre.'
)
String get location {
if (_location != null) {
return _location!;
}
return Uri.decodeComponent(
Uri(
path: uri.path.isEmpty ? '/' : uri.path,
queryParameters: uri.queryParametersAll.isEmpty ? null : uri.queryParametersAll,
fragment: uri.fragment.isEmpty ? null : uri.fragment,
).toString(),
);
}
final String? _location;
/// The uri location of the application.
/// ///
/// It is equivalent to the URL in a web application. /// The host and scheme will not be empty if this object is created from a
final String? location; /// deep link request. They represents the website that redirect the deep
/// link.
///
/// In web platform, the host and scheme are always empty.
Uri get uri {
if (_uri != null){
return _uri!;
}
return Uri.parse(_location!);
}
final Uri? _uri;
/// The state of the application in the [location]. /// The state of the application in the [uri].
/// ///
/// The app can have different states even in the same location. For example, /// The app can have different states even in the same location. For example,
/// the text inside a [TextField] or the scroll position in a [ScrollView]. /// the text inside a [TextField] or the scroll position in a [ScrollView].
...@@ -61,11 +100,11 @@ class RouteInformation { ...@@ -61,11 +100,11 @@ class RouteInformation {
/// On the web, this information is stored in the browser history when the /// On the web, this information is stored in the browser history when the
/// [Router] reports this route information back to the web engine /// [Router] reports this route information back to the web engine
/// through the [PlatformRouteInformationProvider]. The information /// through the [PlatformRouteInformationProvider]. The information
/// is then passed back, along with the [location], when the user /// is then passed back, along with the [uri], when the user
/// clicks the back or forward buttons. /// clicks the back or forward buttons.
/// ///
/// This information is also serialized and persisted alongside the /// This information is also serialized and persisted alongside the
/// [location] for state restoration purposes. During state restoration, /// [uri] for state restoration purposes. During state restoration,
/// the information is made available again to the [Router] so it can restore /// the information is made available again to the [Router] so it can restore
/// its configuration to the previous state. /// its configuration to the previous state.
/// ///
...@@ -252,7 +291,7 @@ class RouterConfig<T> { ...@@ -252,7 +291,7 @@ class RouterConfig<T> {
/// ///
/// One can force the [Router] to report new route information as navigation /// One can force the [Router] to report new route information as navigation
/// event to the [routeInformationProvider] (and thus the browser) even if the /// event to the [routeInformationProvider] (and thus the browser) even if the
/// [RouteInformation.location] has not changed by calling the [Router.navigate] /// [RouteInformation.uri] has not changed by calling the [Router.navigate]
/// method with a callback that performs the state change. This causes [Router] /// method with a callback that performs the state change. This causes [Router]
/// to call the [RouteInformationProvider.routerReportsNewRouteInformation] with /// to call the [RouteInformationProvider.routerReportsNewRouteInformation] with
/// [RouteInformationReportingType.navigate], and thus causes /// [RouteInformationReportingType.navigate], and thus causes
...@@ -471,7 +510,7 @@ class Router<T> extends StatefulWidget { ...@@ -471,7 +510,7 @@ class Router<T> extends StatefulWidget {
/// ///
/// The web application relies on the [Router] to report new route information /// The web application relies on the [Router] to report new route information
/// in order to create browser history entry. The [Router] will only report /// in order to create browser history entry. The [Router] will only report
/// them if it detects the [RouteInformation.location] changes. Use this /// them if it detects the [RouteInformation.uri] changes. Use this
/// method if you want the [Router] to report the route information even if /// method if you want the [Router] to report the route information even if
/// the location does not change. This can be useful when you want to /// the location does not change. This can be useful when you want to
/// support the browser backward and forward button without changing the URL. /// support the browser backward and forward button without changing the URL.
...@@ -502,7 +541,7 @@ class Router<T> extends StatefulWidget { ...@@ -502,7 +541,7 @@ class Router<T> extends StatefulWidget {
/// ///
/// The web application relies on the [Router] to report new route information /// The web application relies on the [Router] to report new route information
/// in order to create browser history entry. The [Router] will report them /// in order to create browser history entry. The [Router] will report them
/// automatically if it detects the [RouteInformation.location] changes. /// automatically if it detects the [RouteInformation.uri] changes.
/// ///
/// Creating a new route history entry makes users feel they have visited a /// Creating a new route history entry makes users feel they have visited a
/// new page, and the browser back button brings them back to previous history /// new page, and the browser back button brings them back to previous history
...@@ -1432,10 +1471,10 @@ class PlatformRouteInformationProvider extends RouteInformationProvider with Wid ...@@ -1432,10 +1471,10 @@ class PlatformRouteInformationProvider extends RouteInformationProvider with Wid
final bool replace = final bool replace =
type == RouteInformationReportingType.neglect || type == RouteInformationReportingType.neglect ||
(type == RouteInformationReportingType.none && (type == RouteInformationReportingType.none &&
_valueInEngine.location == routeInformation.location); _valueInEngine.uri == routeInformation.uri);
SystemNavigator.selectMultiEntryHistory(); SystemNavigator.selectMultiEntryHistory();
SystemNavigator.routeInformationUpdated( SystemNavigator.routeInformationUpdated(
location: routeInformation.location!, uri: routeInformation.uri,
state: routeInformation.state, state: routeInformation.state,
replace: replace, replace: replace,
); );
...@@ -1447,7 +1486,7 @@ class PlatformRouteInformationProvider extends RouteInformationProvider with Wid ...@@ -1447,7 +1486,7 @@ class PlatformRouteInformationProvider extends RouteInformationProvider with Wid
RouteInformation get value => _value; RouteInformation get value => _value;
RouteInformation _value; RouteInformation _value;
RouteInformation _valueInEngine = RouteInformation(location: WidgetsBinding.instance.platformDispatcher.defaultRouteName); RouteInformation _valueInEngine = RouteInformation(uri: Uri.parse(WidgetsBinding.instance.platformDispatcher.defaultRouteName));
void _platformReportsNewRouteInformation(RouteInformation routeInformation) { void _platformReportsNewRouteInformation(RouteInformation routeInformation) {
if (_value == routeInformation) { if (_value == routeInformation) {
...@@ -1492,13 +1531,6 @@ class PlatformRouteInformationProvider extends RouteInformationProvider with Wid ...@@ -1492,13 +1531,6 @@ class PlatformRouteInformationProvider extends RouteInformationProvider with Wid
_platformReportsNewRouteInformation(routeInformation); _platformReportsNewRouteInformation(routeInformation);
return true; return true;
} }
@override
Future<bool> didPushRoute(String route) async {
assert(hasListeners);
_platformReportsNewRouteInformation(RouteInformation(location: route));
return true;
}
} }
/// A mixin that wires [RouterDelegate.popRoute] to the [Navigator] it builds. /// A mixin that wires [RouterDelegate.popRoute] to the [Navigator] it builds.
...@@ -1542,11 +1574,15 @@ class _RestorableRouteInformation extends RestorableValue<RouteInformation?> { ...@@ -1542,11 +1574,15 @@ class _RestorableRouteInformation extends RestorableValue<RouteInformation?> {
} }
assert(data is List<Object?> && data.length == 2); assert(data is List<Object?> && data.length == 2);
final List<Object?> castedData = data as List<Object?>; final List<Object?> castedData = data as List<Object?>;
return RouteInformation(location: castedData.first as String?, state: castedData.last); final String? uri = castedData.first as String?;
if (uri == null) {
return null;
}
return RouteInformation(uri: Uri.parse(uri), state: castedData.last);
} }
@override @override
Object? toPrimitives() { Object? toPrimitives() {
return value == null ? null : <Object?>[value!.location, value!.state]; return value == null ? null : <Object?>[value!.uri.toString(), value!.state];
} }
} }
...@@ -148,17 +148,17 @@ void main() { ...@@ -148,17 +148,17 @@ void main() {
testWidgets('CupertinoApp.router works', (WidgetTester tester) async { testWidgets('CupertinoApp.router works', (WidgetTester tester) async {
final PlatformRouteInformationProvider provider = PlatformRouteInformationProvider( final PlatformRouteInformationProvider provider = PlatformRouteInformationProvider(
initialRouteInformation: const RouteInformation( initialRouteInformation: RouteInformation(
location: 'initial', uri: Uri.parse('initial'),
), ),
); );
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate( final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
builder: (BuildContext context, RouteInformation information) { builder: (BuildContext context, RouteInformation information) {
return Text(information.location!); return Text(information.uri.toString());
}, },
onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) { onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
delegate.routeInformation = const RouteInformation( delegate.routeInformation = RouteInformation(
location: 'popped', uri: Uri.parse('popped'),
); );
return route.didPop(result); return route.didPop(result);
}, },
...@@ -180,16 +180,16 @@ void main() { ...@@ -180,16 +180,16 @@ void main() {
testWidgets('CupertinoApp.router route information parser is optional', (WidgetTester tester) async { testWidgets('CupertinoApp.router route information parser is optional', (WidgetTester tester) async {
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate( final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
builder: (BuildContext context, RouteInformation information) { builder: (BuildContext context, RouteInformation information) {
return Text(information.location!); return Text(information.uri.toString());
}, },
onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) { onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
delegate.routeInformation = const RouteInformation( delegate.routeInformation = RouteInformation(
location: 'popped', uri: Uri.parse('popped'),
); );
return route.didPop(result); return route.didPop(result);
}, },
); );
delegate.routeInformation = const RouteInformation(location: 'initial'); delegate.routeInformation = RouteInformation(uri: Uri.parse('initial'));
await tester.pumpWidget(CupertinoApp.router( await tester.pumpWidget(CupertinoApp.router(
routerDelegate: delegate, routerDelegate: delegate,
)); ));
...@@ -205,19 +205,19 @@ void main() { ...@@ -205,19 +205,19 @@ void main() {
testWidgets('CupertinoApp.router throw if route information provider is provided but no route information parser', (WidgetTester tester) async { testWidgets('CupertinoApp.router throw if route information provider is provided but no route information parser', (WidgetTester tester) async {
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate( final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
builder: (BuildContext context, RouteInformation information) { builder: (BuildContext context, RouteInformation information) {
return Text(information.location!); return Text(information.uri.toString());
}, },
onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) { onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
delegate.routeInformation = const RouteInformation( delegate.routeInformation = RouteInformation(
location: 'popped', uri: Uri.parse('popped'),
); );
return route.didPop(result); return route.didPop(result);
}, },
); );
delegate.routeInformation = const RouteInformation(location: 'initial'); delegate.routeInformation = RouteInformation(uri: Uri.parse('initial'));
final PlatformRouteInformationProvider provider = PlatformRouteInformationProvider( final PlatformRouteInformationProvider provider = PlatformRouteInformationProvider(
initialRouteInformation: const RouteInformation( initialRouteInformation: RouteInformation(
location: 'initial', uri: Uri.parse('initial'),
), ),
); );
await tester.pumpWidget(CupertinoApp.router( await tester.pumpWidget(CupertinoApp.router(
...@@ -230,16 +230,16 @@ void main() { ...@@ -230,16 +230,16 @@ void main() {
testWidgets('CupertinoApp.router throw if route configuration is provided along with other delegate', (WidgetTester tester) async { testWidgets('CupertinoApp.router throw if route configuration is provided along with other delegate', (WidgetTester tester) async {
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate( final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
builder: (BuildContext context, RouteInformation information) { builder: (BuildContext context, RouteInformation information) {
return Text(information.location!); return Text(information.uri.toString());
}, },
onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) { onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
delegate.routeInformation = const RouteInformation( delegate.routeInformation = RouteInformation(
location: 'popped', uri: Uri.parse('popped'),
); );
return route.didPop(result); return route.didPop(result);
}, },
); );
delegate.routeInformation = const RouteInformation(location: 'initial'); delegate.routeInformation = RouteInformation(uri: Uri.parse('initial'));
final RouterConfig<RouteInformation> routerConfig = RouterConfig<RouteInformation>(routerDelegate: delegate); final RouterConfig<RouteInformation> routerConfig = RouterConfig<RouteInformation>(routerDelegate: delegate);
await tester.pumpWidget(CupertinoApp.router( await tester.pumpWidget(CupertinoApp.router(
routerDelegate: delegate, routerDelegate: delegate,
...@@ -251,18 +251,18 @@ void main() { ...@@ -251,18 +251,18 @@ void main() {
testWidgets('CupertinoApp.router router config works', (WidgetTester tester) async { testWidgets('CupertinoApp.router router config works', (WidgetTester tester) async {
final RouterConfig<RouteInformation> routerConfig = RouterConfig<RouteInformation>( final RouterConfig<RouteInformation> routerConfig = RouterConfig<RouteInformation>(
routeInformationProvider: PlatformRouteInformationProvider( routeInformationProvider: PlatformRouteInformationProvider(
initialRouteInformation: const RouteInformation( initialRouteInformation: RouteInformation(
location: 'initial', uri: Uri.parse('initial'),
), ),
), ),
routeInformationParser: SimpleRouteInformationParser(), routeInformationParser: SimpleRouteInformationParser(),
routerDelegate: SimpleNavigatorRouterDelegate( routerDelegate: SimpleNavigatorRouterDelegate(
builder: (BuildContext context, RouteInformation information) { builder: (BuildContext context, RouteInformation information) {
return Text(information.location!); return Text(information.uri.toString());
}, },
onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) { onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
delegate.routeInformation = const RouteInformation( delegate.routeInformation = RouteInformation(
location: 'popped', uri: Uri.parse('popped'),
); );
return route.didPop(result); return route.didPop(result);
}, },
...@@ -532,7 +532,7 @@ class SimpleNavigatorRouterDelegate extends RouterDelegate<RouteInformation> wit ...@@ -532,7 +532,7 @@ class SimpleNavigatorRouterDelegate extends RouterDelegate<RouteInformation> wit
child: Text('base'), child: Text('base'),
), ),
CupertinoPage<void>( CupertinoPage<void>(
key: ValueKey<String?>(routeInformation.location), key: ValueKey<String?>(routeInformation.uri.toString()),
child: builder(context, routeInformation), child: builder(context, routeInformation),
), ),
], ],
......
...@@ -1085,17 +1085,17 @@ void main() { ...@@ -1085,17 +1085,17 @@ void main() {
testWidgets('MaterialApp.router works', (WidgetTester tester) async { testWidgets('MaterialApp.router works', (WidgetTester tester) async {
final PlatformRouteInformationProvider provider = PlatformRouteInformationProvider( final PlatformRouteInformationProvider provider = PlatformRouteInformationProvider(
initialRouteInformation: const RouteInformation( initialRouteInformation: RouteInformation(
location: 'initial', uri: Uri.parse('initial'),
), ),
); );
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate( final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
builder: (BuildContext context, RouteInformation information) { builder: (BuildContext context, RouteInformation information) {
return Text(information.location!); return Text(information.uri.toString());
}, },
onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) { onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
delegate.routeInformation = const RouteInformation( delegate.routeInformation = RouteInformation(
location: 'popped', uri: Uri.parse('popped'),
); );
return route.didPop(result); return route.didPop(result);
}, },
...@@ -1117,16 +1117,16 @@ void main() { ...@@ -1117,16 +1117,16 @@ void main() {
testWidgets('MaterialApp.router route information parser is optional', (WidgetTester tester) async { testWidgets('MaterialApp.router route information parser is optional', (WidgetTester tester) async {
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate( final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
builder: (BuildContext context, RouteInformation information) { builder: (BuildContext context, RouteInformation information) {
return Text(information.location!); return Text(information.uri.toString());
}, },
onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) { onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
delegate.routeInformation = const RouteInformation( delegate.routeInformation = RouteInformation(
location: 'popped', uri: Uri.parse('popped'),
); );
return route.didPop(result); return route.didPop(result);
}, },
); );
delegate.routeInformation = const RouteInformation(location: 'initial'); delegate.routeInformation = RouteInformation(uri: Uri.parse('initial'));
await tester.pumpWidget(MaterialApp.router( await tester.pumpWidget(MaterialApp.router(
routerDelegate: delegate, routerDelegate: delegate,
)); ));
...@@ -1142,19 +1142,19 @@ void main() { ...@@ -1142,19 +1142,19 @@ void main() {
testWidgets('MaterialApp.router throw if route information provider is provided but no route information parser', (WidgetTester tester) async { testWidgets('MaterialApp.router throw if route information provider is provided but no route information parser', (WidgetTester tester) async {
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate( final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
builder: (BuildContext context, RouteInformation information) { builder: (BuildContext context, RouteInformation information) {
return Text(information.location!); return Text(information.uri.toString());
}, },
onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) { onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
delegate.routeInformation = const RouteInformation( delegate.routeInformation = RouteInformation(
location: 'popped', uri: Uri.parse('popped'),
); );
return route.didPop(result); return route.didPop(result);
}, },
); );
delegate.routeInformation = const RouteInformation(location: 'initial'); delegate.routeInformation = RouteInformation(uri: Uri.parse('initial'));
final PlatformRouteInformationProvider provider = PlatformRouteInformationProvider( final PlatformRouteInformationProvider provider = PlatformRouteInformationProvider(
initialRouteInformation: const RouteInformation( initialRouteInformation: RouteInformation(
location: 'initial', uri: Uri.parse('initial'),
), ),
); );
await tester.pumpWidget(MaterialApp.router( await tester.pumpWidget(MaterialApp.router(
...@@ -1167,16 +1167,16 @@ void main() { ...@@ -1167,16 +1167,16 @@ void main() {
testWidgets('MaterialApp.router throw if route configuration is provided along with other delegate', (WidgetTester tester) async { testWidgets('MaterialApp.router throw if route configuration is provided along with other delegate', (WidgetTester tester) async {
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate( final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
builder: (BuildContext context, RouteInformation information) { builder: (BuildContext context, RouteInformation information) {
return Text(information.location!); return Text(information.uri.toString());
}, },
onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) { onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
delegate.routeInformation = const RouteInformation( delegate.routeInformation = RouteInformation(
location: 'popped', uri: Uri.parse('popped'),
); );
return route.didPop(result); return route.didPop(result);
}, },
); );
delegate.routeInformation = const RouteInformation(location: 'initial'); delegate.routeInformation = RouteInformation(uri: Uri.parse('initial'));
final RouterConfig<RouteInformation> routerConfig = RouterConfig<RouteInformation>(routerDelegate: delegate); final RouterConfig<RouteInformation> routerConfig = RouterConfig<RouteInformation>(routerDelegate: delegate);
await tester.pumpWidget(MaterialApp.router( await tester.pumpWidget(MaterialApp.router(
routerDelegate: delegate, routerDelegate: delegate,
...@@ -1188,18 +1188,18 @@ void main() { ...@@ -1188,18 +1188,18 @@ void main() {
testWidgets('MaterialApp.router router config works', (WidgetTester tester) async { testWidgets('MaterialApp.router router config works', (WidgetTester tester) async {
final RouterConfig<RouteInformation> routerConfig = RouterConfig<RouteInformation>( final RouterConfig<RouteInformation> routerConfig = RouterConfig<RouteInformation>(
routeInformationProvider: PlatformRouteInformationProvider( routeInformationProvider: PlatformRouteInformationProvider(
initialRouteInformation: const RouteInformation( initialRouteInformation: RouteInformation(
location: 'initial', uri: Uri.parse('initial'),
), ),
), ),
routeInformationParser: SimpleRouteInformationParser(), routeInformationParser: SimpleRouteInformationParser(),
routerDelegate: SimpleNavigatorRouterDelegate( routerDelegate: SimpleNavigatorRouterDelegate(
builder: (BuildContext context, RouteInformation information) { builder: (BuildContext context, RouteInformation information) {
return Text(information.location!); return Text(information.uri.toString());
}, },
onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) { onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
delegate.routeInformation = const RouteInformation( delegate.routeInformation = RouteInformation(
location: 'popped', uri: Uri.parse('popped'),
); );
return route.didPop(result); return route.didPop(result);
}, },
...@@ -1601,7 +1601,7 @@ class SimpleNavigatorRouterDelegate extends RouterDelegate<RouteInformation> wit ...@@ -1601,7 +1601,7 @@ class SimpleNavigatorRouterDelegate extends RouterDelegate<RouteInformation> wit
child: Text('base'), child: Text('base'),
), ),
MaterialPage<void>( MaterialPage<void>(
key: ValueKey<String>(routeInformation.location!), key: ValueKey<String>(routeInformation.uri.toString()),
child: builder(context, routeInformation), child: builder(context, routeInformation),
), ),
], ],
......
...@@ -45,15 +45,15 @@ void main() { ...@@ -45,15 +45,15 @@ void main() {
]); ]);
await verify(() => SystemNavigator.routeInformationUpdated(location: 'a'), <Object>[ await verify(() => SystemNavigator.routeInformationUpdated(location: 'a'), <Object>[
isMethodCall('routeInformationUpdated', arguments: <String, dynamic>{ 'location': 'a', 'state': null, 'replace': false }), isMethodCall('routeInformationUpdated', arguments: <String, dynamic>{ 'uri': 'a', 'state': null, 'replace': false }),
]); ]);
await verify(() => SystemNavigator.routeInformationUpdated(location: 'a', state: true), <Object>[ await verify(() => SystemNavigator.routeInformationUpdated(location: 'a', state: true), <Object>[
isMethodCall('routeInformationUpdated', arguments: <String, dynamic>{ 'location': 'a', 'state': true, 'replace': false }), isMethodCall('routeInformationUpdated', arguments: <String, dynamic>{ 'uri': 'a', 'state': true, 'replace': false }),
]); ]);
await verify(() => SystemNavigator.routeInformationUpdated(location: 'a', state: true, replace: true), <Object>[ await verify(() => SystemNavigator.routeInformationUpdated(location: 'a', state: true, replace: true), <Object>[
isMethodCall('routeInformationUpdated', arguments: <String, dynamic>{ 'location': 'a', 'state': true, 'replace': true }), isMethodCall('routeInformationUpdated', arguments: <String, dynamic>{ 'uri': 'a', 'state': true, 'replace': true }),
]); ]);
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.navigation, null); TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.navigation, null);
......
...@@ -275,17 +275,17 @@ void main() { ...@@ -275,17 +275,17 @@ void main() {
testWidgets('WidgetsApp.router works', (WidgetTester tester) async { testWidgets('WidgetsApp.router works', (WidgetTester tester) async {
final PlatformRouteInformationProvider provider = PlatformRouteInformationProvider( final PlatformRouteInformationProvider provider = PlatformRouteInformationProvider(
initialRouteInformation: const RouteInformation( initialRouteInformation: RouteInformation(
location: 'initial', uri: Uri.parse('initial'),
), ),
); );
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate( final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
builder: (BuildContext context, RouteInformation information) { builder: (BuildContext context, RouteInformation information) {
return Text(information.location!); return Text(information.uri.toString());
}, },
onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) { onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
delegate.routeInformation = const RouteInformation( delegate.routeInformation = RouteInformation(
location: 'popped', uri: Uri.parse('popped'),
); );
return route.didPop(result); return route.didPop(result);
}, },
...@@ -308,16 +308,16 @@ void main() { ...@@ -308,16 +308,16 @@ void main() {
testWidgets('WidgetsApp.router route information parser is optional', (WidgetTester tester) async { testWidgets('WidgetsApp.router route information parser is optional', (WidgetTester tester) async {
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate( final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
builder: (BuildContext context, RouteInformation information) { builder: (BuildContext context, RouteInformation information) {
return Text(information.location!); return Text(information.uri.toString());
}, },
onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) { onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
delegate.routeInformation = const RouteInformation( delegate.routeInformation = RouteInformation(
location: 'popped', uri: Uri.parse('popped'),
); );
return route.didPop(result); return route.didPop(result);
}, },
); );
delegate.routeInformation = const RouteInformation(location: 'initial'); delegate.routeInformation = RouteInformation(uri: Uri.parse('initial'));
await tester.pumpWidget(WidgetsApp.router( await tester.pumpWidget(WidgetsApp.router(
routerDelegate: delegate, routerDelegate: delegate,
color: const Color(0xFF123456), color: const Color(0xFF123456),
...@@ -334,19 +334,19 @@ void main() { ...@@ -334,19 +334,19 @@ void main() {
testWidgets('WidgetsApp.router throw if route information provider is provided but no route information parser', (WidgetTester tester) async { testWidgets('WidgetsApp.router throw if route information provider is provided but no route information parser', (WidgetTester tester) async {
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate( final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
builder: (BuildContext context, RouteInformation information) { builder: (BuildContext context, RouteInformation information) {
return Text(information.location!); return Text(information.uri.toString());
}, },
onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) { onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
delegate.routeInformation = const RouteInformation( delegate.routeInformation = RouteInformation(
location: 'popped', uri: Uri.parse('popped'),
); );
return route.didPop(result); return route.didPop(result);
}, },
); );
delegate.routeInformation = const RouteInformation(location: 'initial'); delegate.routeInformation = RouteInformation(uri: Uri.parse('initial'));
final PlatformRouteInformationProvider provider = PlatformRouteInformationProvider( final PlatformRouteInformationProvider provider = PlatformRouteInformationProvider(
initialRouteInformation: const RouteInformation( initialRouteInformation: RouteInformation(
location: 'initial', uri: Uri.parse('initial'),
), ),
); );
await expectLater(() async { await expectLater(() async {
...@@ -361,16 +361,16 @@ void main() { ...@@ -361,16 +361,16 @@ void main() {
testWidgets('WidgetsApp.router throw if route configuration is provided along with other delegate', (WidgetTester tester) async { testWidgets('WidgetsApp.router throw if route configuration is provided along with other delegate', (WidgetTester tester) async {
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate( final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
builder: (BuildContext context, RouteInformation information) { builder: (BuildContext context, RouteInformation information) {
return Text(information.location!); return Text(information.uri.toString());
}, },
onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) { onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
delegate.routeInformation = const RouteInformation( delegate.routeInformation = RouteInformation(
location: 'popped', uri: Uri.parse('popped'),
); );
return route.didPop(result); return route.didPop(result);
}, },
); );
delegate.routeInformation = const RouteInformation(location: 'initial'); delegate.routeInformation = RouteInformation(uri: Uri.parse('initial'));
final RouterConfig<RouteInformation> routerConfig = RouterConfig<RouteInformation>(routerDelegate: delegate); final RouterConfig<RouteInformation> routerConfig = RouterConfig<RouteInformation>(routerDelegate: delegate);
await expectLater(() async { await expectLater(() async {
await tester.pumpWidget(WidgetsApp.router( await tester.pumpWidget(WidgetsApp.router(
...@@ -384,18 +384,18 @@ void main() { ...@@ -384,18 +384,18 @@ void main() {
testWidgets('WidgetsApp.router router config works', (WidgetTester tester) async { testWidgets('WidgetsApp.router router config works', (WidgetTester tester) async {
final RouterConfig<RouteInformation> routerConfig = RouterConfig<RouteInformation>( final RouterConfig<RouteInformation> routerConfig = RouterConfig<RouteInformation>(
routeInformationProvider: PlatformRouteInformationProvider( routeInformationProvider: PlatformRouteInformationProvider(
initialRouteInformation: const RouteInformation( initialRouteInformation: RouteInformation(
location: 'initial', uri: Uri.parse('initial'),
), ),
), ),
routeInformationParser: SimpleRouteInformationParser(), routeInformationParser: SimpleRouteInformationParser(),
routerDelegate: SimpleNavigatorRouterDelegate( routerDelegate: SimpleNavigatorRouterDelegate(
builder: (BuildContext context, RouteInformation information) { builder: (BuildContext context, RouteInformation information) {
return Text(information.location!); return Text(information.uri.toString());
}, },
onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) { onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
delegate.routeInformation = const RouteInformation( delegate.routeInformation = RouteInformation(
location: 'popped', uri: Uri.parse('popped'),
); );
return route.didPop(result); return route.didPop(result);
}, },
...@@ -418,7 +418,7 @@ void main() { ...@@ -418,7 +418,7 @@ void main() {
testWidgets('WidgetsApp.router has correct default', (WidgetTester tester) async { testWidgets('WidgetsApp.router has correct default', (WidgetTester tester) async {
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate( final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
builder: (BuildContext context, RouteInformation information) { builder: (BuildContext context, RouteInformation information) {
return Text(information.location!); return Text(information.uri.toString());
}, },
onPopPage: (Route<Object?> route, Object? result, SimpleNavigatorRouterDelegate delegate) => true, onPopPage: (Route<Object?> route, Object? result, SimpleNavigatorRouterDelegate delegate) => true,
); );
...@@ -769,7 +769,7 @@ class SimpleNavigatorRouterDelegate extends RouterDelegate<RouteInformation> wit ...@@ -769,7 +769,7 @@ class SimpleNavigatorRouterDelegate extends RouterDelegate<RouteInformation> wit
child: Text('base'), child: Text('base'),
), ),
MaterialPage<void>( MaterialPage<void>(
key: ValueKey<String>(routeInformation.location!), key: ValueKey<String>(routeInformation.uri.toString()),
child: builder(context, routeInformation), child: builder(context, routeInformation),
), ),
], ],
......
...@@ -111,6 +111,38 @@ void main() { ...@@ -111,6 +111,38 @@ void main() {
WidgetsBinding.instance.removeObserver(observer); WidgetsBinding.instance.removeObserver(observer);
}); });
testWidgets('didPushRouteInformation calls didPushRoute correctly when handling url', (WidgetTester tester) async {
final PushRouteObserver observer = PushRouteObserver();
WidgetsBinding.instance.addObserver(observer);
// A url without any path.
Map<String, dynamic> testRouteInformation = const <String, dynamic>{
'location': 'http://hostname',
'state': 'state',
'restorationData': <dynamic, dynamic>{'test': 'config'},
};
ByteData message = const JSONMethodCodec().encodeMethodCall(
MethodCall('pushRouteInformation', testRouteInformation),
);
await ServicesBinding.instance.defaultBinaryMessenger
.handlePlatformMessage('flutter/navigation', message, (_) {});
expect(observer.pushedRoute, '/');
// A complex url.
testRouteInformation = const <String, dynamic>{
'location': 'http://hostname/abc?def=123&def=456#789',
'state': 'state',
'restorationData': <dynamic, dynamic>{'test': 'config'},
};
message = const JSONMethodCodec().encodeMethodCall(
MethodCall('pushRouteInformation', testRouteInformation),
);
await ServicesBinding.instance.defaultBinaryMessenger
.handlePlatformMessage('flutter/navigation', message, (_) {});
expect(observer.pushedRoute, '/abc?def=123&def=456#789');
WidgetsBinding.instance.removeObserver(observer);
});
testWidgets('didPushRouteInformation callback', (WidgetTester tester) async { testWidgets('didPushRouteInformation callback', (WidgetTester tester) async {
final PushRouteInformationObserver observer = PushRouteInformationObserver(); final PushRouteInformationObserver observer = PushRouteInformationObserver();
WidgetsBinding.instance.addObserver(observer); WidgetsBinding.instance.addObserver(observer);
...@@ -123,7 +155,25 @@ void main() { ...@@ -123,7 +155,25 @@ void main() {
const MethodCall('pushRouteInformation', testRouteInformation), const MethodCall('pushRouteInformation', testRouteInformation),
); );
await tester.binding.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { }); await tester.binding.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
expect(observer.pushedRouteInformation.location, 'testRouteName'); expect(observer.pushedRouteInformation.uri.toString(), 'testRouteName');
expect(observer.pushedRouteInformation.state, 'state');
WidgetsBinding.instance.removeObserver(observer);
});
testWidgets('didPushRouteInformation callback can handle url', (WidgetTester tester) async {
final PushRouteInformationObserver observer = PushRouteInformationObserver();
WidgetsBinding.instance.addObserver(observer);
const Map<String, dynamic> testRouteInformation = <String, dynamic>{
'location': 'http://hostname/abc?def=123&def=456#789',
'state': 'state',
};
final ByteData message = const JSONMethodCodec().encodeMethodCall(
const MethodCall('pushRouteInformation', testRouteInformation),
);
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
expect(observer.pushedRouteInformation.location, '/abc?def=123&def=456#789');
expect(observer.pushedRouteInformation.uri.toString(), 'http://hostname/abc?def=123&def=456#789');
expect(observer.pushedRouteInformation.state, 'state'); expect(observer.pushedRouteInformation.state, 'state');
WidgetsBinding.instance.removeObserver(observer); WidgetsBinding.instance.removeObserver(observer);
}); });
...@@ -139,8 +189,9 @@ void main() { ...@@ -139,8 +189,9 @@ void main() {
final ByteData message = const JSONMethodCodec().encodeMethodCall( final ByteData message = const JSONMethodCodec().encodeMethodCall(
const MethodCall('pushRouteInformation', testRouteInformation), const MethodCall('pushRouteInformation', testRouteInformation),
); );
await tester.binding.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { }); await tester.binding.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
expect(observer.pushedRouteInformation.location, 'testRouteName'); expect(observer.pushedRouteInformation.uri.toString(), 'testRouteName');
expect(observer.pushedRouteInformation.state, null); expect(observer.pushedRouteInformation.state, null);
WidgetsBinding.instance.removeObserver(observer); WidgetsBinding.instance.removeObserver(observer);
}); });
......
...@@ -63,7 +63,7 @@ void main() { ...@@ -63,7 +63,7 @@ void main() {
isMethodCall('selectSingleEntryHistory', arguments: null), isMethodCall('selectSingleEntryHistory', arguments: null),
isMethodCall('routeInformationUpdated', isMethodCall('routeInformationUpdated',
arguments: <String, dynamic>{ arguments: <String, dynamic>{
'location': '/', 'uri': '/',
'state': null, 'state': null,
'replace': false, 'replace': false,
}, },
...@@ -81,7 +81,7 @@ void main() { ...@@ -81,7 +81,7 @@ void main() {
isMethodCall( isMethodCall(
'routeInformationUpdated', 'routeInformationUpdated',
arguments: <String, dynamic>{ arguments: <String, dynamic>{
'location': '/A', 'uri': '/A',
'state': null, 'state': null,
'replace': false, 'replace': false,
}, },
...@@ -99,7 +99,7 @@ void main() { ...@@ -99,7 +99,7 @@ void main() {
isMethodCall( isMethodCall(
'routeInformationUpdated', 'routeInformationUpdated',
arguments: <String, dynamic>{ arguments: <String, dynamic>{
'location': '/', 'uri': '/',
'state': null, 'state': null,
'replace': false, 'replace': false,
}, },
...@@ -173,7 +173,7 @@ void main() { ...@@ -173,7 +173,7 @@ void main() {
isMethodCall('selectSingleEntryHistory', arguments: null), isMethodCall('selectSingleEntryHistory', arguments: null),
isMethodCall('routeInformationUpdated', isMethodCall('routeInformationUpdated',
arguments: <String, dynamic>{ arguments: <String, dynamic>{
'location': '/', 'uri': '/',
'state': null, 'state': null,
'replace': false, 'replace': false,
}, },
...@@ -191,7 +191,7 @@ void main() { ...@@ -191,7 +191,7 @@ void main() {
isMethodCall( isMethodCall(
'routeInformationUpdated', 'routeInformationUpdated',
arguments: <String, dynamic>{ arguments: <String, dynamic>{
'location': '/A', 'uri': '/A',
'state': null, 'state': null,
'replace': false, 'replace': false,
}, },
...@@ -209,7 +209,7 @@ void main() { ...@@ -209,7 +209,7 @@ void main() {
isMethodCall( isMethodCall(
'routeInformationUpdated', 'routeInformationUpdated',
arguments: <String, dynamic>{ arguments: <String, dynamic>{
'location': '/B', 'uri': '/B',
'state': null, 'state': null,
'replace': false, 'replace': false,
}, },
...@@ -246,7 +246,7 @@ void main() { ...@@ -246,7 +246,7 @@ void main() {
isMethodCall('selectSingleEntryHistory', arguments: null), isMethodCall('selectSingleEntryHistory', arguments: null),
isMethodCall('routeInformationUpdated', isMethodCall('routeInformationUpdated',
arguments: <String, dynamic>{ arguments: <String, dynamic>{
'location': '/home', 'uri': '/home',
'state': null, 'state': null,
'replace': false, 'replace': false,
}, },
...@@ -269,14 +269,14 @@ void main() { ...@@ -269,14 +269,14 @@ void main() {
}); });
final PlatformRouteInformationProvider provider = PlatformRouteInformationProvider( final PlatformRouteInformationProvider provider = PlatformRouteInformationProvider(
initialRouteInformation: const RouteInformation( initialRouteInformation: RouteInformation(
location: 'initial', uri: Uri.parse('initial'),
), ),
); );
final SimpleRouterDelegate delegate = SimpleRouterDelegate( final SimpleRouterDelegate delegate = SimpleRouterDelegate(
reportConfiguration: true, reportConfiguration: true,
builder: (BuildContext context, RouteInformation information) { builder: (BuildContext context, RouteInformation information) {
return Text(information.location!); return Text(information.uri.toString());
}, },
); );
...@@ -289,7 +289,7 @@ void main() { ...@@ -289,7 +289,7 @@ void main() {
expect(log, <Object>[ expect(log, <Object>[
isMethodCall('selectMultiEntryHistory', arguments: null), isMethodCall('selectMultiEntryHistory', arguments: null),
isMethodCall('routeInformationUpdated', arguments: <String, dynamic>{ isMethodCall('routeInformationUpdated', arguments: <String, dynamic>{
'location': 'initial', 'uri': 'initial',
'state': null, 'state': null,
'replace': false, 'replace': false,
}), }),
...@@ -298,8 +298,8 @@ void main() { ...@@ -298,8 +298,8 @@ void main() {
// Triggers a router rebuild and verify the route information is reported // Triggers a router rebuild and verify the route information is reported
// to the web engine. // to the web engine.
delegate.routeInformation = const RouteInformation( delegate.routeInformation = RouteInformation(
location: 'update', uri: Uri.parse('update'),
state: 'state', state: 'state',
); );
await tester.pump(); await tester.pump();
...@@ -308,7 +308,7 @@ void main() { ...@@ -308,7 +308,7 @@ void main() {
expect(log, <Object>[ expect(log, <Object>[
isMethodCall('selectMultiEntryHistory', arguments: null), isMethodCall('selectMultiEntryHistory', arguments: null),
isMethodCall('routeInformationUpdated', arguments: <String, dynamic>{ isMethodCall('routeInformationUpdated', arguments: <String, dynamic>{
'location': 'update', 'uri': 'update',
'state': 'state', 'state': 'state',
'replace': false, 'replace': false,
}), }),
......
...@@ -51,7 +51,7 @@ void main() { ...@@ -51,7 +51,7 @@ void main() {
expect(delegate().newRoutePaths, <String>['/home']); expect(delegate().newRoutePaths, <String>['/home']);
expect(delegate().restoredRoutePaths, isEmpty); expect(delegate().restoredRoutePaths, isEmpty);
provider().value = const RouteInformation(location: '/foo'); provider().value = RouteInformation(uri: Uri(path: '/foo'));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('Current config: /foo'), findsOneWidget); expect(find.text('Current config: /foo'), findsOneWidget);
expect(delegate().newRoutePaths, <String>['/home', '/foo']); expect(delegate().newRoutePaths, <String>['/home', '/foo']);
...@@ -64,7 +64,7 @@ void main() { ...@@ -64,7 +64,7 @@ void main() {
final TestRestorationData restorationData = await tester.getRestorationData(); final TestRestorationData restorationData = await tester.getRestorationData();
provider().value = const RouteInformation(location: '/bar'); provider().value = RouteInformation(uri: Uri.parse('/bar'));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(find.text('Current config: /bar'), findsOneWidget); expect(find.text('Current config: /bar'), findsOneWidget);
expect(delegate().newRoutePaths, <String>['/bar']); expect(delegate().newRoutePaths, <String>['/bar']);
...@@ -80,12 +80,12 @@ void main() { ...@@ -80,12 +80,12 @@ void main() {
class _TestRouteInformationParser extends RouteInformationParser<String> { class _TestRouteInformationParser extends RouteInformationParser<String> {
@override @override
Future<String> parseRouteInformation(RouteInformation routeInformation) { Future<String> parseRouteInformation(RouteInformation routeInformation) {
return SynchronousFuture<String>(routeInformation.location!); return SynchronousFuture<String>(routeInformation.uri.toString());
} }
@override @override
RouteInformation? restoreRouteInformation(String configuration) { RouteInformation? restoreRouteInformation(String configuration) {
return RouteInformation(location: configuration); return RouteInformation(uri: Uri.parse(configuration));
} }
} }
...@@ -130,7 +130,7 @@ class _TestRouterDelegate extends RouterDelegate<String> with ChangeNotifier { ...@@ -130,7 +130,7 @@ class _TestRouterDelegate extends RouterDelegate<String> with ChangeNotifier {
class _TestRouteInformationProvider extends RouteInformationProvider with ChangeNotifier { class _TestRouteInformationProvider extends RouteInformationProvider with ChangeNotifier {
@override @override
RouteInformation get value => _value; RouteInformation get value => _value;
RouteInformation _value = const RouteInformation(location: '/home'); RouteInformation _value = RouteInformation(uri: Uri.parse('/home'));
set value(RouteInformation value) { set value(RouteInformation value) {
if (value == _value) { if (value == _value) {
return; return;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment