Add arguments for pushing named routes (#27058)
This commit is contained in:
parent
f365217e6a
commit
e7d6348826
@ -84,22 +84,8 @@ class StocksAppState extends State<StocksApp> {
|
||||
}
|
||||
|
||||
Route<dynamic> _getRoute(RouteSettings settings) {
|
||||
// Routes, by convention, are split on slashes, like filesystem paths.
|
||||
final List<String> path = settings.name.split('/');
|
||||
// We only support paths that start with a slash, so bail if
|
||||
// the first component is not empty:
|
||||
if (path[0] != '')
|
||||
return null;
|
||||
// If the path is "/stock:..." then show a stock page for the
|
||||
// specified stock symbol.
|
||||
if (path[1].startsWith('stock:')) {
|
||||
// We don't yet support subpages of a stock, so bail if there's
|
||||
// any more path components.
|
||||
if (path.length != 2)
|
||||
return null;
|
||||
// Extract the symbol part of "stock:..." and return a route
|
||||
// for that symbol.
|
||||
final String symbol = path[1].substring(6);
|
||||
if (settings.name == '/stocks') {
|
||||
final String symbol = settings.arguments;
|
||||
return MaterialPageRoute<void>(
|
||||
settings: settings,
|
||||
builder: (BuildContext context) => StockSymbolPage(symbol: symbol, stocks: stocks),
|
||||
|
@ -262,7 +262,7 @@ class StockHomeState extends State<StockHome> {
|
||||
stocks: stocks.toList(),
|
||||
onAction: _buyStock,
|
||||
onOpen: (Stock stock) {
|
||||
Navigator.pushNamed(context, '/stock:${stock.symbol}');
|
||||
Navigator.pushNamed(context, '/stock', arguments: stock.symbol);
|
||||
},
|
||||
onShow: (Stock stock) {
|
||||
_scaffoldKey.currentState.showBottomSheet<void>((BuildContext context) => StockSymbolBottomSheet(stock: stock));
|
||||
|
@ -289,6 +289,7 @@ class RouteSettings {
|
||||
const RouteSettings({
|
||||
this.name,
|
||||
this.isInitialRoute = false,
|
||||
this.arguments,
|
||||
});
|
||||
|
||||
/// Creates a copy of this route settings object with the given fields
|
||||
@ -296,10 +297,12 @@ class RouteSettings {
|
||||
RouteSettings copyWith({
|
||||
String name,
|
||||
bool isInitialRoute,
|
||||
Object arguments,
|
||||
}) {
|
||||
return RouteSettings(
|
||||
name: name ?? this.name,
|
||||
isInitialRoute: isInitialRoute ?? this.isInitialRoute,
|
||||
arguments: arguments ?? this.arguments,
|
||||
);
|
||||
}
|
||||
|
||||
@ -313,8 +316,13 @@ class RouteSettings {
|
||||
/// The initial route typically skips any entrance transition to speed startup.
|
||||
final bool isInitialRoute;
|
||||
|
||||
/// The arguments passed to this route.
|
||||
///
|
||||
/// May be used when building the route, e.g. in [Navigator.onGenerateRoute].
|
||||
final Object arguments;
|
||||
|
||||
@override
|
||||
String toString() => '"$name"';
|
||||
String toString() => '$runtimeType("$name", $arguments)';
|
||||
}
|
||||
|
||||
/// An interface for observing the behavior of a [Navigator].
|
||||
@ -725,19 +733,77 @@ class Navigator extends StatefulWidget {
|
||||
/// The `T` type argument is the type of the return value of the route.
|
||||
/// {@endtemplate}
|
||||
///
|
||||
/// {@template flutter.widgets.navigator.pushNamed.arguments}
|
||||
/// The provided `arguments` are passed to the pushed route via
|
||||
/// [RouteSettings.arguments]. Any object can be passed as `arguments` (e.g. a
|
||||
/// [String], [int], or an instance of a custom `MyRouteArguments` class).
|
||||
/// Often, a [Map] is used to pass key-value pairs.
|
||||
///
|
||||
/// The `arguments` may be used in [Navigator.onGenerateRoute] or
|
||||
/// [Navigator.onUnknownRoute] to construct the route.
|
||||
/// {@endtemplate}
|
||||
///
|
||||
/// {@tool sample}
|
||||
///
|
||||
/// Typical usage is as follows:
|
||||
///
|
||||
/// ```dart
|
||||
/// void _didPushButton() {
|
||||
/// Navigator.pushNamed(context, '/nyc/1776');
|
||||
/// Navigator.pushNamed(context, '/settings');
|
||||
/// }
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
///
|
||||
/// {@tool sample}
|
||||
///
|
||||
/// The following example shows how to pass additional `arguments` to the
|
||||
/// route:
|
||||
///
|
||||
/// ```dart
|
||||
/// void _showBerlinWeather() {
|
||||
/// Navigator.pushNamed(
|
||||
/// context,
|
||||
/// '/weather',
|
||||
/// arguments: <String, String>{
|
||||
/// 'city': 'Berlin',
|
||||
/// 'country': 'Germany',
|
||||
/// },
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
///
|
||||
/// {@tool sample}
|
||||
///
|
||||
/// The following example shows how to pass a custom Object to the route:
|
||||
///
|
||||
/// ```dart
|
||||
/// class WeatherRouteArguments {
|
||||
/// WeatherRouteArguments({ this.city, this.country });
|
||||
/// final String city;
|
||||
/// final String country;
|
||||
///
|
||||
/// bool get isGermanCapital {
|
||||
/// return country == 'Germany' && city == 'Berlin';
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// void _showWeather() {
|
||||
/// Navigator.pushNamed(
|
||||
/// context,
|
||||
/// '/weather',
|
||||
/// arguments: WeatherRouteArguments(city: 'Berlin', country: 'Germany'),
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
@optionalTypeArgs
|
||||
static Future<T> pushNamed<T extends Object>(BuildContext context, String routeName) {
|
||||
return Navigator.of(context).pushNamed<T>(routeName);
|
||||
static Future<T> pushNamed<T extends Object>(
|
||||
BuildContext context,
|
||||
String routeName, {
|
||||
Object arguments,
|
||||
}) {
|
||||
return Navigator.of(context).pushNamed<T>(routeName, arguments: arguments);
|
||||
}
|
||||
|
||||
/// Replace the current route of the navigator that most tightly encloses the
|
||||
@ -773,19 +839,26 @@ class Navigator extends StatefulWidget {
|
||||
/// and `TO` is the type of the return value of the old route.
|
||||
/// {@endtemplate}
|
||||
///
|
||||
/// {@macro flutter.widgets.navigator.pushNamed.arguments}
|
||||
///
|
||||
/// {@tool sample}
|
||||
///
|
||||
/// Typical usage is as follows:
|
||||
///
|
||||
/// ```dart
|
||||
/// void _showNext() {
|
||||
/// Navigator.pushReplacementNamed(context, '/jouett/1781');
|
||||
/// void _switchToBrightness() {
|
||||
/// Navigator.pushReplacementNamed(context, '/settings/brightness');
|
||||
/// }
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
@optionalTypeArgs
|
||||
static Future<T> pushReplacementNamed<T extends Object, TO extends Object>(BuildContext context, String routeName, { TO result }) {
|
||||
return Navigator.of(context).pushReplacementNamed<T, TO>(routeName, result: result);
|
||||
static Future<T> pushReplacementNamed<T extends Object, TO extends Object>(
|
||||
BuildContext context,
|
||||
String routeName, {
|
||||
TO result,
|
||||
Object arguments,
|
||||
}) {
|
||||
return Navigator.of(context).pushReplacementNamed<T, TO>(routeName, arguments: arguments, result: result);
|
||||
}
|
||||
|
||||
/// Pop the current route off the navigator that most tightly encloses the
|
||||
@ -821,19 +894,26 @@ class Navigator extends StatefulWidget {
|
||||
/// and `TO` is the return value type of the old route.
|
||||
/// {@endtemplate}
|
||||
///
|
||||
/// {@macro flutter.widgets.navigator.pushNamed.arguments}
|
||||
///
|
||||
/// {@tool sample}
|
||||
///
|
||||
/// Typical usage is as follows:
|
||||
///
|
||||
/// ```dart
|
||||
/// void _selectNewYork() {
|
||||
/// Navigator.popAndPushNamed(context, '/nyc/1776');
|
||||
/// void _selectAccessibility() {
|
||||
/// Navigator.popAndPushNamed(context, '/settings/accessibility');
|
||||
/// }
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
@optionalTypeArgs
|
||||
static Future<T> popAndPushNamed<T extends Object, TO extends Object>(BuildContext context, String routeName, { TO result }) {
|
||||
return Navigator.of(context).popAndPushNamed<T, TO>(routeName, result: result);
|
||||
static Future<T> popAndPushNamed<T extends Object, TO extends Object>(
|
||||
BuildContext context,
|
||||
String routeName, {
|
||||
TO result,
|
||||
Object arguments,
|
||||
}) {
|
||||
return Navigator.of(context).popAndPushNamed<T, TO>(routeName, arguments: arguments, result: result);
|
||||
}
|
||||
|
||||
/// Push the route with the given name onto the navigator that most tightly
|
||||
@ -875,6 +955,8 @@ class Navigator extends StatefulWidget {
|
||||
/// The `T` type argument is the type of the return value of the new route.
|
||||
/// {@endtemplate}
|
||||
///
|
||||
/// {@macro flutter.widgets.navigator.pushNamed.arguments}
|
||||
///
|
||||
/// {@tool sample}
|
||||
///
|
||||
/// Typical usage is as follows:
|
||||
@ -886,8 +968,13 @@ class Navigator extends StatefulWidget {
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
@optionalTypeArgs
|
||||
static Future<T> pushNamedAndRemoveUntil<T extends Object>(BuildContext context, String newRouteName, RoutePredicate predicate) {
|
||||
return Navigator.of(context).pushNamedAndRemoveUntil<T>(newRouteName, predicate);
|
||||
static Future<T> pushNamedAndRemoveUntil<T extends Object>(
|
||||
BuildContext context,
|
||||
String newRouteName,
|
||||
RoutePredicate predicate, {
|
||||
Object arguments,
|
||||
}) {
|
||||
return Navigator.of(context).pushNamedAndRemoveUntil<T>(newRouteName, predicate, arguments: arguments);
|
||||
}
|
||||
|
||||
/// Push the given route onto the navigator that most tightly encloses the
|
||||
@ -1329,7 +1416,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin {
|
||||
Navigator.defaultRouteName,
|
||||
];
|
||||
final List<Route<dynamic>> plannedInitialRoutes = <Route<dynamic>>[
|
||||
_routeNamed<dynamic>(Navigator.defaultRouteName, allowNull: true),
|
||||
_routeNamed<dynamic>(Navigator.defaultRouteName, allowNull: true, arguments: null),
|
||||
];
|
||||
final List<String> routeParts = initialRouteName.split('/');
|
||||
if (initialRouteName.isNotEmpty) {
|
||||
@ -1337,7 +1424,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin {
|
||||
for (String part in routeParts) {
|
||||
routeName += '/$part';
|
||||
plannedInitialRouteNames.add(routeName);
|
||||
plannedInitialRoutes.add(_routeNamed<dynamic>(routeName, allowNull: true));
|
||||
plannedInitialRoutes.add(_routeNamed<dynamic>(routeName, allowNull: true, arguments: null));
|
||||
}
|
||||
}
|
||||
if (plannedInitialRoutes.contains(null)) {
|
||||
@ -1357,15 +1444,15 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin {
|
||||
);
|
||||
return true;
|
||||
}());
|
||||
push(_routeNamed<Object>(Navigator.defaultRouteName));
|
||||
push(_routeNamed<Object>(Navigator.defaultRouteName, arguments: null));
|
||||
} else {
|
||||
plannedInitialRoutes.forEach(push);
|
||||
}
|
||||
} else {
|
||||
Route<Object> route;
|
||||
if (initialRouteName != Navigator.defaultRouteName)
|
||||
route = _routeNamed<Object>(initialRouteName, allowNull: true);
|
||||
route ??= _routeNamed<Object>(Navigator.defaultRouteName);
|
||||
route = _routeNamed<Object>(initialRouteName, allowNull: true, arguments: null);
|
||||
route ??= _routeNamed<Object>(Navigator.defaultRouteName, arguments: null);
|
||||
push(route);
|
||||
}
|
||||
for (Route<dynamic> route in _history)
|
||||
@ -1416,12 +1503,13 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin {
|
||||
|
||||
bool _debugLocked = false; // used to prevent re-entrant calls to push, pop, and friends
|
||||
|
||||
Route<T> _routeNamed<T>(String name, { bool allowNull = false }) {
|
||||
Route<T> _routeNamed<T>(String name, { @required Object arguments, bool allowNull = false }) {
|
||||
assert(!_debugLocked);
|
||||
assert(name != null);
|
||||
final RouteSettings settings = RouteSettings(
|
||||
name: name,
|
||||
isInitialRoute: _history.isEmpty,
|
||||
arguments: arguments,
|
||||
);
|
||||
Route<T> route = widget.onGenerateRoute(settings);
|
||||
if (route == null && !allowNull) {
|
||||
@ -1458,6 +1546,8 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin {
|
||||
///
|
||||
/// {@macro flutter.widgets.navigator.pushNamed}
|
||||
///
|
||||
/// {@macro flutter.widgets.navigator.pushNamed.arguments}
|
||||
///
|
||||
/// {@tool sample}
|
||||
///
|
||||
/// Typical usage is as follows:
|
||||
@ -1469,8 +1559,11 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin {
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
@optionalTypeArgs
|
||||
Future<T> pushNamed<T extends Object>(String routeName) {
|
||||
return push<T>(_routeNamed<T>(routeName));
|
||||
Future<T> pushNamed<T extends Object>(
|
||||
String routeName, {
|
||||
Object arguments,
|
||||
}) {
|
||||
return push<T>(_routeNamed<T>(routeName, arguments: arguments));
|
||||
}
|
||||
|
||||
/// Replace the current route of the navigator by pushing the route named
|
||||
@ -1479,6 +1572,8 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin {
|
||||
///
|
||||
/// {@macro flutter.widgets.navigator.pushReplacementNamed}
|
||||
///
|
||||
/// {@macro flutter.widgets.navigator.pushNamed.arguments}
|
||||
///
|
||||
/// {@tool sample}
|
||||
///
|
||||
/// Typical usage is as follows:
|
||||
@ -1490,8 +1585,12 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin {
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
@optionalTypeArgs
|
||||
Future<T> pushReplacementNamed<T extends Object, TO extends Object>(String routeName, { TO result }) {
|
||||
return pushReplacement<T, TO>(_routeNamed<T>(routeName), result: result);
|
||||
Future<T> pushReplacementNamed<T extends Object, TO extends Object>(
|
||||
String routeName, {
|
||||
TO result,
|
||||
Object arguments,
|
||||
}) {
|
||||
return pushReplacement<T, TO>(_routeNamed<T>(routeName, arguments: arguments), result: result);
|
||||
}
|
||||
|
||||
/// Pop the current route off the navigator and push a named route in its
|
||||
@ -1499,6 +1598,8 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin {
|
||||
///
|
||||
/// {@macro flutter.widgets.navigator.popAndPushNamed}
|
||||
///
|
||||
/// {@macro flutter.widgets.navigator.pushNamed.arguments}
|
||||
///
|
||||
/// {@tool sample}
|
||||
///
|
||||
/// Typical usage is as follows:
|
||||
@ -1510,9 +1611,13 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin {
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
@optionalTypeArgs
|
||||
Future<T> popAndPushNamed<T extends Object, TO extends Object>(String routeName, { TO result }) {
|
||||
Future<T> popAndPushNamed<T extends Object, TO extends Object>(
|
||||
String routeName, {
|
||||
TO result,
|
||||
Object arguments,
|
||||
}) {
|
||||
pop<TO>(result);
|
||||
return pushNamed<T>(routeName);
|
||||
return pushNamed<T>(routeName, arguments: arguments);
|
||||
}
|
||||
|
||||
/// Push the route with the given name onto the navigator, and then remove all
|
||||
@ -1520,6 +1625,8 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin {
|
||||
///
|
||||
/// {@macro flutter.widgets.navigator.pushNamedAndRemoveUntil}
|
||||
///
|
||||
/// {@macro flutter.widgets.navigator.pushNamed.arguments}
|
||||
///
|
||||
/// {@tool sample}
|
||||
///
|
||||
/// Typical usage is as follows:
|
||||
@ -1531,8 +1638,12 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin {
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
@optionalTypeArgs
|
||||
Future<T> pushNamedAndRemoveUntil<T extends Object>(String newRouteName, RoutePredicate predicate) {
|
||||
return pushAndRemoveUntil<T>(_routeNamed<T>(newRouteName), predicate);
|
||||
Future<T> pushNamedAndRemoveUntil<T extends Object>(
|
||||
String newRouteName,
|
||||
RoutePredicate predicate, {
|
||||
Object arguments,
|
||||
}) {
|
||||
return pushAndRemoveUntil<T>(_routeNamed<T>(newRouteName, arguments: arguments), predicate);
|
||||
}
|
||||
|
||||
/// Push the given route onto the navigator.
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
@ -870,4 +871,149 @@ void main() {
|
||||
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('arguments for named routes on Navigator', (WidgetTester tester) async {
|
||||
GlobalKey currentRouteKey;
|
||||
final List<Object> arguments = <Object>[];
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
onGenerateRoute: (RouteSettings settings) {
|
||||
arguments.add(settings.arguments);
|
||||
return MaterialPageRoute<void>(
|
||||
settings: settings,
|
||||
builder: (BuildContext context) => Center(key: currentRouteKey = GlobalKey(), child: Text(settings.name)),
|
||||
);
|
||||
},
|
||||
));
|
||||
|
||||
expect(find.text('/'), findsOneWidget);
|
||||
expect(arguments.single, isNull);
|
||||
arguments.clear();
|
||||
|
||||
Navigator.pushNamed(
|
||||
currentRouteKey.currentContext,
|
||||
'/A',
|
||||
arguments: 'pushNamed',
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('/'), findsNothing);
|
||||
expect(find.text('/A'), findsOneWidget);
|
||||
expect(arguments.single, 'pushNamed');
|
||||
arguments.clear();
|
||||
|
||||
Navigator.popAndPushNamed(
|
||||
currentRouteKey.currentContext,
|
||||
'/B',
|
||||
arguments: 'popAndPushNamed',
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('/'), findsNothing);
|
||||
expect(find.text('/A'), findsNothing);
|
||||
expect(find.text('/B'), findsOneWidget);
|
||||
expect(arguments.single, 'popAndPushNamed');
|
||||
arguments.clear();
|
||||
|
||||
Navigator.pushNamedAndRemoveUntil(
|
||||
currentRouteKey.currentContext,
|
||||
'/C',
|
||||
(Route<dynamic> route) => route.isFirst,
|
||||
arguments: 'pushNamedAndRemoveUntil',
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('/'), findsNothing);
|
||||
expect(find.text('/A'), findsNothing);
|
||||
expect(find.text('/B'), findsNothing);
|
||||
expect(find.text('/C'), findsOneWidget);
|
||||
expect(arguments.single, 'pushNamedAndRemoveUntil');
|
||||
arguments.clear();
|
||||
|
||||
Navigator.pushReplacementNamed(
|
||||
currentRouteKey.currentContext,
|
||||
'/D',
|
||||
arguments: 'pushReplacementNamed',
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('/'), findsNothing);
|
||||
expect(find.text('/A'), findsNothing);
|
||||
expect(find.text('/B'), findsNothing);
|
||||
expect(find.text('/C'), findsNothing);
|
||||
expect(find.text('/D'), findsOneWidget);
|
||||
expect(arguments.single, 'pushReplacementNamed');
|
||||
arguments.clear();
|
||||
});
|
||||
|
||||
testWidgets('arguments for named routes on NavigatorState', (WidgetTester tester) async {
|
||||
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||
final List<Object> arguments = <Object>[];
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
navigatorKey: navigatorKey,
|
||||
onGenerateRoute: (RouteSettings settings) {
|
||||
arguments.add(settings.arguments);
|
||||
return MaterialPageRoute<void>(
|
||||
settings: settings,
|
||||
builder: (BuildContext context) => Center(child: Text(settings.name)),
|
||||
);
|
||||
},
|
||||
));
|
||||
|
||||
expect(find.text('/'), findsOneWidget);
|
||||
expect(arguments.single, isNull);
|
||||
arguments.clear();
|
||||
|
||||
navigatorKey.currentState.pushNamed(
|
||||
'/A',
|
||||
arguments:'pushNamed',
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('/'), findsNothing);
|
||||
expect(find.text('/A'), findsOneWidget);
|
||||
expect(arguments.single, 'pushNamed');
|
||||
arguments.clear();
|
||||
|
||||
navigatorKey.currentState.popAndPushNamed(
|
||||
'/B',
|
||||
arguments: 'popAndPushNamed',
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('/'), findsNothing);
|
||||
expect(find.text('/A'), findsNothing);
|
||||
expect(find.text('/B'), findsOneWidget);
|
||||
expect(arguments.single, 'popAndPushNamed');
|
||||
arguments.clear();
|
||||
|
||||
navigatorKey.currentState.pushNamedAndRemoveUntil(
|
||||
'/C',
|
||||
(Route<dynamic> route) => route.isFirst,
|
||||
arguments: 'pushNamedAndRemoveUntil',
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('/'), findsNothing);
|
||||
expect(find.text('/A'), findsNothing);
|
||||
expect(find.text('/B'), findsNothing);
|
||||
expect(find.text('/C'), findsOneWidget);
|
||||
expect(arguments.single, 'pushNamedAndRemoveUntil');
|
||||
arguments.clear();
|
||||
|
||||
navigatorKey.currentState.pushReplacementNamed(
|
||||
'/D',
|
||||
arguments: 'pushReplacementNamed',
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('/'), findsNothing);
|
||||
expect(find.text('/A'), findsNothing);
|
||||
expect(find.text('/B'), findsNothing);
|
||||
expect(find.text('/C'), findsNothing);
|
||||
expect(find.text('/D'), findsOneWidget);
|
||||
expect(arguments.single, 'pushReplacementNamed');
|
||||
arguments.clear();
|
||||
});
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
@ -114,6 +115,23 @@ void main() {
|
||||
expect(settings3.isInitialRoute, true);
|
||||
});
|
||||
|
||||
testWidgets('Route settings arguments', (WidgetTester tester) async {
|
||||
const RouteSettings settings = RouteSettings(name: 'A');
|
||||
expect(settings.arguments, isNull);
|
||||
|
||||
final Object arguments = Object();
|
||||
final RouteSettings settings2 = RouteSettings(name: 'A', arguments: arguments);
|
||||
expect(settings2.arguments, same(arguments));
|
||||
|
||||
final RouteSettings settings3 = settings2.copyWith();
|
||||
expect(settings3.arguments, equals(arguments));
|
||||
|
||||
final Object arguments2 = Object();
|
||||
final RouteSettings settings4 = settings2.copyWith(arguments: arguments2);
|
||||
expect(settings4.arguments, same(arguments2));
|
||||
expect(settings4.arguments, isNot(same(arguments)));
|
||||
});
|
||||
|
||||
testWidgets('Route management - push, replace, pop', (WidgetTester tester) async {
|
||||
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||
await tester.pumpWidget(
|
||||
|
Loading…
x
Reference in New Issue
Block a user