diff --git a/packages/flutter_tools/lib/src/build_system/targets/android.dart b/packages/flutter_tools/lib/src/build_system/targets/android.dart index fb86dbbc6d2..aa3e55f7d4d 100644 --- a/packages/flutter_tools/lib/src/build_system/targets/android.dart +++ b/packages/flutter_tools/lib/src/build_system/targets/android.dart @@ -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 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]; diff --git a/packages/flutter_tools/lib/src/build_system/targets/assets.dart b/packages/flutter_tools/lib/src/build_system/targets/assets.dart index eac6494a889..8d1ff2bc7c0 100644 --- a/packages/flutter_tools/lib/src/build_system/targets/assets.dart +++ b/packages/flutter_tools/lib/src/build_system/targets/assets.dart @@ -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 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 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 assetEntries = { @@ -85,7 +86,8 @@ Future 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, diff --git a/packages/flutter_tools/lib/src/build_system/targets/common.dart b/packages/flutter_tools/lib/src/build_system/targets/common.dart index 1ce6e853f50..38ebbb2237d 100644 --- a/packages/flutter_tools/lib/src/build_system/targets/common.dart +++ b/packages/flutter_tools/lib/src/build_system/targets/common.dart @@ -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 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 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) { diff --git a/packages/flutter_tools/lib/src/build_system/targets/ios.dart b/packages/flutter_tools/lib/src/build_system/targets/ios.dart index 3e84359069b..4e6ffe42de5 100644 --- a/packages/flutter_tools/lib/src/build_system/targets/ios.dart +++ b/packages/flutter_tools/lib/src/build_system/targets/ios.dart @@ -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 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([ + 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([ '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 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 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'); diff --git a/packages/flutter_tools/test/general.shard/build_system/targets/android_test.dart b/packages/flutter_tools/test/general.shard/build_system/targets/android_test.dart index 126d21ce6a2..9c6859b969b 100644 --- a/packages/flutter_tools/test/general.shard/build_system/targets/android_test.dart +++ b/packages/flutter_tools/test/general.shard/build_system/targets/android_test.dart @@ -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 {}); void main() { - FakeProcessManager fakeProcessManager; - final Testbed testbed = Testbed(overrides: { - Cache: () => FakeCache(), - Platform: () => FakePlatform(operatingSystem: 'linux', environment: const {}), + FakeProcessManager processManager; + FileSystem fileSystem; + Artifacts artifacts; + Logger logger; + + setUp(() { + logger = BufferLogger.test(); + fileSystem = MemoryFileSystem.test(); + processManager = FakeProcessManager.list([]); + 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: { 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: { + 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: { kBuildMode: 'debug', }, inputs: { 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( { '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: { + 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: { 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: { + 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: { 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([]); + testUsingContext('AndroidAot can build provided target platform', () async { + processManager = FakeProcessManager.list([]); final Environment environment = Environment.test( - globals.fs.currentDirectory, - outputDir: globals.fs.directory('out')..createSync(), + fileSystem.currentDirectory, + outputDir: fileSystem.directory('out')..createSync(), defines: { kBuildMode: 'release', }, - artifacts: MockArtifacts(), - processManager: FakeProcessManager.list([]), - fileSystem: globals.fs, - logger: globals.logger, - ); - fakeProcessManager.addCommand(FakeCommand(command: [ - 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: [ + 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: { - ProcessManager: () => fakeProcessManager, + FileSystem: () => fileSystem, + ProcessManager: () => processManager, }); - testbed.test('kExtraGenSnapshotOptions passes values to gen_snapshot', () async { - fakeProcessManager = FakeProcessManager.list([]); + testUsingContext('kExtraGenSnapshotOptions passes values to gen_snapshot', () async { + processManager = FakeProcessManager.list([]); final Environment environment = Environment.test( - globals.fs.currentDirectory, - outputDir: globals.fs.directory('out')..createSync(), + fileSystem.currentDirectory, + outputDir: fileSystem.directory('out')..createSync(), defines: { 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: [ - 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: { - 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: { 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 {} diff --git a/packages/flutter_tools/test/general.shard/build_system/targets/dart_test.dart b/packages/flutter_tools/test/general.shard/build_system/targets/dart_test.dart index 6776350c303..86c4132b9f6 100644 --- a/packages/flutter_tools/test/general.shard/build_system/targets/dart_test.dart +++ b/packages/flutter_tools/test/general.shard/build_system/targets/dart_test.dart @@ -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: {}); 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: { - 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: { - 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: { - Platform: () => FakePlatform(operatingSystem: 'macos', environment: {}), - FileSystem: () => MemoryFileSystem.test(style: FileSystemStyle.posix), - ProcessManager: () => processManager, - }); + processManager = FakeProcessManager.list([]); + logger = BufferLogger.test(); + artifacts = Artifacts.test(); + fileSystem = MemoryFileSystem.test(style: FileSystemStyle.posix); + androidEnvironment = Environment.test( + fileSystem.currentDirectory, + defines: { + 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: { + 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())); - })); + }); - 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([ + processManager.addCommands([ FakeCommand(command: [ 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())); 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([ + processManager.addCommands([ FakeCommand(command: [ 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([ + processManager.addCommands([ FakeCommand(command: [ 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([ + processManager.addCommands([ FakeCommand(command: [ 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([ + processManager.addCommands([ FakeCommand(command: [ 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([ + processManager.addCommands([ FakeCommand(command: [ 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: { 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([ + processManager.addCommands([ FakeCommand(command: [ 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([ + processManager.addCommands([ FakeCommand(command: [ - 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())); - })); + }); - 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())); - })); + }); - 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())); - })); + }, overrides: { + 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())); - })); + }, overrides: { + 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())); - })); + }, overrides: { + 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([ + processManager.addCommands([ FakeCommand(command: [ // 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: [ // 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: { + 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([ + processManager.addCommands([ FakeCommand(command: [ // 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: { + 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([ + processManager.addCommands([ FakeCommand(command: [ - 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); - })); + }); } diff --git a/packages/flutter_tools/test/general.shard/build_system/targets/ios_test.dart b/packages/flutter_tools/test/general.shard/build_system/targets/ios_test.dart index fb2e7bdec42..34fbcf489d7 100644 --- a/packages/flutter_tools/test/general.shard/build_system/targets/ios_test.dart +++ b/packages/flutter_tools/test/general.shard/build_system/targets/ios_test.dart @@ -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: {}); const List _kSharedConfig = [ '-dynamiclib', @@ -37,35 +38,39 @@ const List _kSharedConfig = [ ]; 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: { - kTargetPlatform: 'ios', - }, - inputs: {}, - processManager: processManager, - artifacts: MockArtifacts(), - logger: globals.logger, - fileSystem: globals.fs, - engineVersion: '2', - ); - }); + fileSystem = MemoryFileSystem.test(); + processManager = FakeProcessManager.list([]); + logger = BufferLogger.test(); + artifacts = Artifacts.test(); + environment = Environment.test( + fileSystem.currentDirectory, + defines: { + kTargetPlatform: 'ios', + }, + inputs: {}, + 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([ + processManager.addCommands([ // Create iphone stub. const FakeCommand(command: ['xcrun', '--sdk', 'iphoneos', '--show-sdk-path']), FakeCommand(command: [ @@ -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: { + 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( { '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: { - 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: { + 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: { + FileSystem: () => fileSystem, + ProcessManager: () => processManager, + Platform: () => macPlatform, + }); } - -class MockArtifacts extends Mock implements Artifacts {} diff --git a/packages/flutter_tools/test/src/fake_process_manager.dart b/packages/flutter_tools/test/src/fake_process_manager.dart index 192c48c9feb..26a29ce5656 100644 --- a/packages/flutter_tools/test/src/fake_process_manager.dart +++ b/packages/flutter_tools/test/src/fake_process_manager.dart @@ -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 commands) { + commands.forEach(addCommand); + } + /// Whether this fake has more [FakeCommand]s that are expected to run. /// /// This is always `true` for [FakeProcessManager.any].