Skip to content

Commit 3cb7907

Browse files
authored
Fix silent test failure in image cache tests (flutter#56492)
1 parent 0a4f6cd commit 3cb7907

10 files changed

+1011
-916
lines changed

packages/flutter/lib/src/painting/image_cache.dart

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -286,10 +286,9 @@ class ImageCache {
286286
}
287287
}
288288

289-
void _trackLiveImage(Object key, _LiveImage image, { bool debugPutOk = true }) {
289+
void _trackLiveImage(Object key, _LiveImage image) {
290290
// Avoid adding unnecessary callbacks to the completer.
291291
_liveImages.putIfAbsent(key, () {
292-
assert(debugPutOk);
293292
// Even if no callers to ImageProvider.resolve have listened to the stream,
294293
// the cache is listening to the stream and will remove itself once the
295294
// image completes to move it from pending to keepAlive.
@@ -400,10 +399,6 @@ class ImageCache {
400399
imageSize,
401400
() => _liveImages.remove(key),
402401
),
403-
// This should result in a put if `loader()` above executed
404-
// synchronously, in which case syncCall is true and we arrived here
405-
// before we got a chance to track the image otherwise.
406-
debugPutOk: syncCall,
407402
);
408403

409404
final _PendingImage pendingImage = untrackedPendingImage ?? _pendingImages.remove(key);

packages/flutter/lib/src/painting/image_provider.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -347,10 +347,10 @@ abstract class ImageProvider<T> {
347347
stack: stack,
348348
context: ErrorDescription('while resolving an image'),
349349
silent: true, // could be a network error or whatnot
350-
informationCollector: collector
351-
);
352-
},
353-
);
350+
informationCollector: collector,
351+
);
352+
},
353+
);
354354
return stream;
355355
}
356356

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:async';
6+
import 'dart:typed_data';
7+
8+
import 'package:flutter/painting.dart';
9+
import 'package:flutter_test/flutter_test.dart';
10+
11+
import '../rendering/rendering_tester.dart';
12+
import 'image_data.dart';
13+
14+
void main() {
15+
TestRenderingFlutterBinding();
16+
17+
test('Clearing images while they\'re pending does not crash', () async {
18+
final Uint8List bytes = Uint8List.fromList(kTransparentImage);
19+
final MemoryImage memoryImage = MemoryImage(bytes);
20+
final ImageStream stream = memoryImage.resolve(ImageConfiguration.empty);
21+
final Completer<void> completer = Completer<void>();
22+
FlutterError.onError = (FlutterErrorDetails error) { completer.completeError(error.exception, error.stack); };
23+
stream.addListener(ImageStreamListener(
24+
(ImageInfo image, bool synchronousCall) {
25+
completer.complete();
26+
}
27+
));
28+
imageCache.clearLiveImages();
29+
await completer.future;
30+
});
31+
}

packages/flutter/test/painting/image_cache_resize_test.dart

Lines changed: 49 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -9,71 +9,70 @@ import '../rendering/rendering_tester.dart';
99
import 'mocks_for_image_cache.dart';
1010

