Fix test that leaks images. (#148494)

Contributes to https://github.com/flutter/flutter/issues/145599

Repro:
`flutter test test/cupertino/tab_scaffold_test.dart  --dart-define LEAK_TRACKING=true --plain-name "Adding new tabs does not crash the app"`

What is going on: 
1. ImageCache.putIfAbsent, in case the image already existed in the cache, invokes ImageCache._trackLiveImage, that creates _LiveImage and passes the image's completer as parameter `completer`
3. _LiveImage constructor invokes super constructor (of _CachedImageBase) that initializes the member `handle`
4. `handle` is disposed [using scheduler](c698e694c8/packages/flutter/lib/src/painting/image_cache.dart (L633)), and disposal does not happen in time of test completion.

Adding delay to the test increases number of not disposed objects from 30 to 120.
Should we force schedule at the end of the widget tests somehow to make scheduler switched to right state?

Creation call stack:

```
#9______new_ImageStreamCompleterHandle.__(package:flutter/src/painting/image_stream.dart:465:41)
#10_____ImageStreamCompleter.keepAlive_(package:flutter/src/painting/image_stream.dart:655:39)
#11_____new__CachedImageBase_(package:flutter/src/painting/image_cache.dart:609:27)
#12_____new__LiveImage_(package:flutter/src/painting/image_cache.dart:647:9)
#13_____ImageCache._trackLiveImage.<anonymous_closure>_(package:flutter/src/painting/image_cache.dart:302:14)
#14______LinkedHashMapMixin.putIfAbsent_(dart:collection-patch/compact_hash.dart:543:23)
#15_____ImageCache._trackLiveImage_(package:flutter/src/painting/image_cache.dart:296:17)
#16_____ImageCache.putIfAbsent_(package:flutter/src/painting/image_cache.dart:378:7)
#17_____ImageProvider.resolveStreamForKey_(package:flutter/src/painting/image_provider.dart:517:81)
                      #18_____ScrollAwareImageProvider.resolveStreamForKey_(package:flutter/src/widgets/scroll_aware_image_provider.dart:104:19)
#19_____ImageProvider.resolve.<anonymous_closure>_(package:flutter/src/painting/image_provider.dart:366:9)
#20_____ImageProvider._createErrorHandlerAndKey.<anonymous_closure>_(package:flutter/src/painting/image_provider.dart:479:24)
#21_____SynchronousFuture.then_(package:flutter/src/foundation/synchronous_future.dart:43:39)
                      #22_____ImageProvider._createErrorHandlerAndKey_(package:flutter/src/painting/image_provider.dart:476:9)
#23_____ImageProvider.resolve_(package:flutter/src/painting/image_provider.dart:363:5)
#24______ImageState._resolveImage_(package:flutter/src/widgets/image.dart:1111:16)
#25______ImageState.didChangeDependencies_(package:flutter/src/widgets/image.dart:1061:5)
#26_____StatefulElement._firstBuild_(package:flutter/src/widgets/framework.dart:5630:11)
#27_____ComponentElement.mount_(package:flutter/src/widgets/framework.dart:5457:5)
#28_____Element.inflateWidget_(package:flutter/src/widgets/framework.dart:4334:16)
#29_____Element.updateChild_(package:flutter/src/widgets/framework.dart:3843:18)
#30_____SingleChildRenderObjectElement.mount_(package:flutter/src/widgets/framework.dart:6763:14)
```
This commit is contained in:
Polina Cherkasova 2024-05-21 14:33:20 -07:00 committed by GitHub
parent 24979ab2c5
commit 87aa8423a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -47,6 +47,10 @@ void main() {
selectedTabs = <int>[];
});
tearDown(() {
imageCache.clear();
});
BottomNavigationBarItem tabGenerator(int index) {
return BottomNavigationBarItem(
icon: ImageIcon(MemoryImage(Uint8List.fromList(kTransparentImage))),
@ -632,7 +636,9 @@ void main() {
});
// Regression test for https://github.com/flutter/flutter/issues/33455
testWidgets('Adding new tabs does not crash the app', (WidgetTester tester) async {
testWidgets('Adding new tabs does not crash the app',
experimentalLeakTesting: LeakTesting.settings.withTrackedAll(),
(WidgetTester tester) async {
final List<int> tabsPainted = <int>[];
final CupertinoTabController controller = CupertinoTabController();
addTearDown(controller.dispose);