| // Copyright 2014 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'dart:async'; |
| |
| import 'package:file/memory.dart'; |
| import 'package:flutter_tools/src/application_package.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/bundle.dart'; |
| import 'package:flutter_tools/src/bundle_builder.dart'; |
| import 'package:flutter_tools/src/cache.dart'; |
| import 'package:flutter_tools/src/device.dart'; |
| import 'package:flutter_tools/src/preview_device.dart'; |
| import 'package:flutter_tools/src/project.dart'; |
| import 'package:meta/meta.dart'; |
| import 'package:test/fake.dart'; |
| |
| import '../src/common.dart'; |
| import '../src/context.dart'; |
| import '../src/fakes.dart'; |
| |
| void main() { |
| String? flutterRootBackup; |
| late MemoryFileSystem fs; |
| late File previewBinary; |
| |
| setUp(() { |
| fs = MemoryFileSystem.test(style: FileSystemStyle.windows); |
| Cache.flutterRoot = r'C:\path\to\flutter'; |
| previewBinary = fs.file('${Cache.flutterRoot}\\bin\\cache\\artifacts\\flutter_preview\\flutter_preview.exe'); |
| previewBinary.createSync(recursive: true); |
| flutterRootBackup = Cache.flutterRoot; |
| }); |
| |
| tearDown(() { |
| Cache.flutterRoot = flutterRootBackup; |
| }); |
| |
| testWithoutContext('PreviewDevice defaults', () async { |
| final PreviewDevice device = PreviewDevice( |
| artifacts: Artifacts.test(), |
| fileSystem: fs, |
| processManager: FakeProcessManager.any(), |
| previewBinary: previewBinary, |
| logger: BufferLogger.test(), |
| ); |
| |
| expect(await device.isLocalEmulator, false); |
| expect(device.name, 'Preview'); |
| expect(await device.sdkNameAndVersion, 'preview'); |
| expect(await device.targetPlatform, TargetPlatform.windows_x64); |
| expect(device.category, Category.desktop); |
| expect(device.ephemeral, false); |
| expect(device.id, 'preview'); |
| |
| expect(device.isSupported(), true); |
| expect(device.isSupportedForProject(FakeFlutterProject()), true); |
| expect(await device.isLatestBuildInstalled(FakeApplicationPackage()), false); |
| expect(await device.isAppInstalled(FakeApplicationPackage()), false); |
| expect(await device.uninstallApp(FakeApplicationPackage()), true); |
| }); |
| |
| testUsingContext('Can build a simulator app', () async { |
| final Completer<void> completer = Completer<void>(); |
| final BufferLogger logger = BufferLogger.test(); |
| final PreviewDevice device = PreviewDevice( |
| artifacts: Artifacts.test(), |
| fileSystem: fs, |
| previewBinary: previewBinary, |
| processManager: FakeProcessManager.list(<FakeCommand>[ |
| FakeCommand( |
| command: const <String>[ |
| r'C:\.tmp_rand0\flutter_preview.rand0\flutter_preview.exe', |
| ], |
| stdout: 'The Dart VM service is listening on http://127.0.0.1:64494/fZ_B2N6JRwY=/\n', |
| completer: completer, |
| ), |
| ]), |
| logger: logger, |
| builderFactory: () => FakeBundleBuilder(fs), |
| ); |
| final Directory previewDeviceCacheDir = fs |
| .directory('Artifact.windowsDesktopPath.TargetPlatform.windows_x64.debug') |
| ..createSync(recursive: true); |
| previewDeviceCacheDir.childFile('flutter_windows.dll').writeAsStringSync('1010101'); |
| previewDeviceCacheDir.childFile('icudtl.dat').writeAsStringSync('1010101'); |
| |
| final LaunchResult result = await device.startApp( |
| FakeApplicationPackage(), |
| debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), |
| ); |
| |
| expect(result.started, true); |
| expect(result.vmServiceUri, Uri.parse('http://127.0.0.1:64494/fZ_B2N6JRwY=/')); |
| }); |
| |
| group('PreviewDeviceDiscovery', () { |
| late Artifacts artifacts; |
| late ProcessManager processManager; |
| final FakePlatform windowsPlatform = FakePlatform(operatingSystem: 'windows'); |
| final FakePlatform macPlatform = FakePlatform(operatingSystem: 'macos'); |
| final FakePlatform linuxPlatform = FakePlatform(); |
| final TestFeatureFlags featureFlags = TestFeatureFlags(isPreviewDeviceEnabled: true); |
| |
| setUp(() { |
| artifacts = Artifacts.test(fileSystem: fs); |
| processManager = FakeProcessManager.empty(); |
| }); |
| |
| testWithoutContext('PreviewDeviceDiscovery on linux', () async { |
| final PreviewDeviceDiscovery discovery = PreviewDeviceDiscovery( |
| artifacts: artifacts, |
| fileSystem: fs, |
| logger: BufferLogger.test(), |
| processManager: processManager, |
| platform: linuxPlatform, |
| featureFlags: featureFlags, |
| ); |
| |
| final List<Device> devices = await discovery.devices(); |
| |
| expect(devices, isEmpty); |
| }); |
| |
| testWithoutContext('PreviewDeviceDiscovery on macOS', () async { |
| final PreviewDeviceDiscovery discovery = PreviewDeviceDiscovery( |
| artifacts: artifacts, |
| fileSystem: fs, |
| logger: BufferLogger.test(), |
| processManager: processManager, |
| platform: macPlatform, |
| featureFlags: featureFlags, |
| ); |
| |
| final List<Device> devices = await discovery.devices(); |
| |
| expect(devices, isEmpty); |
| }); |
| |
| testWithoutContext('PreviewDeviceDiscovery on Windows returns preview when binary exists', () async { |
| // ensure Flutter preview binary exists in cache. |
| fs.file(artifacts.getArtifactPath(Artifact.flutterPreviewDevice)).writeAsBytesSync(<int>[1, 0, 0, 1]); |
| final PreviewDeviceDiscovery discovery = PreviewDeviceDiscovery( |
| artifacts: artifacts, |
| fileSystem: fs, |
| logger: BufferLogger.test(), |
| processManager: processManager, |
| platform: windowsPlatform, |
| featureFlags: featureFlags, |
| ); |
| |
| final List<Device> devices = await discovery.devices(); |
| |
| expect(devices, hasLength(1)); |
| final Device previewDevice = devices.first; |
| expect(previewDevice, isA<PreviewDevice>()); |
| }); |
| |
| testWithoutContext('PreviewDeviceDiscovery on Windows returns nothing when binary does not exist', () async { |
| final PreviewDeviceDiscovery discovery = PreviewDeviceDiscovery( |
| artifacts: artifacts, |
| fileSystem: fs, |
| logger: BufferLogger.test(), |
| processManager: processManager, |
| platform: windowsPlatform, |
| featureFlags: featureFlags, |
| ); |
| |
| final List<Device> devices = await discovery.devices(); |
| |
| expect(devices, isEmpty); |
| }); |
| }); |
| } |
| |
| class FakeFlutterProject extends Fake implements FlutterProject { } |
| class FakeApplicationPackage extends Fake implements ApplicationPackage { } |
| class FakeBundleBuilder extends Fake implements BundleBuilder { |
| FakeBundleBuilder(this.fileSystem); |
| |
| final FileSystem fileSystem; |
| |
| @override |
| Future<void> build({ |
| required TargetPlatform platform, |
| required BuildInfo buildInfo, |
| FlutterProject? project, |
| String? mainPath, |
| String manifestPath = defaultManifestPath, |
| String? applicationKernelFilePath, |
| String? depfilePath, |
| String? assetDirPath, |
| bool buildNativeAssets = true, |
| @visibleForTesting BuildSystem? buildSystem |
| }) async { |
| final Directory assetDirectory = fileSystem |
| .directory(assetDirPath) |
| .childDirectory('flutter_assets') |
| ..createSync(recursive: true); |
| assetDirectory.childFile('kernel_blob.bin').createSync(); |
| } |
| } |