Allow filtering devices to only those supported by current project (#31446)
diff --git a/packages/flutter_tools/lib/src/android/android_device.dart b/packages/flutter_tools/lib/src/android/android_device.dart index 83a651a..e6cfdac 100644 --- a/packages/flutter_tools/lib/src/android/android_device.dart +++ b/packages/flutter_tools/lib/src/android/android_device.dart
@@ -535,6 +535,11 @@ await runCheckedAsync(adbCommandForDevice(<String>['pull', remotePath, outputFile.path])); await runCheckedAsync(adbCommandForDevice(<String>['shell', 'rm', remotePath])); } + + @override + bool isSupportedForProject(FlutterProject flutterProject) { + return flutterProject.android.existsSync(); + } } Map<String, String> parseAdbDeviceProperties(String str) {
diff --git a/packages/flutter_tools/lib/src/commands/attach.dart b/packages/flutter_tools/lib/src/commands/attach.dart index bf98583..9fca77e 100644 --- a/packages/flutter_tools/lib/src/commands/attach.dart +++ b/packages/flutter_tools/lib/src/commands/attach.dart
@@ -243,6 +243,7 @@ final bool useHot = getBuildInfo().isDebug; final FlutterDevice flutterDevice = await FlutterDevice.create( device, + flutterProject: flutterProject, trackWidgetCreation: argResults['track-widget-creation'], dillOutputPath: argResults['output-dill'], fileSystemRoots: argResults['filesystem-root'],
diff --git a/packages/flutter_tools/lib/src/commands/daemon.dart b/packages/flutter_tools/lib/src/commands/daemon.dart index c7e7b9e..f9fbc24 100644 --- a/packages/flutter_tools/lib/src/commands/daemon.dart +++ b/packages/flutter_tools/lib/src/commands/daemon.dart
@@ -19,6 +19,7 @@ import '../device.dart'; import '../emulator.dart'; import '../globals.dart'; +import '../project.dart'; import '../resident_runner.dart'; import '../run_cold.dart'; import '../run_hot.dart'; @@ -344,9 +345,11 @@ // We change the current working directory for the duration of the `start` command. final Directory cwd = fs.currentDirectory; fs.currentDirectory = fs.directory(projectDirectory); + final FlutterProject flutterProject = await FlutterProject.current(); final FlutterDevice flutterDevice = await FlutterDevice.create( device, + flutterProject: flutterProject, trackWidgetCreation: trackWidgetCreation, dillOutputPath: dillOutputPath, viewFilter: isolateFilter,
diff --git a/packages/flutter_tools/lib/src/commands/run.dart b/packages/flutter_tools/lib/src/commands/run.dart index ba5be91..80771e8 100644 --- a/packages/flutter_tools/lib/src/commands/run.dart +++ b/packages/flutter_tools/lib/src/commands/run.dart
@@ -13,6 +13,7 @@ import '../device.dart'; import '../globals.dart'; import '../ios/mac.dart'; +import '../project.dart'; import '../resident_runner.dart'; import '../run_cold.dart'; import '../run_hot.dart'; @@ -364,9 +365,11 @@ expFlags = argResults[FlutterOptions.kEnableExperiment]; } final List<FlutterDevice> flutterDevices = <FlutterDevice>[]; + final FlutterProject flutterProject = await FlutterProject.current(); for (Device device in devices) { final FlutterDevice flutterDevice = await FlutterDevice.create( device, + flutterProject: flutterProject, trackWidgetCreation: argResults['track-widget-creation'], dillOutputPath: argResults['output-dill'], fileSystemRoots: argResults['filesystem-root'],
diff --git a/packages/flutter_tools/lib/src/device.dart b/packages/flutter_tools/lib/src/device.dart index 29bb3e7..028894e 100644 --- a/packages/flutter_tools/lib/src/device.dart +++ b/packages/flutter_tools/lib/src/device.dart
@@ -19,6 +19,7 @@ import 'ios/simulators.dart'; import 'linux/linux_device.dart'; import 'macos/macos_device.dart'; +import 'project.dart'; import 'tester/flutter_tester.dart'; import 'web/web_device.dart'; import 'windows/windows_device.dart'; @@ -235,6 +236,9 @@ } } + /// Whether the device is supported for the current project directory. + bool isSupportedForProject(FlutterProject flutterProject); + /// Check if a version of the given app is already installed Future<bool> isAppInstalled(ApplicationPackage app);
diff --git a/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart b/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart index 9aa1fb5..c7b1ba8 100644 --- a/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart +++ b/packages/flutter_tools/lib/src/fuchsia/fuchsia_device.dart
@@ -17,6 +17,7 @@ import '../build_info.dart'; import '../device.dart'; import '../globals.dart'; +import '../project.dart'; import '../vmservice.dart'; import 'fuchsia_sdk.dart'; @@ -302,6 +303,9 @@ } FuchsiaIsolateDiscoveryProtocol getIsolateDiscoveryProtocol(String isolateName) => FuchsiaIsolateDiscoveryProtocol(this, isolateName); + + @override + bool isSupportedForProject(FlutterProject flutterProject) => true; } class FuchsiaIsolateDiscoveryProtocol {
diff --git a/packages/flutter_tools/lib/src/ios/devices.dart b/packages/flutter_tools/lib/src/ios/devices.dart index d469da1..02ede71 100644 --- a/packages/flutter_tools/lib/src/ios/devices.dart +++ b/packages/flutter_tools/lib/src/ios/devices.dart
@@ -17,6 +17,7 @@ import '../convert.dart'; import '../device.dart'; import '../globals.dart'; +import '../project.dart'; import '../protocol_discovery.dart'; import 'code_signing.dart'; import 'ios_workflow.dart'; @@ -401,6 +402,11 @@ Future<void> takeScreenshot(File outputFile) async { await iMobileDevice.takeScreenshot(outputFile); } + + @override + bool isSupportedForProject(FlutterProject flutterProject) { + return flutterProject.ios.existsSync(); + } } /// Decodes a vis-encoded syslog string to a UTF-8 representation.
diff --git a/packages/flutter_tools/lib/src/ios/simulators.dart b/packages/flutter_tools/lib/src/ios/simulators.dart index a60ba54..9573dfe 100644 --- a/packages/flutter_tools/lib/src/ios/simulators.dart +++ b/packages/flutter_tools/lib/src/ios/simulators.dart
@@ -19,6 +19,7 @@ import '../convert.dart'; import '../device.dart'; import '../globals.dart'; +import '../project.dart'; import '../protocol_discovery.dart'; import 'ios_workflow.dart'; import 'mac.dart'; @@ -473,6 +474,11 @@ Future<void> takeScreenshot(File outputFile) { return SimControl.instance.takeScreenshot(id, outputFile.path); } + + @override + bool isSupportedForProject(FlutterProject flutterProject) { + return flutterProject.ios.existsSync(); + } } /// Launches the device log reader process on the host.
diff --git a/packages/flutter_tools/lib/src/linux/linux_device.dart b/packages/flutter_tools/lib/src/linux/linux_device.dart index d98afc4..5c50a94 100644 --- a/packages/flutter_tools/lib/src/linux/linux_device.dart +++ b/packages/flutter_tools/lib/src/linux/linux_device.dart
@@ -108,6 +108,11 @@ @override Future<bool> uninstallApp(ApplicationPackage app) async => true; + @override + bool isSupportedForProject(FlutterProject flutterProject) { + return flutterProject.linux.existsSync(); + } + // Track the last built mode from startApp. BuildMode _lastBuiltMode; }
diff --git a/packages/flutter_tools/lib/src/macos/macos_device.dart b/packages/flutter_tools/lib/src/macos/macos_device.dart index b3309bb..79cdb6f 100644 --- a/packages/flutter_tools/lib/src/macos/macos_device.dart +++ b/packages/flutter_tools/lib/src/macos/macos_device.dart
@@ -117,6 +117,11 @@ // to uninstall the application. @override Future<bool> uninstallApp(ApplicationPackage app) async => true; + + @override + bool isSupportedForProject(FlutterProject flutterProject) { + return flutterProject.macos.existsSync(); + } } class MacOSDevices extends PollingDeviceDiscovery {
diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart index 641c281..2f132de 100644 --- a/packages/flutter_tools/lib/src/project.dart +++ b/packages/flutter_tools/lib/src/project.dart
@@ -208,8 +208,6 @@ Directory get _ephemeralDirectory => parent.directory.childDirectory('.ios'); Directory get _editableDirectory => parent.directory.childDirectory('ios'); - bool existsSync() => parent.isModule || _editableDirectory.existsSync(); - /// This parent folder of `Runner.xcodeproj`. Directory get hostAppRoot { if (!isModule || _editableDirectory.existsSync()) @@ -264,6 +262,11 @@ /// Xcode workspace shared workspace settings file for the host app. File get xcodeWorkspaceSharedSettings => xcodeWorkspaceSharedData.childFile('WorkspaceSettings.xcsettings'); + /// Whether the current flutter project has an iOS subproject. + bool existsSync() { + return parent.isModule || _editableDirectory.existsSync(); + } + /// The product bundle identifier of the host app, or null if not set or if /// iOS tooling needed to read it is not installed. String get productBundleIdentifier { @@ -391,8 +394,6 @@ return _ephemeralDirectory; } - bool existsSync() => parent.isModule || _flutterLibGradleRoot.existsSync(); - /// The Gradle root directory of the Android wrapping of Flutter and plugins. /// This is the same as [hostAppGradleRoot] except when the project is /// a Flutter module with an editable host app. @@ -420,6 +421,11 @@ return fs.directory(fs.path.join(hostAppGradleRoot.path, 'app', 'build', 'outputs', 'bundle')); } + /// Whether the current flutter project has an Android sub-project. + bool existsSync() { + return parent.isModule || _editableHostAppDirectory.existsSync(); + } + bool get isUsingGradle { return hostAppGradleRoot.childFile('build.gradle').existsSync(); } @@ -498,7 +504,10 @@ final FlutterProject parent; - bool existsSync() => parent.directory.childDirectory('web').existsSync(); + /// Whether this flutter project has a web sub-project. + bool existsSync() { + return parent.directory.childDirectory('web').existsSync(); + } Future<void> ensureReadyForPlatformSpecificTooling() async { /// Generate index.html in build/web. Eventually we could support @@ -590,4 +599,4 @@ /// The Linux project makefile. File get makeFile => editableHostAppDirectory.childFile('Makefile'); -} \ No newline at end of file +}
diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart index 3325255..8725555 100644 --- a/packages/flutter_tools/lib/src/resident_runner.dart +++ b/packages/flutter_tools/lib/src/resident_runner.dart
@@ -52,6 +52,7 @@ /// Create a [FlutterDevice] with optional code generation enabled. static Future<FlutterDevice> create( Device device, { + @required FlutterProject flutterProject, @required bool trackWidgetCreation, String dillOutputPath, List<String> fileSystemRoots, @@ -64,7 +65,6 @@ @required BuildMode buildMode, }) async { ResidentCompiler generator; - final FlutterProject flutterProject = await FlutterProject.current(); if (flutterProject.hasBuilders) { generator = await CodeGeneratingResidentCompiler.create( flutterProject: flutterProject,
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart index 5aae159..4b5706c 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart
@@ -527,6 +527,13 @@ } devices = devices.where((Device device) => device.isSupported()).toList(); + // If the user has not specified all devices and has multiple connected + // then filter then list by those supported in the current project. If + // this ends up with a single device we can proceed as normal. + if (devices.length > 1 && !deviceManager.hasSpecifiedAllDevices && !deviceManager.hasSpecifiedDeviceId) { + final FlutterProject flutterProject = await FlutterProject.current(); + devices.removeWhere((Device device) => !device.isSupportedForProject(flutterProject)); + } if (devices.isEmpty) { printStatus(userMessages.flutterNoSupportedDevices);
diff --git a/packages/flutter_tools/lib/src/tester/flutter_tester.dart b/packages/flutter_tools/lib/src/tester/flutter_tester.dart index 14c5d3e..988fbeb 100644 --- a/packages/flutter_tools/lib/src/tester/flutter_tester.dart +++ b/packages/flutter_tools/lib/src/tester/flutter_tester.dart
@@ -18,6 +18,7 @@ import '../dart/package_map.dart'; import '../device.dart'; import '../globals.dart'; +import '../project.dart'; import '../protocol_discovery.dart'; import '../version.dart'; @@ -192,6 +193,9 @@ @override Future<bool> uninstallApp(ApplicationPackage app) async => true; + + @override + bool isSupportedForProject(FlutterProject flutterProject) => true; } class FlutterTesterDevices extends PollingDeviceDiscovery {
diff --git a/packages/flutter_tools/lib/src/web/web_device.dart b/packages/flutter_tools/lib/src/web/web_device.dart index fd78729..fd47dfa 100644 --- a/packages/flutter_tools/lib/src/web/web_device.dart +++ b/packages/flutter_tools/lib/src/web/web_device.dart
@@ -166,6 +166,11 @@ await request.response.addStream(file.openRead()); await request.response.close(); } + + @override + bool isSupportedForProject(FlutterProject flutterProject) { + return flutterProject.web.existsSync(); + } } class WebDevices extends PollingDeviceDiscovery {
diff --git a/packages/flutter_tools/lib/src/windows/windows_device.dart b/packages/flutter_tools/lib/src/windows/windows_device.dart index 9843dea..50a96a4 100644 --- a/packages/flutter_tools/lib/src/windows/windows_device.dart +++ b/packages/flutter_tools/lib/src/windows/windows_device.dart
@@ -114,6 +114,11 @@ // to uninstall the application. @override Future<bool> uninstallApp(ApplicationPackage app) async => true; + + @override + bool isSupportedForProject(FlutterProject flutterProject) { + return flutterProject.windows.existsSync(); + } } class WindowsDevices extends PollingDeviceDiscovery {
diff --git a/packages/flutter_tools/test/android/android_device_test.dart b/packages/flutter_tools/test/android/android_device_test.dart index d7945e5..6b02717 100644 --- a/packages/flutter_tools/test/android/android_device_test.dart +++ b/packages/flutter_tools/test/android/android_device_test.dart
@@ -10,6 +10,7 @@ import 'package:flutter_tools/src/base/config.dart'; import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/io.dart'; +import 'package:flutter_tools/src/project.dart'; import 'package:mockito/mockito.dart'; import 'package:process/process.dart'; @@ -157,6 +158,44 @@ ProcessManager: () => mockProcessManager, }); }); + + testUsingContext('isSupportedForProject is true on module project', () async { + fs.file('pubspec.yaml') + ..createSync() + ..writeAsStringSync(r''' +name: example + +flutter: + module: {} +'''); + fs.file('.packages').createSync(); + final FlutterProject flutterProject = await FlutterProject.current(); + + expect(AndroidDevice('test').isSupportedForProject(flutterProject), true); + }, overrides: <Type, Generator>{ + FileSystem: () => MemoryFileSystem(), + }); + + testUsingContext('isSupportedForProject is true with editable host app', () async { + fs.file('pubspec.yaml').createSync(); + fs.file('.packages').createSync(); + fs.directory('android').createSync(); + final FlutterProject flutterProject = await FlutterProject.current(); + + expect(AndroidDevice('test').isSupportedForProject(flutterProject), true); + }, overrides: <Type, Generator>{ + FileSystem: () => MemoryFileSystem(), + }); + + testUsingContext('isSupportedForProject is false with no host app and no module', () async { + fs.file('pubspec.yaml').createSync(); + fs.file('.packages').createSync(); + final FlutterProject flutterProject = await FlutterProject.current(); + + expect(AndroidDevice('test').isSupportedForProject(flutterProject), false); + }, overrides: <Type, Generator>{ + FileSystem: () => MemoryFileSystem(), + }); } class MockProcessManager extends Mock implements ProcessManager {}
diff --git a/packages/flutter_tools/test/fuchsia/fuchsa_device_test.dart b/packages/flutter_tools/test/fuchsia/fuchsa_device_test.dart index 7654d85..7851f88 100644 --- a/packages/flutter_tools/test/fuchsia/fuchsa_device_test.dart +++ b/packages/flutter_tools/test/fuchsia/fuchsa_device_test.dart
@@ -53,6 +53,7 @@ expect(device.supportsHotReload, true); expect(device.supportsHotRestart, false); expect(device.supportsStopApp, false); + expect(device.isSupportedForProject(null), true); expect(await device.stopApp(null), false); }); });
diff --git a/packages/flutter_tools/test/ios/devices_test.dart b/packages/flutter_tools/test/ios/devices_test.dart index 80b2b49..8c3cb31 100644 --- a/packages/flutter_tools/test/ios/devices_test.dart +++ b/packages/flutter_tools/test/ios/devices_test.dart
@@ -5,12 +5,14 @@ import 'dart:async'; import 'package:file/file.dart'; +import 'package:file/memory.dart'; import 'package:flutter_tools/src/application_package.dart'; import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/device.dart'; import 'package:flutter_tools/src/ios/devices.dart'; import 'package:flutter_tools/src/ios/mac.dart'; +import 'package:flutter_tools/src/project.dart'; import 'package:mockito/mockito.dart'; import 'package:platform/platform.dart'; import 'package:process/process.dart'; @@ -183,4 +185,42 @@ IMobileDevice: () => mockIMobileDevice, }); }); + + testUsingContext('IOSDevice.isSupportedForProject is true on module project', () async { + fs.file('pubspec.yaml') + ..createSync() + ..writeAsStringSync(r''' +name: example + +flutter: + module: {} +'''); + fs.file('.packages').createSync(); + final FlutterProject flutterProject = await FlutterProject.current(); + + expect(IOSDevice('test').isSupportedForProject(flutterProject), true); + }, overrides: <Type, Generator>{ + FileSystem: () => MemoryFileSystem(), + }); + + testUsingContext('IOSDevice.isSupportedForProject is true with editable host app', () async { + fs.file('pubspec.yaml').createSync(); + fs.file('.packages').createSync(); + fs.directory('ios').createSync(); + final FlutterProject flutterProject = await FlutterProject.current(); + + expect(IOSDevice('test').isSupportedForProject(flutterProject), true); + }, overrides: <Type, Generator>{ + FileSystem: () => MemoryFileSystem(), + }); + + testUsingContext('IOSDevice.isSupportedForProject is false with no host app and no module', () async { + fs.file('pubspec.yaml').createSync(); + fs.file('.packages').createSync(); + final FlutterProject flutterProject = await FlutterProject.current(); + + expect(IOSDevice('test').isSupportedForProject(flutterProject), false); + }, overrides: <Type, Generator>{ + FileSystem: () => MemoryFileSystem(), + }); }
diff --git a/packages/flutter_tools/test/ios/simulators_test.dart b/packages/flutter_tools/test/ios/simulators_test.dart index bc3ea07..143f77c 100644 --- a/packages/flutter_tools/test/ios/simulators_test.dart +++ b/packages/flutter_tools/test/ios/simulators_test.dart
@@ -6,11 +6,13 @@ import 'dart:io' show ProcessResult, Process; import 'package:file/file.dart'; +import 'package:file/memory.dart'; import 'package:flutter_tools/src/device.dart'; import 'package:flutter_tools/src/application_package.dart'; import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/ios/mac.dart'; import 'package:flutter_tools/src/ios/simulators.dart'; +import 'package:flutter_tools/src/project.dart'; import 'package:mockito/mockito.dart'; import 'package:platform/platform.dart'; import 'package:process/process.dart'; @@ -414,4 +416,42 @@ SimControl: () => simControl, }); }); + + testUsingContext('IOSDevice.isSupportedForProject is true on module project', () async { + fs.file('pubspec.yaml') + ..createSync() + ..writeAsStringSync(r''' +name: example + +flutter: + module: {} +'''); + fs.file('.packages').createSync(); + final FlutterProject flutterProject = await FlutterProject.current(); + + expect(IOSSimulator('test').isSupportedForProject(flutterProject), true); + }, overrides: <Type, Generator>{ + FileSystem: () => MemoryFileSystem(), + }); + + testUsingContext('IOSDevice.isSupportedForProject is true with editable host app', () async { + fs.file('pubspec.yaml').createSync(); + fs.file('.packages').createSync(); + fs.directory('ios').createSync(); + final FlutterProject flutterProject = await FlutterProject.current(); + + expect(IOSSimulator('test').isSupportedForProject(flutterProject), true); + }, overrides: <Type, Generator>{ + FileSystem: () => MemoryFileSystem(), + }); + + testUsingContext('IOSDevice.isSupportedForProject is false with no host app and no module', () async { + fs.file('pubspec.yaml').createSync(); + fs.file('.packages').createSync(); + final FlutterProject flutterProject = await FlutterProject.current(); + + expect(IOSSimulator('test').isSupportedForProject(flutterProject), false); + }, overrides: <Type, Generator>{ + FileSystem: () => MemoryFileSystem(), + }); }
diff --git a/packages/flutter_tools/test/linux/linux_device_test.dart b/packages/flutter_tools/test/linux/linux_device_test.dart index c06743d..2efef0d 100644 --- a/packages/flutter_tools/test/linux/linux_device_test.dart +++ b/packages/flutter_tools/test/linux/linux_device_test.dart
@@ -2,6 +2,7 @@ // 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:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/base/platform.dart'; @@ -9,6 +10,7 @@ import 'package:flutter_tools/src/linux/application_package.dart'; import 'package:flutter_tools/src/linux/linux_device.dart'; import 'package:flutter_tools/src/device.dart'; +import 'package:flutter_tools/src/project.dart'; import 'package:mockito/mockito.dart'; import 'package:process/process.dart'; @@ -59,6 +61,27 @@ Platform: () => notLinux, }); }); + + testUsingContext('LinuxDevice.isSupportedForProject is true with editable host app', () async { + fs.file('pubspec.yaml').createSync(); + fs.file('.packages').createSync(); + fs.directory('linux').createSync(); + final FlutterProject flutterProject = await FlutterProject.current(); + + expect(LinuxDevice().isSupportedForProject(flutterProject), true); + }, overrides: <Type, Generator>{ + FileSystem: () => MemoryFileSystem(), + }); + + testUsingContext('LinuxDevice.isSupportedForProject is false with no host app', () async { + fs.file('pubspec.yaml').createSync(); + fs.file('.packages').createSync(); + final FlutterProject flutterProject = await FlutterProject.current(); + + expect(LinuxDevice().isSupportedForProject(flutterProject), false); + }, overrides: <Type, Generator>{ + FileSystem: () => MemoryFileSystem(), + }); } class MockPlatform extends Mock implements Platform {}
diff --git a/packages/flutter_tools/test/macos/macos_device_test.dart b/packages/flutter_tools/test/macos/macos_device_test.dart index 715350b..4817a19 100644 --- a/packages/flutter_tools/test/macos/macos_device_test.dart +++ b/packages/flutter_tools/test/macos/macos_device_test.dart
@@ -4,7 +4,9 @@ import 'dart:convert'; +import 'package:file/memory.dart'; import 'package:flutter_tools/src/base/context.dart'; +import 'package:flutter_tools/src/project.dart'; import 'package:mockito/mockito.dart'; import 'package:process/process.dart'; @@ -106,6 +108,27 @@ }, overrides: <Type, Generator>{ Platform: () => notMac, }); + + testUsingContext('isSupportedForProject is true with editable host app', () async { + fs.file('pubspec.yaml').createSync(); + fs.file('.packages').createSync(); + fs.directory('macos').createSync(); + final FlutterProject flutterProject = await FlutterProject.current(); + + expect(MacOSDevice().isSupportedForProject(flutterProject), true); + }, overrides: <Type, Generator>{ + FileSystem: () => MemoryFileSystem(), + }); + + testUsingContext('isSupportedForProject is false with no host app', () async { + fs.file('pubspec.yaml').createSync(); + fs.file('.packages').createSync(); + final FlutterProject flutterProject = await FlutterProject.current(); + + expect(MacOSDevice().isSupportedForProject(flutterProject), false); + }, overrides: <Type, Generator>{ + FileSystem: () => MemoryFileSystem(), + }); }); }
diff --git a/packages/flutter_tools/test/src/mocks.dart b/packages/flutter_tools/test/src/mocks.dart index 72410aa..70049bc 100644 --- a/packages/flutter_tools/test/src/mocks.dart +++ b/packages/flutter_tools/test/src/mocks.dart
@@ -379,6 +379,9 @@ @override bool isSupported() => true; + + @override + bool isSupportedForProject(FlutterProject flutterProject) => true; } class MockIOSDevice extends Mock implements IOSDevice { @@ -387,6 +390,9 @@ @override bool isSupported() => true; + + @override + bool isSupportedForProject(FlutterProject flutterProject) => true; } class MockIOSSimulator extends Mock implements IOSSimulator { @@ -395,6 +401,9 @@ @override bool isSupported() => true; + + @override + bool isSupportedForProject(FlutterProject flutterProject) => true; } class MockDeviceLogReader extends DeviceLogReader {
diff --git a/packages/flutter_tools/test/windows/windows_device_test.dart b/packages/flutter_tools/test/windows/windows_device_test.dart index 7a18c2c..32a798f 100644 --- a/packages/flutter_tools/test/windows/windows_device_test.dart +++ b/packages/flutter_tools/test/windows/windows_device_test.dart
@@ -2,10 +2,12 @@ // 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:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/base/platform.dart'; import 'package:flutter_tools/src/build_info.dart'; +import 'package:flutter_tools/src/project.dart'; import 'package:flutter_tools/src/windows/application_package.dart'; import 'package:flutter_tools/src/windows/windows_device.dart'; import 'package:flutter_tools/src/device.dart'; @@ -58,6 +60,27 @@ }, overrides: <Type, Generator>{ Platform: () => notWindows, }); + + testUsingContext('isSupportedForProject is true with editable host app', () async { + fs.file('pubspec.yaml').createSync(); + fs.file('.packages').createSync(); + fs.directory('windows').createSync(); + final FlutterProject flutterProject = await FlutterProject.current(); + + expect(WindowsDevice().isSupportedForProject(flutterProject), true); + }, overrides: <Type, Generator>{ + FileSystem: () => MemoryFileSystem(), + }); + + testUsingContext('isSupportedForProject is false with no host app', () async { + fs.file('pubspec.yaml').createSync(); + fs.file('.packages').createSync(); + final FlutterProject flutterProject = await FlutterProject.current(); + + expect(WindowsDevice().isSupportedForProject(flutterProject), false); + }, overrides: <Type, Generator>{ + FileSystem: () => MemoryFileSystem(), + }); }); } @@ -71,4 +94,4 @@ class MockProcess extends Mock implements Process {} -class MockProcessResult extends Mock implements ProcessResult {} \ No newline at end of file +class MockProcessResult extends Mock implements ProcessResult {}