File tree Expand file tree Collapse file tree 6 files changed +50
-14
lines changed Expand file tree Collapse file tree 6 files changed +50
-14
lines changed Original file line number Diff line number Diff line change @@ -38,11 +38,11 @@ class SynchronousFuture<T> implements Future<T> {
3838
3939 @override
4040 Future <R > then <R >(FutureOr <R > Function (T value) onValue, { Function ? onError }) {
41- final dynamic result = onValue (_value);
41+ final FutureOr < R > result = onValue (_value);
4242 if (result is Future <R >) {
4343 return result;
4444 }
45- return SynchronousFuture <R >(result as R );
45+ return SynchronousFuture <R >(result);
4646 }
4747
4848 @override
Original file line number Diff line number Diff line change @@ -247,17 +247,24 @@ abstract class CachingAssetBundle extends AssetBundle {
247247/// An [AssetBundle] that loads resources using platform messages.
248248class PlatformAssetBundle extends CachingAssetBundle {
249249 @override
250- Future <ByteData > load (String key) async {
250+ Future <ByteData > load (String key) {
251251 final Uint8List encoded = utf8.encoder.convert (Uri (path: Uri .encodeFull (key)).path);
252- final ByteData ? asset =
253- await ServicesBinding .instance.defaultBinaryMessenger.send ('flutter/assets' , encoded.buffer.asByteData ());
254- if (asset == null ) {
252+ final Future <ByteData >? future = ServicesBinding .instance.defaultBinaryMessenger.send ('flutter/assets' , encoded.buffer.asByteData ())? .then ((ByteData ? asset) {
253+ if (asset == null ) {
254+ throw FlutterError .fromParts (< DiagnosticsNode > [
255+ _errorSummaryWithKey (key),
256+ ErrorDescription ('The asset does not exist or has empty data.' ),
257+ ]);
258+ }
259+ return asset;
260+ });
261+ if (future == null ) {
255262 throw FlutterError .fromParts (< DiagnosticsNode > [
256- _errorSummaryWithKey (key),
257- ErrorDescription ('The asset does not exist or has empty data.' ),
258- ]);
263+ _errorSummaryWithKey (key),
264+ ErrorDescription ('The asset does not exist or has empty data.' ),
265+ ]);
259266 }
260- return asset ;
267+ return future ;
261268 }
262269
263270 @override
Original file line number Diff line number Diff line change @@ -645,7 +645,11 @@ class _FutureBuilderState<T> extends State<FutureBuilder<T>> {
645645 }());
646646
647647 });
648- _snapshot = _snapshot.inState (ConnectionState .waiting);
648+ // An implementation like `SynchronousFuture` may have already called the
649+ // .then closure. Do not overwrite it in that case.
650+ if (_snapshot.connectionState != ConnectionState .done) {
651+ _snapshot = _snapshot.inState (ConnectionState .waiting);
652+ }
649653 }
650654 }
651655
Original file line number Diff line number Diff line change 44
55import 'dart:async' ;
66
7+ import 'package:flutter/foundation.dart' ;
78import 'package:flutter/widgets.dart' ;
89import 'package:flutter_test/flutter_test.dart' ;
910
@@ -87,6 +88,20 @@ void main() {
8788 });
8889 });
8990 group ('FutureBuilder' , () {
91+ testWidgets ('gives expected snapshot with SynchronousFuture' , (WidgetTester tester) async {
92+ final SynchronousFuture <String > future = SynchronousFuture <String >('flutter' );
93+ await tester.pumpWidget (FutureBuilder <String >(
94+ future: future,
95+ builder: (BuildContext context, AsyncSnapshot <String > snapshot) {
96+ expect (snapshot.connectionState, ConnectionState .done);
97+ expect (snapshot.data, 'flutter' );
98+ expect (snapshot.error, null );
99+ expect (snapshot.stackTrace, null );
100+ return const Placeholder ();
101+ },
102+ ));
103+ });
104+
90105 testWidgets ('gracefully handles transition from null future' , (WidgetTester tester) async {
91106 final GlobalKey key = GlobalKey ();
92107 await tester.pumpWidget (FutureBuilder <String >(
Original file line number Diff line number Diff line change @@ -6,8 +6,8 @@ import 'dart:async';
66import 'dart:convert' ;
77import 'dart:io' ;
88
9+ import 'package:flutter/foundation.dart' ;
910import 'package:flutter/services.dart' ;
10- import 'package:flutter/widgets.dart' ;
1111import 'package:path/path.dart' as path;
1212// ignore: deprecated_member_use
1313import 'package:test_api/test_api.dart' as test_package;
@@ -42,7 +42,7 @@ void mockFlutterAssets() {
4242 /// platform messages.
4343 SystemChannels .navigation.setMockMethodCallHandler ((MethodCall methodCall) async {});
4444
45- ServicesBinding .instance.defaultBinaryMessenger.setMockMessageHandler ('flutter/assets' , (ByteData ? message) async {
45+ ServicesBinding .instance.defaultBinaryMessenger.setMockMessageHandler ('flutter/assets' , (ByteData ? message) {
4646 assert (message != null );
4747 String key = utf8.decode (message! .buffer.asUint8List ());
4848 File asset = File (path.join (assetFolderPath, key));
@@ -62,7 +62,7 @@ void mockFlutterAssets() {
6262 }
6363
6464 final Uint8List encoded = Uint8List .fromList (asset.readAsBytesSync ());
65- return Future <ByteData >. value (encoded.buffer.asByteData ());
65+ return SynchronousFuture <ByteData >(encoded.buffer.asByteData ());
6666 });
6767}
6868
Original file line number Diff line number Diff line change 1010import 'dart:async' ;
1111import 'dart:io' ;
1212
13+ import 'package:flutter/services.dart' ;
1314import 'package:flutter/widgets.dart' ;
1415import 'package:flutter_test/flutter_test.dart' ;
1516
@@ -90,4 +91,13 @@ void main() {
9091 binding.idle ();
9192 });
9293 });
94+
95+ testWidgets ('Assets in the tester can be loaded without turning event loop' , (WidgetTester tester) async {
96+ bool responded = false ;
97+ // The particular asset does not matter, as long as it exists.
98+ rootBundle.load ('AssetManifest.json' ).then ((ByteData data) {
99+ responded = true ;
100+ });
101+ expect (responded, true );
102+ });
93103}
You can’t perform that action at this time.
0 commit comments