mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[flutter_tools] remove most globals from build system and tests (#63697)
Remove globals and testbed to simplify test cases, using the existing environment configuration. This is some pre-factoring work to make landing #63610 easier
This commit is contained in:
parent
32ee00849c
commit
06c3de3285
@ -6,7 +6,7 @@ import '../../artifacts.dart';
|
||||
import '../../base/build.dart';
|
||||
import '../../base/file_system.dart';
|
||||
import '../../build_info.dart';
|
||||
import '../../globals.dart' as globals;
|
||||
import '../../globals.dart' as globals hide fs, artifacts, logger, processManager;
|
||||
import '../build_system.dart';
|
||||
import '../depfile.dart';
|
||||
import '../exceptions.dart';
|
||||
@ -52,13 +52,13 @@ abstract class AndroidAssetBundle extends Target {
|
||||
|
||||
// Only copy the prebuilt runtimes and kernel blob in debug mode.
|
||||
if (buildMode == BuildMode.debug) {
|
||||
final String vmSnapshotData = globals.artifacts.getArtifactPath(Artifact.vmSnapshotData, mode: BuildMode.debug);
|
||||
final String isolateSnapshotData = globals.artifacts.getArtifactPath(Artifact.isolateSnapshotData, mode: BuildMode.debug);
|
||||
final String vmSnapshotData = environment.artifacts.getArtifactPath(Artifact.vmSnapshotData, mode: BuildMode.debug);
|
||||
final String isolateSnapshotData = environment.artifacts.getArtifactPath(Artifact.isolateSnapshotData, mode: BuildMode.debug);
|
||||
environment.buildDir.childFile('app.dill')
|
||||
.copySync(outputDirectory.childFile('kernel_blob.bin').path);
|
||||
globals.fs.file(vmSnapshotData)
|
||||
environment.fileSystem.file(vmSnapshotData)
|
||||
.copySync(outputDirectory.childFile('vm_snapshot_data').path);
|
||||
globals.fs.file(isolateSnapshotData)
|
||||
environment.fileSystem.file(isolateSnapshotData)
|
||||
.copySync(outputDirectory.childFile('isolate_snapshot_data').path);
|
||||
}
|
||||
if (_copyAssets) {
|
||||
@ -68,8 +68,8 @@ abstract class AndroidAssetBundle extends Target {
|
||||
targetPlatform: TargetPlatform.android,
|
||||
);
|
||||
final DepfileService depfileService = DepfileService(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
fileSystem: environment.fileSystem,
|
||||
logger: environment.logger,
|
||||
);
|
||||
depfileService.writeToFile(
|
||||
assetDepfile,
|
||||
@ -215,11 +215,11 @@ class AndroidAot extends AotElfBase {
|
||||
Future<void> build(Environment environment) async {
|
||||
final AOTSnapshotter snapshotter = AOTSnapshotter(
|
||||
reportTimings: false,
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
fileSystem: environment.fileSystem,
|
||||
logger: environment.logger,
|
||||
xcode: globals.xcode,
|
||||
processManager: globals.processManager,
|
||||
artifacts: globals.artifacts,
|
||||
processManager: environment.processManager,
|
||||
artifacts: environment.artifacts,
|
||||
);
|
||||
final Directory output = environment.buildDir.childDirectory(_androidAbiName);
|
||||
final String splitDebugInfo = environment.defines[kSplitDebugInfo];
|
||||
|
||||
@ -11,7 +11,6 @@ import '../../base/logger.dart';
|
||||
import '../../build_info.dart';
|
||||
import '../../convert.dart';
|
||||
import '../../devfs.dart';
|
||||
import '../../globals.dart' as globals;
|
||||
import '../build_system.dart';
|
||||
import '../depfile.dart';
|
||||
import 'common.dart';
|
||||
@ -44,10 +43,12 @@ Future<Depfile> copyAssets(Environment environment, Directory outputDirectory, {
|
||||
);
|
||||
|
||||
final File pubspecFile = environment.projectDir.childFile('pubspec.yaml');
|
||||
final AssetBundle assetBundle = AssetBundleFactory.instance.createBundle();
|
||||
// Only the default asset bundle style is supported in assemble.
|
||||
final AssetBundle assetBundle = AssetBundleFactory.defaultInstance.createBundle();
|
||||
final int resultCode = await assetBundle.build(
|
||||
manifestPath: pubspecFile.path,
|
||||
packagesPath: environment.projectDir.childFile('.packages').path,
|
||||
assetDirPath: null,
|
||||
);
|
||||
if (resultCode != 0) {
|
||||
throw Exception('Failed to bundle asset files.');
|
||||
@ -63,10 +64,10 @@ Future<Depfile> copyAssets(Environment environment, Directory outputDirectory, {
|
||||
final IconTreeShaker iconTreeShaker = IconTreeShaker(
|
||||
environment,
|
||||
assetBundle.entries[kFontManifestJson] as DevFSStringContent,
|
||||
processManager: globals.processManager,
|
||||
logger: globals.logger,
|
||||
fileSystem: globals.fs,
|
||||
artifacts: globals.artifacts,
|
||||
processManager: environment.processManager,
|
||||
logger: environment.logger,
|
||||
fileSystem: environment.fileSystem,
|
||||
artifacts: environment.artifacts,
|
||||
);
|
||||
|
||||
final Map<String, DevFSContent> assetEntries = <String, DevFSContent>{
|
||||
@ -85,7 +86,8 @@ Future<Depfile> copyAssets(Environment environment, Directory outputDirectory, {
|
||||
// to `%23.ext`. However, we have to keep it this way since the
|
||||
// platform channels in the framework will URI encode these values,
|
||||
// and the native APIs will look for files this way.
|
||||
final File file = globals.fs.file(globals.fs.path.join(outputDirectory.path, entry.key));
|
||||
final File file = environment.fileSystem.file(
|
||||
environment.fileSystem.path.join(outputDirectory.path, entry.key));
|
||||
outputs.add(file);
|
||||
file.parent.createSync(recursive: true);
|
||||
final DevFSContent content = entry.value;
|
||||
@ -222,8 +224,8 @@ class CopyAssets extends Target {
|
||||
targetPlatform: TargetPlatform.android,
|
||||
);
|
||||
final DepfileService depfileService = DepfileService(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
fileSystem: environment.fileSystem,
|
||||
logger: environment.logger,
|
||||
);
|
||||
depfileService.writeToFile(
|
||||
depfile,
|
||||
|
||||
@ -10,8 +10,7 @@ import '../../base/file_system.dart';
|
||||
import '../../build_info.dart';
|
||||
import '../../compile.dart';
|
||||
import '../../dart/package_map.dart';
|
||||
import '../../globals.dart' as globals;
|
||||
import '../../project.dart';
|
||||
import '../../globals.dart' as globals hide fs, processManager, artifacts, logger;
|
||||
import '../build_system.dart';
|
||||
import '../depfile.dart';
|
||||
import '../exceptions.dart';
|
||||
@ -107,13 +106,13 @@ class CopyFlutterBundle extends Target {
|
||||
|
||||
// Only copy the prebuilt runtimes and kernel blob in debug mode.
|
||||
if (buildMode == BuildMode.debug) {
|
||||
final String vmSnapshotData = globals.artifacts.getArtifactPath(Artifact.vmSnapshotData, mode: BuildMode.debug);
|
||||
final String isolateSnapshotData = globals.artifacts.getArtifactPath(Artifact.isolateSnapshotData, mode: BuildMode.debug);
|
||||
final String vmSnapshotData = environment.artifacts.getArtifactPath(Artifact.vmSnapshotData, mode: BuildMode.debug);
|
||||
final String isolateSnapshotData = environment.artifacts.getArtifactPath(Artifact.isolateSnapshotData, mode: BuildMode.debug);
|
||||
environment.buildDir.childFile('app.dill')
|
||||
.copySync(environment.outputDir.childFile('kernel_blob.bin').path);
|
||||
globals.fs.file(vmSnapshotData)
|
||||
environment.fileSystem.file(vmSnapshotData)
|
||||
.copySync(environment.outputDir.childFile('vm_snapshot_data').path);
|
||||
globals.fs.file(isolateSnapshotData)
|
||||
environment.fileSystem.file(isolateSnapshotData)
|
||||
.copySync(environment.outputDir.childFile('isolate_snapshot_data').path);
|
||||
}
|
||||
final Depfile assetDepfile = await copyAssets(
|
||||
@ -122,8 +121,8 @@ class CopyFlutterBundle extends Target {
|
||||
targetPlatform: TargetPlatform.android,
|
||||
);
|
||||
final DepfileService depfileService = DepfileService(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
fileSystem: environment.fileSystem,
|
||||
logger: environment.logger,
|
||||
);
|
||||
depfileService.writeToFile(
|
||||
assetDepfile,
|
||||
@ -191,8 +190,11 @@ class KernelSnapshot extends Target {
|
||||
|
||||
@override
|
||||
Future<void> build(Environment environment) async {
|
||||
final KernelCompiler compiler = await kernelCompilerFactory.create(
|
||||
FlutterProject.fromDirectory(environment.projectDir),
|
||||
final KernelCompiler compiler = KernelCompiler(
|
||||
fileSystem: environment.fileSystem,
|
||||
logger: environment.logger,
|
||||
processManager: environment.processManager,
|
||||
artifacts: environment.artifacts,
|
||||
);
|
||||
if (environment.defines[kBuildMode] == null) {
|
||||
throw MissingDefineException(kBuildMode, 'kernel_snapshot');
|
||||
@ -201,9 +203,9 @@ class KernelSnapshot extends Target {
|
||||
throw MissingDefineException(kTargetPlatform, 'kernel_snapshot');
|
||||
}
|
||||
final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]);
|
||||
final String targetFile = environment.defines[kTargetFile] ?? globals.fs.path.join('lib', 'main.dart');
|
||||
final String targetFile = environment.defines[kTargetFile] ?? environment.fileSystem.path.join('lib', 'main.dart');
|
||||
final File packagesFile = environment.projectDir.childFile('.packages');
|
||||
final String targetFileAbsolute = globals.fs.file(targetFile).absolute.path;
|
||||
final String targetFileAbsolute = environment.fileSystem.file(targetFile).absolute.path;
|
||||
// everything besides 'false' is considered to be enabled.
|
||||
final bool trackWidgetCreation = environment.defines[kTrackWidgetCreation] != 'false';
|
||||
final TargetPlatform targetPlatform = getTargetPlatformForName(environment.defines[kTargetPlatform]);
|
||||
@ -238,7 +240,7 @@ class KernelSnapshot extends Target {
|
||||
);
|
||||
|
||||
final CompilerOutput output = await compiler.compile(
|
||||
sdkRoot: globals.artifacts.getArtifactPath(
|
||||
sdkRoot: environment.artifacts.getArtifactPath(
|
||||
Artifact.flutterPatchedSdkPath,
|
||||
platform: targetPlatform,
|
||||
mode: buildMode,
|
||||
@ -275,11 +277,11 @@ abstract class AotElfBase extends Target {
|
||||
Future<void> build(Environment environment) async {
|
||||
final AOTSnapshotter snapshotter = AOTSnapshotter(
|
||||
reportTimings: false,
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
fileSystem: environment.fileSystem,
|
||||
logger: environment.logger,
|
||||
xcode: globals.xcode,
|
||||
processManager: globals.processManager,
|
||||
artifacts: globals.artifacts,
|
||||
processManager: environment.processManager,
|
||||
artifacts: environment.artifacts,
|
||||
);
|
||||
final String outputPath = environment.buildDir.path;
|
||||
if (environment.defines[kBuildMode] == null) {
|
||||
|
||||
@ -9,7 +9,7 @@ import '../../base/file_system.dart';
|
||||
import '../../base/io.dart';
|
||||
import '../../base/process.dart';
|
||||
import '../../build_info.dart';
|
||||
import '../../globals.dart' as globals;
|
||||
import '../../globals.dart' as globals hide fs, logger, processManager, artifacts;
|
||||
import '../../macos/xcode.dart';
|
||||
import '../../project.dart';
|
||||
import '../build_system.dart';
|
||||
@ -33,11 +33,11 @@ abstract class AotAssemblyBase extends Target {
|
||||
Future<void> build(Environment environment) async {
|
||||
final AOTSnapshotter snapshotter = AOTSnapshotter(
|
||||
reportTimings: false,
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
fileSystem: environment.fileSystem,
|
||||
logger: environment.logger,
|
||||
xcode: globals.xcode,
|
||||
artifacts: globals.artifacts,
|
||||
processManager: globals.processManager,
|
||||
artifacts: environment.artifacts,
|
||||
processManager: environment.processManager,
|
||||
);
|
||||
final String buildOutputPath = environment.buildDir.path;
|
||||
if (environment.defines[kBuildMode] == null) {
|
||||
@ -76,7 +76,7 @@ abstract class AotAssemblyBase extends Target {
|
||||
buildMode: buildMode,
|
||||
mainPath: environment.buildDir.childFile('app.dill').path,
|
||||
packagesPath: environment.projectDir.childFile('.packages').path,
|
||||
outputPath: globals.fs.path.join(buildOutputPath, getNameForDarwinArch(iosArch)),
|
||||
outputPath: environment.fileSystem.path.join(buildOutputPath, getNameForDarwinArch(iosArch)),
|
||||
darwinArch: iosArch,
|
||||
bitcode: bitcode,
|
||||
quiet: true,
|
||||
@ -89,12 +89,12 @@ abstract class AotAssemblyBase extends Target {
|
||||
if (results.any((int result) => result != 0)) {
|
||||
throw Exception('AOT snapshotter exited with code ${results.join()}');
|
||||
}
|
||||
final String resultPath = globals.fs.path.join(environment.buildDir.path, 'App.framework', 'App');
|
||||
globals.fs.directory(resultPath).parent.createSync(recursive: true);
|
||||
final ProcessResult result = await globals.processManager.run(<String>[
|
||||
final String resultPath = environment.fileSystem.path.join(environment.buildDir.path, 'App.framework', 'App');
|
||||
environment.fileSystem.directory(resultPath).parent.createSync(recursive: true);
|
||||
final ProcessResult result = await environment.processManager.run(<String>[
|
||||
'lipo',
|
||||
...iosArchs.map((DarwinArch iosArch) =>
|
||||
globals.fs.path.join(buildOutputPath, getNameForDarwinArch(iosArch), 'App.framework', 'App')),
|
||||
environment.fileSystem.path.join(buildOutputPath, getNameForDarwinArch(iosArch), 'App.framework', 'App')),
|
||||
'-create',
|
||||
'-output',
|
||||
resultPath,
|
||||
@ -294,13 +294,13 @@ abstract class IosAssetBundle extends Target {
|
||||
.childFile('App')
|
||||
.copySync(frameworkDirectory.childFile('App').path);
|
||||
|
||||
final String vmSnapshotData = globals.artifacts.getArtifactPath(Artifact.vmSnapshotData, mode: BuildMode.debug);
|
||||
final String isolateSnapshotData = globals.artifacts.getArtifactPath(Artifact.isolateSnapshotData, mode: BuildMode.debug);
|
||||
final String vmSnapshotData = environment.artifacts.getArtifactPath(Artifact.vmSnapshotData, mode: BuildMode.debug);
|
||||
final String isolateSnapshotData = environment.artifacts.getArtifactPath(Artifact.isolateSnapshotData, mode: BuildMode.debug);
|
||||
environment.buildDir.childFile('app.dill')
|
||||
.copySync(assetDirectory.childFile('kernel_blob.bin').path);
|
||||
globals.fs.file(vmSnapshotData)
|
||||
environment.fileSystem.file(vmSnapshotData)
|
||||
.copySync(assetDirectory.childFile('vm_snapshot_data').path);
|
||||
globals.fs.file(isolateSnapshotData)
|
||||
environment.fileSystem.file(isolateSnapshotData)
|
||||
.copySync(assetDirectory.childFile('isolate_snapshot_data').path);
|
||||
} else {
|
||||
environment.buildDir.childDirectory('App.framework').childFile('App')
|
||||
@ -314,8 +314,8 @@ abstract class IosAssetBundle extends Target {
|
||||
targetPlatform: TargetPlatform.ios,
|
||||
);
|
||||
final DepfileService depfileService = DepfileService(
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
fileSystem: environment.fileSystem,
|
||||
logger: environment.logger,
|
||||
);
|
||||
depfileService.writeToFile(
|
||||
assetDepfile,
|
||||
@ -406,7 +406,8 @@ Future<RunResult> createStubAppFramework(File outputFile, SdkType sdk, { bool in
|
||||
throwToolExit('Failed to create App.framework stub at ${outputFile.path}: $e');
|
||||
}
|
||||
|
||||
final Directory tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_tools_stub_source.');
|
||||
final Directory tempDir = outputFile.fileSystem.systemTempDirectory
|
||||
.createTempSync('flutter_tools_stub_source.');
|
||||
try {
|
||||
final File stubSource = tempDir.childFile('debug_app.cc')
|
||||
..writeAsStringSync(r'''
|
||||
@ -444,7 +445,7 @@ Future<RunResult> createStubAppFramework(File outputFile, SdkType sdk, { bool in
|
||||
} finally {
|
||||
try {
|
||||
tempDir.deleteSync(recursive: true);
|
||||
} on FileSystemException catch (_) {
|
||||
} on FileSystemException {
|
||||
// Best effort. Sometimes we can't delete things from system temp.
|
||||
} on Exception catch (e) {
|
||||
throwToolExit('Failed to create App.framework stub at ${outputFile.path}: $e');
|
||||
|
||||
@ -2,83 +2,93 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:file_testing/file_testing.dart';
|
||||
import 'package:flutter_tools/src/artifacts.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/base/logger.dart';
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
import 'package:flutter_tools/src/build_info.dart';
|
||||
import 'package:flutter_tools/src/build_system/build_system.dart';
|
||||
import 'package:flutter_tools/src/build_system/targets/android.dart';
|
||||
import 'package:flutter_tools/src/build_system/targets/assets.dart';
|
||||
import 'package:flutter_tools/src/build_system/targets/common.dart';
|
||||
import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:flutter_tools/src/convert.dart';
|
||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import '../../../src/common.dart';
|
||||
import '../../../src/context.dart';
|
||||
import '../../../src/fake_process_manager.dart';
|
||||
import '../../../src/testbed.dart';
|
||||
|
||||
final Platform platform = FakePlatform(operatingSystem: 'linux', environment: const <String, String>{});
|
||||
void main() {
|
||||
FakeProcessManager fakeProcessManager;
|
||||
final Testbed testbed = Testbed(overrides: <Type, Generator>{
|
||||
Cache: () => FakeCache(),
|
||||
Platform: () => FakePlatform(operatingSystem: 'linux', environment: const <String, String>{}),
|
||||
FakeProcessManager processManager;
|
||||
FileSystem fileSystem;
|
||||
Artifacts artifacts;
|
||||
Logger logger;
|
||||
|
||||
setUp(() {
|
||||
logger = BufferLogger.test();
|
||||
fileSystem = MemoryFileSystem.test();
|
||||
processManager = FakeProcessManager.list(<FakeCommand>[]);
|
||||
artifacts = Artifacts.test();
|
||||
});
|
||||
|
||||
test('Android AOT targets has analyicsName', () {
|
||||
testWithoutContext('Android AOT targets has analyicsName', () {
|
||||
expect(androidArmProfile.analyticsName, 'android_aot');
|
||||
});
|
||||
|
||||
testbed.test('debug bundle contains expected resources', () async {
|
||||
testUsingContext('debug bundle contains expected resources', () async {
|
||||
final Environment environment = Environment.test(
|
||||
globals.fs.currentDirectory,
|
||||
outputDir: globals.fs.directory('out')..createSync(),
|
||||
fileSystem.currentDirectory,
|
||||
outputDir: fileSystem.directory('out')..createSync(),
|
||||
defines: <String, String>{
|
||||
kBuildMode: 'debug',
|
||||
},
|
||||
processManager: fakeProcessManager,
|
||||
artifacts: MockArtifacts(),
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: processManager,
|
||||
artifacts: artifacts,
|
||||
fileSystem: fileSystem,
|
||||
logger: logger,
|
||||
);
|
||||
environment.buildDir.createSync(recursive: true);
|
||||
|
||||
// create pre-requisites.
|
||||
environment.buildDir.childFile('app.dill')
|
||||
.writeAsStringSync('abcd');
|
||||
final Directory hostDirectory = globals.fs.currentDirectory
|
||||
.childDirectory(getNameForHostPlatform(getCurrentHostPlatform()))
|
||||
..createSync(recursive: true);
|
||||
hostDirectory.childFile('vm_isolate_snapshot.bin').createSync();
|
||||
hostDirectory.childFile('isolate_snapshot.bin').createSync();
|
||||
fileSystem
|
||||
.file(artifacts.getArtifactPath(Artifact.vmSnapshotData, mode: BuildMode.debug))
|
||||
.createSync(recursive: true);
|
||||
fileSystem
|
||||
.file(artifacts.getArtifactPath(Artifact.isolateSnapshotData, mode: BuildMode.debug))
|
||||
.createSync(recursive: true);
|
||||
|
||||
await const DebugAndroidApplication().build(environment);
|
||||
|
||||
expect(globals.fs.file(globals.fs.path.join('out', 'flutter_assets', 'isolate_snapshot_data')).existsSync(), true);
|
||||
expect(globals.fs.file(globals.fs.path.join('out', 'flutter_assets', 'vm_snapshot_data')).existsSync(), true);
|
||||
expect(globals.fs.file(globals.fs.path.join('out', 'flutter_assets', 'kernel_blob.bin')).existsSync(), true);
|
||||
expect(fileSystem.file(fileSystem.path.join('out', 'flutter_assets', 'isolate_snapshot_data')).existsSync(), true);
|
||||
expect(fileSystem.file(fileSystem.path.join('out', 'flutter_assets', 'vm_snapshot_data')).existsSync(), true);
|
||||
expect(fileSystem.file(fileSystem.path.join('out', 'flutter_assets', 'kernel_blob.bin')).existsSync(), true);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => processManager,
|
||||
});
|
||||
|
||||
testbed.test('debug bundle contains expected resources with bundle SkSL', () async {
|
||||
testUsingContext('debug bundle contains expected resources with bundle SkSL', () async {
|
||||
final Environment environment = Environment.test(
|
||||
globals.fs.currentDirectory,
|
||||
outputDir: globals.fs.directory('out')..createSync(),
|
||||
fileSystem.currentDirectory,
|
||||
outputDir: fileSystem.directory('out')..createSync(),
|
||||
defines: <String, String>{
|
||||
kBuildMode: 'debug',
|
||||
},
|
||||
inputs: <String, String>{
|
||||
kBundleSkSLPath: 'bundle.sksl'
|
||||
},
|
||||
processManager: fakeProcessManager,
|
||||
artifacts: MockArtifacts(),
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: processManager,
|
||||
artifacts: artifacts,
|
||||
fileSystem: fileSystem,
|
||||
logger: logger,
|
||||
engineVersion: '2',
|
||||
);
|
||||
environment.buildDir.createSync(recursive: true);
|
||||
globals.fs.file('bundle.sksl').writeAsStringSync(json.encode(
|
||||
fileSystem.file('bundle.sksl').writeAsStringSync(json.encode(
|
||||
<String, Object>{
|
||||
'engineRevision': '2',
|
||||
'platform': 'android',
|
||||
@ -91,31 +101,35 @@ void main() {
|
||||
// create pre-requisites.
|
||||
environment.buildDir.childFile('app.dill')
|
||||
.writeAsStringSync('abcd');
|
||||
final Directory hostDirectory = globals.fs.currentDirectory
|
||||
.childDirectory(getNameForHostPlatform(getCurrentHostPlatform()))
|
||||
..createSync(recursive: true);
|
||||
hostDirectory.childFile('vm_isolate_snapshot.bin').createSync();
|
||||
hostDirectory.childFile('isolate_snapshot.bin').createSync();
|
||||
fileSystem
|
||||
.file(artifacts.getArtifactPath(Artifact.vmSnapshotData, mode: BuildMode.debug))
|
||||
.createSync(recursive: true);
|
||||
fileSystem
|
||||
.file(artifacts.getArtifactPath(Artifact.isolateSnapshotData, mode: BuildMode.debug))
|
||||
.createSync(recursive: true);
|
||||
|
||||
await const DebugAndroidApplication().build(environment);
|
||||
|
||||
expect(globals.fs.file(globals.fs.path.join('out', 'flutter_assets', 'isolate_snapshot_data')), exists);
|
||||
expect(globals.fs.file(globals.fs.path.join('out', 'flutter_assets', 'vm_snapshot_data')), exists);
|
||||
expect(globals.fs.file(globals.fs.path.join('out', 'flutter_assets', 'kernel_blob.bin')), exists);
|
||||
expect(globals.fs.file(globals.fs.path.join('out', 'flutter_assets', 'io.flutter.shaders.json')), exists);
|
||||
expect(fileSystem.file(fileSystem.path.join('out', 'flutter_assets', 'isolate_snapshot_data')), exists);
|
||||
expect(fileSystem.file(fileSystem.path.join('out', 'flutter_assets', 'vm_snapshot_data')), exists);
|
||||
expect(fileSystem.file(fileSystem.path.join('out', 'flutter_assets', 'kernel_blob.bin')), exists);
|
||||
expect(fileSystem.file(fileSystem.path.join('out', 'flutter_assets', 'io.flutter.shaders.json')), exists);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => processManager,
|
||||
});
|
||||
|
||||
testbed.test('profile bundle contains expected resources', () async {
|
||||
testUsingContext('profile bundle contains expected resources', () async {
|
||||
final Environment environment = Environment.test(
|
||||
globals.fs.currentDirectory,
|
||||
outputDir: globals.fs.directory('out')..createSync(),
|
||||
fileSystem.currentDirectory,
|
||||
outputDir: fileSystem.directory('out')..createSync(),
|
||||
defines: <String, String>{
|
||||
kBuildMode: 'profile',
|
||||
},
|
||||
artifacts: MockArtifacts(),
|
||||
processManager: fakeProcessManager,
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
artifacts: artifacts,
|
||||
processManager: processManager,
|
||||
fileSystem: fileSystem,
|
||||
logger: logger,
|
||||
);
|
||||
environment.buildDir.createSync(recursive: true);
|
||||
|
||||
@ -125,20 +139,23 @@ void main() {
|
||||
|
||||
await const ProfileAndroidApplication().build(environment);
|
||||
|
||||
expect(globals.fs.file(globals.fs.path.join('out', 'app.so')).existsSync(), true);
|
||||
expect(fileSystem.file(fileSystem.path.join('out', 'app.so')).existsSync(), true);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => processManager,
|
||||
});
|
||||
|
||||
testbed.test('release bundle contains expected resources', () async {
|
||||
testWithoutContext('release bundle contains expected resources', () async {
|
||||
final Environment environment = Environment.test(
|
||||
globals.fs.currentDirectory,
|
||||
outputDir: globals.fs.directory('out')..createSync(),
|
||||
fileSystem.currentDirectory,
|
||||
outputDir: fileSystem.directory('out')..createSync(),
|
||||
defines: <String, String>{
|
||||
kBuildMode: 'release',
|
||||
},
|
||||
artifacts: MockArtifacts(),
|
||||
processManager: fakeProcessManager,
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
artifacts: artifacts,
|
||||
processManager: processManager,
|
||||
fileSystem: fileSystem,
|
||||
logger: logger,
|
||||
);
|
||||
environment.buildDir.createSync(recursive: true);
|
||||
|
||||
@ -148,34 +165,37 @@ void main() {
|
||||
|
||||
await const ReleaseAndroidApplication().build(environment);
|
||||
|
||||
expect(globals.fs.file(globals.fs.path.join('out', 'app.so')).existsSync(), true);
|
||||
expect(fileSystem.file(fileSystem.path.join('out', 'app.so')).existsSync(), true);
|
||||
});
|
||||
|
||||
testbed.test('AndroidAot can build provided target platform', () async {
|
||||
fakeProcessManager = FakeProcessManager.list(<FakeCommand>[]);
|
||||
testUsingContext('AndroidAot can build provided target platform', () async {
|
||||
processManager = FakeProcessManager.list(<FakeCommand>[]);
|
||||
final Environment environment = Environment.test(
|
||||
globals.fs.currentDirectory,
|
||||
outputDir: globals.fs.directory('out')..createSync(),
|
||||
fileSystem.currentDirectory,
|
||||
outputDir: fileSystem.directory('out')..createSync(),
|
||||
defines: <String, String>{
|
||||
kBuildMode: 'release',
|
||||
},
|
||||
artifacts: MockArtifacts(),
|
||||
processManager: FakeProcessManager.list(<FakeCommand>[]),
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
);
|
||||
fakeProcessManager.addCommand(FakeCommand(command: <String>[
|
||||
globals.fs.path.absolute(globals.fs.path.join('android-arm64-release', 'linux-x64', 'gen_snapshot')),
|
||||
'--deterministic',
|
||||
'--snapshot_kind=app-aot-elf',
|
||||
'--elf=${environment.buildDir.childDirectory('arm64-v8a').childFile('app.so').path}',
|
||||
'--strip',
|
||||
'--no-causal-async-stacks',
|
||||
'--lazy-async-stacks',
|
||||
environment.buildDir.childFile('app.dill').path,
|
||||
],
|
||||
)
|
||||
artifacts: artifacts,
|
||||
processManager: processManager,
|
||||
fileSystem: fileSystem,
|
||||
logger: logger,
|
||||
);
|
||||
processManager.addCommand(FakeCommand(command: <String>[
|
||||
artifacts.getArtifactPath(
|
||||
Artifact.genSnapshot,
|
||||
platform: TargetPlatform.android_arm64,
|
||||
mode: BuildMode.release,
|
||||
),
|
||||
'--deterministic',
|
||||
'--snapshot_kind=app-aot-elf',
|
||||
'--elf=${environment.buildDir.childDirectory('arm64-v8a').childFile('app.so').path}',
|
||||
'--strip',
|
||||
'--no-causal-async-stacks',
|
||||
'--lazy-async-stacks',
|
||||
environment.buildDir.childFile('app.dill').path,
|
||||
],
|
||||
));
|
||||
environment.buildDir.createSync(recursive: true);
|
||||
environment.buildDir.childFile('app.dill').createSync();
|
||||
environment.projectDir.childFile('.packages').writeAsStringSync('\n');
|
||||
@ -183,29 +203,34 @@ void main() {
|
||||
|
||||
await androidAot.build(environment);
|
||||
|
||||
expect(fakeProcessManager.hasRemainingExpectations, false);
|
||||
expect(processManager.hasRemainingExpectations, false);
|
||||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => fakeProcessManager,
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => processManager,
|
||||
});
|
||||
|
||||
testbed.test('kExtraGenSnapshotOptions passes values to gen_snapshot', () async {
|
||||
fakeProcessManager = FakeProcessManager.list(<FakeCommand>[]);
|
||||
testUsingContext('kExtraGenSnapshotOptions passes values to gen_snapshot', () async {
|
||||
processManager = FakeProcessManager.list(<FakeCommand>[]);
|
||||
final Environment environment = Environment.test(
|
||||
globals.fs.currentDirectory,
|
||||
outputDir: globals.fs.directory('out')..createSync(),
|
||||
fileSystem.currentDirectory,
|
||||
outputDir: fileSystem.directory('out')..createSync(),
|
||||
defines: <String, String>{
|
||||
kBuildMode: 'release',
|
||||
kExtraGenSnapshotOptions: 'foo,bar,baz=2',
|
||||
kTargetPlatform: 'android-arm',
|
||||
},
|
||||
processManager: fakeProcessManager,
|
||||
artifacts: MockArtifacts(),
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: processManager,
|
||||
artifacts: artifacts,
|
||||
fileSystem: fileSystem,
|
||||
logger: logger,
|
||||
);
|
||||
fakeProcessManager.addCommand(
|
||||
processManager.addCommand(
|
||||
FakeCommand(command: <String>[
|
||||
globals.fs.path.absolute(globals.fs.path.join('android-arm64-release', 'linux-x64', 'gen_snapshot')),
|
||||
artifacts.getArtifactPath(
|
||||
Artifact.genSnapshot,
|
||||
platform: TargetPlatform.android_arm64,
|
||||
mode: BuildMode.release,
|
||||
),
|
||||
'--deterministic',
|
||||
'foo',
|
||||
'bar',
|
||||
@ -216,7 +241,8 @@ void main() {
|
||||
'--no-causal-async-stacks',
|
||||
'--lazy-async-stacks',
|
||||
environment.buildDir.childFile('app.dill').path
|
||||
]));
|
||||
],
|
||||
));
|
||||
environment.buildDir.createSync(recursive: true);
|
||||
environment.buildDir.childFile('app.dill').createSync();
|
||||
environment.projectDir.childFile('.packages').writeAsStringSync('\n');
|
||||
@ -224,20 +250,21 @@ void main() {
|
||||
await const AndroidAot(TargetPlatform.android_arm64, BuildMode.release)
|
||||
.build(environment);
|
||||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => fakeProcessManager,
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => processManager,
|
||||
});
|
||||
|
||||
testbed.test('android aot bundle copies so from abi directory', () async {
|
||||
testWithoutContext('android aot bundle copies so from abi directory', () async {
|
||||
final Environment environment = Environment.test(
|
||||
globals.fs.currentDirectory,
|
||||
outputDir: globals.fs.directory('out')..createSync(),
|
||||
fileSystem.currentDirectory,
|
||||
outputDir: fileSystem.directory('out')..createSync(),
|
||||
defines: <String, String>{
|
||||
kBuildMode: 'release',
|
||||
},
|
||||
processManager: fakeProcessManager,
|
||||
artifacts: MockArtifacts(),
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
processManager: processManager,
|
||||
artifacts: artifacts,
|
||||
fileSystem: fileSystem,
|
||||
logger: logger,
|
||||
);
|
||||
environment.buildDir.createSync(recursive: true);
|
||||
const AndroidAot androidAot = AndroidAot(TargetPlatform.android_arm64, BuildMode.release);
|
||||
@ -255,5 +282,3 @@ void main() {
|
||||
.childFile('app.so').existsSync(), true);
|
||||
});
|
||||
}
|
||||
|
||||
class MockArtifacts extends Mock implements Artifacts {}
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
import 'package:file/memory.dart';
|
||||
import 'package:flutter_tools/src/artifacts.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/base/logger.dart';
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
import 'package:flutter_tools/src/build_info.dart';
|
||||
import 'package:flutter_tools/src/build_system/build_system.dart';
|
||||
@ -13,83 +14,80 @@ import 'package:flutter_tools/src/build_system/targets/common.dart';
|
||||
import 'package:flutter_tools/src/build_system/targets/ios.dart';
|
||||
import 'package:flutter_tools/src/cache.dart';
|
||||
import 'package:flutter_tools/src/compile.dart';
|
||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
import 'package:process/process.dart';
|
||||
|
||||
import '../../../src/common.dart';
|
||||
import '../../../src/context.dart';
|
||||
import '../../../src/fake_process_manager.dart';
|
||||
import '../../../src/testbed.dart';
|
||||
|
||||
const String kBoundaryKey = '4d2d9609-c662-4571-afde-31410f96caa6';
|
||||
const String kElfAot = '--snapshot_kind=app-aot-elf';
|
||||
const String kAssemblyAot = '--snapshot_kind=app-aot-assembly';
|
||||
|
||||
final Platform macPlatform = FakePlatform(operatingSystem: 'macos', environment: <String, String>{});
|
||||
void main() {
|
||||
Testbed testbed;
|
||||
FakeProcessManager processManager;
|
||||
Environment androidEnvironment;
|
||||
Environment iosEnvironment;
|
||||
Artifacts artifacts;
|
||||
FileSystem fileSystem;
|
||||
Logger logger;
|
||||
|
||||
setUpAll(() {
|
||||
Cache.disableLocking();
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
testbed = Testbed(setup: () {
|
||||
androidEnvironment = Environment.test(
|
||||
globals.fs.currentDirectory,
|
||||
defines: <String, String>{
|
||||
kBuildMode: getNameForBuildMode(BuildMode.profile),
|
||||
kTargetPlatform: getNameForTargetPlatform(TargetPlatform.android_arm),
|
||||
},
|
||||
artifacts: artifacts,
|
||||
processManager: processManager,
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
);
|
||||
androidEnvironment.buildDir.createSync(recursive: true);
|
||||
iosEnvironment = Environment.test(
|
||||
globals.fs.currentDirectory,
|
||||
defines: <String, String>{
|
||||
kBuildMode: getNameForBuildMode(BuildMode.profile),
|
||||
kTargetPlatform: getNameForTargetPlatform(TargetPlatform.ios),
|
||||
},
|
||||
artifacts: artifacts,
|
||||
processManager: processManager,
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
);
|
||||
iosEnvironment.buildDir.createSync(recursive: true);
|
||||
artifacts = CachedArtifacts(
|
||||
cache: globals.cache,
|
||||
platform: globals.platform,
|
||||
fileSystem: globals.fs,
|
||||
);
|
||||
}, overrides: <Type, Generator>{
|
||||
Platform: () => FakePlatform(operatingSystem: 'macos', environment: <String, String>{}),
|
||||
FileSystem: () => MemoryFileSystem.test(style: FileSystemStyle.posix),
|
||||
ProcessManager: () => processManager,
|
||||
});
|
||||
processManager = FakeProcessManager.list(<FakeCommand>[]);
|
||||
logger = BufferLogger.test();
|
||||
artifacts = Artifacts.test();
|
||||
fileSystem = MemoryFileSystem.test(style: FileSystemStyle.posix);
|
||||
androidEnvironment = Environment.test(
|
||||
fileSystem.currentDirectory,
|
||||
defines: <String, String>{
|
||||
kBuildMode: getNameForBuildMode(BuildMode.profile),
|
||||
kTargetPlatform: getNameForTargetPlatform(TargetPlatform.android_arm),
|
||||
},
|
||||
artifacts: artifacts,
|
||||
processManager: processManager,
|
||||
fileSystem: fileSystem,
|
||||
logger: logger,
|
||||
);
|
||||
androidEnvironment.buildDir.createSync(recursive: true);
|
||||
iosEnvironment = Environment.test(
|
||||
fileSystem.currentDirectory,
|
||||
defines: <String, String>{
|
||||
kBuildMode: getNameForBuildMode(BuildMode.profile),
|
||||
kTargetPlatform: getNameForTargetPlatform(TargetPlatform.ios),
|
||||
},
|
||||
artifacts: artifacts,
|
||||
processManager: processManager,
|
||||
fileSystem: fileSystem,
|
||||
logger: logger,
|
||||
);
|
||||
iosEnvironment.buildDir.createSync(recursive: true);
|
||||
});
|
||||
|
||||
test('KernelSnapshot throws error if missing build mode', () => testbed.run(() async {
|
||||
testWithoutContext('KernelSnapshot throws error if missing build mode', () async {
|
||||
androidEnvironment.defines.remove(kBuildMode);
|
||||
expect(
|
||||
const KernelSnapshot().build(androidEnvironment),
|
||||
throwsA(isA<MissingDefineException>()));
|
||||
}));
|
||||
});
|
||||
|
||||
test('KernelSnapshot handles null result from kernel compilation', () => testbed.run(() async {
|
||||
globals.fs.file('.packages').writeAsStringSync('\n');
|
||||
testWithoutContext('KernelSnapshot handles null result from kernel compilation', () async {
|
||||
fileSystem.file('.packages').writeAsStringSync('\n');
|
||||
final String build = androidEnvironment.buildDir.path;
|
||||
processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
processManager.addCommands(<FakeCommand>[
|
||||
FakeCommand(command: <String>[
|
||||
artifacts.getArtifactPath(Artifact.engineDartBinary),
|
||||
'--disable-dart-dev',
|
||||
artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
|
||||
'--sdk-root',
|
||||
artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath) + '/',
|
||||
artifacts.getArtifactPath(
|
||||
Artifact.flutterPatchedSdkPath,
|
||||
platform: TargetPlatform.android_arm,
|
||||
mode: BuildMode.profile,
|
||||
) + '/',
|
||||
'--target=flutter',
|
||||
'-Ddart.developer.causal_async_stacks=false',
|
||||
...buildModeOptions(BuildMode.profile),
|
||||
@ -108,18 +106,22 @@ void main() {
|
||||
await expectLater(() => const KernelSnapshot().build(androidEnvironment),
|
||||
throwsA(isA<Exception>()));
|
||||
expect(processManager.hasRemainingExpectations, false);
|
||||
}));
|
||||
});
|
||||
|
||||
test('KernelSnapshot does not use track widget creation on profile builds', () => testbed.run(() async {
|
||||
globals.fs.file('.packages').writeAsStringSync('\n');
|
||||
testWithoutContext('KernelSnapshot does not use track widget creation on profile builds', () async {
|
||||
fileSystem.file('.packages').writeAsStringSync('\n');
|
||||
final String build = androidEnvironment.buildDir.path;
|
||||
processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
processManager.addCommands(<FakeCommand>[
|
||||
FakeCommand(command: <String>[
|
||||
artifacts.getArtifactPath(Artifact.engineDartBinary),
|
||||
'--disable-dart-dev',
|
||||
artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
|
||||
'--sdk-root',
|
||||
artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath) + '/',
|
||||
artifacts.getArtifactPath(
|
||||
Artifact.flutterPatchedSdkPath,
|
||||
platform: TargetPlatform.android_arm,
|
||||
mode: BuildMode.profile,
|
||||
) + '/',
|
||||
'--target=flutter',
|
||||
'-Ddart.developer.causal_async_stacks=false',
|
||||
...buildModeOptions(BuildMode.profile),
|
||||
@ -138,18 +140,22 @@ void main() {
|
||||
await const KernelSnapshot().build(androidEnvironment);
|
||||
|
||||
expect(processManager.hasRemainingExpectations, false);
|
||||
}));
|
||||
});
|
||||
|
||||
test('KernelSnapshot correctly handles an empty string in ExtraFrontEndOptions', () => testbed.run(() async {
|
||||
globals.fs.file('.packages').writeAsStringSync('\n');
|
||||
testWithoutContext('KernelSnapshot correctly handles an empty string in ExtraFrontEndOptions', () async {
|
||||
fileSystem.file('.packages').writeAsStringSync('\n');
|
||||
final String build = androidEnvironment.buildDir.path;
|
||||
processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
processManager.addCommands(<FakeCommand>[
|
||||
FakeCommand(command: <String>[
|
||||
artifacts.getArtifactPath(Artifact.engineDartBinary),
|
||||
'--disable-dart-dev',
|
||||
artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
|
||||
'--sdk-root',
|
||||
artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath) + '/',
|
||||
artifacts.getArtifactPath(
|
||||
Artifact.flutterPatchedSdkPath,
|
||||
platform: TargetPlatform.android_arm,
|
||||
mode: BuildMode.profile,
|
||||
) + '/',
|
||||
'--target=flutter',
|
||||
'-Ddart.developer.causal_async_stacks=false',
|
||||
...buildModeOptions(BuildMode.profile),
|
||||
@ -169,18 +175,22 @@ void main() {
|
||||
.build(androidEnvironment..defines[kExtraFrontEndOptions] = '');
|
||||
|
||||
expect(processManager.hasRemainingExpectations, false);
|
||||
}));
|
||||
});
|
||||
|
||||
test('KernelSnapshot correctly forwards ExtraFrontEndOptions', () => testbed.run(() async {
|
||||
globals.fs.file('.packages').writeAsStringSync('\n');
|
||||
testWithoutContext('KernelSnapshot correctly forwards ExtraFrontEndOptions', () async {
|
||||
fileSystem.file('.packages').writeAsStringSync('\n');
|
||||
final String build = androidEnvironment.buildDir.path;
|
||||
processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
processManager.addCommands(<FakeCommand>[
|
||||
FakeCommand(command: <String>[
|
||||
artifacts.getArtifactPath(Artifact.engineDartBinary),
|
||||
'--disable-dart-dev',
|
||||
artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
|
||||
'--sdk-root',
|
||||
artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath) + '/',
|
||||
artifacts.getArtifactPath(
|
||||
Artifact.flutterPatchedSdkPath,
|
||||
platform: TargetPlatform.android_arm,
|
||||
mode: BuildMode.profile,
|
||||
) + '/',
|
||||
'--target=flutter',
|
||||
'-Ddart.developer.causal_async_stacks=false',
|
||||
...buildModeOptions(BuildMode.profile),
|
||||
@ -202,18 +212,22 @@ void main() {
|
||||
.build(androidEnvironment..defines[kExtraFrontEndOptions] = 'foo,bar');
|
||||
|
||||
expect(processManager.hasRemainingExpectations, false);
|
||||
}));
|
||||
});
|
||||
|
||||
test('KernelSnapshot can disable track-widget-creation on debug builds', () => testbed.run(() async {
|
||||
globals.fs.file('.packages').writeAsStringSync('\n');
|
||||
testWithoutContext('KernelSnapshot can disable track-widget-creation on debug builds', () async {
|
||||
fileSystem.file('.packages').writeAsStringSync('\n');
|
||||
final String build = androidEnvironment.buildDir.path;
|
||||
processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
processManager.addCommands(<FakeCommand>[
|
||||
FakeCommand(command: <String>[
|
||||
artifacts.getArtifactPath(Artifact.engineDartBinary),
|
||||
'--disable-dart-dev',
|
||||
artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
|
||||
'--sdk-root',
|
||||
artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath) + '/',
|
||||
artifacts.getArtifactPath(
|
||||
Artifact.flutterPatchedSdkPath,
|
||||
platform: TargetPlatform.android_arm,
|
||||
mode: BuildMode.debug,
|
||||
) + '/',
|
||||
'--target=flutter',
|
||||
'-Ddart.developer.causal_async_stacks=true',
|
||||
...buildModeOptions(BuildMode.debug),
|
||||
@ -233,18 +247,22 @@ void main() {
|
||||
..defines[kTrackWidgetCreation] = 'false');
|
||||
|
||||
expect(processManager.hasRemainingExpectations, false);
|
||||
}));
|
||||
});
|
||||
|
||||
test('KernelSnapshot forces platform linking on debug for darwin target platforms', () => testbed.run(() async {
|
||||
globals.fs.file('.packages').writeAsStringSync('\n');
|
||||
testWithoutContext('KernelSnapshot forces platform linking on debug for darwin target platforms', () async {
|
||||
fileSystem.file('.packages').writeAsStringSync('\n');
|
||||
final String build = androidEnvironment.buildDir.path;
|
||||
processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
processManager.addCommands(<FakeCommand>[
|
||||
FakeCommand(command: <String>[
|
||||
artifacts.getArtifactPath(Artifact.engineDartBinary),
|
||||
'--disable-dart-dev',
|
||||
artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
|
||||
'--sdk-root',
|
||||
artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath) + '/',
|
||||
artifacts.getArtifactPath(
|
||||
Artifact.flutterPatchedSdkPath,
|
||||
platform: TargetPlatform.darwin_x64,
|
||||
mode: BuildMode.debug,
|
||||
) + '/',
|
||||
'--target=flutter',
|
||||
'-Ddart.developer.causal_async_stacks=true',
|
||||
...buildModeOptions(BuildMode.debug),
|
||||
@ -265,29 +283,33 @@ void main() {
|
||||
);
|
||||
|
||||
expect(processManager.hasRemainingExpectations, false);
|
||||
}));
|
||||
});
|
||||
|
||||
test('KernelSnapshot does use track widget creation on debug builds', () => testbed.run(() async {
|
||||
globals.fs.file('.packages').writeAsStringSync('\n');
|
||||
testWithoutContext('KernelSnapshot does use track widget creation on debug builds', () async {
|
||||
fileSystem.file('.packages').writeAsStringSync('\n');
|
||||
final Environment testEnvironment = Environment.test(
|
||||
globals.fs.currentDirectory,
|
||||
fileSystem.currentDirectory,
|
||||
defines: <String, String>{
|
||||
kBuildMode: getNameForBuildMode(BuildMode.debug),
|
||||
kTargetPlatform: getNameForTargetPlatform(TargetPlatform.android_arm),
|
||||
},
|
||||
processManager: processManager,
|
||||
artifacts: artifacts,
|
||||
fileSystem: globals.fs,
|
||||
logger: globals.logger,
|
||||
fileSystem: fileSystem,
|
||||
logger: logger,
|
||||
);
|
||||
final String build = testEnvironment.buildDir.path;
|
||||
processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
processManager.addCommands(<FakeCommand>[
|
||||
FakeCommand(command: <String>[
|
||||
artifacts.getArtifactPath(Artifact.engineDartBinary),
|
||||
'--disable-dart-dev',
|
||||
artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
|
||||
'--sdk-root',
|
||||
artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath) + '/',
|
||||
artifacts.getArtifactPath(
|
||||
Artifact.flutterPatchedSdkPath,
|
||||
platform: TargetPlatform.android_arm,
|
||||
mode: BuildMode.debug,
|
||||
) + '/',
|
||||
'--target=flutter',
|
||||
'-Ddart.developer.causal_async_stacks=true',
|
||||
...buildModeOptions(BuildMode.debug),
|
||||
@ -306,13 +328,17 @@ void main() {
|
||||
await const KernelSnapshot().build(testEnvironment);
|
||||
|
||||
expect(processManager.hasRemainingExpectations, false);
|
||||
}));
|
||||
});
|
||||
|
||||
test('AotElfProfile Produces correct output directory', () => testbed.run(() async {
|
||||
testUsingContext('AotElfProfile Produces correct output directory', () async {
|
||||
final String build = androidEnvironment.buildDir.path;
|
||||
processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
processManager.addCommands(<FakeCommand>[
|
||||
FakeCommand(command: <String>[
|
||||
artifacts.getArtifactPath(Artifact.genSnapshot, mode: BuildMode.profile),
|
||||
artifacts.getArtifactPath(
|
||||
Artifact.genSnapshot,
|
||||
platform: TargetPlatform.android_arm,
|
||||
mode: BuildMode.profile,
|
||||
),
|
||||
'--deterministic',
|
||||
kElfAot,
|
||||
'--elf=$build/app.so',
|
||||
@ -329,47 +355,60 @@ void main() {
|
||||
await const AotElfProfile(TargetPlatform.android_arm).build(androidEnvironment);
|
||||
|
||||
expect(processManager.hasRemainingExpectations, false);
|
||||
}));
|
||||
});
|
||||
|
||||
test('AotElfProfile throws error if missing build mode', () => testbed.run(() async {
|
||||
testUsingContext('AotElfProfile throws error if missing build mode', () async {
|
||||
androidEnvironment.defines.remove(kBuildMode);
|
||||
|
||||
expect(const AotElfProfile(TargetPlatform.android_arm).build(androidEnvironment),
|
||||
throwsA(isA<MissingDefineException>()));
|
||||
}));
|
||||
});
|
||||
|
||||
test('AotElfProfile throws error if missing target platform', () => testbed.run(() async {
|
||||
testUsingContext('AotElfProfile throws error if missing target platform', () async {
|
||||
androidEnvironment.defines.remove(kTargetPlatform);
|
||||
|
||||
expect(const AotElfProfile(TargetPlatform.android_arm).build(androidEnvironment),
|
||||
throwsA(isA<MissingDefineException>()));
|
||||
}));
|
||||
});
|
||||
|
||||
test('AotAssemblyProfile throws error if missing build mode', () => testbed.run(() async {
|
||||
testUsingContext('AotAssemblyProfile throws error if missing build mode', () async {
|
||||
iosEnvironment.defines.remove(kBuildMode);
|
||||
|
||||
expect(const AotAssemblyProfile().build(iosEnvironment),
|
||||
throwsA(isA<MissingDefineException>()));
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Platform: () => macPlatform,
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => processManager,
|
||||
});
|
||||
|
||||
test('AotAssemblyProfile throws error if missing target platform', () => testbed.run(() async {
|
||||
|
||||
testUsingContext('AotAssemblyProfile throws error if missing target platform', () async {
|
||||
iosEnvironment.defines.remove(kTargetPlatform);
|
||||
|
||||
expect(const AotAssemblyProfile().build(iosEnvironment),
|
||||
throwsA(isA<MissingDefineException>()));
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Platform: () => macPlatform,
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => processManager,
|
||||
});
|
||||
|
||||
test('AotAssemblyProfile throws error if built for non-iOS platform', () => testbed.run(() async {
|
||||
testUsingContext('AotAssemblyProfile throws error if built for non-iOS platform', () async {
|
||||
expect(const AotAssemblyProfile().build(androidEnvironment),
|
||||
throwsA(isA<Exception>()));
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Platform: () => macPlatform,
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => processManager,
|
||||
});
|
||||
|
||||
test('AotAssemblyProfile generates multiple arches and lipos together', () => testbed.run(() async {
|
||||
testUsingContext('AotAssemblyProfile generates multiple arches and lipos together', () async {
|
||||
final String build = iosEnvironment.buildDir.path;
|
||||
processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
processManager.addCommands(<FakeCommand>[
|
||||
FakeCommand(command: <String>[
|
||||
// This path is not known by the cache due to the iOS gen_snapshot split.
|
||||
'bin/cache/artifacts/engine/ios-profile/gen_snapshot_armv7',
|
||||
'Artifact.genSnapshot.TargetPlatform.ios.profile_armv7',
|
||||
'--deterministic',
|
||||
kAssemblyAot,
|
||||
'--assembly=$build/armv7/snapshot_assembly.S',
|
||||
@ -382,7 +421,7 @@ void main() {
|
||||
]),
|
||||
FakeCommand(command: <String>[
|
||||
// This path is not known by the cache due to the iOS gen_snapshot split.
|
||||
'bin/cache/artifacts/engine/ios-profile/gen_snapshot_arm64',
|
||||
'Artifact.genSnapshot.TargetPlatform.ios.profile_arm64',
|
||||
'--deterministic',
|
||||
kAssemblyAot,
|
||||
'--assembly=$build/arm64/snapshot_assembly.S',
|
||||
@ -487,16 +526,20 @@ void main() {
|
||||
await const AotAssemblyProfile().build(iosEnvironment);
|
||||
|
||||
expect(processManager.hasRemainingExpectations, false);
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Platform: () => macPlatform,
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => processManager,
|
||||
});
|
||||
|
||||
test('AotAssemblyProfile with bitcode sends correct argument to snapshotter (one arch)', () => testbed.run(() async {
|
||||
testUsingContext('AotAssemblyProfile with bitcode sends correct argument to snapshotter (one arch)', () async {
|
||||
iosEnvironment.defines[kIosArchs] = 'arm64';
|
||||
iosEnvironment.defines[kBitcodeFlag] = 'true';
|
||||
final String build = iosEnvironment.buildDir.path;
|
||||
processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
processManager.addCommands(<FakeCommand>[
|
||||
FakeCommand(command: <String>[
|
||||
// This path is not known by the cache due to the iOS gen_snapshot split.
|
||||
'bin/cache/artifacts/engine/ios-profile/gen_snapshot_arm64',
|
||||
'Artifact.genSnapshot.TargetPlatform.ios.profile_arm64',
|
||||
'--deterministic',
|
||||
kAssemblyAot,
|
||||
'--assembly=$build/arm64/snapshot_assembly.S',
|
||||
@ -562,16 +605,24 @@ void main() {
|
||||
await const AotAssemblyProfile().build(iosEnvironment);
|
||||
|
||||
expect(processManager.hasRemainingExpectations, false);
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
Platform: () => macPlatform,
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => processManager,
|
||||
});
|
||||
|
||||
test('kExtraGenSnapshotOptions passes values to gen_snapshot', () => testbed.run(() async {
|
||||
testUsingContext('kExtraGenSnapshotOptions passes values to gen_snapshot', () async {
|
||||
androidEnvironment.defines[kExtraGenSnapshotOptions] = 'foo,bar,baz=2';
|
||||
androidEnvironment.defines[kBuildMode] = getNameForBuildMode(BuildMode.profile);
|
||||
final String build = androidEnvironment.buildDir.path;
|
||||
|
||||
processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
processManager.addCommands(<FakeCommand>[
|
||||
FakeCommand(command: <String>[
|
||||
artifacts.getArtifactPath(Artifact.genSnapshot, mode: BuildMode.profile),
|
||||
artifacts.getArtifactPath(
|
||||
Artifact.genSnapshot,
|
||||
platform: TargetPlatform.android_arm,
|
||||
mode: BuildMode.profile,
|
||||
),
|
||||
'--deterministic',
|
||||
'foo',
|
||||
'bar',
|
||||
@ -590,5 +641,5 @@ void main() {
|
||||
await const AotElfRelease(TargetPlatform.android_arm).build(androidEnvironment);
|
||||
|
||||
expect(processManager.hasRemainingExpectations, false);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
@ -7,18 +7,19 @@ import 'package:file_testing/file_testing.dart';
|
||||
import 'package:flutter_tools/src/artifacts.dart';
|
||||
import 'package:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/base/logger.dart';
|
||||
import 'package:flutter_tools/src/base/platform.dart';
|
||||
import 'package:flutter_tools/src/build_info.dart';
|
||||
import 'package:flutter_tools/src/build_system/build_system.dart';
|
||||
import 'package:flutter_tools/src/build_system/targets/assets.dart';
|
||||
import 'package:flutter_tools/src/build_system/targets/common.dart';
|
||||
import 'package:flutter_tools/src/build_system/targets/ios.dart';
|
||||
import 'package:flutter_tools/src/convert.dart';
|
||||
import 'package:flutter_tools/src/globals.dart' as globals;
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import '../../../src/common.dart';
|
||||
import '../../../src/context.dart';
|
||||
import '../../../src/fake_process_manager.dart';
|
||||
import '../../../src/testbed.dart';
|
||||
|
||||
final Platform macPlatform = FakePlatform(operatingSystem: 'macos', environment: <String, String>{});
|
||||
|
||||
const List<String> _kSharedConfig = <String>[
|
||||
'-dynamiclib',
|
||||
@ -37,35 +38,39 @@ const List<String> _kSharedConfig = <String>[
|
||||
];
|
||||
|
||||
void main() {
|
||||
Testbed testbed;
|
||||
Environment environment;
|
||||
ProcessManager processManager;
|
||||
FileSystem fileSystem;
|
||||
FakeProcessManager processManager;
|
||||
Artifacts artifacts;
|
||||
Logger logger;
|
||||
|
||||
setUp(() {
|
||||
testbed = Testbed(setup: () {
|
||||
environment = Environment.test(
|
||||
globals.fs.currentDirectory,
|
||||
defines: <String, String>{
|
||||
kTargetPlatform: 'ios',
|
||||
},
|
||||
inputs: <String, String>{},
|
||||
processManager: processManager,
|
||||
artifacts: MockArtifacts(),
|
||||
logger: globals.logger,
|
||||
fileSystem: globals.fs,
|
||||
engineVersion: '2',
|
||||
);
|
||||
});
|
||||
fileSystem = MemoryFileSystem.test();
|
||||
processManager = FakeProcessManager.list(<FakeCommand>[]);
|
||||
logger = BufferLogger.test();
|
||||
artifacts = Artifacts.test();
|
||||
environment = Environment.test(
|
||||
fileSystem.currentDirectory,
|
||||
defines: <String, String>{
|
||||
kTargetPlatform: 'ios',
|
||||
},
|
||||
inputs: <String, String>{},
|
||||
processManager: processManager,
|
||||
artifacts: artifacts,
|
||||
logger: logger,
|
||||
fileSystem: fileSystem,
|
||||
engineVersion: '2',
|
||||
);
|
||||
});
|
||||
|
||||
test('iOS AOT targets has analyicsName', () {
|
||||
testWithoutContext('iOS AOT targets has analyicsName', () {
|
||||
expect(const AotAssemblyRelease().analyticsName, 'ios_aot');
|
||||
expect(const AotAssemblyProfile().analyticsName, 'ios_aot');
|
||||
});
|
||||
|
||||
test('DebugUniveralFramework creates expected binary with arm64 only arch', () => testbed.run(() async {
|
||||
testUsingContext('DebugUniveralFramework creates expected binary with arm64 only arch', () async {
|
||||
environment.defines[kIosArchs] = 'arm64';
|
||||
processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
processManager.addCommands(<FakeCommand>[
|
||||
// Create iphone stub.
|
||||
const FakeCommand(command: <String>['xcrun', '--sdk', 'iphoneos', '--show-sdk-path']),
|
||||
FakeCommand(command: <String>[
|
||||
@ -76,7 +81,7 @@ void main() {
|
||||
// iphone only gets 64 bit arch based on kIosArchs
|
||||
'-arch',
|
||||
'arm64',
|
||||
globals.fs.path.absolute(globals.fs.path.join('.tmp_rand0', 'flutter_tools_stub_source.rand0', 'debug_app.cc')),
|
||||
fileSystem.path.absolute(fileSystem.path.join('.tmp_rand0', 'flutter_tools_stub_source.rand0', 'debug_app.cc')),
|
||||
..._kSharedConfig,
|
||||
'',
|
||||
'-o',
|
||||
@ -92,7 +97,7 @@ void main() {
|
||||
// Simulator only as x86_64 arch
|
||||
'-arch',
|
||||
'x86_64',
|
||||
globals.fs.path.absolute(globals.fs.path.join('.tmp_rand0', 'flutter_tools_stub_source.rand0', 'debug_app.cc')),
|
||||
fileSystem.path.absolute(fileSystem.path.join('.tmp_rand0', 'flutter_tools_stub_source.rand0', 'debug_app.cc')),
|
||||
..._kSharedConfig,
|
||||
'',
|
||||
'-o',
|
||||
@ -112,24 +117,25 @@ void main() {
|
||||
|
||||
await const DebugUniveralFramework().build(environment);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => processManager,
|
||||
}));
|
||||
Platform: () => macPlatform,
|
||||
});
|
||||
|
||||
test('DebugIosApplicationBundle', () => testbed.run(() async {
|
||||
testUsingContext('DebugIosApplicationBundle', () async {
|
||||
environment.inputs[kBundleSkSLPath] = 'bundle.sksl';
|
||||
environment.defines[kBuildMode] = 'debug';
|
||||
// Precompiled dart data
|
||||
when(globals.artifacts.getArtifactPath(Artifact.vmSnapshotData, mode: BuildMode.debug))
|
||||
.thenReturn('vm_snapshot_data');
|
||||
when(globals.artifacts.getArtifactPath(Artifact.isolateSnapshotData, mode: BuildMode.debug))
|
||||
.thenReturn('isolate_snapshot_data');
|
||||
globals.fs.file('vm_snapshot_data').createSync();
|
||||
globals.fs.file('isolate_snapshot_data').createSync();
|
||||
|
||||
fileSystem.file(artifacts.getArtifactPath(Artifact.vmSnapshotData, mode: BuildMode.debug))
|
||||
.createSync();
|
||||
fileSystem.file(artifacts.getArtifactPath(Artifact.isolateSnapshotData, mode: BuildMode.debug))
|
||||
.createSync();
|
||||
// Project info
|
||||
globals.fs.file('pubspec.yaml').writeAsStringSync('name: hello');
|
||||
globals.fs.file('.packages').writeAsStringSync('\n');
|
||||
fileSystem.file('pubspec.yaml').writeAsStringSync('name: hello');
|
||||
fileSystem.file('.packages').writeAsStringSync('\n');
|
||||
// Plist file
|
||||
globals.fs.file(globals.fs.path.join('ios', 'Flutter', 'AppFrameworkInfo.plist'))
|
||||
fileSystem.file(fileSystem.path.join('ios', 'Flutter', 'AppFrameworkInfo.plist'))
|
||||
.createSync(recursive: true);
|
||||
// App kernel
|
||||
environment.buildDir.childFile('app.dill').createSync(recursive: true);
|
||||
@ -139,7 +145,7 @@ void main() {
|
||||
.childFile('App')
|
||||
.createSync(recursive: true);
|
||||
// sksl bundle
|
||||
globals.fs.file('bundle.sksl').writeAsStringSync(json.encode(
|
||||
fileSystem.file('bundle.sksl').writeAsStringSync(json.encode(
|
||||
<String, Object>{
|
||||
'engineRevision': '2',
|
||||
'platform': 'ios',
|
||||
@ -162,18 +168,16 @@ void main() {
|
||||
expect(assetDirectory.childFile('isolate_snapshot_data'), exists);
|
||||
expect(assetDirectory.childFile('io.flutter.shaders.json'), exists);
|
||||
expect(assetDirectory.childFile('io.flutter.shaders.json').readAsStringSync(), '{"data":{"A":"B"}}');
|
||||
}, overrides: <Type, Generator>{
|
||||
Artifacts: () => MockArtifacts(),
|
||||
}));
|
||||
});
|
||||
|
||||
test('ReleaseIosApplicationBundle', () => testbed.run(() async {
|
||||
testUsingContext('ReleaseIosApplicationBundle', () async {
|
||||
environment.defines[kBuildMode] = 'release';
|
||||
|
||||
// Project info
|
||||
globals.fs.file('pubspec.yaml').writeAsStringSync('name: hello');
|
||||
globals.fs.file('.packages').writeAsStringSync('\n');
|
||||
fileSystem.file('pubspec.yaml').writeAsStringSync('name: hello');
|
||||
fileSystem.file('.packages').writeAsStringSync('\n');
|
||||
// Plist file
|
||||
globals.fs.file(globals.fs.path.join('ios', 'Flutter', 'AppFrameworkInfo.plist'))
|
||||
fileSystem.file(fileSystem.path.join('ios', 'Flutter', 'AppFrameworkInfo.plist'))
|
||||
.createSync(recursive: true);
|
||||
|
||||
// Real framework
|
||||
@ -193,9 +197,13 @@ void main() {
|
||||
expect(assetDirectory.childFile('AssetManifest.json'), exists);
|
||||
expect(assetDirectory.childFile('vm_snapshot_data'), isNot(exists));
|
||||
expect(assetDirectory.childFile('isolate_snapshot_data'), isNot(exists));
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => processManager,
|
||||
Platform: () => macPlatform,
|
||||
});
|
||||
|
||||
test('AotAssemblyRelease throws exception if asked to build for x86 target', () => testbed.run(() async {
|
||||
testUsingContext('AotAssemblyRelease throws exception if asked to build for x86 target', () async {
|
||||
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||
final Environment environment = Environment.test(
|
||||
fileSystem.currentDirectory,
|
||||
@ -203,8 +211,8 @@ void main() {
|
||||
kTargetPlatform: 'ios',
|
||||
},
|
||||
processManager: processManager,
|
||||
artifacts: MockArtifacts(),
|
||||
logger: BufferLogger.test(),
|
||||
artifacts: artifacts,
|
||||
logger: logger,
|
||||
fileSystem: fileSystem,
|
||||
);
|
||||
environment.defines[kBuildMode] = 'release';
|
||||
@ -217,7 +225,9 @@ void main() {
|
||||
contains('release/profile builds are only supported for physical devices.'),
|
||||
)
|
||||
));
|
||||
}));
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => fileSystem,
|
||||
ProcessManager: () => processManager,
|
||||
Platform: () => macPlatform,
|
||||
});
|
||||
}
|
||||
|
||||
class MockArtifacts extends Mock implements Artifacts {}
|
||||
|
||||
@ -10,6 +10,7 @@ import 'package:flutter_tools/src/base/io.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:process/process.dart';
|
||||
import 'common.dart';
|
||||
import 'context.dart';
|
||||
|
||||
export 'package:process/process.dart' show ProcessManager;
|
||||
|
||||
@ -199,6 +200,11 @@ abstract class FakeProcessManager implements ProcessManager {
|
||||
/// This is a no-op on [FakeProcessManager.any].
|
||||
void addCommand(FakeCommand command);
|
||||
|
||||
/// Add multiple [FakeCommand] to the current process manager.
|
||||
void addCommands(Iterable<FakeCommand> commands) {
|
||||
commands.forEach(addCommand);
|
||||
}
|
||||
|
||||
/// Whether this fake has more [FakeCommand]s that are expected to run.
|
||||
///
|
||||
/// This is always `true` for [FakeProcessManager.any].
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user