Add more checks when use Navigator 2.0 (#75624)
This commit is contained in:
parent
278065284d
commit
6ad9f784b3
@ -4450,10 +4450,30 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
|
||||
/// state restoration.
|
||||
@optionalTypeArgs
|
||||
Future<T?> push<T extends Object?>(Route<T> route) {
|
||||
assert(_debugCheckIsPagelessRoute(route));
|
||||
_pushEntry(_RouteEntry(route, initialState: _RouteLifecycle.push));
|
||||
return route.popped;
|
||||
}
|
||||
|
||||
bool _debugCheckIsPagelessRoute(Route<dynamic> route) {
|
||||
assert((){
|
||||
if (route.settings is Page) {
|
||||
FlutterError.reportError(
|
||||
FlutterErrorDetails(
|
||||
exception: FlutterError(
|
||||
'A page-based route should not be added using the imperative api. '
|
||||
'Provide a new list with the corresponding Page to Navigator.pages instead.'
|
||||
),
|
||||
library: 'widget library',
|
||||
stack: StackTrace.current,
|
||||
),
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool _debugIsStaticCallback(Function callback) {
|
||||
bool result = false;
|
||||
assert(() {
|
||||
@ -4596,6 +4616,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
|
||||
Future<T?> pushReplacement<T extends Object?, TO extends Object?>(Route<T> newRoute, { TO? result }) {
|
||||
assert(newRoute != null);
|
||||
assert(newRoute._navigator == null);
|
||||
assert(_debugCheckIsPagelessRoute(newRoute));
|
||||
_pushReplacementEntry(_RouteEntry(newRoute, initialState: _RouteLifecycle.pushReplace), result);
|
||||
return newRoute.popped;
|
||||
}
|
||||
@ -4703,6 +4724,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
|
||||
assert(newRoute != null);
|
||||
assert(newRoute._navigator == null);
|
||||
assert(newRoute.overlayEntries.isEmpty);
|
||||
assert(_debugCheckIsPagelessRoute(newRoute));
|
||||
_pushEntryAndRemoveUntil(_RouteEntry(newRoute, initialState: _RouteLifecycle.push), predicate);
|
||||
return newRoute.popped;
|
||||
}
|
||||
|
@ -2648,6 +2648,63 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
Widget _buildFrame(String action) {
|
||||
const TestPage myPage = TestPage(key: ValueKey<String>('1'), name:'initial');
|
||||
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
|
||||
'/' : (BuildContext context) => OnTapPage(
|
||||
id: action,
|
||||
onTap: (){
|
||||
if (action == 'push') {
|
||||
Navigator.of(context).push(myPage.createRoute(context));
|
||||
} else if (action == 'pushReplacement') {
|
||||
Navigator.of(context).pushReplacement(myPage.createRoute(context));
|
||||
} else if (action == 'pushAndRemoveUntil') {
|
||||
Navigator.of(context).pushAndRemoveUntil(myPage.createRoute(context), (_) => true);
|
||||
}
|
||||
},
|
||||
),
|
||||
};
|
||||
|
||||
return MaterialApp(routes: routes);
|
||||
}
|
||||
|
||||
void _checkException(WidgetTester tester) {
|
||||
final dynamic exception = tester.takeException();
|
||||
expect(exception, isFlutterError);
|
||||
final FlutterError error = exception as FlutterError;
|
||||
expect(
|
||||
error.toStringDeep(),
|
||||
equalsIgnoringHashCodes(
|
||||
'FlutterError\n'
|
||||
' A page-based route should not be added using the imperative api.\n'
|
||||
' Provide a new list with the corresponding Page to Navigator.pages\n'
|
||||
' instead.\n'
|
||||
''
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('throw if add page-based route using the imperative api - push', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(_buildFrame('push'));
|
||||
await tester.tap(find.text('push'));
|
||||
await tester.pumpAndSettle();
|
||||
_checkException(tester);
|
||||
});
|
||||
|
||||
testWidgets('throw if add page-based route using the imperative api - pushReplacement', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(_buildFrame('pushReplacement'));
|
||||
await tester.tap(find.text('pushReplacement'));
|
||||
await tester.pumpAndSettle();
|
||||
_checkException(tester);
|
||||
});
|
||||
|
||||
testWidgets('throw if add page-based route using the imperative api - pushAndRemoveUntil', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(_buildFrame('pushAndRemoveUntil'));
|
||||
await tester.tap(find.text('pushAndRemoveUntil'));
|
||||
await tester.pumpAndSettle();
|
||||
_checkException(tester);
|
||||
});
|
||||
|
||||
testWidgets('throw if page list is empty', (WidgetTester tester) async {
|
||||
final List<TestPage> myPages = <TestPage>[];
|
||||
final FlutterExceptionHandler? originalOnError = FlutterError.onError;
|
||||
|
Loading…
x
Reference in New Issue
Block a user