Unverified Commit 457972b7 authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Move doctor into globals (#54912)

* Move doctor into globals

* Fix tests
parent 6f9ee13e
...@@ -242,12 +242,8 @@ Future<String> _doctorText() async { ...@@ -242,12 +242,8 @@ Future<String> _doctorText() async {
outputPreferences: globals.outputPreferences, outputPreferences: globals.outputPreferences,
); );
await context.run<bool>( final Doctor doctor = Doctor(logger: logger);
body: () => doctor.diagnose(verbose: true, showColor: false), await doctor.diagnose(verbose: true, showColor: false);
overrides: <Type, Generator>{
Logger: () => logger,
},
);
return logger.statusText; return logger.statusText;
} on Exception catch (error, trace) { } on Exception catch (error, trace) {
......
...@@ -19,7 +19,6 @@ import '../base/utils.dart'; ...@@ -19,7 +19,6 @@ import '../base/utils.dart';
import '../cache.dart'; import '../cache.dart';
import '../convert.dart'; import '../convert.dart';
import '../dart/pub.dart'; import '../dart/pub.dart';
import '../doctor.dart';
import '../features.dart'; import '../features.dart';
import '../flutter_project_metadata.dart'; import '../flutter_project_metadata.dart';
import '../globals.dart' as globals; import '../globals.dart' as globals;
...@@ -417,9 +416,9 @@ class CreateCommand extends FlutterCommand { ...@@ -417,9 +416,9 @@ class CreateCommand extends FlutterCommand {
final String relativeAppMain = globals.fs.path.join(relativeAppPath, 'lib', 'main.dart'); final String relativeAppMain = globals.fs.path.join(relativeAppPath, 'lib', 'main.dart');
final String relativePluginPath = globals.fs.path.normalize(globals.fs.path.relative(projectDirPath)); final String relativePluginPath = globals.fs.path.normalize(globals.fs.path.relative(projectDirPath));
final String relativePluginMain = globals.fs.path.join(relativePluginPath, 'lib', '$projectName.dart'); final String relativePluginMain = globals.fs.path.join(relativePluginPath, 'lib', '$projectName.dart');
if (doctor.canLaunchAnything) { if (globals.doctor.canLaunchAnything) {
// Let them know a summary of the state of their tooling. // Let them know a summary of the state of their tooling.
await doctor.summary(); await globals.doctor.summary();
globals.printStatus(''' globals.printStatus('''
In order to run your $application, type: In order to run your $application, type:
...@@ -443,7 +442,7 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi ...@@ -443,7 +442,7 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi
globals.printStatus(''); globals.printStatus('');
// Give the user more detailed analysis. // Give the user more detailed analysis.
await doctor.diagnose(); await globals.doctor.diagnose();
globals.printStatus(''); globals.printStatus('');
globals.printStatus("After installing components, run 'flutter doctor' in order to " globals.printStatus("After installing components, run 'flutter doctor' in order to "
're-validate your setup.'); 're-validate your setup.');
......
...@@ -8,7 +8,6 @@ import '../base/common.dart'; ...@@ -8,7 +8,6 @@ import '../base/common.dart';
import '../base/utils.dart'; import '../base/utils.dart';
import '../convert.dart'; import '../convert.dart';
import '../device.dart'; import '../device.dart';
import '../doctor.dart';
import '../globals.dart' as globals; import '../globals.dart' as globals;
import '../runner/flutter_command.dart'; import '../runner/flutter_command.dart';
...@@ -52,7 +51,7 @@ class DevicesCommand extends FlutterCommand { ...@@ -52,7 +51,7 @@ class DevicesCommand extends FlutterCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
if (!doctor.canListAnything) { if (!globals.doctor.canListAnything) {
throwToolExit( throwToolExit(
"Unable to locate a development device; please run 'flutter doctor' for " "Unable to locate a development device; please run 'flutter doctor' for "
'information about installing additional components.', 'information about installing additional components.',
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
import 'dart:async'; import 'dart:async';
import '../base/common.dart'; import '../base/common.dart';
import '../doctor.dart';
import '../globals.dart' as globals; import '../globals.dart' as globals;
import '../runner/flutter_command.dart'; import '../runner/flutter_command.dart';
...@@ -47,7 +46,7 @@ class DoctorCommand extends FlutterCommand { ...@@ -47,7 +46,7 @@ class DoctorCommand extends FlutterCommand {
if (argResults.wasParsed('check-for-remote-artifacts')) { if (argResults.wasParsed('check-for-remote-artifacts')) {
final String engineRevision = stringArg('check-for-remote-artifacts'); final String engineRevision = stringArg('check-for-remote-artifacts');
if (engineRevision.startsWith(RegExp(r'[a-f0-9]{1,40}'))) { if (engineRevision.startsWith(RegExp(r'[a-f0-9]{1,40}'))) {
final bool success = await doctor.checkRemoteArtifacts(engineRevision); final bool success = await globals.doctor.checkRemoteArtifacts(engineRevision);
if (!success) { if (!success) {
throwToolExit('Artifacts for engine $engineRevision are missing or are ' throwToolExit('Artifacts for engine $engineRevision are missing or are '
'not yet available.', exitCode: 1); 'not yet available.', exitCode: 1);
...@@ -57,7 +56,7 @@ class DoctorCommand extends FlutterCommand { ...@@ -57,7 +56,7 @@ class DoctorCommand extends FlutterCommand {
'git hash.'); 'git hash.');
} }
} }
final bool success = await doctor.diagnose(androidLicenses: boolArg('android-licenses'), verbose: verbose); final bool success = await globals.doctor.diagnose(androidLicenses: boolArg('android-licenses'), verbose: verbose);
return FlutterCommandResult(success ? ExitStatus.success : ExitStatus.warning); return FlutterCommandResult(success ? ExitStatus.success : ExitStatus.warning);
} }
} }
...@@ -33,7 +33,7 @@ class EmulatorsCommand extends FlutterCommand { ...@@ -33,7 +33,7 @@ class EmulatorsCommand extends FlutterCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
if (doctor.workflows.every((Workflow w) => !w.canListEmulators)) { if (globals.doctor.workflows.every((Workflow w) => !w.canListEmulators)) {
throwToolExit( throwToolExit(
'Unable to find any emulator sources. Please ensure you have some\n' 'Unable to find any emulator sources. Please ensure you have some\n'
'Android AVD images ' + 'Android AVD images ' +
......
...@@ -126,7 +126,7 @@ Future<T> runInContext<T>( ...@@ -126,7 +126,7 @@ Future<T> runInContext<T>(
), ),
DevFSConfig: () => DevFSConfig(), DevFSConfig: () => DevFSConfig(),
DeviceManager: () => DeviceManager(), DeviceManager: () => DeviceManager(),
Doctor: () => const Doctor(), Doctor: () => Doctor(logger: globals.logger),
DoctorValidatorsProvider: () => DoctorValidatorsProvider.defaultInstance, DoctorValidatorsProvider: () => DoctorValidatorsProvider.defaultInstance,
EmulatorManager: () => EmulatorManager(), EmulatorManager: () => EmulatorManager(),
FeatureFlags: () => const FeatureFlags(), FeatureFlags: () => const FeatureFlags(),
......
...@@ -40,8 +40,6 @@ import 'web/workflow.dart'; ...@@ -40,8 +40,6 @@ import 'web/workflow.dart';
import 'windows/visual_studio_validator.dart'; import 'windows/visual_studio_validator.dart';
import 'windows/windows_workflow.dart'; import 'windows/windows_workflow.dart';
Doctor get doctor => context.get<Doctor>();
abstract class DoctorValidatorsProvider { abstract class DoctorValidatorsProvider {
/// The singleton instance, pulled from the [AppContext]. /// The singleton instance, pulled from the [AppContext].
static DoctorValidatorsProvider get instance => context.get<DoctorValidatorsProvider>(); static DoctorValidatorsProvider get instance => context.get<DoctorValidatorsProvider>();
...@@ -153,7 +151,11 @@ class ValidatorTask { ...@@ -153,7 +151,11 @@ class ValidatorTask {
} }
class Doctor { class Doctor {
const Doctor(); Doctor({
@required Logger logger,
}) : _logger = logger;
final Logger _logger;
List<DoctorValidator> get validators { List<DoctorValidator> get validators {
return DoctorValidatorsProvider.instance.validators; return DoctorValidatorsProvider.instance.validators;
...@@ -184,7 +186,7 @@ class Doctor { ...@@ -184,7 +186,7 @@ class Doctor {
/// Print a summary of the state of the tooling, as well as how to get more info. /// Print a summary of the state of the tooling, as well as how to get more info.
Future<void> summary() async { Future<void> summary() async {
globals.printStatus(await _summaryText()); _logger.printStatus(await _summaryText());
} }
Future<String> _summaryText() async { Future<String> _summaryText() async {
...@@ -263,7 +265,7 @@ class Doctor { ...@@ -263,7 +265,7 @@ class Doctor {
} }
if (!verbose) { if (!verbose) {
globals.printStatus('Doctor summary (to see all details, run flutter doctor -v):'); _logger.printStatus('Doctor summary (to see all details, run flutter doctor -v):');
} }
bool doctorResult = true; bool doctorResult = true;
int issues = 0; int issues = 0;
...@@ -307,10 +309,10 @@ class Doctor { ...@@ -307,10 +309,10 @@ class Doctor {
final String leadingBox = showColor ? result.coloredLeadingBox : result.leadingBox; final String leadingBox = showColor ? result.coloredLeadingBox : result.leadingBox;
if (result.statusInfo != null) { if (result.statusInfo != null) {
globals.printStatus('$leadingBox ${validator.title} (${result.statusInfo})', _logger.printStatus('$leadingBox ${validator.title} (${result.statusInfo})',
hangingIndent: result.leadingBox.length + 1); hangingIndent: result.leadingBox.length + 1);
} else { } else {
globals.printStatus('$leadingBox ${validator.title}', _logger.printStatus('$leadingBox ${validator.title}',
hangingIndent: result.leadingBox.length + 1); hangingIndent: result.leadingBox.length + 1);
} }
...@@ -320,7 +322,7 @@ class Doctor { ...@@ -320,7 +322,7 @@ class Doctor {
int indent = 4; int indent = 4;
final String indicator = showColor ? message.coloredIndicator : message.indicator; final String indicator = showColor ? message.coloredIndicator : message.indicator;
for (final String line in '$indicator ${message.message}'.split('\n')) { for (final String line in '$indicator ${message.message}'.split('\n')) {
globals.printStatus(line, hangingIndent: hangingIndent, indent: indent, emphasis: true); _logger.printStatus(line, hangingIndent: hangingIndent, indent: indent, emphasis: true);
// Only do hanging indent for the first line. // Only do hanging indent for the first line.
hangingIndent = 0; hangingIndent = 0;
indent = 6; indent = 6;
...@@ -328,20 +330,20 @@ class Doctor { ...@@ -328,20 +330,20 @@ class Doctor {
} }
} }
if (verbose) { if (verbose) {
globals.printStatus(''); _logger.printStatus('');
} }
} }
// Make sure there's always one line before the summary even when not verbose. // Make sure there's always one line before the summary even when not verbose.
if (!verbose) { if (!verbose) {
globals.printStatus(''); _logger.printStatus('');
} }
if (issues > 0) { if (issues > 0) {
globals.printStatus('${showColor ? globals.terminal.color('!', TerminalColor.yellow) : '!'}' _logger.printStatus('${showColor ? globals.terminal.color('!', TerminalColor.yellow) : '!'}'
' Doctor found issues in $issues categor${issues > 1 ? "ies" : "y"}.', hangingIndent: 2); ' Doctor found issues in $issues categor${issues > 1 ? "ies" : "y"}.', hangingIndent: 2);
} else { } else {
globals.printStatus('${showColor ? globals.terminal.color('•', TerminalColor.green) : '•'}' _logger.printStatus('${showColor ? globals.terminal.color('•', TerminalColor.green) : '•'}'
' No issues found!', hangingIndent: 2); ' No issues found!', hangingIndent: 2);
} }
......
...@@ -22,6 +22,7 @@ import 'base/terminal.dart'; ...@@ -22,6 +22,7 @@ import 'base/terminal.dart';
import 'base/user_messages.dart'; import 'base/user_messages.dart';
import 'build_system/build_system.dart'; import 'build_system/build_system.dart';
import 'cache.dart'; import 'cache.dart';
import 'doctor.dart';
import 'fuchsia/fuchsia_sdk.dart'; import 'fuchsia/fuchsia_sdk.dart';
import 'ios/ios_workflow.dart'; import 'ios/ios_workflow.dart';
import 'ios/plist_parser.dart'; import 'ios/plist_parser.dart';
...@@ -39,6 +40,7 @@ Artifacts get artifacts => context.get<Artifacts>(); ...@@ -39,6 +40,7 @@ Artifacts get artifacts => context.get<Artifacts>();
BuildSystem get buildSystem => context.get<BuildSystem>(); BuildSystem get buildSystem => context.get<BuildSystem>();
Cache get cache => context.get<Cache>(); Cache get cache => context.get<Cache>();
Config get config => context.get<Config>(); Config get config => context.get<Config>();
Doctor get doctor => context.get<Doctor>();
Logger get logger => context.get<Logger>(); Logger get logger => context.get<Logger>();
OperatingSystemUtils get os => context.get<OperatingSystemUtils>(); OperatingSystemUtils get os => context.get<OperatingSystemUtils>();
PersistentToolState get persistentToolState => PersistentToolState.instance; PersistentToolState get persistentToolState => PersistentToolState.instance;
......
...@@ -25,7 +25,6 @@ import '../cache.dart'; ...@@ -25,7 +25,6 @@ import '../cache.dart';
import '../dart/package_map.dart'; import '../dart/package_map.dart';
import '../dart/pub.dart'; import '../dart/pub.dart';
import '../device.dart'; import '../device.dart';
import '../doctor.dart';
import '../features.dart'; import '../features.dart';
import '../globals.dart' as globals; import '../globals.dart' as globals;
import '../project.dart'; import '../project.dart';
...@@ -762,7 +761,7 @@ abstract class FlutterCommand extends Command<void> { ...@@ -762,7 +761,7 @@ abstract class FlutterCommand extends Command<void> {
/// If no device can be found that meets specified criteria, /// If no device can be found that meets specified criteria,
/// then print an error message and return null. /// then print an error message and return null.
Future<List<Device>> findAllTargetDevices() async { Future<List<Device>> findAllTargetDevices() async {
if (!doctor.canLaunchAnything) { if (!globals.doctor.canLaunchAnything) {
globals.printError(userMessages.flutterNoDevelopmentDevice); globals.printError(userMessages.flutterNoDevelopmentDevice);
return null; return null;
} }
......
...@@ -11,6 +11,7 @@ import 'package:flutter_tools/src/base/common.dart'; ...@@ -11,6 +11,7 @@ import 'package:flutter_tools/src/base/common.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/io.dart'; import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/terminal.dart'; import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/base/user_messages.dart'; import 'package:flutter_tools/src/base/user_messages.dart';
import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/cache.dart';
...@@ -45,10 +46,12 @@ final Map<Type, Generator> noColorTerminalOverride = <Type, Generator>{ ...@@ -45,10 +46,12 @@ final Map<Type, Generator> noColorTerminalOverride = <Type, Generator>{
void main() { void main() {
MockProcessManager mockProcessManager; MockProcessManager mockProcessManager;
MockFlutterVersion mockFlutterVersion; MockFlutterVersion mockFlutterVersion;
BufferLogger logger;
setUp(() { setUp(() {
mockProcessManager = MockProcessManager(); mockProcessManager = MockProcessManager();
mockFlutterVersion = MockFlutterVersion(); mockFlutterVersion = MockFlutterVersion();
logger = BufferLogger.test();
}); });
group('doctor', () { group('doctor', () {
...@@ -220,8 +223,9 @@ void main() { ...@@ -220,8 +223,9 @@ void main() {
group('doctor with overridden validators', () { group('doctor with overridden validators', () {
testUsingContext('validate non-verbose output format for run without issues', () async { testUsingContext('validate non-verbose output format for run without issues', () async {
final Doctor doctor = Doctor(logger: logger);
expect(await doctor.diagnose(verbose: false), isTrue); expect(await doctor.diagnose(verbose: false), isTrue);
expect(testLogger.statusText, equals( expect(logger.statusText, equals(
'Doctor summary (to see all details, run flutter doctor -v):\n' 'Doctor summary (to see all details, run flutter doctor -v):\n'
'[✓] Passing Validator (with statusInfo)\n' '[✓] Passing Validator (with statusInfo)\n'
'[✓] Another Passing Validator (with statusInfo)\n' '[✓] Another Passing Validator (with statusInfo)\n'
...@@ -244,6 +248,7 @@ void main() { ...@@ -244,6 +248,7 @@ void main() {
}); });
testUsingContext('contains installed', () async { testUsingContext('contains installed', () async {
final Doctor doctor = Doctor(logger: logger);
await doctor.diagnose(verbose: false); await doctor.diagnose(verbose: false);
expect( expect(
...@@ -261,7 +266,7 @@ void main() { ...@@ -261,7 +266,7 @@ void main() {
}); });
testUsingContext('contains installed and partial', () async { testUsingContext('contains installed and partial', () async {
await FakePassingDoctor().diagnose(verbose: false); await FakePassingDoctor(logger).diagnose(verbose: false);
expect( expect(
verify(mockUsage.sendEvent( verify(mockUsage.sendEvent(
...@@ -293,7 +298,7 @@ void main() { ...@@ -293,7 +298,7 @@ void main() {
}); });
testUsingContext('contains installed, missing and partial', () async { testUsingContext('contains installed, missing and partial', () async {
await FakeDoctor().diagnose(verbose: false); await FakeDoctor(logger).diagnose(verbose: false);
expect( expect(
verify(mockUsage.sendEvent( verify(mockUsage.sendEvent(
...@@ -341,7 +346,7 @@ void main() { ...@@ -341,7 +346,7 @@ void main() {
}); });
testUsingContext('events for grouped validators are properly decomposed', () async { testUsingContext('events for grouped validators are properly decomposed', () async {
await FakeGroupedDoctor().diagnose(verbose: false); await FakeGroupedDoctor(logger).diagnose(verbose: false);
expect( expect(
verify(mockUsage.sendEvent( verify(mockUsage.sendEvent(
...@@ -377,8 +382,8 @@ void main() { ...@@ -377,8 +382,8 @@ void main() {
}); });
testUsingContext('validate non-verbose output format for run without issues', () async { testUsingContext('validate non-verbose output format for run without issues', () async {
expect(await FakeQuietDoctor().diagnose(verbose: false), isTrue); expect(await FakeQuietDoctor(logger).diagnose(verbose: false), isTrue);
expect(testLogger.statusText, equals( expect(logger.statusText, equals(
'Doctor summary (to see all details, run flutter doctor -v):\n' 'Doctor summary (to see all details, run flutter doctor -v):\n'
'[✓] Passing Validator (with statusInfo)\n' '[✓] Passing Validator (with statusInfo)\n'
'[✓] Another Passing Validator (with statusInfo)\n' '[✓] Another Passing Validator (with statusInfo)\n'
...@@ -390,8 +395,8 @@ void main() { ...@@ -390,8 +395,8 @@ void main() {
}, overrides: noColorTerminalOverride); }, overrides: noColorTerminalOverride);
testUsingContext('validate non-verbose output format for run with crash', () async { testUsingContext('validate non-verbose output format for run with crash', () async {
expect(await FakeCrashingDoctor().diagnose(verbose: false), isFalse); expect(await FakeCrashingDoctor(logger).diagnose(verbose: false), isFalse);
expect(testLogger.statusText, equals( expect(logger.statusText, equals(
'Doctor summary (to see all details, run flutter doctor -v):\n' 'Doctor summary (to see all details, run flutter doctor -v):\n'
'[✓] Passing Validator (with statusInfo)\n' '[✓] Passing Validator (with statusInfo)\n'
'[✓] Another Passing Validator (with statusInfo)\n' '[✓] Another Passing Validator (with statusInfo)\n'
...@@ -407,15 +412,15 @@ void main() { ...@@ -407,15 +412,15 @@ void main() {
}, overrides: noColorTerminalOverride); }, overrides: noColorTerminalOverride);
testUsingContext('validate verbose output format contains trace for run with crash', () async { testUsingContext('validate verbose output format contains trace for run with crash', () async {
expect(await FakeCrashingDoctor().diagnose(verbose: true), isFalse); expect(await FakeCrashingDoctor(logger).diagnose(verbose: true), isFalse);
expect(testLogger.statusText, contains('#0 CrashingValidator.validate')); expect(logger.statusText, contains('#0 CrashingValidator.validate'));
}, overrides: noColorTerminalOverride); }, overrides: noColorTerminalOverride);
testUsingContext('validate non-verbose output format for run with an async crash', () async { testUsingContext('validate non-verbose output format for run with an async crash', () async {
final Completer<void> completer = Completer<void>(); final Completer<void> completer = Completer<void>();
await FakeAsync().run((FakeAsync time) { await FakeAsync().run((FakeAsync time) {
unawaited(FakeAsyncCrashingDoctor(time).diagnose(verbose: false).then((bool r) { unawaited(FakeAsyncCrashingDoctor(time, logger).diagnose(verbose: false).then((bool r) {
expect(r, isFalse); expect(r, isFalse);
completer.complete(null); completer.complete(null);
})); }));
...@@ -423,7 +428,7 @@ void main() { ...@@ -423,7 +428,7 @@ void main() {
time.flushMicrotasks(); time.flushMicrotasks();
return completer.future; return completer.future;
}); });
expect(testLogger.statusText, equals( expect(logger.statusText, equals(
'Doctor summary (to see all details, run flutter doctor -v):\n' 'Doctor summary (to see all details, run flutter doctor -v):\n'
'[✓] Passing Validator (with statusInfo)\n' '[✓] Passing Validator (with statusInfo)\n'
'[✓] Another Passing Validator (with statusInfo)\n' '[✓] Another Passing Validator (with statusInfo)\n'
...@@ -440,8 +445,8 @@ void main() { ...@@ -440,8 +445,8 @@ void main() {
testUsingContext('validate non-verbose output format when only one category fails', () async { testUsingContext('validate non-verbose output format when only one category fails', () async {
expect(await FakeSinglePassingDoctor().diagnose(verbose: false), isTrue); expect(await FakeSinglePassingDoctor(logger).diagnose(verbose: false), isTrue);
expect(testLogger.statusText, equals( expect(logger.statusText, equals(
'Doctor summary (to see all details, run flutter doctor -v):\n' 'Doctor summary (to see all details, run flutter doctor -v):\n'
'[!] Partial Validator with only a Hint\n' '[!] Partial Validator with only a Hint\n'
' ! There is a hint here\n' ' ! There is a hint here\n'
...@@ -451,8 +456,8 @@ void main() { ...@@ -451,8 +456,8 @@ void main() {
}, overrides: noColorTerminalOverride); }, overrides: noColorTerminalOverride);
testUsingContext('validate non-verbose output format for a passing run', () async { testUsingContext('validate non-verbose output format for a passing run', () async {
expect(await FakePassingDoctor().diagnose(verbose: false), isTrue); expect(await FakePassingDoctor(logger).diagnose(verbose: false), isTrue);
expect(testLogger.statusText, equals( expect(logger.statusText, equals(
'Doctor summary (to see all details, run flutter doctor -v):\n' 'Doctor summary (to see all details, run flutter doctor -v):\n'
'[✓] Passing Validator (with statusInfo)\n' '[✓] Passing Validator (with statusInfo)\n'
'[!] Partial Validator with only a Hint\n' '[!] Partial Validator with only a Hint\n'
...@@ -467,8 +472,8 @@ void main() { ...@@ -467,8 +472,8 @@ void main() {
}, overrides: noColorTerminalOverride); }, overrides: noColorTerminalOverride);
testUsingContext('validate non-verbose output format', () async { testUsingContext('validate non-verbose output format', () async {
expect(await FakeDoctor().diagnose(verbose: false), isFalse); expect(await FakeDoctor(logger).diagnose(verbose: false), isFalse);
expect(testLogger.statusText, equals( expect(logger.statusText, equals(
'Doctor summary (to see all details, run flutter doctor -v):\n' 'Doctor summary (to see all details, run flutter doctor -v):\n'
'[✓] Passing Validator (with statusInfo)\n' '[✓] Passing Validator (with statusInfo)\n'
'[✗] Missing Validator\n' '[✗] Missing Validator\n'
...@@ -488,8 +493,8 @@ void main() { ...@@ -488,8 +493,8 @@ void main() {
}, overrides: noColorTerminalOverride); }, overrides: noColorTerminalOverride);
testUsingContext('validate verbose output format', () async { testUsingContext('validate verbose output format', () async {
expect(await FakeDoctor().diagnose(verbose: true), isFalse); expect(await FakeDoctor(logger).diagnose(verbose: true), isFalse);
expect(testLogger.statusText, equals( expect(logger.statusText, equals(
'[✓] Passing Validator (with statusInfo)\n' '[✓] Passing Validator (with statusInfo)\n'
' • A helpful message\n' ' • A helpful message\n'
' • A second, somewhat longer helpful message\n' ' • A second, somewhat longer helpful message\n'
...@@ -525,8 +530,8 @@ void main() { ...@@ -525,8 +530,8 @@ void main() {
environment: anyNamed('environment'), environment: anyNamed('environment'),
)).thenReturn(ProcessResult(101, 1, '', '')); )).thenReturn(ProcessResult(101, 1, '', ''));
expect(await FlutterValidatorDoctor().diagnose(verbose: false), isTrue); expect(await FlutterValidatorDoctor(logger).diagnose(verbose: false), isTrue);
final List<String> statusLines = testLogger.statusText.split('\n'); final List<String> statusLines = logger.statusText.split('\n');
for (final String msg in userMessages.flutterBinariesDoNotRun.split('\n')) { for (final String msg in userMessages.flutterBinariesDoNotRun.split('\n')) {
expect(statusLines, contains(contains(msg))); expect(statusLines, contains(contains(msg)));
} }
...@@ -544,10 +549,10 @@ void main() { ...@@ -544,10 +549,10 @@ void main() {
}); });
testUsingContext('gen_snapshot binary not available', () async { testUsingContext('gen_snapshot binary not available', () async {
expect(await FlutterValidatorDoctor().diagnose(verbose: false), isTrue); expect(await FlutterValidatorDoctor(logger).diagnose(verbose: false), isTrue);
// gen_snapshot is downloaded on demand, and the doctor should not // gen_snapshot is downloaded on demand, and the doctor should not
// fail if the gen_snapshot binary is not present. // fail if the gen_snapshot binary is not present.
expect(testLogger.statusText, contains('No issues found!')); expect(logger.statusText, contains('No issues found!'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Artifacts: () => mockArtifacts, Artifacts: () => mockArtifacts,
FileSystem: () => MemoryFileSystem(), FileSystem: () => MemoryFileSystem(),
...@@ -568,9 +573,9 @@ void main() { ...@@ -568,9 +573,9 @@ void main() {
environment: anyNamed('environment'), environment: anyNamed('environment'),
)).thenReturn(ProcessResult(101, 255, '', '')); )).thenReturn(ProcessResult(101, 255, '', ''));
expect(await FlutterValidatorDoctor().diagnose(verbose: false), isTrue); expect(await FlutterValidatorDoctor(logger).diagnose(verbose: false), isTrue);
expect(testLogger.statusText, equals( expect(logger.statusText, equals(
'Doctor summary (to see all details, run flutter doctor -v):\n' 'Doctor summary (to see all details, run flutter doctor -v):\n'
'[!] Flutter (Channel unknown, v0.0.0, on fake OS name and version, locale en_US.UTF-8)\n' '[!] Flutter (Channel unknown, v0.0.0, on fake OS name and version, locale en_US.UTF-8)\n'
' ✗ version error\n\n' ' ✗ version error\n\n'
...@@ -587,8 +592,11 @@ void main() { ...@@ -587,8 +592,11 @@ void main() {
}); });
testUsingContext('validate non-verbose output wrapping', () async { testUsingContext('validate non-verbose output wrapping', () async {
expect(await FakeDoctor().diagnose(verbose: false), isFalse); final BufferLogger wrapLogger = BufferLogger.test(
expect(testLogger.statusText, equals( outputPreferences: OutputPreferences(wrapText: true, wrapColumn: 30),
);
expect(await FakeDoctor(wrapLogger).diagnose(verbose: false), isFalse);
expect(wrapLogger.statusText, equals(
'Doctor summary (to see all\n' 'Doctor summary (to see all\n'
'details, run flutter doctor\n' 'details, run flutter doctor\n'
'-v):\n' '-v):\n'
...@@ -616,13 +624,15 @@ void main() { ...@@ -616,13 +624,15 @@ void main() {
'' ''
)); ));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
OutputPreferences: () => OutputPreferences(wrapText: true, wrapColumn: 30),
Platform: _kNoColorOutputPlatform, Platform: _kNoColorOutputPlatform,
}); });
testUsingContext('validate verbose output wrapping', () async { testUsingContext('validate verbose output wrapping', () async {
expect(await FakeDoctor().diagnose(verbose: true), isFalse); final BufferLogger wrapLogger = BufferLogger.test(
expect(testLogger.statusText, equals( outputPreferences: OutputPreferences(wrapText: true, wrapColumn: 30),
);
expect(await FakeDoctor(wrapLogger).diagnose(verbose: true), isFalse);
expect(wrapLogger.statusText, equals(
'[✓] Passing Validator (with\n' '[✓] Passing Validator (with\n'
' statusInfo)\n' ' statusInfo)\n'
' • A helpful message\n' ' • A helpful message\n'
...@@ -661,15 +671,14 @@ void main() { ...@@ -661,15 +671,14 @@ void main() {
'' ''
)); ));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
OutputPreferences: () => OutputPreferences(wrapText: true, wrapColumn: 30),
Platform: _kNoColorOutputPlatform, Platform: _kNoColorOutputPlatform,
}); });
group('doctor with grouped validators', () { group('doctor with grouped validators', () {
testUsingContext('validate diagnose combines validator output', () async { testUsingContext('validate diagnose combines validator output', () async {
expect(await FakeGroupedDoctor().diagnose(), isTrue); expect(await FakeGroupedDoctor(logger).diagnose(), isTrue);
expect(testLogger.statusText, equals( expect(logger.statusText, equals(
'[✓] Category 1\n' '[✓] Category 1\n'
' • A helpful message\n' ' • A helpful message\n'
' • A helpful message\n' ' • A helpful message\n'
...@@ -684,8 +693,8 @@ void main() { ...@@ -684,8 +693,8 @@ void main() {
testUsingContext('validate merging assigns statusInfo and title', () async { testUsingContext('validate merging assigns statusInfo and title', () async {
// There are two subvalidators. Only the second contains statusInfo. // There are two subvalidators. Only the second contains statusInfo.
expect(await FakeGroupedDoctorWithStatus().diagnose(), isTrue); expect(await FakeGroupedDoctorWithStatus(logger).diagnose(), isTrue);
expect(testLogger.statusText, equals( expect(logger.statusText, equals(
'[✓] First validator title (A status message)\n' '[✓] First validator title (A status message)\n'
' • A helpful message\n' ' • A helpful message\n'
' • A different message\n' ' • A different message\n'
...@@ -702,48 +711,48 @@ void main() { ...@@ -702,48 +711,48 @@ void main() {
final MissingGroupedValidator missing = MissingGroupedValidator('Category'); final MissingGroupedValidator missing = MissingGroupedValidator('Category');
testUsingContext('validate installed + installed = installed', () async { testUsingContext('validate installed + installed = installed', () async {
expect(await FakeSmallGroupDoctor(installed, installed).diagnose(), isTrue); expect(await FakeSmallGroupDoctor(logger, installed, installed).diagnose(), isTrue);
expect(testLogger.statusText, startsWith('[✓]')); expect(logger.statusText, startsWith('[✓]'));
}, overrides: noColorTerminalOverride); }, overrides: noColorTerminalOverride);
testUsingContext('validate installed + partial = partial', () async { testUsingContext('validate installed + partial = partial', () async {
expect(await FakeSmallGroupDoctor(installed, partial).diagnose(), isTrue); expect(await FakeSmallGroupDoctor(logger, installed, partial).diagnose(), isTrue);
expect(testLogger.statusText, startsWith('[!]')); expect(logger.statusText, startsWith('[!]'));
}, overrides: noColorTerminalOverride); }, overrides: noColorTerminalOverride);
testUsingContext('validate installed + missing = partial', () async { testUsingContext('validate installed + missing = partial', () async {
expect(await FakeSmallGroupDoctor(installed, missing).diagnose(), isTrue); expect(await FakeSmallGroupDoctor(logger, installed, missing).diagnose(), isTrue);
expect(testLogger.statusText, startsWith('[!]')); expect(logger.statusText, startsWith('[!]'));
}, overrides: noColorTerminalOverride); }, overrides: noColorTerminalOverride);
testUsingContext('validate partial + installed = partial', () async { testUsingContext('validate partial + installed = partial', () async {
expect(await FakeSmallGroupDoctor(partial, installed).diagnose(), isTrue); expect(await FakeSmallGroupDoctor(logger, partial, installed).diagnose(), isTrue);
expect(testLogger.statusText, startsWith('[!]')); expect(logger.statusText, startsWith('[!]'));
}, overrides: noColorTerminalOverride); }, overrides: noColorTerminalOverride);
testUsingContext('validate partial + partial = partial', () async { testUsingContext('validate partial + partial = partial', () async {
expect(await FakeSmallGroupDoctor(partial, partial).diagnose(), isTrue); expect(await FakeSmallGroupDoctor(logger, partial, partial).diagnose(), isTrue);
expect(testLogger.statusText, startsWith('[!]')); expect(logger.statusText, startsWith('[!]'));
}, overrides: noColorTerminalOverride); }, overrides: noColorTerminalOverride);
testUsingContext('validate partial + missing = partial', () async { testUsingContext('validate partial + missing = partial', () async {
expect(await FakeSmallGroupDoctor(partial, missing).diagnose(), isTrue); expect(await FakeSmallGroupDoctor(logger, partial, missing).diagnose(), isTrue);
expect(testLogger.statusText, startsWith('[!]')); expect(logger.statusText, startsWith('[!]'));
}, overrides: noColorTerminalOverride); }, overrides: noColorTerminalOverride);
testUsingContext('validate missing + installed = partial', () async { testUsingContext('validate missing + installed = partial', () async {
expect(await FakeSmallGroupDoctor(missing, installed).diagnose(), isTrue); expect(await FakeSmallGroupDoctor(logger, missing, installed).diagnose(), isTrue);
expect(testLogger.statusText, startsWith('[!]')); expect(logger.statusText, startsWith('[!]'));
}, overrides: noColorTerminalOverride); }, overrides: noColorTerminalOverride);
testUsingContext('validate missing + partial = partial', () async { testUsingContext('validate missing + partial = partial', () async {
expect(await FakeSmallGroupDoctor(missing, partial).diagnose(), isTrue); expect(await FakeSmallGroupDoctor(logger, missing, partial).diagnose(), isTrue);
expect(testLogger.statusText, startsWith('[!]')); expect(logger.statusText, startsWith('[!]'));
}, overrides: noColorTerminalOverride); }, overrides: noColorTerminalOverride);
testUsingContext('validate missing + missing = missing', () async { testUsingContext('validate missing + missing = missing', () async {
expect(await FakeSmallGroupDoctor(missing, missing).diagnose(), isFalse); expect(await FakeSmallGroupDoctor(logger, missing, missing).diagnose(), isFalse);
expect(testLogger.statusText, startsWith('[✗]')); expect(logger.statusText, startsWith('[✗]'));
}, overrides: noColorTerminalOverride); }, overrides: noColorTerminalOverride);
}); });
...@@ -912,6 +921,8 @@ class AsyncCrashingValidator extends DoctorValidator { ...@@ -912,6 +921,8 @@ class AsyncCrashingValidator extends DoctorValidator {
/// A doctor that fails with a missing [ValidationResult]. /// A doctor that fails with a missing [ValidationResult].
class FakeDoctor extends Doctor { class FakeDoctor extends Doctor {
FakeDoctor(Logger logger) : super(logger: logger);
List<DoctorValidator> _validators; List<DoctorValidator> _validators;
@override @override
...@@ -928,6 +939,8 @@ class FakeDoctor extends Doctor { ...@@ -928,6 +939,8 @@ class FakeDoctor extends Doctor {
/// A doctor that should pass, but still has issues in some categories. /// A doctor that should pass, but still has issues in some categories.
class FakePassingDoctor extends Doctor { class FakePassingDoctor extends Doctor {
FakePassingDoctor(Logger logger) : super(logger: logger);
List<DoctorValidator> _validators; List<DoctorValidator> _validators;
@override @override
List<DoctorValidator> get validators { List<DoctorValidator> get validators {
...@@ -943,6 +956,8 @@ class FakePassingDoctor extends Doctor { ...@@ -943,6 +956,8 @@ class FakePassingDoctor extends Doctor {
/// A doctor that should pass, but still has 1 issue to test the singular of /// A doctor that should pass, but still has 1 issue to test the singular of
/// categories. /// categories.
class FakeSinglePassingDoctor extends Doctor { class FakeSinglePassingDoctor extends Doctor {
FakeSinglePassingDoctor(Logger logger) : super(logger: logger);
List<DoctorValidator> _validators; List<DoctorValidator> _validators;
@override @override
List<DoctorValidator> get validators { List<DoctorValidator> get validators {
...@@ -954,6 +969,8 @@ class FakeSinglePassingDoctor extends Doctor { ...@@ -954,6 +969,8 @@ class FakeSinglePassingDoctor extends Doctor {
/// A doctor that passes and has no issues anywhere. /// A doctor that passes and has no issues anywhere.
class FakeQuietDoctor extends Doctor { class FakeQuietDoctor extends Doctor {
FakeQuietDoctor(Logger logger) : super(logger: logger);
List<DoctorValidator> _validators; List<DoctorValidator> _validators;
@override @override
List<DoctorValidator> get validators { List<DoctorValidator> get validators {
...@@ -968,6 +985,8 @@ class FakeQuietDoctor extends Doctor { ...@@ -968,6 +985,8 @@ class FakeQuietDoctor extends Doctor {
/// A doctor with a validator that throws an exception. /// A doctor with a validator that throws an exception.
class FakeCrashingDoctor extends Doctor { class FakeCrashingDoctor extends Doctor {
FakeCrashingDoctor(Logger logger) : super(logger: logger);
List<DoctorValidator> _validators; List<DoctorValidator> _validators;
@override @override
List<DoctorValidator> get validators { List<DoctorValidator> get validators {
...@@ -985,7 +1004,7 @@ class FakeCrashingDoctor extends Doctor { ...@@ -985,7 +1004,7 @@ class FakeCrashingDoctor extends Doctor {
/// A doctor with a validator that throws an exception. /// A doctor with a validator that throws an exception.
class FakeAsyncCrashingDoctor extends Doctor { class FakeAsyncCrashingDoctor extends Doctor {
FakeAsyncCrashingDoctor(this._time); FakeAsyncCrashingDoctor(this._time, Logger logger) : super(logger: logger);
final FakeAsync _time; final FakeAsync _time;
...@@ -1070,6 +1089,8 @@ class PassingGroupedValidatorWithStatus extends DoctorValidator { ...@@ -1070,6 +1089,8 @@ class PassingGroupedValidatorWithStatus extends DoctorValidator {
/// A doctor that has two groups of two validators each. /// A doctor that has two groups of two validators each.
class FakeGroupedDoctor extends Doctor { class FakeGroupedDoctor extends Doctor {
FakeGroupedDoctor(Logger logger) : super(logger: logger);
List<DoctorValidator> _validators; List<DoctorValidator> _validators;
@override @override
List<DoctorValidator> get validators { List<DoctorValidator> get validators {
...@@ -1087,6 +1108,8 @@ class FakeGroupedDoctor extends Doctor { ...@@ -1087,6 +1108,8 @@ class FakeGroupedDoctor extends Doctor {
} }
class FakeGroupedDoctorWithStatus extends Doctor { class FakeGroupedDoctorWithStatus extends Doctor {
FakeGroupedDoctorWithStatus(Logger logger) : super(logger: logger);
List<DoctorValidator> _validators; List<DoctorValidator> _validators;
@override @override
List<DoctorValidator> get validators { List<DoctorValidator> get validators {
...@@ -1100,6 +1123,8 @@ class FakeGroupedDoctorWithStatus extends Doctor { ...@@ -1100,6 +1123,8 @@ class FakeGroupedDoctorWithStatus extends Doctor {
} }
class FlutterValidatorDoctor extends Doctor { class FlutterValidatorDoctor extends Doctor {
FlutterValidatorDoctor(Logger logger) : super(logger: logger);
List<DoctorValidator> _validators; List<DoctorValidator> _validators;
@override @override
List<DoctorValidator> get validators { List<DoctorValidator> get validators {
...@@ -1112,7 +1137,7 @@ class FlutterValidatorDoctor extends Doctor { ...@@ -1112,7 +1137,7 @@ class FlutterValidatorDoctor extends Doctor {
/// A doctor that takes any two validators. Used to check behavior when /// A doctor that takes any two validators. Used to check behavior when
/// merging ValidationTypes (installed, missing, partial). /// merging ValidationTypes (installed, missing, partial).
class FakeSmallGroupDoctor extends Doctor { class FakeSmallGroupDoctor extends Doctor {
FakeSmallGroupDoctor(DoctorValidator val1, DoctorValidator val2) { FakeSmallGroupDoctor(Logger logger, DoctorValidator val1, DoctorValidator val2) : super(logger: logger) {
_validators = <DoctorValidator>[GroupedValidator(<DoctorValidator>[val1, val2])]; _validators = <DoctorValidator>[GroupedValidator(<DoctorValidator>[val1, val2])];
} }
......
...@@ -109,7 +109,7 @@ void testUsingContext( ...@@ -109,7 +109,7 @@ void testUsingContext(
AnsiTerminal: () => AnsiTerminal(platform: globals.platform, stdio: globals.stdio), AnsiTerminal: () => AnsiTerminal(platform: globals.platform, stdio: globals.stdio),
Config: () => buildConfig(globals.fs), Config: () => buildConfig(globals.fs),
DeviceManager: () => FakeDeviceManager(), DeviceManager: () => FakeDeviceManager(),
Doctor: () => FakeDoctor(), Doctor: () => FakeDoctor(globals.logger),
FlutterVersion: () => MockFlutterVersion(), FlutterVersion: () => MockFlutterVersion(),
HttpClient: () => MockHttpClient(), HttpClient: () => MockHttpClient(),
IOSSimulatorUtils: () { IOSSimulatorUtils: () {
...@@ -261,6 +261,8 @@ class FakeAndroidLicenseValidator extends AndroidLicenseValidator { ...@@ -261,6 +261,8 @@ class FakeAndroidLicenseValidator extends AndroidLicenseValidator {
} }
class FakeDoctor extends Doctor { class FakeDoctor extends Doctor {
FakeDoctor(Logger logger) : super(logger: logger);
// True for testing. // True for testing.
@override @override
bool get canListAnything => true; bool get canListAnything => true;
......
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