Unverified Commit 859fce90 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] add feature for iOS, android, and fuchsia (#61481)

Add feature flags for android, ios, and fuchsia (on by default). After updating the g3 rollers, the fuchsia feature will be turned off by default. Creates a simpler base type of feature flags for g3 to extend.

Updates android, ios, fuchsia workflows to use feature flags check.
Removes concept of stable artifacts and checks on flutter version.

Fixes #58999
#52859
#12768
parent 045f3a54
...@@ -40,7 +40,7 @@ class AndroidDevices extends PollingDeviceDiscovery { ...@@ -40,7 +40,7 @@ class AndroidDevices extends PollingDeviceDiscovery {
final AndroidSdk _androidSdk; final AndroidSdk _androidSdk;
@override @override
bool get supportsPlatform => true; bool get supportsPlatform => _androidWorkflow.appliesToHostPlatform;
@override @override
bool get canListAnything => _androidWorkflow.canListDevices; bool get canListAnything => _androidWorkflow.canListDevices;
......
...@@ -20,6 +20,7 @@ import '../base/utils.dart'; ...@@ -20,6 +20,7 @@ import '../base/utils.dart';
import '../base/version.dart'; import '../base/version.dart';
import '../convert.dart'; import '../convert.dart';
import '../doctor.dart'; import '../doctor.dart';
import '../features.dart';
import '../globals.dart' as globals; import '../globals.dart' as globals;
import 'android_sdk.dart'; import 'android_sdk.dart';
import 'android_studio.dart'; import 'android_studio.dart';
...@@ -46,12 +47,15 @@ final RegExp licenseAccepted = RegExp(r'All SDK package licenses accepted.'); ...@@ -46,12 +47,15 @@ final RegExp licenseAccepted = RegExp(r'All SDK package licenses accepted.');
class AndroidWorkflow implements Workflow { class AndroidWorkflow implements Workflow {
AndroidWorkflow({ AndroidWorkflow({
@required AndroidSdk androidSdk, @required AndroidSdk androidSdk,
}) : _androidSdk = androidSdk; @required FeatureFlags featureFlags,
}) : _androidSdk = androidSdk,
_featureFlags = featureFlags;
final AndroidSdk _androidSdk; final AndroidSdk _androidSdk;
final FeatureFlags _featureFlags;
@override @override
bool get appliesToHostPlatform => true; bool get appliesToHostPlatform => _featureFlags.isAndroidEnabled;
@override @override
bool get canListDevices => getAdbPath(_androidSdk) != null; bool get canListDevices => getAdbPath(_androidSdk) != null;
......
...@@ -21,28 +21,25 @@ import 'globals.dart' as globals; ...@@ -21,28 +21,25 @@ import 'globals.dart' as globals;
/// A tag for a set of development artifacts that need to be cached. /// A tag for a set of development artifacts that need to be cached.
class DevelopmentArtifact { class DevelopmentArtifact {
const DevelopmentArtifact._(this.name, {this.unstable = false, this.feature}); const DevelopmentArtifact._(this.name, {this.feature});
/// The name of the artifact. /// The name of the artifact.
/// ///
/// This should match the flag name in precache.dart /// This should match the flag name in precache.dart
final String name; final String name;
/// Whether this artifact should be unavailable on master branch only.
final bool unstable;
/// A feature to control the visibility of this artifact. /// A feature to control the visibility of this artifact.
final Feature feature; final Feature feature;
/// Artifacts required for Android development. /// Artifacts required for Android development.
static const DevelopmentArtifact androidGenSnapshot = DevelopmentArtifact._('android_gen_snapshot'); static const DevelopmentArtifact androidGenSnapshot = DevelopmentArtifact._('android_gen_snapshot', feature: flutterAndroidFeature);
static const DevelopmentArtifact androidMaven = DevelopmentArtifact._('android_maven'); static const DevelopmentArtifact androidMaven = DevelopmentArtifact._('android_maven', feature: flutterAndroidFeature);
// Artifacts used for internal builds. // Artifacts used for internal builds.
static const DevelopmentArtifact androidInternalBuild = DevelopmentArtifact._('android_internal_build'); static const DevelopmentArtifact androidInternalBuild = DevelopmentArtifact._('android_internal_build', feature: flutterAndroidFeature);
/// Artifacts required for iOS development. /// Artifacts required for iOS development.
static const DevelopmentArtifact iOS = DevelopmentArtifact._('ios'); static const DevelopmentArtifact iOS = DevelopmentArtifact._('ios', feature: flutterIOSFeature);
/// Artifacts required for web development. /// Artifacts required for web development.
static const DevelopmentArtifact web = DevelopmentArtifact._('web', feature: flutterWebFeature); static const DevelopmentArtifact web = DevelopmentArtifact._('web', feature: flutterWebFeature);
...@@ -57,10 +54,10 @@ class DevelopmentArtifact { ...@@ -57,10 +54,10 @@ class DevelopmentArtifact {
static const DevelopmentArtifact linux = DevelopmentArtifact._('linux', feature: flutterLinuxDesktopFeature); static const DevelopmentArtifact linux = DevelopmentArtifact._('linux', feature: flutterLinuxDesktopFeature);
/// Artifacts required for Fuchsia. /// Artifacts required for Fuchsia.
static const DevelopmentArtifact fuchsia = DevelopmentArtifact._('fuchsia', unstable: true); static const DevelopmentArtifact fuchsia = DevelopmentArtifact._('fuchsia', feature: flutterFuchsiaFeature);
/// Artifacts required for the Flutter Runner. /// Artifacts required for the Flutter Runner.
static const DevelopmentArtifact flutterRunner = DevelopmentArtifact._('flutter_runner', unstable: true); static const DevelopmentArtifact flutterRunner = DevelopmentArtifact._('flutter_runner', feature: flutterFuchsiaFeature);
/// Artifacts required for any development platform. /// Artifacts required for any development platform.
/// ///
...@@ -84,7 +81,7 @@ class DevelopmentArtifact { ...@@ -84,7 +81,7 @@ class DevelopmentArtifact {
]; ];
@override @override
String toString() => 'Artifact($name, $unstable)'; String toString() => 'Artifact($name)';
} }
/// A wrapper around the `bin/cache/` directory. /// A wrapper around the `bin/cache/` directory.
......
...@@ -11,9 +11,7 @@ import '../base/logger.dart'; ...@@ -11,9 +11,7 @@ import '../base/logger.dart';
import '../base/platform.dart'; import '../base/platform.dart';
import '../cache.dart'; import '../cache.dart';
import '../features.dart'; import '../features.dart';
import '../globals.dart' as globals;
import '../runner/flutter_command.dart'; import '../runner/flutter_command.dart';
import '../version.dart';
/// The flutter precache command allows downloading of cache artifacts without /// The flutter precache command allows downloading of cache artifacts without
/// the use of device/artifact autodetection. /// the use of device/artifact autodetection.
...@@ -24,12 +22,10 @@ class PrecacheCommand extends FlutterCommand { ...@@ -24,12 +22,10 @@ class PrecacheCommand extends FlutterCommand {
@required Platform platform, @required Platform platform,
@required Logger logger, @required Logger logger,
@required FeatureFlags featureFlags, @required FeatureFlags featureFlags,
FlutterVersion flutterVersion, // flutter version cannot be injected.
}) : _cache = cache, }) : _cache = cache,
_platform = platform, _platform = platform,
_logger = logger, _logger = logger,
_featureFlags = featureFlags, _featureFlags = featureFlags {
_flutterVersion = flutterVersion {
argParser.addFlag('all-platforms', abbr: 'a', negatable: false, argParser.addFlag('all-platforms', abbr: 'a', negatable: false,
help: 'Precache artifacts for all host platforms.'); help: 'Precache artifacts for all host platforms.');
argParser.addFlag('force', abbr: 'f', negatable: false, argParser.addFlag('force', abbr: 'f', negatable: false,
...@@ -70,7 +66,6 @@ class PrecacheCommand extends FlutterCommand { ...@@ -70,7 +66,6 @@ class PrecacheCommand extends FlutterCommand {
final Logger _logger; final Logger _logger;
final Platform _platform; final Platform _platform;
final FeatureFlags _featureFlags; final FeatureFlags _featureFlags;
final FlutterVersion _flutterVersion;
@override @override
final String name = 'precache'; final String name = 'precache';
...@@ -154,10 +149,6 @@ class PrecacheCommand extends FlutterCommand { ...@@ -154,10 +149,6 @@ class PrecacheCommand extends FlutterCommand {
final Map<String, String> umbrellaForArtifact = _umbrellaForArtifactMap(); final Map<String, String> umbrellaForArtifact = _umbrellaForArtifactMap();
final Set<DevelopmentArtifact> requiredArtifacts = <DevelopmentArtifact>{}; final Set<DevelopmentArtifact> requiredArtifacts = <DevelopmentArtifact>{};
for (final DevelopmentArtifact artifact in DevelopmentArtifact.values) { for (final DevelopmentArtifact artifact in DevelopmentArtifact.values) {
// Don't include unstable artifacts on stable branches.
if (!(_flutterVersion ?? globals.flutterVersion).isMaster && artifact.unstable) {
continue;
}
if (artifact.feature != null && !_featureFlags.isEnabled(artifact.feature)) { if (artifact.feature != null && !_featureFlags.isEnabled(artifact.feature)) {
continue; continue;
} }
......
...@@ -81,6 +81,7 @@ Future<T> runInContext<T>( ...@@ -81,6 +81,7 @@ Future<T> runInContext<T>(
), ),
AndroidWorkflow: () => AndroidWorkflow( AndroidWorkflow: () => AndroidWorkflow(
androidSdk: globals.androidSdk, androidSdk: globals.androidSdk,
featureFlags: featureFlags,
), ),
ApplicationPackageFactory: () => ApplicationPackageFactory(), ApplicationPackageFactory: () => ApplicationPackageFactory(),
Artifacts: () => CachedArtifacts( Artifacts: () => CachedArtifacts(
...@@ -149,12 +150,16 @@ Future<T> runInContext<T>( ...@@ -149,12 +150,16 @@ Future<T> runInContext<T>(
fileSystem: globals.fs, fileSystem: globals.fs,
androidWorkflow: androidWorkflow, androidWorkflow: androidWorkflow,
), ),
FeatureFlags: () => const FeatureFlags(), FeatureFlags: () => const FlutterFeatureFlags(),
FlutterVersion: () => FlutterVersion(const SystemClock()), FlutterVersion: () => FlutterVersion(const SystemClock()),
FuchsiaArtifacts: () => FuchsiaArtifacts.find(), FuchsiaArtifacts: () => FuchsiaArtifacts.find(),
FuchsiaDeviceTools: () => FuchsiaDeviceTools(), FuchsiaDeviceTools: () => FuchsiaDeviceTools(),
FuchsiaSdk: () => FuchsiaSdk(), FuchsiaSdk: () => FuchsiaSdk(),
FuchsiaWorkflow: () => FuchsiaWorkflow(), FuchsiaWorkflow: () => FuchsiaWorkflow(
featureFlags: featureFlags,
platform: globals.platform,
fuchsiaArtifacts: globals.fuchsiaArtifacts,
),
GradleUtils: () => GradleUtils(), GradleUtils: () => GradleUtils(),
HotRunnerConfig: () => HotRunnerConfig(), HotRunnerConfig: () => HotRunnerConfig(),
IOSSimulatorUtils: () => IOSSimulatorUtils( IOSSimulatorUtils: () => IOSSimulatorUtils(
...@@ -162,7 +167,11 @@ Future<T> runInContext<T>( ...@@ -162,7 +167,11 @@ Future<T> runInContext<T>(
processManager: globals.processManager, processManager: globals.processManager,
xcode: globals.xcode, xcode: globals.xcode,
), ),
IOSWorkflow: () => const IOSWorkflow(), IOSWorkflow: () => IOSWorkflow(
featureFlags: featureFlags,
xcode: globals.xcode,
platform: globals.platform,
),
KernelCompilerFactory: () => KernelCompilerFactory( KernelCompilerFactory: () => KernelCompilerFactory(
logger: globals.logger, logger: globals.logger,
processManager: globals.processManager, processManager: globals.processManager,
......
...@@ -19,27 +19,68 @@ FeatureFlags get featureFlags => context.get<FeatureFlags>(); ...@@ -19,27 +19,68 @@ FeatureFlags get featureFlags => context.get<FeatureFlags>();
/// flags should be provided with a default implementation here. Clients that /// flags should be provided with a default implementation here. Clients that
/// use this class should extent instead of implement, so that new flags are /// use this class should extent instead of implement, so that new flags are
/// picked up automatically. /// picked up automatically.
class FeatureFlags { abstract class FeatureFlags {
/// const constructor so that subclasses can be const.
const FeatureFlags(); const FeatureFlags();
/// Whether flutter desktop for linux is enabled. /// Whether flutter desktop for linux is enabled.
bool get isLinuxEnabled => isEnabled(flutterLinuxDesktopFeature); bool get isLinuxEnabled => false;
/// Whether flutter desktop for macOS is enabled. /// Whether flutter desktop for macOS is enabled.
bool get isMacOSEnabled => isEnabled(flutterMacOSDesktopFeature); bool get isMacOSEnabled => false;
/// Whether flutter web is enabled. /// Whether flutter web is enabled.
bool get isWebEnabled => isEnabled(flutterWebFeature); bool get isWebEnabled => false;
/// Whether flutter desktop for Windows is enabled. /// Whether flutter desktop for Windows is enabled.
bool get isWindowsEnabled => isEnabled(flutterWindowsDesktopFeature); bool get isWindowsEnabled => false;
/// Whether android is enabled.
bool get isAndroidEnabled => true;
/// Whether iOS is enabled.
bool get isIOSEnabled => true;
/// Whether fuchsia is enabled.
bool get isFuchsiaEnabled => true;
/// Whether fast single widget reloads are enabled. /// Whether fast single widget reloads are enabled.
bool get isSingleWidgetReloadEnabled => isEnabled(singleWidgetReload); bool get isSingleWidgetReloadEnabled => false;
/// Whether a particular feature is enabled for the current channel. /// Whether a particular feature is enabled for the current channel.
/// ///
/// Prefer using one of the specific getters above instead of this API. /// Prefer using one of the specific getters above instead of this API.
bool isEnabled(Feature feature) => false;
}
class FlutterFeatureFlags implements FeatureFlags {
const FlutterFeatureFlags();
@override
bool get isLinuxEnabled => isEnabled(flutterLinuxDesktopFeature);
@override
bool get isMacOSEnabled => isEnabled(flutterMacOSDesktopFeature);
@override
bool get isWebEnabled => isEnabled(flutterWebFeature);
@override
bool get isWindowsEnabled => isEnabled(flutterWindowsDesktopFeature);
@override
bool get isAndroidEnabled => isEnabled(flutterAndroidFeature);
@override
bool get isIOSEnabled => isEnabled(flutterIOSFeature);
@override
bool get isFuchsiaEnabled => isEnabled(flutterFuchsiaFeature);
@override
bool get isSingleWidgetReloadEnabled => isEnabled(singleWidgetReload);
@override
bool isEnabled(Feature feature) { bool isEnabled(Feature feature) {
final String currentChannel = globals.flutterVersion.channel; final String currentChannel = globals.flutterVersion.channel;
final FeatureChannelSetting featureSetting = feature.getSettingForChannel(currentChannel); final FeatureChannelSetting featureSetting = feature.getSettingForChannel(currentChannel);
...@@ -69,6 +110,9 @@ const List<Feature> allFeatures = <Feature>[ ...@@ -69,6 +110,9 @@ const List<Feature> allFeatures = <Feature>[
flutterMacOSDesktopFeature, flutterMacOSDesktopFeature,
flutterWindowsDesktopFeature, flutterWindowsDesktopFeature,
singleWidgetReload, singleWidgetReload,
flutterAndroidFeature,
flutterIOSFeature,
flutterFuchsiaFeature,
]; ];
/// The [Feature] for flutter web. /// The [Feature] for flutter web.
...@@ -131,6 +175,62 @@ const Feature flutterWindowsDesktopFeature = Feature( ...@@ -131,6 +175,62 @@ const Feature flutterWindowsDesktopFeature = Feature(
), ),
); );
/// The [Feature] for Android devices.
const Feature flutterAndroidFeature = Feature(
name: 'Flutter for Android',
configSetting: 'enable-android',
master: FeatureChannelSetting(
available: true,
enabledByDefault: true,
),
dev: FeatureChannelSetting(
available: true,
enabledByDefault: true,
),
beta: FeatureChannelSetting(
available: true,
enabledByDefault: true,
),
stable: FeatureChannelSetting(
available: true,
enabledByDefault: true,
),
);
/// The [Feature] for iOS devices.
const Feature flutterIOSFeature = Feature(
name: 'Flutter for iOS',
configSetting: 'enable-ios',
master: FeatureChannelSetting(
available: true,
enabledByDefault: true,
),
dev: FeatureChannelSetting(
available: true,
enabledByDefault: true,
),
beta: FeatureChannelSetting(
available: true,
enabledByDefault: true,
),
stable: FeatureChannelSetting(
available: true,
enabledByDefault: true,
),
);
/// The [Feature] for Fuchsia support.
const Feature flutterFuchsiaFeature = Feature(
name: 'Flutter for Fuchsia',
configSetting: 'enable-fuchsia',
environmentOverride: 'FLUTTER_FUCHSIA',
master: FeatureChannelSetting(
available: true,
enabledByDefault: true,
),
);
/// The fast hot reload feature for https://github.com/flutter/flutter/issues/61407. /// The fast hot reload feature for https://github.com/flutter/flutter/issues/61407.
const Feature singleWidgetReload = Feature( const Feature singleWidgetReload = Feature(
name: 'Hot reload optimization for changes to class body of a single widget', name: 'Hot reload optimization for changes to class body of a single widget',
......
...@@ -2,9 +2,13 @@ ...@@ -2,9 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:meta/meta.dart';
import '../base/context.dart'; import '../base/context.dart';
import '../base/platform.dart';
import '../doctor.dart'; import '../doctor.dart';
import '../globals.dart' as globals; import '../features.dart';
import 'fuchsia_sdk.dart';
/// The [FuchsiaWorkflow] instance. /// The [FuchsiaWorkflow] instance.
FuchsiaWorkflow get fuchsiaWorkflow => context.get<FuchsiaWorkflow>(); FuchsiaWorkflow get fuchsiaWorkflow => context.get<FuchsiaWorkflow>();
...@@ -14,18 +18,29 @@ FuchsiaWorkflow get fuchsiaWorkflow => context.get<FuchsiaWorkflow>(); ...@@ -14,18 +18,29 @@ FuchsiaWorkflow get fuchsiaWorkflow => context.get<FuchsiaWorkflow>();
/// This workflow assumes development within the fuchsia source tree, /// This workflow assumes development within the fuchsia source tree,
/// including a working fx command-line tool in the user's PATH. /// including a working fx command-line tool in the user's PATH.
class FuchsiaWorkflow implements Workflow { class FuchsiaWorkflow implements Workflow {
FuchsiaWorkflow({
@required Platform platform,
@required FeatureFlags featureFlags,
@required FuchsiaArtifacts fuchsiaArtifacts,
}) : _platform = platform,
_featureFlags = featureFlags,
_fuchsiaArtifacts = fuchsiaArtifacts;
final Platform _platform;
final FeatureFlags _featureFlags;
final FuchsiaArtifacts _fuchsiaArtifacts;
@override @override
bool get appliesToHostPlatform => globals.platform.isLinux || globals.platform.isMacOS; bool get appliesToHostPlatform => _featureFlags.isFuchsiaEnabled && (_platform.isLinux || _platform.isMacOS);
@override @override
bool get canListDevices { bool get canListDevices {
return globals.fuchsiaArtifacts.devFinder != null; return _fuchsiaArtifacts.devFinder != null;
} }
@override @override
bool get canLaunchDevices { bool get canLaunchDevices {
return globals.fuchsiaArtifacts.devFinder != null && globals.fuchsiaArtifacts.sshConfig != null; return _fuchsiaArtifacts.devFinder != null && _fuchsiaArtifacts.sshConfig != null;
} }
@override @override
......
...@@ -2,23 +2,37 @@ ...@@ -2,23 +2,37 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:meta/meta.dart';
import '../base/platform.dart';
import '../doctor.dart'; import '../doctor.dart';
import '../globals.dart' as globals; import '../features.dart';
import '../macos/xcode.dart';
class IOSWorkflow implements Workflow { class IOSWorkflow implements Workflow {
const IOSWorkflow(); const IOSWorkflow({
@required Platform platform,
@required FeatureFlags featureFlags,
@required Xcode xcode,
}) : _platform = platform,
_featureFlags = featureFlags,
_xcode = xcode;
final Platform _platform;
final FeatureFlags _featureFlags;
final Xcode _xcode;
@override @override
bool get appliesToHostPlatform => globals.platform.isMacOS; bool get appliesToHostPlatform => _featureFlags.isIOSEnabled && _platform.isMacOS;
// We need xcode (+simctl) to list simulator devices, and libimobiledevice to list real devices. // We need xcode (+simctl) to list simulator devices, and libimobiledevice to list real devices.
@override @override
bool get canListDevices => globals.xcode.isInstalledAndMeetsVersionCheck && globals.xcode.isSimctlInstalled; bool get canListDevices => _xcode.isInstalledAndMeetsVersionCheck && _xcode.isSimctlInstalled;
// We need xcode to launch simulator devices, and ios-deploy // We need xcode to launch simulator devices, and ios-deploy
// for real devices. // for real devices.
@override @override
bool get canLaunchDevices => globals.xcode.isInstalledAndMeetsVersionCheck; bool get canLaunchDevices => _xcode.isInstalledAndMeetsVersionCheck;
@override @override
bool get canListEmulators => false; bool get canListEmulators => false;
......
...@@ -7,7 +7,6 @@ import 'package:flutter_tools/src/base/platform.dart'; ...@@ -7,7 +7,6 @@ import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/precache.dart'; import 'package:flutter_tools/src/commands/precache.dart';
import 'package:flutter_tools/src/runner/flutter_command.dart'; import 'package:flutter_tools/src/runner/flutter_command.dart';
import 'package:flutter_tools/src/version.dart';
import 'package:mockito/mockito.dart'; import 'package:mockito/mockito.dart';
import '../../src/common.dart'; import '../../src/common.dart';
...@@ -18,8 +17,6 @@ import '../../src/testbed.dart'; ...@@ -18,8 +17,6 @@ import '../../src/testbed.dart';
void main() { void main() {
MockCache cache; MockCache cache;
Set<DevelopmentArtifact> artifacts; Set<DevelopmentArtifact> artifacts;
MockFlutterVersion flutterVersion;
MockFlutterVersion masterFlutterVersion;
setUp(() { setUp(() {
cache = MockCache(); cache = MockCache();
...@@ -31,10 +28,6 @@ void main() { ...@@ -31,10 +28,6 @@ void main() {
artifacts = invocation.positionalArguments.first as Set<DevelopmentArtifact>; artifacts = invocation.positionalArguments.first as Set<DevelopmentArtifact>;
return Future<void>.value(null); return Future<void>.value(null);
}); });
flutterVersion = MockFlutterVersion();
when(flutterVersion.isMaster).thenReturn(false);
masterFlutterVersion = MockFlutterVersion();
when(masterFlutterVersion.isMaster).thenReturn(true);
}); });
testUsingContext('precache should acquire lock', () async { testUsingContext('precache should acquire lock', () async {
...@@ -42,7 +35,6 @@ void main() { ...@@ -42,7 +35,6 @@ void main() {
final PrecacheCommand command = PrecacheCommand( final PrecacheCommand command = PrecacheCommand(
cache: cache, cache: cache,
logger: BufferLogger.test(), logger: BufferLogger.test(),
flutterVersion: flutterVersion,
platform: platform, platform: platform,
featureFlags: TestFeatureFlags(), featureFlags: TestFeatureFlags(),
); );
...@@ -65,7 +57,6 @@ void main() { ...@@ -65,7 +57,6 @@ void main() {
final PrecacheCommand command = PrecacheCommand( final PrecacheCommand command = PrecacheCommand(
cache: cache, cache: cache,
logger: BufferLogger.test(), logger: BufferLogger.test(),
flutterVersion: flutterVersion,
featureFlags: TestFeatureFlags(), featureFlags: TestFeatureFlags(),
platform: platform, platform: platform,
); );
...@@ -81,7 +72,6 @@ void main() { ...@@ -81,7 +72,6 @@ void main() {
final PrecacheCommand command = PrecacheCommand( final PrecacheCommand command = PrecacheCommand(
cache: cache, cache: cache,
logger: BufferLogger.test(), logger: BufferLogger.test(),
flutterVersion: flutterVersion,
featureFlags: TestFeatureFlags(isWebEnabled: true), featureFlags: TestFeatureFlags(isWebEnabled: true),
platform: FakePlatform(environment: <String, String>{}), platform: FakePlatform(environment: <String, String>{}),
); );
...@@ -98,7 +88,6 @@ void main() { ...@@ -98,7 +88,6 @@ void main() {
final PrecacheCommand command = PrecacheCommand( final PrecacheCommand command = PrecacheCommand(
cache: cache, cache: cache,
logger: BufferLogger.test(), logger: BufferLogger.test(),
flutterVersion: flutterVersion,
featureFlags: TestFeatureFlags(isWebEnabled: false), featureFlags: TestFeatureFlags(isWebEnabled: false),
platform: FakePlatform(environment: <String, String>{}), platform: FakePlatform(environment: <String, String>{}),
); );
...@@ -114,7 +103,6 @@ void main() { ...@@ -114,7 +103,6 @@ void main() {
final PrecacheCommand command = PrecacheCommand( final PrecacheCommand command = PrecacheCommand(
cache: cache, cache: cache,
logger: BufferLogger.test(), logger: BufferLogger.test(),
flutterVersion: flutterVersion,
featureFlags: TestFeatureFlags(isMacOSEnabled: true), featureFlags: TestFeatureFlags(isMacOSEnabled: true),
platform: FakePlatform(environment: <String, String>{}), platform: FakePlatform(environment: <String, String>{}),
); );
...@@ -131,7 +119,6 @@ void main() { ...@@ -131,7 +119,6 @@ void main() {
final PrecacheCommand command = PrecacheCommand( final PrecacheCommand command = PrecacheCommand(
cache: cache, cache: cache,
logger: BufferLogger.test(), logger: BufferLogger.test(),
flutterVersion: flutterVersion,
featureFlags: TestFeatureFlags(isMacOSEnabled: false), featureFlags: TestFeatureFlags(isMacOSEnabled: false),
platform: FakePlatform(environment: <String, String>{}), platform: FakePlatform(environment: <String, String>{}),
); );
...@@ -147,7 +134,6 @@ void main() { ...@@ -147,7 +134,6 @@ void main() {
final PrecacheCommand command = PrecacheCommand( final PrecacheCommand command = PrecacheCommand(
cache: cache, cache: cache,
logger: BufferLogger.test(), logger: BufferLogger.test(),
flutterVersion: flutterVersion,
featureFlags: TestFeatureFlags(isWindowsEnabled: true), featureFlags: TestFeatureFlags(isWindowsEnabled: true),
platform: FakePlatform(environment: <String, String>{}), platform: FakePlatform(environment: <String, String>{}),
); );
...@@ -164,7 +150,6 @@ void main() { ...@@ -164,7 +150,6 @@ void main() {
final PrecacheCommand command = PrecacheCommand( final PrecacheCommand command = PrecacheCommand(
cache: cache, cache: cache,
logger: BufferLogger.test(), logger: BufferLogger.test(),
flutterVersion: flutterVersion,
featureFlags: TestFeatureFlags(isWindowsEnabled: false), featureFlags: TestFeatureFlags(isWindowsEnabled: false),
platform: FakePlatform(environment: <String, String>{}), platform: FakePlatform(environment: <String, String>{}),
); );
...@@ -180,7 +165,6 @@ void main() { ...@@ -180,7 +165,6 @@ void main() {
final PrecacheCommand command = PrecacheCommand( final PrecacheCommand command = PrecacheCommand(
cache: cache, cache: cache,
logger: BufferLogger.test(), logger: BufferLogger.test(),
flutterVersion: flutterVersion,
featureFlags: TestFeatureFlags(isLinuxEnabled: true), featureFlags: TestFeatureFlags(isLinuxEnabled: true),
platform: FakePlatform(environment: <String, String>{}), platform: FakePlatform(environment: <String, String>{}),
); );
...@@ -197,7 +181,6 @@ void main() { ...@@ -197,7 +181,6 @@ void main() {
final PrecacheCommand command = PrecacheCommand( final PrecacheCommand command = PrecacheCommand(
cache: cache, cache: cache,
logger: BufferLogger.test(), logger: BufferLogger.test(),
flutterVersion: flutterVersion,
featureFlags: TestFeatureFlags(isLinuxEnabled: false), featureFlags: TestFeatureFlags(isLinuxEnabled: false),
platform: FakePlatform(environment: <String, String>{}), platform: FakePlatform(environment: <String, String>{}),
); );
...@@ -213,7 +196,6 @@ void main() { ...@@ -213,7 +196,6 @@ void main() {
final PrecacheCommand command = PrecacheCommand( final PrecacheCommand command = PrecacheCommand(
cache: cache, cache: cache,
logger: BufferLogger.test(), logger: BufferLogger.test(),
flutterVersion: flutterVersion,
featureFlags: TestFeatureFlags(isWebEnabled: false), featureFlags: TestFeatureFlags(isWebEnabled: false),
platform: FakePlatform(environment: <String, String>{}), platform: FakePlatform(environment: <String, String>{}),
); );
...@@ -229,7 +211,6 @@ void main() { ...@@ -229,7 +211,6 @@ void main() {
final PrecacheCommand command = PrecacheCommand( final PrecacheCommand command = PrecacheCommand(
cache: cache, cache: cache,
logger: BufferLogger.test(), logger: BufferLogger.test(),
flutterVersion: masterFlutterVersion,
featureFlags: TestFeatureFlags( featureFlags: TestFeatureFlags(
isWebEnabled: true, isWebEnabled: true,
isLinuxEnabled: true, isLinuxEnabled: true,
...@@ -271,7 +252,6 @@ void main() { ...@@ -271,7 +252,6 @@ void main() {
final PrecacheCommand command = PrecacheCommand( final PrecacheCommand command = PrecacheCommand(
cache: cache, cache: cache,
logger: BufferLogger.test(), logger: BufferLogger.test(),
flutterVersion: flutterVersion,
featureFlags: TestFeatureFlags(), featureFlags: TestFeatureFlags(),
platform: FakePlatform(environment: <String, String>{}), platform: FakePlatform(environment: <String, String>{}),
); );
...@@ -295,7 +275,6 @@ void main() { ...@@ -295,7 +275,6 @@ void main() {
final PrecacheCommand command = PrecacheCommand( final PrecacheCommand command = PrecacheCommand(
cache: cache, cache: cache,
logger: BufferLogger.test(), logger: BufferLogger.test(),
flutterVersion: flutterVersion,
featureFlags: TestFeatureFlags(), featureFlags: TestFeatureFlags(),
platform: FakePlatform(environment: <String, String>{}), platform: FakePlatform(environment: <String, String>{}),
); );
...@@ -317,44 +296,10 @@ void main() { ...@@ -317,44 +296,10 @@ void main() {
})); }));
}); });
testUsingContext('precache adds artifact flags to requested artifacts on stable', () async {
final PrecacheCommand command = PrecacheCommand(
cache: cache,
logger: BufferLogger.test(),
flutterVersion: flutterVersion,
featureFlags: TestFeatureFlags(),
platform: FakePlatform(environment: <String, String>{}),
);
applyMocksToCommand(command);
await createTestCommandRunner(command).run(
const <String>[
'precache',
'--ios',
'--android_gen_snapshot',
'--android_maven',
'--android_internal_build',
'--web',
'--macos',
'--linux',
'--windows',
'--fuchsia',
'--flutter_runner',
],
);
expect(artifacts, unorderedEquals(<DevelopmentArtifact>{
DevelopmentArtifact.universal,
DevelopmentArtifact.iOS,
DevelopmentArtifact.androidGenSnapshot,
DevelopmentArtifact.androidMaven,
DevelopmentArtifact.androidInternalBuild,
}));
});
testUsingContext('precache downloads iOS and Android artifacts by default', () async { testUsingContext('precache downloads iOS and Android artifacts by default', () async {
final PrecacheCommand command = PrecacheCommand( final PrecacheCommand command = PrecacheCommand(
cache: cache, cache: cache,
logger: BufferLogger.test(), logger: BufferLogger.test(),
flutterVersion: flutterVersion,
featureFlags: TestFeatureFlags(), featureFlags: TestFeatureFlags(),
platform: FakePlatform(environment: <String, String>{}), platform: FakePlatform(environment: <String, String>{}),
); );
...@@ -379,7 +324,6 @@ void main() { ...@@ -379,7 +324,6 @@ void main() {
final PrecacheCommand command = PrecacheCommand( final PrecacheCommand command = PrecacheCommand(
cache: cache, cache: cache,
logger: BufferLogger.test(), logger: BufferLogger.test(),
flutterVersion: masterFlutterVersion,
featureFlags: TestFeatureFlags( featureFlags: TestFeatureFlags(
isWebEnabled: true, isWebEnabled: true,
isLinuxEnabled: true, isLinuxEnabled: true,
...@@ -416,7 +360,6 @@ void main() { ...@@ -416,7 +360,6 @@ void main() {
final PrecacheCommand command = PrecacheCommand( final PrecacheCommand command = PrecacheCommand(
cache: cache, cache: cache,
logger: BufferLogger.test(), logger: BufferLogger.test(),
flutterVersion: masterFlutterVersion,
featureFlags: TestFeatureFlags(), featureFlags: TestFeatureFlags(),
platform: FakePlatform(environment: <String, String>{}), platform: FakePlatform(environment: <String, String>{}),
); );
...@@ -435,7 +378,6 @@ void main() { ...@@ -435,7 +378,6 @@ void main() {
final PrecacheCommand command = PrecacheCommand( final PrecacheCommand command = PrecacheCommand(
cache: cache, cache: cache,
logger: BufferLogger.test(), logger: BufferLogger.test(),
flutterVersion: masterFlutterVersion,
featureFlags: TestFeatureFlags( featureFlags: TestFeatureFlags(
isMacOSEnabled: true, isMacOSEnabled: true,
), ),
...@@ -470,7 +412,6 @@ void main() { ...@@ -470,7 +412,6 @@ void main() {
final PrecacheCommand command = PrecacheCommand( final PrecacheCommand command = PrecacheCommand(
cache: cache, cache: cache,
logger: BufferLogger.test(), logger: BufferLogger.test(),
flutterVersion: flutterVersion,
featureFlags: TestFeatureFlags( featureFlags: TestFeatureFlags(
isMacOSEnabled: true, isMacOSEnabled: true,
), ),
...@@ -483,5 +424,4 @@ void main() { ...@@ -483,5 +424,4 @@ void main() {
}); });
} }
class MockFlutterVersion extends Mock implements FlutterVersion {}
class MockCache extends Mock implements Cache {} class MockCache extends Mock implements Cache {}
...@@ -14,6 +14,7 @@ import 'package:mockito/mockito.dart'; ...@@ -14,6 +14,7 @@ import 'package:mockito/mockito.dart';
import '../../src/common.dart'; import '../../src/common.dart';
import '../../src/fake_process_manager.dart'; import '../../src/fake_process_manager.dart';
import '../../src/testbed.dart';
void main() { void main() {
testWithoutContext('AndroidDevices returns empty device list on null adb', () async { testWithoutContext('AndroidDevices returns empty device list on null adb', () async {
...@@ -22,6 +23,7 @@ void main() { ...@@ -22,6 +23,7 @@ void main() {
logger: BufferLogger.test(), logger: BufferLogger.test(),
androidWorkflow: AndroidWorkflow( androidWorkflow: AndroidWorkflow(
androidSdk: MockAndroidSdk(null), androidSdk: MockAndroidSdk(null),
featureFlags: TestFeatureFlags(),
), ),
processManager: FakeProcessManager.list(<FakeCommand>[]), processManager: FakeProcessManager.list(<FakeCommand>[]),
); );
...@@ -43,6 +45,7 @@ void main() { ...@@ -43,6 +45,7 @@ void main() {
logger: BufferLogger.test(), logger: BufferLogger.test(),
androidWorkflow: AndroidWorkflow( androidWorkflow: AndroidWorkflow(
androidSdk: MockAndroidSdk(), androidSdk: MockAndroidSdk(),
featureFlags: TestFeatureFlags(),
), ),
processManager: processManager, processManager: processManager,
); );
...@@ -63,6 +66,7 @@ void main() { ...@@ -63,6 +66,7 @@ void main() {
logger: BufferLogger.test(), logger: BufferLogger.test(),
androidWorkflow: AndroidWorkflow( androidWorkflow: AndroidWorkflow(
androidSdk: MockAndroidSdk(), androidSdk: MockAndroidSdk(),
featureFlags: TestFeatureFlags(),
), ),
processManager: processManager, processManager: processManager,
); );
...@@ -71,6 +75,22 @@ void main() { ...@@ -71,6 +75,22 @@ void main() {
throwsToolExit(message: RegExp('Unable to run "adb"'))); throwsToolExit(message: RegExp('Unable to run "adb"')));
}); });
testWithoutContext('AndroidDevices is disabled if feature is disabled', () {
final AndroidDevices androidDevices = AndroidDevices(
androidSdk: MockAndroidSdk(),
logger: BufferLogger.test(),
androidWorkflow: AndroidWorkflow(
androidSdk: MockAndroidSdk(),
featureFlags: TestFeatureFlags(
isAndroidEnabled: false,
),
),
processManager: FakeProcessManager.any(),
);
expect(androidDevices.supportsPlatform, false);
});
testWithoutContext('physical devices', () { testWithoutContext('physical devices', () {
final List<AndroidDevice> devices = <AndroidDevice>[]; final List<AndroidDevice> devices = <AndroidDevice>[];
AndroidDevices.parseADBDeviceOutput(''' AndroidDevices.parseADBDeviceOutput('''
......
...@@ -261,15 +261,6 @@ void main() { ...@@ -261,15 +261,6 @@ void main() {
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
}); });
test('Unstable artifacts', () {
expect(DevelopmentArtifact.web.unstable, false);
expect(DevelopmentArtifact.linux.unstable, false);
expect(DevelopmentArtifact.macOS.unstable, false);
expect(DevelopmentArtifact.windows.unstable, false);
expect(DevelopmentArtifact.fuchsia.unstable, true);
expect(DevelopmentArtifact.flutterRunner.unstable, true);
});
group('EngineCachedArtifact', () { group('EngineCachedArtifact', () {
FakeHttpClient fakeHttpClient; FakeHttpClient fakeHttpClient;
FakePlatform fakePlatform; FakePlatform fakePlatform;
......
...@@ -19,6 +19,7 @@ import 'package:process/process.dart'; ...@@ -19,6 +19,7 @@ import 'package:process/process.dart';
import '../src/common.dart'; import '../src/common.dart';
import '../src/context.dart'; import '../src/context.dart';
import '../src/mocks.dart'; import '../src/mocks.dart';
import '../src/testbed.dart';
const FakeEmulator emulator1 = FakeEmulator('Nexus_5', 'Nexus 5', 'Google'); const FakeEmulator emulator1 = FakeEmulator('Nexus_5', 'Nexus 5', 'Google');
const FakeEmulator emulator2 = FakeEmulator('Nexus_5X_API_27_x86', 'Nexus 5X', 'Google'); const FakeEmulator emulator2 = FakeEmulator('Nexus_5X_API_27_x86', 'Nexus 5X', 'Google');
...@@ -75,6 +76,7 @@ void main() { ...@@ -75,6 +76,7 @@ void main() {
androidSdk: mockSdk, androidSdk: mockSdk,
androidWorkflow: AndroidWorkflow( androidWorkflow: AndroidWorkflow(
androidSdk: mockSdk, androidSdk: mockSdk,
featureFlags: TestFeatureFlags(),
), ),
); );
...@@ -108,6 +110,7 @@ void main() { ...@@ -108,6 +110,7 @@ void main() {
androidSdk: mockSdk, androidSdk: mockSdk,
androidWorkflow: AndroidWorkflow( androidWorkflow: AndroidWorkflow(
androidSdk: mockSdk, androidSdk: mockSdk,
featureFlags: TestFeatureFlags(),
), ),
); );
final CreateEmulatorResult result = await emulatorManager.createEmulator(); final CreateEmulatorResult result = await emulatorManager.createEmulator();
...@@ -148,6 +151,7 @@ void main() { ...@@ -148,6 +151,7 @@ void main() {
androidSdk: mockSdk, androidSdk: mockSdk,
androidWorkflow: AndroidWorkflow( androidWorkflow: AndroidWorkflow(
androidSdk: mockSdk, androidSdk: mockSdk,
featureFlags: TestFeatureFlags(),
), ),
); );
final CreateEmulatorResult result = await emulatorManager.createEmulator(); final CreateEmulatorResult result = await emulatorManager.createEmulator();
...@@ -183,6 +187,7 @@ void main() { ...@@ -183,6 +187,7 @@ void main() {
androidSdk: mockSdk, androidSdk: mockSdk,
androidWorkflow: AndroidWorkflow( androidWorkflow: AndroidWorkflow(
androidSdk: mockSdk, androidSdk: mockSdk,
featureFlags: TestFeatureFlags(),
), ),
); );
final CreateEmulatorResult result = await emulatorManager.createEmulator(name: 'test'); final CreateEmulatorResult result = await emulatorManager.createEmulator(name: 'test');
...@@ -220,6 +225,7 @@ void main() { ...@@ -220,6 +225,7 @@ void main() {
androidSdk: mockSdk, androidSdk: mockSdk,
androidWorkflow: AndroidWorkflow( androidWorkflow: AndroidWorkflow(
androidSdk: mockSdk, androidSdk: mockSdk,
featureFlags: TestFeatureFlags(),
), ),
); );
final CreateEmulatorResult result = await emulatorManager.createEmulator(name: 'existing-avd-1'); final CreateEmulatorResult result = await emulatorManager.createEmulator(name: 'existing-avd-1');
...@@ -260,6 +266,7 @@ void main() { ...@@ -260,6 +266,7 @@ void main() {
androidSdk: mockSdk, androidSdk: mockSdk,
androidWorkflow: AndroidWorkflow( androidWorkflow: AndroidWorkflow(
androidSdk: mockSdk, androidSdk: mockSdk,
featureFlags: TestFeatureFlags(),
), ),
); );
final CreateEmulatorResult result = await emulatorManager.createEmulator(); final CreateEmulatorResult result = await emulatorManager.createEmulator();
......
...@@ -26,7 +26,7 @@ void main() { ...@@ -26,7 +26,7 @@ void main() {
when(mockPlatform.environment).thenReturn(const <String, String>{}); when(mockPlatform.environment).thenReturn(const <String, String>{});
testbed = Testbed(overrides: <Type, Generator>{ testbed = Testbed(overrides: <Type, Generator>{
FlutterVersion: () => mockFlutterVerion, FlutterVersion: () => mockFlutterVerion,
FeatureFlags: () => const FeatureFlags(), FeatureFlags: () => const FlutterFeatureFlags(),
Config: () => mockFlutterConfig, Config: () => mockFlutterConfig,
Platform: () => mockPlatform, Platform: () => mockPlatform,
}); });
......
...@@ -2,46 +2,85 @@ ...@@ -2,46 +2,85 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // 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/file_system.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_sdk.dart'; import 'package:flutter_tools/src/fuchsia/fuchsia_sdk.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_workflow.dart'; import 'package:flutter_tools/src/fuchsia/fuchsia_workflow.dart';
import 'package:mockito/mockito.dart';
import '../../src/common.dart'; import '../../src/common.dart';
import '../../src/context.dart'; import '../../src/testbed.dart';
class MockFile extends Mock implements File {}
void main() { void main() {
group('Fuchsia workflow', () { final FileSystem fileSystem = MemoryFileSystem.test();
final MockFile devFinder = MockFile(); final File devFinder = fileSystem.file('dev_finder');
final MockFile sshConfig = MockFile(); final File sshConfig = fileSystem.file('ssh_config');
when(devFinder.absolute).thenReturn(devFinder);
when(sshConfig.absolute).thenReturn(sshConfig); testWithoutContext('Fuchsia workflow does not apply to host platform if feature is disabled', () {
final FuchsiaWorkflow fuchsiaWorkflow = FuchsiaWorkflow(
featureFlags: TestFeatureFlags(isFuchsiaEnabled: false),
fuchsiaArtifacts: FuchsiaArtifacts(devFinder: devFinder, sshConfig: sshConfig),
platform: FakePlatform(operatingSystem: 'linux'),
);
expect(fuchsiaWorkflow.appliesToHostPlatform, false);
});
testWithoutContext('Fuchsia workflow does not apply to host platform on Windows', () {
final FuchsiaWorkflow fuchsiaWorkflow = FuchsiaWorkflow(
featureFlags: TestFeatureFlags(isFuchsiaEnabled: true),
fuchsiaArtifacts: FuchsiaArtifacts(devFinder: devFinder, sshConfig: sshConfig),
platform: FakePlatform(operatingSystem: 'windows'),
);
expect(fuchsiaWorkflow.appliesToHostPlatform, false);
});
testWithoutContext('Fuchsia workflow can not list and launch devices if there is no ssh config and dev finder', () {
final FuchsiaWorkflow fuchsiaWorkflow = FuchsiaWorkflow(
featureFlags: TestFeatureFlags(),
fuchsiaArtifacts: FuchsiaArtifacts(devFinder: null, sshConfig: null),
platform: FakePlatform(operatingSystem: 'linux'),
);
testUsingContext('can not list and launch devices if there is not ssh config and dev finder', () {
expect(fuchsiaWorkflow.canLaunchDevices, false); expect(fuchsiaWorkflow.canLaunchDevices, false);
expect(fuchsiaWorkflow.canListDevices, false); expect(fuchsiaWorkflow.canListDevices, false);
expect(fuchsiaWorkflow.canListEmulators, false); expect(fuchsiaWorkflow.canListEmulators, false);
}, overrides: <Type, Generator>{
FuchsiaArtifacts: () => FuchsiaArtifacts(devFinder: null, sshConfig: null),
}); });
testUsingContext('can not list and launch devices if there is not ssh config and dev finder', () { testWithoutContext('Fuchsia workflow can not list and launch devices if there is no ssh config and dev finder', () {
final FuchsiaWorkflow fuchsiaWorkflow = FuchsiaWorkflow(
featureFlags: TestFeatureFlags(),
fuchsiaArtifacts: FuchsiaArtifacts(devFinder: devFinder, sshConfig: null),
platform: FakePlatform(operatingSystem: 'linux'),
);
expect(fuchsiaWorkflow.canLaunchDevices, false); expect(fuchsiaWorkflow.canLaunchDevices, false);
expect(fuchsiaWorkflow.canListDevices, true); expect(fuchsiaWorkflow.canListDevices, true);
expect(fuchsiaWorkflow.canListEmulators, false); expect(fuchsiaWorkflow.canListEmulators, false);
}, overrides: <Type, Generator>{
FuchsiaArtifacts: () => FuchsiaArtifacts(devFinder: devFinder, sshConfig: null),
}); });
testUsingContext('can list and launch devices supported with sufficient SDK artifacts', () { testWithoutContext('Fuchsia workflow can list and launch devices supported with sufficient SDK artifacts', () {
final FuchsiaWorkflow fuchsiaWorkflow = FuchsiaWorkflow(
featureFlags: TestFeatureFlags(),
fuchsiaArtifacts: FuchsiaArtifacts(devFinder: devFinder, sshConfig: sshConfig),
platform: FakePlatform(operatingSystem: 'linux'),
);
expect(fuchsiaWorkflow.canLaunchDevices, true); expect(fuchsiaWorkflow.canLaunchDevices, true);
expect(fuchsiaWorkflow.canListDevices, true); expect(fuchsiaWorkflow.canListDevices, true);
expect(fuchsiaWorkflow.canListEmulators, false); expect(fuchsiaWorkflow.canListEmulators, false);
}, overrides: <Type, Generator>{
FuchsiaArtifacts: () =>
FuchsiaArtifacts(devFinder: devFinder, sshConfig: sshConfig),
}); });
testWithoutContext('Fuchsia workflow can list and launch devices supported with sufficient SDK artifacts on macOS', () {
final FuchsiaWorkflow fuchsiaWorkflow = FuchsiaWorkflow(
featureFlags: TestFeatureFlags(),
fuchsiaArtifacts: FuchsiaArtifacts(devFinder: devFinder, sshConfig: sshConfig),
platform: FakePlatform(operatingSystem: 'macOS'),
);
expect(fuchsiaWorkflow.canLaunchDevices, true);
expect(fuchsiaWorkflow.canListDevices, true);
expect(fuchsiaWorkflow.canListEmulators, false);
}); });
} }
// 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 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/ios/ios_workflow.dart';
import 'package:flutter_tools/src/macos/xcode.dart';
import 'package:mockito/mockito.dart';
import '../../src/common.dart';
import '../../src/testbed.dart';
void main() {
testWithoutContext('iOS workflow is disabled if feature is disabled', () {
final IOSWorkflow iosWorkflow = IOSWorkflow(
platform: FakePlatform(operatingSystem: 'macOS'),
xcode: MockXcode(),
featureFlags: TestFeatureFlags(isIOSEnabled: false),
);
expect(iosWorkflow.appliesToHostPlatform, false);
});
testWithoutContext('iOS workflow is disabled on Linux', () {
final IOSWorkflow iosWorkflow = IOSWorkflow(
platform: FakePlatform(operatingSystem: 'linux'),
xcode: MockXcode(),
featureFlags: TestFeatureFlags(isIOSEnabled: true),
);
expect(iosWorkflow.appliesToHostPlatform, false);
});
testWithoutContext('iOS workflow is disabled on windows', () {
final IOSWorkflow iosWorkflow = IOSWorkflow(
platform: FakePlatform(operatingSystem: 'windows'),
xcode: MockXcode(),
featureFlags: TestFeatureFlags(isIOSEnabled: true),
);
expect(iosWorkflow.appliesToHostPlatform, false);
});
testWithoutContext('iOS workflow is enabled on macOS', () {
final IOSWorkflow iosWorkflow = IOSWorkflow(
platform: FakePlatform(operatingSystem: 'macos'),
xcode: MockXcode(),
featureFlags: TestFeatureFlags(isIOSEnabled: true),
);
expect(iosWorkflow.appliesToHostPlatform, true);
expect(iosWorkflow.canListEmulators, false);
});
testWithoutContext('iOS workflow can launch and list devices when Xcode is set up', () {
final Xcode xcode = MockXcode();
final IOSWorkflow iosWorkflow = IOSWorkflow(
platform: FakePlatform(operatingSystem: 'macos'),
xcode: xcode,
featureFlags: TestFeatureFlags(isIOSEnabled: true),
);
when(xcode.isInstalledAndMeetsVersionCheck).thenReturn(true);
when(xcode.isSimctlInstalled).thenReturn(true);
expect(iosWorkflow.canLaunchDevices, true);
expect(iosWorkflow.canListDevices, true);
});
}
class MockXcode extends Mock implements Xcode {}
\ No newline at end of file
...@@ -730,6 +730,9 @@ class TestFeatureFlags implements FeatureFlags { ...@@ -730,6 +730,9 @@ class TestFeatureFlags implements FeatureFlags {
this.isWebEnabled = false, this.isWebEnabled = false,
this.isWindowsEnabled = false, this.isWindowsEnabled = false,
this.isSingleWidgetReloadEnabled = false, this.isSingleWidgetReloadEnabled = false,
this.isAndroidEnabled = true,
this.isIOSEnabled = true,
this.isFuchsiaEnabled = true,
}); });
@override @override
...@@ -747,6 +750,15 @@ class TestFeatureFlags implements FeatureFlags { ...@@ -747,6 +750,15 @@ class TestFeatureFlags implements FeatureFlags {
@override @override
final bool isSingleWidgetReloadEnabled; final bool isSingleWidgetReloadEnabled;
@override
final bool isAndroidEnabled;
@override
final bool isIOSEnabled;
@override
final bool isFuchsiaEnabled;
@override @override
bool isEnabled(Feature feature) { bool isEnabled(Feature feature) {
switch (feature) { switch (feature) {
...@@ -758,6 +770,14 @@ class TestFeatureFlags implements FeatureFlags { ...@@ -758,6 +770,14 @@ class TestFeatureFlags implements FeatureFlags {
return isMacOSEnabled; return isMacOSEnabled;
case flutterWindowsDesktopFeature: case flutterWindowsDesktopFeature:
return isWindowsEnabled; return isWindowsEnabled;
case singleWidgetReload:
return isSingleWidgetReloadEnabled;
case flutterAndroidFeature:
return isAndroidEnabled;
case flutterIOSFeature:
return isIOSEnabled;
case flutterFuchsiaFeature:
return isFuchsiaEnabled;
} }
return false; return false;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment