Load assets in flutter_test without turning event loop. (#115123)
* Load assets in flutter_test without turning event loop. This makes it possible to load an asset without actually turning the event loop. This is importnat because our FakeAsync zones may cause people to sprinkle in extra pumpAndSettles in when running tests that load assets, which is undesirable. * fix null checking
This commit is contained in:
parent
6e89042d9b
commit
88e49ed274
@ -38,11 +38,11 @@ class SynchronousFuture<T> implements Future<T> {
|
||||
|
||||
@override
|
||||
Future<R> then<R>(FutureOr<R> Function(T value) onValue, { Function? onError }) {
|
||||
final dynamic result = onValue(_value);
|
||||
final FutureOr<R> result = onValue(_value);
|
||||
if (result is Future<R>) {
|
||||
return result;
|
||||
}
|
||||
return SynchronousFuture<R>(result as R);
|
||||
return SynchronousFuture<R>(result);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -247,17 +247,24 @@ abstract class CachingAssetBundle extends AssetBundle {
|
||||
/// An [AssetBundle] that loads resources using platform messages.
|
||||
class PlatformAssetBundle extends CachingAssetBundle {
|
||||
@override
|
||||
Future<ByteData> load(String key) async {
|
||||
Future<ByteData> load(String key) {
|
||||
final Uint8List encoded = utf8.encoder.convert(Uri(path: Uri.encodeFull(key)).path);
|
||||
final ByteData? asset =
|
||||
await ServicesBinding.instance.defaultBinaryMessenger.send('flutter/assets', encoded.buffer.asByteData());
|
||||
if (asset == null) {
|
||||
final Future<ByteData>? future = ServicesBinding.instance.defaultBinaryMessenger.send('flutter/assets', encoded.buffer.asByteData())?.then((ByteData? asset) {
|
||||
if (asset == null) {
|
||||
throw FlutterError.fromParts(<DiagnosticsNode>[
|
||||
_errorSummaryWithKey(key),
|
||||
ErrorDescription('The asset does not exist or has empty data.'),
|
||||
]);
|
||||
}
|
||||
return asset;
|
||||
});
|
||||
if (future == null) {
|
||||
throw FlutterError.fromParts(<DiagnosticsNode>[
|
||||
_errorSummaryWithKey(key),
|
||||
ErrorDescription('The asset does not exist or has empty data.'),
|
||||
]);
|
||||
_errorSummaryWithKey(key),
|
||||
ErrorDescription('The asset does not exist or has empty data.'),
|
||||
]);
|
||||
}
|
||||
return asset;
|
||||
return future;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -6,8 +6,8 @@ import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
// ignore: deprecated_member_use
|
||||
import 'package:test_api/test_api.dart' as test_package;
|
||||
@ -42,7 +42,7 @@ void mockFlutterAssets() {
|
||||
/// platform messages.
|
||||
SystemChannels.navigation.setMockMethodCallHandler((MethodCall methodCall) async {});
|
||||
|
||||
ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler('flutter/assets', (ByteData? message) async {
|
||||
ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler('flutter/assets', (ByteData? message) {
|
||||
assert(message != null);
|
||||
String key = utf8.decode(message!.buffer.asUint8List());
|
||||
File asset = File(path.join(assetFolderPath, key));
|
||||
@ -62,7 +62,7 @@ void mockFlutterAssets() {
|
||||
}
|
||||
|
||||
final Uint8List encoded = Uint8List.fromList(asset.readAsBytesSync());
|
||||
return Future<ByteData>.value(encoded.buffer.asByteData());
|
||||
return SynchronousFuture<ByteData>(encoded.buffer.asByteData());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
@ -90,4 +91,13 @@ void main() {
|
||||
binding.idle();
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('Assets in the tester can be loaded without turning event loop', (WidgetTester tester) async {
|
||||
bool responded = false;
|
||||
// The particular asset does not matter, as long as it exists.
|
||||
rootBundle.load('AssetManifest.json').then((ByteData data) {
|
||||
responded = true;
|
||||
});
|
||||
expect(responded, true);
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user