1111
void main() {
12-
TestRenderingFlutterBinding(); // initializes the imageCache
13-
group(ImageCache, () {
14-
tearDown(() {
15-
imageCache.clear();
16-
imageCache.maximumSize = 1000;
17-
imageCache.maximumSizeBytes = 10485760;
18-
});
12+
TestRenderingFlutterBinding();
1913

20-
test('Image cache resizing based on count', () async {
21-
imageCache.maximumSize = 2;
14+
tearDown(() {
15+
imageCache.clear();
16+
imageCache.maximumSize = 1000;
17+
imageCache.maximumSizeBytes = 10485760;
18+
});
19+
20+
test('Image cache resizing based on count', () async {
21+
imageCache.maximumSize = 2;
2222

23-
final TestImageInfo a = await extractOneFrame(const TestImageProvider(1, 1).resolve(ImageConfiguration.empty)) as TestImageInfo;
24-
final TestImageInfo b = await extractOneFrame(const TestImageProvider(2, 2).resolve(ImageConfiguration.empty)) as TestImageInfo;
25-
final TestImageInfo c = await extractOneFrame(const TestImageProvider(3, 3).resolve(ImageConfiguration.empty)) as TestImageInfo;
26-
final TestImageInfo d = await extractOneFrame(const TestImageProvider(1, 4).resolve(ImageConfiguration.empty)) as TestImageInfo;
27-
expect(a.value, equals(1));
28-
expect(b.value, equals(2));
29-
expect(c.value, equals(3));
30-
expect(d.value, equals(4));
23+
final TestImageInfo a = await extractOneFrame(const TestImageProvider(1, 1).resolve(ImageConfiguration.empty)) as TestImageInfo;
24+
final TestImageInfo b = await extractOneFrame(const TestImageProvider(2, 2).resolve(ImageConfiguration.empty)) as TestImageInfo;
25+
final TestImageInfo c = await extractOneFrame(const TestImageProvider(3, 3).resolve(ImageConfiguration.empty)) as TestImageInfo;
26+
final TestImageInfo d = await extractOneFrame(const TestImageProvider(1, 4).resolve(ImageConfiguration.empty)) as TestImageInfo;
27+
expect(a.value, equals(1));
28+
expect(b.value, equals(2));
29+
expect(c.value, equals(3));
30+
expect(d.value, equals(4));
3131

32-
imageCache.maximumSize = 0;
32+
imageCache.maximumSize = 0;
3333

34-
final TestImageInfo e = await extractOneFrame(const TestImageProvider(1, 5).resolve(ImageConfiguration.empty)) as TestImageInfo;
35-
expect(e.value, equals(5));
34+
final TestImageInfo e = await extractOneFrame(const TestImageProvider(1, 5).resolve(ImageConfiguration.empty)) as TestImageInfo;
35+
expect(e.value, equals(5));
3636

37-
final TestImageInfo f = await extractOneFrame(const TestImageProvider(1, 6).resolve(ImageConfiguration.empty)) as TestImageInfo;
38-
expect(f.value, equals(6));
37+
final TestImageInfo f = await extractOneFrame(const TestImageProvider(1, 6).resolve(ImageConfiguration.empty)) as TestImageInfo;
38+
expect(f.value, equals(6));
3939

40-
imageCache.maximumSize = 3;
40+
imageCache.maximumSize = 3;
4141

42-
final TestImageInfo g = await extractOneFrame(const TestImageProvider(1, 7).resolve(ImageConfiguration.empty)) as TestImageInfo;
43-
expect(g.value, equals(7));
42+
final TestImageInfo g = await extractOneFrame(const TestImageProvider(1, 7).resolve(ImageConfiguration.empty)) as TestImageInfo;
43+
expect(g.value, equals(7));
4444

45-
final TestImageInfo h = await extractOneFrame(const TestImageProvider(1, 8).resolve(ImageConfiguration.empty)) as TestImageInfo;
46-
expect(h.value, equals(7));
47-
});
45+
final TestImageInfo h = await extractOneFrame(const TestImageProvider(1, 8).resolve(ImageConfiguration.empty)) as TestImageInfo;
46+
expect(h.value, equals(7));
47+
});
4848

49-
test('Image cache resizing based on size', () async {
50-
const TestImage testImage = TestImage(width: 8, height: 8); // 256 B.
51-
imageCache.maximumSizeBytes = 256 * 2;
49+
test('Image cache resizing based on size', () async {
50+
const TestImage testImage = TestImage(width: 8, height: 8); // 256 B.
51+
imageCache.maximumSizeBytes = 256 * 2;
5252

53-
final TestImageInfo a = await extractOneFrame(const TestImageProvider(1, 1, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
54-
final TestImageInfo b = await extractOneFrame(const TestImageProvider(2, 2, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
55-
final TestImageInfo c = await extractOneFrame(const TestImageProvider(3, 3, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
56-
final TestImageInfo d = await extractOneFrame(const TestImageProvider(1, 4, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
57-
expect(a.value, equals(1));
58-
expect(b.value, equals(2));
59-
expect(c.value, equals(3));
60-
expect(d.value, equals(4));
53+
final TestImageInfo a = await extractOneFrame(const TestImageProvider(1, 1, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
54+
final TestImageInfo b = await extractOneFrame(const TestImageProvider(2, 2, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
55+
final TestImageInfo c = await extractOneFrame(const TestImageProvider(3, 3, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
56+
final TestImageInfo d = await extractOneFrame(const TestImageProvider(1, 4, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
57+
expect(a.value, equals(1));
58+
expect(b.value, equals(2));
59+
expect(c.value, equals(3));
60+
expect(d.value, equals(4));
6161

62-
imageCache.maximumSizeBytes = 0;
62+
imageCache.maximumSizeBytes = 0;
6363

64-
final TestImageInfo e = await extractOneFrame(const TestImageProvider(1, 5, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
65-
expect(e.value, equals(5));
64+
final TestImageInfo e = await extractOneFrame(const TestImageProvider(1, 5, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
65+
expect(e.value, equals(5));
6666

67-
final TestImageInfo f = await extractOneFrame(const TestImageProvider(1, 6, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
68-
expect(f.value, equals(6));
67+
final TestImageInfo f = await extractOneFrame(const TestImageProvider(1, 6, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
68+
expect(f.value, equals(6));
6969

70-
imageCache.maximumSizeBytes = 256 * 3;
70+
imageCache.maximumSizeBytes = 256 * 3;
7171

72-
final TestImageInfo g = await extractOneFrame(const TestImageProvider(1, 7, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
73-
expect(g.value, equals(7));
72+
final TestImageInfo g = await extractOneFrame(const TestImageProvider(1, 7, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
73+
expect(g.value, equals(7));
7474

75-
final TestImageInfo h = await extractOneFrame(const TestImageProvider(1, 8, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
76-
expect(h.value, equals(7));
77-
});
75+
final TestImageInfo h = await extractOneFrame(const TestImageProvider(1, 8, image: testImage).resolve(ImageConfiguration.empty)) as TestImageInfo;
76+
expect(h.value, equals(7));
7877
});
7978
}

0 commit comments

Comments
 (0)