diff --git a/packages/flutter_tools/lib/src/android/android_device_discovery.dart b/packages/flutter_tools/lib/src/android/android_device_discovery.dart index 41eb5e99b9..8b144d52c6 100644 --- a/packages/flutter_tools/lib/src/android/android_device_discovery.dart +++ b/packages/flutter_tools/lib/src/android/android_device_discovery.dart @@ -16,7 +16,7 @@ import '../device.dart'; import 'adb.dart'; import 'android_device.dart'; import 'android_sdk.dart'; -import 'android_workflow.dart' hide androidWorkflow; +import 'android_workflow.dart'; /// Device discovery for Android physical devices and emulators. /// diff --git a/packages/flutter_tools/lib/src/android/android_sdk.dart b/packages/flutter_tools/lib/src/android/android_sdk.dart index 8daed2fe09..674227a57a 100644 --- a/packages/flutter_tools/lib/src/android/android_sdk.dart +++ b/packages/flutter_tools/lib/src/android/android_sdk.dart @@ -382,7 +382,7 @@ class AndroidSdk { return fileSystem.path.join(javaHome, 'bin', 'java'); } } - } on Exception catch (_) { /* ignore */ } + } on Exception { /* ignore */ } } // Fallback to PATH based lookup. diff --git a/packages/flutter_tools/lib/src/android/android_workflow.dart b/packages/flutter_tools/lib/src/android/android_workflow.dart index 4f7bc62353..db2426e50c 100644 --- a/packages/flutter_tools/lib/src/android/android_workflow.dart +++ b/packages/flutter_tools/lib/src/android/android_workflow.dart @@ -12,12 +12,11 @@ import '../base/io.dart'; import '../base/logger.dart'; import '../base/os.dart'; import '../base/platform.dart'; -import '../base/user_messages.dart'; +import '../base/user_messages.dart' hide userMessages; import '../base/version.dart'; import '../convert.dart'; import '../doctor.dart'; import '../features.dart'; -import '../globals.dart' as globals; import 'android_sdk.dart'; import 'android_studio.dart'; @@ -252,7 +251,36 @@ class AndroidValidator extends DoctorValidator { /// A subvalidator that checks if the licenses within the detected Android /// SDK have been accepted. class AndroidLicenseValidator extends DoctorValidator { - AndroidLicenseValidator() : super('Android license subvalidator',); + AndroidLicenseValidator({ + @required AndroidSdk androidSdk, + @required Platform platform, + @required OperatingSystemUtils operatingSystemUtils, + @required FileSystem fileSystem, + @required ProcessManager processManager, + @required Logger logger, + @required AndroidStudio androidStudio, + @required Stdio stdio, + @required UserMessages userMessages, + }) : _androidSdk = androidSdk, + _platform = platform, + _operatingSystemUtils = operatingSystemUtils, + _fileSystem = fileSystem, + _processManager = processManager, + _logger = logger, + _androidStudio = androidStudio, + _stdio = stdio, + _userMessages = userMessages, + super('Android license subvalidator'); + + final AndroidSdk _androidSdk; + final AndroidStudio _androidStudio; + final Stdio _stdio; + final OperatingSystemUtils _operatingSystemUtils; + final Platform _platform; + final FileSystem _fileSystem; + final ProcessManager _processManager; + final Logger _logger; + final UserMessages _userMessages; @override String get slowWarning => 'Checking Android licenses is taking an unexpectedly long time...'; @@ -262,27 +290,27 @@ class AndroidLicenseValidator extends DoctorValidator { final List messages = []; // Match pre-existing early termination behavior - if (globals.androidSdk == null || globals.androidSdk.latestVersion == null || - globals.androidSdk.validateSdkWellFormed().isNotEmpty || + if (_androidSdk == null || _androidSdk.latestVersion == null || + _androidSdk.validateSdkWellFormed().isNotEmpty || ! await _checkJavaVersionNoOutput()) { return ValidationResult(ValidationType.missing, messages); } - final String sdkVersionText = userMessages.androidStatusInfo(globals.androidSdk.latestVersion.buildToolsVersionName); + final String sdkVersionText = _userMessages.androidStatusInfo(_androidSdk.latestVersion.buildToolsVersionName); // Check for licenses. switch (await licensesAccepted) { case LicensesAccepted.all: - messages.add(ValidationMessage(userMessages.androidLicensesAll)); + messages.add(ValidationMessage(_userMessages.androidLicensesAll)); break; case LicensesAccepted.some: - messages.add(ValidationMessage.hint(userMessages.androidLicensesSome)); + messages.add(ValidationMessage.hint(_userMessages.androidLicensesSome)); return ValidationResult(ValidationType.partial, messages, statusInfo: sdkVersionText); case LicensesAccepted.none: - messages.add(ValidationMessage.error(userMessages.androidLicensesNone)); + messages.add(ValidationMessage.error(_userMessages.androidLicensesNone)); return ValidationResult(ValidationType.partial, messages, statusInfo: sdkVersionText); case LicensesAccepted.unknown: - messages.add(ValidationMessage.error(userMessages.androidLicensesUnknown(globals.platform))); + messages.add(ValidationMessage.error(_userMessages.androidLicensesUnknown(_platform))); return ValidationResult(ValidationType.partial, messages, statusInfo: sdkVersionText); } return ValidationResult(ValidationType.installed, messages, statusInfo: sdkVersionText); @@ -290,26 +318,26 @@ class AndroidLicenseValidator extends DoctorValidator { Future _checkJavaVersionNoOutput() async { final String javaBinary = AndroidSdk.findJavaBinary( - androidStudio: globals.androidStudio, - fileSystem: globals.fs, - operatingSystemUtils: globals.os, - platform: globals.platform, + androidStudio: _androidStudio, + fileSystem: _fileSystem, + operatingSystemUtils: _operatingSystemUtils, + platform: _platform, ); if (javaBinary == null) { return false; } - if (!globals.processManager.canRun(javaBinary)) { + if (!_processManager.canRun(javaBinary)) { return false; } String javaVersion; try { - final ProcessResult result = await globals.processManager.run([javaBinary, '-version']); + final ProcessResult result = await _processManager.run([javaBinary, '-version']); if (result.exitCode == 0) { final List versionLines = (result.stderr as String).split('\n'); javaVersion = versionLines.length >= 2 ? versionLines[1] : versionLines[0]; } } on Exception catch (error) { - globals.printTrace(error.toString()); + _logger.printTrace(error.toString()); } if (javaVersion == null) { // Could not determine the java version. @@ -344,9 +372,9 @@ class AndroidLicenseValidator extends DoctorValidator { } try { - final Process process = await globals.processUtils.start( - [globals.androidSdk.sdkManagerPath, '--licenses'], - environment: globals.androidSdk.sdkManagerEnv, + final Process process = await _processManager.start( + [_androidSdk.sdkManagerPath, '--licenses'], + environment: _androidSdk.sdkManagerEnv, ); process.stdin.write('n\n'); // We expect logcat streams to occasionally contain invalid utf-8, @@ -364,36 +392,36 @@ class AndroidLicenseValidator extends DoctorValidator { await Future.wait(>[output, errors]); return status ?? LicensesAccepted.unknown; } on ProcessException catch (e) { - globals.printTrace('Failed to run Android sdk manager: $e'); + _logger.printTrace('Failed to run Android sdk manager: $e'); return LicensesAccepted.unknown; } } /// Run the Android SDK manager tool in order to accept SDK licenses. - static Future runLicenseManager() async { - if (globals.androidSdk == null) { - globals.printStatus(userMessages.androidSdkShort); + Future runLicenseManager() async { + if (_androidSdk == null) { + _logger.printStatus(_userMessages.androidSdkShort); return false; } if (!_canRunSdkManager()) { - throwToolExit(userMessages.androidMissingSdkManager(globals.androidSdk.sdkManagerPath, globals.platform)); + throwToolExit(_userMessages.androidMissingSdkManager(_androidSdk.sdkManagerPath, _platform)); } try { - final Process process = await globals.processUtils.start( - [globals.androidSdk.sdkManagerPath, '--licenses'], - environment: globals.androidSdk.sdkManagerEnv, + final Process process = await _processManager.start( + [_androidSdk.sdkManagerPath, '--licenses'], + environment: _androidSdk.sdkManagerEnv, ); // The real stdin will never finish streaming. Pipe until the child process // finishes. - unawaited(process.stdin.addStream(globals.stdio.stdin) + unawaited(process.stdin.addStream(_stdio.stdin) // If the process exits unexpectedly with an error, that will be // handled by the caller. .catchError((dynamic err, StackTrace stack) { - globals.printTrace('Echoing stdin to the licenses subprocess failed:'); - globals.printTrace('$err\n$stack'); + _logger.printTrace('Echoing stdin to the licenses subprocess failed:'); + _logger.printTrace('$err\n$stack'); } )); @@ -401,29 +429,28 @@ class AndroidLicenseValidator extends DoctorValidator { // may complete first. try { await Future.wait(>[ - globals.stdio.addStdoutStream(process.stdout), - globals.stdio.addStderrStream(process.stderr), + _stdio.addStdoutStream(process.stdout), + _stdio.addStderrStream(process.stderr), ]); } on Exception catch (err, stack) { - globals.printTrace('Echoing stdout or stderr from the license subprocess failed:'); - globals.printTrace('$err\n$stack'); + _logger.printTrace('Echoing stdout or stderr from the license subprocess failed:'); + _logger.printTrace('$err\n$stack'); } final int exitCode = await process.exitCode; return exitCode == 0; } on ProcessException catch (e) { - throwToolExit(userMessages.androidCannotRunSdkManager( - globals.androidSdk.sdkManagerPath, + throwToolExit(_userMessages.androidCannotRunSdkManager( + _androidSdk.sdkManagerPath, e.toString(), - globals.platform, + _platform, )); return false; } } - static bool _canRunSdkManager() { - assert(globals.androidSdk != null); - final String sdkManagerPath = globals.androidSdk.sdkManagerPath; - return globals.processManager.canRun(sdkManagerPath); + bool _canRunSdkManager() { + final String sdkManagerPath = _androidSdk.sdkManagerPath; + return _processManager.canRun(sdkManagerPath); } } diff --git a/packages/flutter_tools/lib/src/commands/doctor.dart b/packages/flutter_tools/lib/src/commands/doctor.dart index 7f834115cf..32e045e0e3 100644 --- a/packages/flutter_tools/lib/src/commands/doctor.dart +++ b/packages/flutter_tools/lib/src/commands/doctor.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 '../android/android_workflow.dart'; import '../base/common.dart'; import '../globals.dart' as globals; import '../runner/flutter_command.dart'; @@ -44,7 +45,11 @@ class DoctorCommand extends FlutterCommand { 'git hash.'); } } - final bool success = await globals.doctor.diagnose(androidLicenses: boolArg('android-licenses'), verbose: verbose); + final bool success = await globals.doctor.diagnose( + androidLicenses: boolArg('android-licenses'), + verbose: verbose, + androidLicenseValidator: androidLicenseValidator, + ); return FlutterCommandResult(success ? ExitStatus.success : ExitStatus.warning); } } diff --git a/packages/flutter_tools/lib/src/context_runner.dart b/packages/flutter_tools/lib/src/context_runner.dart index ee3a80fb8a..fb9f7e9e20 100644 --- a/packages/flutter_tools/lib/src/context_runner.dart +++ b/packages/flutter_tools/lib/src/context_runner.dart @@ -72,7 +72,17 @@ Future runInContext( body: runnerWrapper, overrides: overrides, fallbacks: { - AndroidLicenseValidator: () => AndroidLicenseValidator(), + AndroidLicenseValidator: () => AndroidLicenseValidator( + operatingSystemUtils: globals.os, + platform: globals.platform, + userMessages: globals.userMessages, + processManager: globals.processManager, + androidStudio: globals.androidStudio, + androidSdk: globals.androidSdk, + logger: globals.logger, + fileSystem: globals.fs, + stdio: globals.stdio, + ), AndroidSdk: AndroidSdk.locateAndroidSdk, AndroidStudio: AndroidStudio.latestValid, AndroidValidator: () => AndroidValidator( diff --git a/packages/flutter_tools/lib/src/doctor.dart b/packages/flutter_tools/lib/src/doctor.dart index d91b783db3..0f1f9fedca 100644 --- a/packages/flutter_tools/lib/src/doctor.dart +++ b/packages/flutter_tools/lib/src/doctor.dart @@ -288,9 +288,14 @@ class Doctor { } /// Print information about the state of installed tooling. - Future diagnose({ bool androidLicenses = false, bool verbose = true, bool showColor = true }) async { - if (androidLicenses) { - return AndroidLicenseValidator.runLicenseManager(); + Future diagnose({ + bool androidLicenses = false, + bool verbose = true, + bool showColor = true, + AndroidLicenseValidator androidLicenseValidator, + }) async { + if (androidLicenses && androidLicenseValidator != null) { + return androidLicenseValidator.runLicenseManager(); } if (!verbose) { diff --git a/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart index c9f3f69a45..709d1e78cc 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/doctor_test.dart @@ -7,6 +7,7 @@ import 'dart:async'; import 'package:args/command_runner.dart'; import 'package:file/memory.dart'; import 'package:flutter_tools/src/android/android_studio_validator.dart'; +import 'package:flutter_tools/src/android/android_workflow.dart'; import 'package:flutter_tools/src/base/common.dart'; import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/logger.dart'; @@ -704,7 +705,12 @@ class NoOpDoctor implements Doctor { Future checkRemoteArtifacts(String engineRevision) async => true; @override - Future diagnose({ bool androidLicenses = false, bool verbose = true, bool showColor = true }) async => true; + Future diagnose({ + bool androidLicenses = false, + bool verbose = true, + bool showColor = true, + AndroidLicenseValidator androidLicenseValidator, + }) async => true; @override List startValidatorTasks() => []; diff --git a/packages/flutter_tools/test/general.shard/analytics_test.dart b/packages/flutter_tools/test/general.shard/analytics_test.dart index 97e415ba1f..377f04ca55 100644 --- a/packages/flutter_tools/test/general.shard/analytics_test.dart +++ b/packages/flutter_tools/test/general.shard/analytics_test.dart @@ -173,6 +173,7 @@ void main() { when(mockDoctor.diagnose( androidLicenses: false, verbose: false, + androidLicenseValidator: anyNamed('androidLicenseValidator') )).thenAnswer((_) async => true); final DoctorCommand command = DoctorCommand(); final CommandRunner runner = createTestCommandRunner(command); @@ -197,7 +198,8 @@ void main() { testUsingContext('doctor fail sends warning', () async { mockTimes = [1000, 2000]; - when(mockDoctor.diagnose(androidLicenses: false, verbose: false)).thenAnswer((_) async => false); + when(mockDoctor.diagnose(androidLicenses: false, verbose: false, androidLicenseValidator: anyNamed('androidLicenseValidator'))) + .thenAnswer((_) async => false); final DoctorCommand command = DoctorCommand(); final CommandRunner runner = createTestCommandRunner(command); await runner.run(['doctor']); diff --git a/packages/flutter_tools/test/general.shard/android/android_workflow_test.dart b/packages/flutter_tools/test/general.shard/android/android_workflow_test.dart index 60f228a461..3a377ff9f1 100644 --- a/packages/flutter_tools/test/general.shard/android/android_workflow_test.dart +++ b/packages/flutter_tools/test/general.shard/android/android_workflow_test.dart @@ -5,17 +5,14 @@ import 'package:file/memory.dart'; import 'package:flutter_tools/src/android/android_sdk.dart'; import 'package:flutter_tools/src/android/android_workflow.dart'; -import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/os.dart'; import 'package:flutter_tools/src/base/platform.dart'; -import 'package:flutter_tools/src/base/terminal.dart' show AnsiTerminal, OutputPreferences; import 'package:flutter_tools/src/base/user_messages.dart'; import 'package:flutter_tools/src/base/version.dart'; import 'package:flutter_tools/src/doctor.dart'; import 'package:mockito/mockito.dart'; -import 'package:process/process.dart'; import '../../src/common.dart'; import '../../src/context.dart'; @@ -28,25 +25,17 @@ class MockOperatingSystemUtils extends Mock implements OperatingSystemUtils {} void main() { AndroidSdk sdk; Logger logger; - MemoryFileSystem fs; + MemoryFileSystem fileSystem; MockProcessManager processManager; MockStdio stdio; - UserMessages userMessages; setUp(() { sdk = MockAndroidSdk(); - fs = MemoryFileSystem.test(); - fs.directory('/home/me').createSync(recursive: true); - logger = BufferLogger( - terminal: AnsiTerminal( - stdio: null, - platform: const LocalPlatform(), - ), - outputPreferences: OutputPreferences.test(), - ); + fileSystem = MemoryFileSystem.test(); + fileSystem.directory('/home/me').createSync(recursive: true); + logger = BufferLogger.test(); processManager = MockProcessManager(); stdio = MockStdio(); - userMessages = UserMessages(); }); MockProcess Function(List) processMetaFactory(List stdout) { @@ -80,68 +69,88 @@ void main() { }); - testUsingContext('licensesAccepted returns LicensesAccepted.unknown if cannot find sdkmanager', () async { + testWithoutContext('licensesAccepted returns LicensesAccepted.unknown if cannot find sdkmanager', () async { processManager.canRunSucceeds = false; when(sdk.sdkManagerPath).thenReturn('/foo/bar/sdkmanager'); - final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(); + final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator( + androidSdk: sdk, + fileSystem: fileSystem, + processManager: processManager, + platform: FakePlatform(environment: {'HOME': '/home/me'}), + stdio: stdio, + logger: BufferLogger.test(), + userMessages: UserMessages(), + androidStudio: null, + operatingSystemUtils: FakeOperatingSystemUtils(), + ); final LicensesAccepted licenseStatus = await licenseValidator.licensesAccepted; - expect(licenseStatus, LicensesAccepted.unknown); - }, overrides: Map.unmodifiable({ - AndroidSdk: () => sdk, - FileSystem: () => fs, - ProcessManager: () => processManager, - Platform: () => FakePlatform()..environment = {'HOME': '/home/me'}, - Stdio: () => stdio, - })); - testUsingContext('licensesAccepted returns LicensesAccepted.unknown if cannot run sdkmanager', () async { + expect(licenseStatus, LicensesAccepted.unknown); + }); + + testWithoutContext('licensesAccepted returns LicensesAccepted.unknown if cannot run sdkmanager', () async { processManager.runSucceeds = false; when(sdk.sdkManagerPath).thenReturn('/foo/bar/sdkmanager'); - final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(); + final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator( + androidSdk: sdk, + fileSystem: fileSystem, + processManager: processManager, + platform: FakePlatform(environment: {'HOME': '/home/me'}), + stdio: stdio, + logger: BufferLogger.test(), + userMessages: UserMessages(), + androidStudio: null, + operatingSystemUtils: FakeOperatingSystemUtils(), + ); final LicensesAccepted licenseStatus = await licenseValidator.licensesAccepted; - expect(licenseStatus, LicensesAccepted.unknown); - }, overrides: Map.unmodifiable({ - AndroidSdk: () => sdk, - FileSystem: () => fs, - ProcessManager: () => processManager, - Platform: () => FakePlatform()..environment = {'HOME': '/home/me'}, - Stdio: () => stdio, - })); - testUsingContext('licensesAccepted handles garbage/no output', () async { + expect(licenseStatus, LicensesAccepted.unknown); + }); + + testWithoutContext('licensesAccepted handles garbage/no output', () async { when(sdk.sdkManagerPath).thenReturn('/foo/bar/sdkmanager'); - final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(); + final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator( + androidSdk: sdk, + fileSystem: fileSystem, + processManager: processManager, + platform: FakePlatform(environment: {'HOME': '/home/me'}), + stdio: stdio, + logger: BufferLogger.test(), + userMessages: UserMessages(), + androidStudio: null, + operatingSystemUtils: FakeOperatingSystemUtils(), + ); final LicensesAccepted result = await licenseValidator.licensesAccepted; + expect(result, equals(LicensesAccepted.unknown)); expect(processManager.commands.first, equals('/foo/bar/sdkmanager')); expect(processManager.commands.last, equals('--licenses')); - }, overrides: Map.unmodifiable({ - AndroidSdk: () => sdk, - FileSystem: () => fs, - ProcessManager: () => processManager, - Platform: () => FakePlatform()..environment = {'HOME': '/home/me'}, - Stdio: () => stdio, - })); + }); - testUsingContext('licensesAccepted works for all licenses accepted', () async { + testWithoutContext('licensesAccepted works for all licenses accepted', () async { when(sdk.sdkManagerPath).thenReturn('/foo/bar/sdkmanager'); processManager.processFactory = processMetaFactory([ '[=======================================] 100% Computing updates... ', 'All SDK package licenses accepted.', ]); - final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(); + final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator( + androidSdk: sdk, + fileSystem: fileSystem, + processManager: processManager, + platform: FakePlatform(environment: {'HOME': '/home/me'}), + stdio: stdio, + logger: BufferLogger.test(), + userMessages: UserMessages(), + androidStudio: null, + operatingSystemUtils: FakeOperatingSystemUtils(), + ); final LicensesAccepted result = await licenseValidator.licensesAccepted; - expect(result, equals(LicensesAccepted.all)); - }, overrides: Map.unmodifiable({ - AndroidSdk: () => sdk, - FileSystem: () => fs, - ProcessManager: () => processManager, - Platform: () => FakePlatform()..environment = {'HOME': '/home/me'}, - Stdio: () => stdio, - })); - testUsingContext('licensesAccepted works for some licenses accepted', () async { + expect(result, equals(LicensesAccepted.all)); + }); + + testWithoutContext('licensesAccepted works for some licenses accepted', () async { when(sdk.sdkManagerPath).thenReturn('/foo/bar/sdkmanager'); processManager.processFactory = processMetaFactory([ '[=======================================] 100% Computing updates... ', @@ -149,18 +158,23 @@ void main() { 'Review licenses that have not been accepted (y/N)?', ]); - final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(); + final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator( + androidSdk: sdk, + fileSystem: fileSystem, + processManager: processManager, + platform: FakePlatform(environment: {'HOME': '/home/me'}), + stdio: stdio, + logger: BufferLogger.test(), + userMessages: UserMessages(), + androidStudio: null, + operatingSystemUtils: FakeOperatingSystemUtils(), + ); final LicensesAccepted result = await licenseValidator.licensesAccepted; - expect(result, equals(LicensesAccepted.some)); - }, overrides: Map.unmodifiable({ - AndroidSdk: () => sdk, - FileSystem: () => fs, - ProcessManager: () => processManager, - Platform: () => FakePlatform()..environment = {'HOME': '/home/me'}, - Stdio: () => stdio, - })); - testUsingContext('licensesAccepted works for no licenses accepted', () async { + expect(result, equals(LicensesAccepted.some)); + }); + + testWithoutContext('licensesAccepted works for no licenses accepted', () async { when(sdk.sdkManagerPath).thenReturn('/foo/bar/sdkmanager'); processManager.processFactory = processMetaFactory([ '[=======================================] 100% Computing updates... ', @@ -168,55 +182,78 @@ void main() { 'Review licenses that have not been accepted (y/N)?', ]); - final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator(); + final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator( + androidSdk: sdk, + fileSystem: fileSystem, + processManager: processManager, + platform: FakePlatform(environment: {'HOME': '/home/me'}), + stdio: stdio, + logger: BufferLogger.test(), + userMessages: UserMessages(), + androidStudio: null, + operatingSystemUtils: FakeOperatingSystemUtils(), + ); final LicensesAccepted result = await licenseValidator.licensesAccepted; - expect(result, equals(LicensesAccepted.none)); - }, overrides: Map.unmodifiable({ - AndroidSdk: () => sdk, - FileSystem: () => fs, - ProcessManager: () => processManager, - Platform: () => FakePlatform()..environment = {'HOME': '/home/me'}, - Stdio: () => stdio, - })); - testUsingContext('runLicenseManager succeeds for version >= 26', () async { + expect(result, equals(LicensesAccepted.none)); + }); + + testWithoutContext('runLicenseManager succeeds for version >= 26', () async { when(sdk.sdkManagerPath).thenReturn('/foo/bar/sdkmanager'); when(sdk.sdkManagerVersion).thenReturn('26.0.0'); - expect(await AndroidLicenseValidator.runLicenseManager(), isTrue); - }, overrides: Map.unmodifiable({ - AndroidSdk: () => sdk, - FileSystem: () => fs, - ProcessManager: () => processManager, - Platform: () => FakePlatform()..environment = {'HOME': '/home/me'}, - Stdio: () => stdio, - })); + final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator( + androidSdk: sdk, + fileSystem: fileSystem, + processManager: processManager, + platform: FakePlatform(environment: {'HOME': '/home/me'}), + stdio: stdio, + logger: BufferLogger.test(), + userMessages: UserMessages(), + androidStudio: null, + operatingSystemUtils: FakeOperatingSystemUtils(), + ); - testUsingContext('runLicenseManager errors when sdkmanager is not found', () async { + expect(await licenseValidator.runLicenseManager(), isTrue); + }); + + testWithoutContext('runLicenseManager errors when sdkmanager is not found', () async { when(sdk.sdkManagerPath).thenReturn('/foo/bar/sdkmanager'); processManager.canRunSucceeds = false; - expect(AndroidLicenseValidator.runLicenseManager(), throwsToolExit()); - }, overrides: Map.unmodifiable({ - AndroidSdk: () => sdk, - FileSystem: () => fs, - ProcessManager: () => processManager, - Platform: () => FakePlatform()..environment = {'HOME': '/home/me'}, - Stdio: () => stdio, - })); + final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator( + androidSdk: sdk, + fileSystem: fileSystem, + processManager: processManager, + platform: FakePlatform(environment: {'HOME': '/home/me'}), + stdio: stdio, + logger: BufferLogger.test(), + userMessages: UserMessages(), + androidStudio: null, + operatingSystemUtils: FakeOperatingSystemUtils(), + ); - testUsingContext('runLicenseManager errors when sdkmanager fails to run', () async { + expect(licenseValidator.runLicenseManager(), throwsToolExit()); + }); + + testWithoutContext('runLicenseManager errors when sdkmanager fails to run', () async { when(sdk.sdkManagerPath).thenReturn('/foo/bar/sdkmanager'); processManager.runSucceeds = false; - expect(AndroidLicenseValidator.runLicenseManager(), throwsToolExit()); - }, overrides: Map.unmodifiable({ - AndroidSdk: () => sdk, - FileSystem: () => fs, - ProcessManager: () => processManager, - Platform: () => FakePlatform()..environment = {'HOME': '/home/me'}, - Stdio: () => stdio, - })); + final AndroidLicenseValidator licenseValidator = AndroidLicenseValidator( + androidSdk: sdk, + fileSystem: fileSystem, + processManager: processManager, + platform: FakePlatform(environment: {'HOME': '/home/me'}), + stdio: stdio, + logger: BufferLogger.test(), + userMessages: UserMessages(), + androidStudio: null, + operatingSystemUtils: FakeOperatingSystemUtils(), + ); + + expect(licenseValidator.runLicenseManager(), throwsToolExit()); + }); testWithoutContext('detects license-only SDK installation', () async { when(sdk.licensesAvailable).thenReturn(true); @@ -224,16 +261,16 @@ void main() { final ValidationResult validationResult = await AndroidValidator( androidStudio: null, androidSdk: sdk, - fileSystem: fs, + fileSystem: fileSystem, logger: logger, processManager: processManager, platform: FakePlatform()..environment = {'HOME': '/home/me'}, - userMessages: userMessages, + userMessages: UserMessages(), ).validate(); expect(validationResult.type, ValidationType.partial); expect( validationResult.messages.last.message, - userMessages.androidSdkLicenseOnly(kAndroidHome), + UserMessages().androidSdkLicenseOnly(kAndroidHome), ); }); @@ -249,7 +286,7 @@ void main() { when(sdk.latestVersion).thenReturn(mockSdkVersion); when(sdk.validateSdkWellFormed()).thenReturn([]); when(processManager.runSync(['which', 'java'])).thenReturn(ProcessResult(123, 1, '', '')); - final String errorMessage = userMessages.androidSdkBuildToolsOutdated( + final String errorMessage = UserMessages().androidSdkBuildToolsOutdated( sdk.sdkManagerPath, kAndroidSdkMinVersion, kAndroidSdkBuildToolsMinVersion.toString(), @@ -259,11 +296,11 @@ void main() { final AndroidValidator androidValidator = AndroidValidator( androidStudio: null, androidSdk: sdk, - fileSystem: fs, + fileSystem: fileSystem, logger: logger, processManager: processManager, platform: FakePlatform()..environment = {'HOME': '/home/me'}, - userMessages: userMessages, + userMessages: UserMessages(), ); ValidationResult validationResult = await androidValidator.validate(); @@ -313,16 +350,16 @@ void main() { const String javaVersionText = 'openjdk version "1.7.0_212"'; when(processManager.run(argThat(contains('-version')))).thenAnswer((_) => Future.value(ProcessResult(0, 0, null, javaVersionText))); - final String errorMessage = userMessages.androidJavaMinimumVersion(javaVersionText); + final String errorMessage = UserMessages().androidJavaMinimumVersion(javaVersionText); final ValidationResult validationResult = await AndroidValidator( androidSdk: sdk, androidStudio: null, - fileSystem: fs, + fileSystem: fileSystem, logger: logger, platform: FakePlatform()..environment = {'HOME': '/home/me', 'JAVA_HOME': 'home/java'}, processManager: processManager, - userMessages: userMessages, + userMessages: UserMessages(), ).validate(); expect(validationResult.type, ValidationType.partial); expect( @@ -341,12 +378,13 @@ void main() { final ValidationResult validationResult = await AndroidValidator( androidSdk: null, androidStudio: null, - fileSystem: fs, + fileSystem: fileSystem, logger: logger, platform: FakePlatform()..environment = {'HOME': '/home/me', 'JAVA_HOME': 'home/java'}, processManager: processManager, - userMessages: userMessages, + userMessages: UserMessages(), ).validate(); + expect( validationResult.messages.any( (ValidationMessage message) => message.message.contains('flutter config --android-sdk')