Unverified Commit 6ad9f784 authored by xubaolin's avatar xubaolin Committed by GitHub

Add more checks when use Navigator 2.0 (#75624)

parent 27806528
......@@ -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;
......
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