fix issue 12999: Make assets available during tests (#31207)

This commit is contained in:
chunhtai 2019-04-18 15:31:47 -07:00 committed by GitHub
parent e69a8a15b3
commit b275e11170
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 71 additions and 2 deletions

View file

@ -5,6 +5,7 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
@ -16,6 +17,7 @@ import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart' show TestWindow;
import 'package:quiver/testing/async.dart';
import 'package:quiver/time.dart';
import 'package:path/path.dart' as path;
import 'package:test_api/test_api.dart' as test_package;
import 'package:stack_trace/stack_trace.dart' as stack_trace;
import 'package:vector_math/vector_math_64.dart';
@ -707,6 +709,7 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
super.initInstances();
window.onBeginFrame = null;
window.onDrawFrame = null;
_mockFlutterAssets();
}
FakeAsync _currentFakeAsync; // set in runTest; cleared in postTest
@ -736,6 +739,40 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
@override
int get microtaskCount => _currentFakeAsync.microtaskCount;
static Set<String> _allowedKeys;
void _mockFlutterAssets() {
if (!Platform.environment.containsKey('UNIT_TEST_ASSETS')) {
return;
}
final String assetFolderPath = Platform.environment['UNIT_TEST_ASSETS'];
_ensureInitialized(assetFolderPath);
BinaryMessages.setMockMessageHandler('flutter/assets', (ByteData message) {
final String key = utf8.decode(message.buffer.asUint8List());
if (_allowedKeys.contains(key)) {
final File asset = File(path.join(assetFolderPath, key));
final Uint8List encoded = Uint8List.fromList(asset.readAsBytesSync());
return Future<ByteData>.value(encoded.buffer.asByteData());
}
});
}
void _ensureInitialized(String assetFolderPath) {
if (_allowedKeys == null) {
final File manifestFile = File(
path.join(assetFolderPath, 'AssetManifest.json'));
final Map<String, dynamic> manifest = json.decode(
manifestFile.readAsStringSync());
_allowedKeys = <String>{
'AssetManifest.json',
};
for (List<dynamic> value in manifest.values) {
final List<String> strList = List<String>.from(value);
_allowedKeys.addAll(strList);
}
}
}
@override
Future<void> pump([ Duration duration, EnginePhase newPhase = EnginePhase.sendSemanticsUpdate ]) {
return TestAsyncUtils.guard<void>(() {

View file

@ -5,9 +5,11 @@
import 'dart:async';
import 'dart:math' as math;
import '../asset.dart';
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/platform.dart';
import '../bundle.dart';
import '../cache.dart';
import '../codegen.dart';
import '../dart/pub.dart';
@ -18,7 +20,6 @@ import '../test/coverage_collector.dart';
import '../test/event_printer.dart';
import '../test/runner.dart';
import '../test/watcher.dart';
class TestCommand extends FastFlutterCommand {
TestCommand({ bool verboseHelp = false }) {
requiresPubspecYaml();
@ -83,7 +84,14 @@ class TestCommand extends FastFlutterCommand {
abbr: 'j',
defaultsTo: math.max<int>(1, platform.numberOfProcessors - 2).toString(),
help: 'The number of concurrent test processes to run.',
valueHelp: 'jobs');
valueHelp: 'jobs'
)
..addFlag('test-assets',
defaultsTo: true,
negatable: true,
help: 'Whether to build the assets bundle for testing.\n'
'Consider using --no-test-assets if assets are not required.',
);
}
@override
@ -110,6 +118,10 @@ class TestCommand extends FastFlutterCommand {
if (shouldRunPub) {
await pubGet(context: PubContext.getVerifyContext(name), skipPubspecYamlCheck: true);
}
final bool buildTestAssets = argResults['test-assets'];
if (buildTestAssets) {
await _buildTestAsset();
}
final List<String> names = argResults['name'];
final List<String> plainNames = argResults['plain-name'];
final FlutterProject flutterProject = await FlutterProject.current();
@ -195,6 +207,7 @@ class TestCommand extends FastFlutterCommand {
trackWidgetCreation: argResults['track-widget-creation'],
updateGoldens: argResults['update-goldens'],
concurrency: jobs,
buildTestAssets: buildTestAssets,
flutterProject: flutterProject,
);
@ -208,6 +221,15 @@ class TestCommand extends FastFlutterCommand {
throwToolExit(null);
return const FlutterCommandResult(ExitStatus.success);
}
Future<void> _buildTestAsset() async {
final AssetBundle assetBundle = AssetBundleFactory.instance.createBundle();
final int build = await assetBundle.build();
if (build != 0) {
throwToolExit('Error: Failed to build asset bundle');
}
await writeBundle(fs.directory(fs.path.join('build', 'unit_test_assets')), assetBundle.entries);
}
}
Iterable<String> _findTests(Directory directory) {

View file

@ -88,6 +88,7 @@ void installHook({
Map<String, String> precompiledDillFiles,
bool trackWidgetCreation = false,
bool updateGoldens = false,
bool buildTestAssets = false,
int observatoryPort,
InternetAddressType serverType = InternetAddressType.IPv4,
Uri projectRootDirectory,
@ -110,6 +111,7 @@ void installHook({
precompiledDillFiles: precompiledDillFiles,
trackWidgetCreation: trackWidgetCreation,
updateGoldens: updateGoldens,
buildTestAssets: buildTestAssets,
projectRootDirectory: projectRootDirectory,
flutterProject: flutterProject,
icudtlPath: icudtlPath,
@ -390,6 +392,7 @@ class _FlutterPlatform extends PlatformPlugin {
this.precompiledDillFiles,
this.trackWidgetCreation,
this.updateGoldens,
this.buildTestAssets,
this.projectRootDirectory,
this.flutterProject,
this.icudtlPath,
@ -407,6 +410,7 @@ class _FlutterPlatform extends PlatformPlugin {
final Map<String, String> precompiledDillFiles;
final bool trackWidgetCreation;
final bool updateGoldens;
final bool buildTestAssets;
final Uri projectRootDirectory;
final FlutterProject flutterProject;
final String icudtlPath;
@ -977,6 +981,10 @@ class _FlutterPlatform extends PlatformPlugin {
'FONTCONFIG_FILE': _fontConfigFile.path,
'SERVER_PORT': serverPort.toString(),
};
if (buildTestAssets) {
environment['UNIT_TEST_ASSETS'] = fs.path.join(
flutterProject.directory.path, 'build', 'unit_test_assets');
}
return processManager.start(command, environment: environment);
}

View file

@ -35,6 +35,7 @@ Future<int> runTests(
bool updateGoldens = false,
TestWatcher watcher,
@required int concurrency,
bool buildTestAssets = false,
FlutterProject flutterProject,
String icudtlPath,
Directory coverageDirectory,
@ -83,6 +84,7 @@ Future<int> runTests(
precompiledDillFiles: precompiledDillFiles,
trackWidgetCreation: trackWidgetCreation,
updateGoldens: updateGoldens,
buildTestAssets: buildTestAssets,
projectRootDirectory: fs.currentDirectory.uri,
flutterProject: flutterProject,
icudtlPath: icudtlPath,