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.
|
/// state restoration.
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
Future<T?> push<T extends Object?>(Route<T> route) {
|
Future<T?> push<T extends Object?>(Route<T> route) {
|
||||||
|
assert(_debugCheckIsPagelessRoute(route));
|
||||||
_pushEntry(_RouteEntry(route, initialState: _RouteLifecycle.push));
|
_pushEntry(_RouteEntry(route, initialState: _RouteLifecycle.push));
|
||||||
return route.popped;
|
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 _debugIsStaticCallback(Function callback) {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
assert(() {
|
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 }) {
|
Future<T?> pushReplacement<T extends Object?, TO extends Object?>(Route<T> newRoute, { TO? result }) {
|
||||||
assert(newRoute != null);
|
assert(newRoute != null);
|
||||||
assert(newRoute._navigator == null);
|
assert(newRoute._navigator == null);
|
||||||
|
assert(_debugCheckIsPagelessRoute(newRoute));
|
||||||
_pushReplacementEntry(_RouteEntry(newRoute, initialState: _RouteLifecycle.pushReplace), result);
|
_pushReplacementEntry(_RouteEntry(newRoute, initialState: _RouteLifecycle.pushReplace), result);
|
||||||
return newRoute.popped;
|
return newRoute.popped;
|
||||||
}
|
}
|
||||||
@ -4703,6 +4724,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
|
|||||||
assert(newRoute != null);
|
assert(newRoute != null);
|
||||||
assert(newRoute._navigator == null);
|
assert(newRoute._navigator == null);
|
||||||
assert(newRoute.overlayEntries.isEmpty);
|
assert(newRoute.overlayEntries.isEmpty);
|
||||||
|
assert(_debugCheckIsPagelessRoute(newRoute));
|
||||||
_pushEntryAndRemoveUntil(_RouteEntry(newRoute, initialState: _RouteLifecycle.push), predicate);
|
_pushEntryAndRemoveUntil(_RouteEntry(newRoute, initialState: _RouteLifecycle.push), predicate);
|
||||||
return newRoute.popped;
|
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 {
|
testWidgets('throw if page list is empty', (WidgetTester tester) async {
|
||||||
final List<TestPage> myPages = <TestPage>[];
|
final List<TestPage> myPages = <TestPage>[];
|
||||||
final FlutterExceptionHandler? originalOnError = FlutterError.onError;
|
final FlutterExceptionHandler? originalOnError = FlutterError.onError;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user