_RouterState should dispose created _RestorableRouteInformation. (#136556)

### Description
- Fixes https://github.com/flutter/flutter/issues/134205.

### Tests
- Removes ignoring the `_RestorableRouteInformation` leak from `cupertino/app_test.dart`;
- Removes ignoring the `_RestorableRouteInformation` leak from `material/app_test.dart`;
- Removes ignoring the `_RestorableRouteInformation` leak from `widgets/app_test.dart`;
- Removes ignoring the `_RestorableRouteInformation` leak from `widgets/route_notification_messages_test.dart`;
- Removes ignoring the `_RestorableRouteInformation` leak from `widgets/router_restoration_test.dart`;
- Updates `widgets/router_test.dart` to use `testWidgetsWithLeakTracking`.
This commit is contained in:
Kostia Sokolovskyi
2023-10-14 04:58:17 +02:00
committed by GitHub
parent 5b7e9d6072
commit 2c3db435a8
7 changed files with 421 additions and 373 deletions

View File

@@ -632,6 +632,10 @@ class _RouterState<T> extends State<Router<T>> with RestorationMixin {
}
void _reportRouteInformation(Duration timestamp) {
if (!mounted) {
return;
}
assert(_routeInformationReportingTaskScheduled);
_routeInformationReportingTaskScheduled = false;
@@ -726,6 +730,7 @@ class _RouterState<T> extends State<Router<T>> with RestorationMixin {
@override
void dispose() {
_routeInformation.dispose();
widget.routeInformationProvider?.removeListener(_handleRouteInformationProviderNotification);
widget.backButtonDispatcher?.removeCallback(_handleBackButtonDispatcherNotification);
widget.routerDelegate.removeListener(_handleRouterDelegateNotification);

View File

@@ -178,12 +178,7 @@ void main() {
await tester.binding.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
await tester.pumpAndSettle();
expect(find.text('popped'), findsOneWidget);
},
// TODO(polina-c): remove after fixing
// https://github.com/flutter/flutter/issues/134205
leakTrackingTestConfig: const LeakTrackingTestConfig(
allowAllNotDisposed: true,
));
});
testWidgetsWithLeakTracking('CupertinoApp.router route information parser is optional', (WidgetTester tester) async {
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
@@ -209,12 +204,7 @@ void main() {
await tester.binding.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
await tester.pumpAndSettle();
expect(find.text('popped'), findsOneWidget);
},
// TODO(polina-c): remove after fixing
// https://github.com/flutter/flutter/issues/134205
leakTrackingTestConfig: const LeakTrackingTestConfig(
allowAllNotDisposed: true,
));
});
testWidgetsWithLeakTracking('CupertinoApp.router throw if route information provider is provided but no route information parser', (WidgetTester tester) async {
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
@@ -300,12 +290,7 @@ void main() {
await tester.binding.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
await tester.pumpAndSettle();
expect(find.text('popped'), findsOneWidget);
},
// TODO(polina-c): remove after fixing
// https://github.com/flutter/flutter/issues/134205
leakTrackingTestConfig: const LeakTrackingTestConfig(
allowAllNotDisposed: true,
));
});
testWidgetsWithLeakTracking('CupertinoApp has correct default ScrollBehavior', (WidgetTester tester) async {
late BuildContext capturedContext;

View File

@@ -1114,12 +1114,7 @@ void main() {
await tester.binding.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
await tester.pumpAndSettle();
expect(find.text('popped'), findsOneWidget);
},
// TODO(polina-c): remove after fixing
// https://github.com/flutter/flutter/issues/134205
leakTrackingTestConfig: const LeakTrackingTestConfig(
allowAllNotDisposed: true,
));
});
testWidgetsWithLeakTracking('MaterialApp.router route information parser is optional', (WidgetTester tester) async {
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
@@ -1145,12 +1140,7 @@ void main() {
await tester.binding.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
await tester.pumpAndSettle();
expect(find.text('popped'), findsOneWidget);
},
// TODO(polina-c): remove after fixing
// https://github.com/flutter/flutter/issues/134205
leakTrackingTestConfig: const LeakTrackingTestConfig(
allowAllNotDisposed: true,
));
});
testWidgetsWithLeakTracking('MaterialApp.router throw if route information provider is provided but no route information parser', (WidgetTester tester) async {
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
@@ -1236,12 +1226,7 @@ void main() {
await tester.binding.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
await tester.pumpAndSettle();
expect(find.text('popped'), findsOneWidget);
},
// TODO(polina-c): remove after fixing
// https://github.com/flutter/flutter/issues/134205
leakTrackingTestConfig: const LeakTrackingTestConfig(
allowAllNotDisposed: true,
));
});
testWidgetsWithLeakTracking('MaterialApp.builder can build app without a Navigator', (WidgetTester tester) async {
Widget? builderChild;

View File

@@ -304,12 +304,7 @@ void main() {
await tester.binding.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
await tester.pumpAndSettle();
expect(find.text('popped'), findsOneWidget);
},
leakTrackingTestConfig: const LeakTrackingTestConfig(
// TODO(ksokolovskyi): remove after fixing
// https://github.com/flutter/flutter/issues/134205
notDisposedAllowList: <String, int?> {'_RestorableRouteInformation': 1},
));
});
testWidgetsWithLeakTracking('WidgetsApp.router route information parser is optional', (WidgetTester tester) async {
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
@@ -336,12 +331,7 @@ void main() {
await tester.binding.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
await tester.pumpAndSettle();
expect(find.text('popped'), findsOneWidget);
},
leakTrackingTestConfig: const LeakTrackingTestConfig(
// TODO(ksokolovskyi): remove after fixing
// https://github.com/flutter/flutter/issues/134205
notDisposedAllowList: <String, int?> {'_RestorableRouteInformation': 1},
));
});
testWidgetsWithLeakTracking('WidgetsApp.router throw if route information provider is provided but no route information parser', (WidgetTester tester) async {
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
@@ -432,12 +422,7 @@ void main() {
await tester.binding.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
await tester.pumpAndSettle();
expect(find.text('popped'), findsOneWidget);
},
leakTrackingTestConfig: const LeakTrackingTestConfig(
// TODO(ksokolovskyi): remove after fixing
// https://github.com/flutter/flutter/issues/134205
notDisposedAllowList: <String, int?> {'_RestorableRouteInformation': 1},
));
});
testWidgetsWithLeakTracking('WidgetsApp.router has correct default', (WidgetTester tester) async {
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
@@ -453,12 +438,7 @@ void main() {
color: const Color(0xFF123456),
));
expect(find.text('/'), findsOneWidget);
},
leakTrackingTestConfig: const LeakTrackingTestConfig(
// TODO(ksokolovskyi): remove after fixing
// https://github.com/flutter/flutter/issues/134205
notDisposedAllowList: <String, int?> {'_RestorableRouteInformation': 1},
));
});
testWidgetsWithLeakTracking('WidgetsApp has correct default ScrollBehavior', (WidgetTester tester) async {
late BuildContext capturedContext;

View File

@@ -316,12 +316,7 @@ void main() {
'replace': false,
}),
]);
},
leakTrackingTestConfig: const LeakTrackingTestConfig(
// TODO(ksokolovskyi): remove after fixing
// https://github.com/flutter/flutter/issues/134205
notDisposedAllowList: <String, int?> {'_RestorableRouteInformation': 1},
));
});
}
typedef SimpleRouterDelegateBuilder = Widget Function(BuildContext, RouteInformation);

View File

@@ -40,12 +40,7 @@ void main() {
expect(find.text('Current config: /foo'), findsOneWidget);
expect(delegate().newRoutePaths, isEmpty);
expect(delegate().restoredRoutePaths, <String>['/foo', '/foo']);
},
leakTrackingTestConfig: const LeakTrackingTestConfig(
// TODO(ksokolovskyi): remove after fixing
// https://github.com/flutter/flutter/issues/134205
notDisposedAllowList: <String, int?> {'_RestorableRouteInformation': 2},
));
});
testWidgets('Router state restoration with RouteInformationProvider', (WidgetTester tester) async {
final UniqueKey router = UniqueKey();

File diff suppressed because it is too large Load Diff