Unverified Commit 0763a57a authored by Rene Floor's avatar Rene Floor Committed by GitHub

Created method to report ImageChunkEvents (#55044)

parent 5c5bb485
...@@ -516,6 +516,23 @@ abstract class ImageStreamCompleter with Diagnosticable { ...@@ -516,6 +516,23 @@ abstract class ImageStreamCompleter with Diagnosticable {
} }
} }
/// Calls all the registered [ImageChunkListener]s (listeners with an
/// [ImageStreamListener.onChunk] specified) to notify them of a new
/// [ImageChunkEvent].
@protected
void reportImageChunkEvent(ImageChunkEvent event){
if (hasListeners) {
// Make a copy to allow for concurrent modification.
final List<ImageChunkListener> localListeners = _listeners
.map<ImageChunkListener>((ImageStreamListener listener) => listener.onChunk)
.where((ImageChunkListener chunkListener) => chunkListener != null)
.toList();
for (final ImageChunkListener listener in localListeners) {
listener(event);
}
}
}
/// Accumulates a list of strings describing the object's state. Subclasses /// Accumulates a list of strings describing the object's state. Subclasses
/// should override this to have their information included in [toString]. /// should override this to have their information included in [toString].
@override @override
...@@ -626,19 +643,8 @@ class MultiFrameImageStreamCompleter extends ImageStreamCompleter { ...@@ -626,19 +643,8 @@ class MultiFrameImageStreamCompleter extends ImageStreamCompleter {
); );
}); });
if (chunkEvents != null) { if (chunkEvents != null) {
chunkEvents.listen( chunkEvents.listen(reportImageChunkEvent,
(ImageChunkEvent event) { onError: (dynamic error, StackTrace stack) {
if (hasListeners) {
// Make a copy to allow for concurrent modification.
final List<ImageChunkListener> localListeners = _listeners
.map<ImageChunkListener>((ImageStreamListener listener) => listener.onChunk)
.where((ImageChunkListener chunkListener) => chunkListener != null)
.toList();
for (final ImageChunkListener listener in localListeners) {
listener(event);
}
}
}, onError: (dynamic error, StackTrace stack) {
reportError( reportError(
context: ErrorDescription('loading an image'), context: ErrorDescription('loading an image'),
exception: error, exception: error,
......
...@@ -78,6 +78,17 @@ class MockCodec implements Codec { ...@@ -78,6 +78,17 @@ class MockCodec implements Codec {
} }
class FakeEventReportingImageStreamCompleter extends ImageStreamCompleter {
FakeEventReportingImageStreamCompleter({Stream<ImageChunkEvent> chunkEvents,}) {
if (chunkEvents != null) {
chunkEvents.listen((ImageChunkEvent event) {
reportImageChunkEvent(event);
},
);
}
}
}
void main() { void main() {
testWidgets('Codec future fails', (WidgetTester tester) async { testWidgets('Codec future fails', (WidgetTester tester) async {
final Completer<Codec> completer = Completer<Codec>(); final Completer<Codec> completer = Completer<Codec>();
...@@ -128,7 +139,54 @@ void main() { ...@@ -128,7 +139,54 @@ void main() {
expect(mockCodec.numFramesAsked, 1); expect(mockCodec.numFramesAsked, 1);
}); });
testWidgets('Chunk events are delivered', (WidgetTester tester) async { testWidgets('Chunk events of base ImageStreamCompleter are delivered', (WidgetTester tester) async {
final List<ImageChunkEvent> chunkEvents = <ImageChunkEvent>[];
final StreamController<ImageChunkEvent> streamController = StreamController<ImageChunkEvent>();
final ImageStreamCompleter imageStream = FakeEventReportingImageStreamCompleter(
chunkEvents: streamController.stream,
);
imageStream.addListener(ImageStreamListener(
(ImageInfo image, bool synchronousCall) { },
onChunk: (ImageChunkEvent event) {
chunkEvents.add(event);
},
));
streamController.add(const ImageChunkEvent(cumulativeBytesLoaded: 1, expectedTotalBytes: 3));
streamController.add(const ImageChunkEvent(cumulativeBytesLoaded: 2, expectedTotalBytes: 3));
await tester.idle();
expect(chunkEvents.length, 2);
expect(chunkEvents[0].cumulativeBytesLoaded, 1);
expect(chunkEvents[0].expectedTotalBytes, 3);
expect(chunkEvents[1].cumulativeBytesLoaded, 2);
expect(chunkEvents[1].expectedTotalBytes, 3);
});
testWidgets('Chunk events of base ImageStreamCompleter are not buffered before listener registration', (WidgetTester tester) async {
final List<ImageChunkEvent> chunkEvents = <ImageChunkEvent>[];
final StreamController<ImageChunkEvent> streamController = StreamController<ImageChunkEvent>();
final ImageStreamCompleter imageStream = FakeEventReportingImageStreamCompleter(
chunkEvents: streamController.stream,
);
streamController.add(const ImageChunkEvent(cumulativeBytesLoaded: 1, expectedTotalBytes: 3));
await tester.idle();
imageStream.addListener(ImageStreamListener(
(ImageInfo image, bool synchronousCall) { },
onChunk: (ImageChunkEvent event) {
chunkEvents.add(event);
},
));
streamController.add(const ImageChunkEvent(cumulativeBytesLoaded: 2, expectedTotalBytes: 3));
await tester.idle();
expect(chunkEvents.length, 1);
expect(chunkEvents[0].cumulativeBytesLoaded, 2);
expect(chunkEvents[0].expectedTotalBytes, 3);
});
testWidgets('Chunk events of MultiFrameImageStreamCompleter are delivered', (WidgetTester tester) async {
final List<ImageChunkEvent> chunkEvents = <ImageChunkEvent>[]; final List<ImageChunkEvent> chunkEvents = <ImageChunkEvent>[];
final Completer<Codec> completer = Completer<Codec>(); final Completer<Codec> completer = Completer<Codec>();
final StreamController<ImageChunkEvent> streamController = StreamController<ImageChunkEvent>(); final StreamController<ImageChunkEvent> streamController = StreamController<ImageChunkEvent>();
...@@ -155,7 +213,7 @@ void main() { ...@@ -155,7 +213,7 @@ void main() {
expect(chunkEvents[1].expectedTotalBytes, 3); expect(chunkEvents[1].expectedTotalBytes, 3);
}); });
testWidgets('Chunk events are not buffered before listener registration', (WidgetTester tester) async { testWidgets('Chunk events of MultiFrameImageStreamCompleter are not buffered before listener registration', (WidgetTester tester) async {
final List<ImageChunkEvent> chunkEvents = <ImageChunkEvent>[]; final List<ImageChunkEvent> chunkEvents = <ImageChunkEvent>[];
final Completer<Codec> completer = Completer<Codec>(); final Completer<Codec> completer = Completer<Codec>();
final StreamController<ImageChunkEvent> streamController = StreamController<ImageChunkEvent>(); final StreamController<ImageChunkEvent> streamController = StreamController<ImageChunkEvent>();
......
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