[flutter_tool] Refactor Logger and Terminal to (mostly) no longer depend directly on context (#47269)
diff --git a/packages/flutter_tools/lib/runner.dart b/packages/flutter_tools/lib/runner.dart index 2285c2a..c08a004 100644 --- a/packages/flutter_tools/lib/runner.dart +++ b/packages/flutter_tools/lib/runner.dart
@@ -15,6 +15,7 @@ import 'src/base/io.dart'; import 'src/base/logger.dart'; import 'src/base/process.dart'; +import 'src/base/terminal.dart'; import 'src/base/utils.dart'; import 'src/context_runner.dart'; import 'src/doctor.dart'; @@ -223,7 +224,10 @@ Future<String> _doctorText() async { try { - final BufferLogger logger = BufferLogger(); + final BufferLogger logger = BufferLogger( + terminal: terminal, + outputPreferences: outputPreferences, + ); await context.run<bool>( body: () => doctor.diagnose(verbose: true, showColor: false),
diff --git a/packages/flutter_tools/lib/src/base/io.dart b/packages/flutter_tools/lib/src/base/io.dart index 4748512..40ca323 100644 --- a/packages/flutter_tools/lib/src/base/io.dart +++ b/packages/flutter_tools/lib/src/base/io.dart
@@ -247,11 +247,10 @@ bool get supportsAnsiEscapes => hasTerminal && io.stdout.supportsAnsiEscapes; } -Stdio get stdio => context.get<Stdio>() ?? const Stdio(); -io.Stdout get stdout => stdio.stdout; -Stream<List<int>> get stdin => stdio.stdin; -io.IOSink get stderr => stdio.stderr; -bool get stdinHasTerminal => stdio.stdinHasTerminal; +io.Stdout get stdout => globals.stdio.stdout; +Stream<List<int>> get stdin => globals.stdio.stdin; +io.IOSink get stderr => globals.stdio.stderr; +bool get stdinHasTerminal => globals.stdio.stdinHasTerminal; /// An overridable version of io.ProcessInfo. abstract class ProcessInfo {
diff --git a/packages/flutter_tools/lib/src/base/logger.dart b/packages/flutter_tools/lib/src/base/logger.dart index 0291f5a..6dbebee 100644 --- a/packages/flutter_tools/lib/src/base/logger.dart +++ b/packages/flutter_tools/lib/src/base/logger.dart
@@ -8,8 +8,8 @@ import '../base/context.dart'; import '../globals.dart' as globals; -import 'io.dart'; -import 'terminal.dart'; +import 'io.dart' hide stderr, stdin, stdout; +import 'terminal.dart' show AnsiTerminal, TerminalColor, OutputPreferences; import 'utils.dart'; const int kDefaultStatusPadding = 59; @@ -44,9 +44,15 @@ bool quiet = false; - bool get supportsColor => globals.terminal.supportsColor; + bool get supportsColor; - bool get hasTerminal => stdio.hasTerminal; + bool get hasTerminal; + + AnsiTerminal get _terminal; + + OutputPreferences get _outputPreferences; + + TimeoutConfiguration get _timeoutConfiguration; /// Display an error `message` to the user. Commands should use this if they /// fail in some way. @@ -155,12 +161,37 @@ } class StdoutLogger extends Logger { + StdoutLogger({ + @required AnsiTerminal terminal, + @required Stdio stdio, + @required OutputPreferences outputPreferences, + @required TimeoutConfiguration timeoutConfiguration, + }) + : _stdio = stdio, + _terminal = terminal, + _timeoutConfiguration = timeoutConfiguration, + _outputPreferences = outputPreferences; + + @override + final AnsiTerminal _terminal; + @override + final OutputPreferences _outputPreferences; + @override + final TimeoutConfiguration _timeoutConfiguration; + final Stdio _stdio; + Status _status; @override bool get isVerbose => false; @override + bool get supportsColor => _terminal.supportsColor; + + @override + bool get hasTerminal => _stdio.stdinHasTerminal; + + @override void printError( String message, { StackTrace stackTrace, @@ -172,14 +203,19 @@ }) { _status?.pause(); message ??= ''; - message = wrapText(message, indent: indent, hangingIndent: hangingIndent, shouldWrap: wrap); + message = wrapText(message, + indent: indent, + hangingIndent: hangingIndent, + shouldWrap: wrap ?? _outputPreferences.wrapText, + columnWidth: _outputPreferences.wrapColumn, + ); if (emphasis == true) { - message = globals.terminal.bolden(message); + message = _terminal.bolden(message); } - message = globals.terminal.color(message, color ?? TerminalColor.red); - stderr.writeln(message); + message = _terminal.color(message, color ?? TerminalColor.red); + _stdio.stderr.writeln(message); if (stackTrace != null) { - stderr.writeln(stackTrace.toString()); + _stdio.stderr.writeln(stackTrace.toString()); } _status?.resume(); } @@ -196,12 +232,17 @@ }) { _status?.pause(); message ??= ''; - message = wrapText(message, indent: indent, hangingIndent: hangingIndent, shouldWrap: wrap); + message = wrapText(message, + indent: indent, + hangingIndent: hangingIndent, + shouldWrap: wrap ?? _outputPreferences.wrapText, + columnWidth: _outputPreferences.wrapColumn, + ); if (emphasis == true) { - message = globals.terminal.bolden(message); + message = _terminal.bolden(message); } if (color != null) { - message = globals.terminal.color(message, color); + message = _terminal.color(message, color); } if (newline != false) { message = '$message\n'; @@ -212,7 +253,7 @@ @protected void writeToStdOut(String message) { - stdout.write(message); + _stdio.stdout.write(message); } @override @@ -232,15 +273,18 @@ return SilentStatus( timeout: timeout, onFinish: _clearStatus, + timeoutConfiguration: _timeoutConfiguration )..start(); } - if (globals.terminal.supportsColor) { + if (supportsColor) { _status = AnsiStatus( message: message, timeout: timeout, multilineOutput: multilineOutput, padding: progressIndicatorPadding, onFinish: _clearStatus, + stdio: _stdio, + timeoutConfiguration: _timeoutConfiguration, )..start(); } else { _status = SummaryStatus( @@ -248,6 +292,8 @@ timeout: timeout, padding: progressIndicatorPadding, onFinish: _clearStatus, + stdio: _stdio, + timeoutConfiguration: _timeoutConfiguration, )..start(); } return _status; @@ -270,10 +316,22 @@ /// fonts, should be replaced by this class with printable symbols. Otherwise, /// they will show up as the unrepresentable character symbol '�'. class WindowsStdoutLogger extends StdoutLogger { + WindowsStdoutLogger({ + @required AnsiTerminal terminal, + @required Stdio stdio, + @required OutputPreferences outputPreferences, + @required TimeoutConfiguration timeoutConfiguration, + }) : super( + terminal: terminal, + stdio: stdio, + outputPreferences: outputPreferences, + timeoutConfiguration: timeoutConfiguration, + ); + @override void writeToStdOut(String message) { // TODO(jcollins-g): wrong abstraction layer for this, move to [Stdio]. - stdout.write(message + _stdio.stdout.write(message .replaceAll('✗', 'X') .replaceAll('✓', '√') ); @@ -281,9 +339,29 @@ } class BufferLogger extends Logger { + BufferLogger({ + @required AnsiTerminal terminal, + @required OutputPreferences outputPreferences, + TimeoutConfiguration timeoutConfiguration = const TimeoutConfiguration() + }) : _outputPreferences = outputPreferences, + _terminal = terminal, + _timeoutConfiguration = timeoutConfiguration; + + @override + final OutputPreferences _outputPreferences; + + @override + final AnsiTerminal _terminal; + + @override + final TimeoutConfiguration _timeoutConfiguration; + @override bool get isVerbose => false; + @override + bool get supportsColor => _terminal.supportsColor; + final StringBuffer _error = StringBuffer(); final StringBuffer _status = StringBuffer(); final StringBuffer _trace = StringBuffer(); @@ -305,8 +383,13 @@ int hangingIndent, bool wrap, }) { - _error.writeln(globals.terminal.color( - wrapText(message, indent: indent, hangingIndent: hangingIndent, shouldWrap: wrap), + _error.writeln(_terminal.color( + wrapText(message, + indent: indent, + hangingIndent: hangingIndent, + shouldWrap: wrap ?? _outputPreferences.wrapText, + columnWidth: _outputPreferences.wrapColumn, + ), color ?? TerminalColor.red, )); } @@ -322,9 +405,19 @@ bool wrap, }) { if (newline != false) { - _status.writeln(wrapText(message, indent: indent, hangingIndent: hangingIndent, shouldWrap: wrap)); + _status.writeln(wrapText(message, + indent: indent, + hangingIndent: hangingIndent, + shouldWrap: wrap ?? _outputPreferences.wrapText, + columnWidth: _outputPreferences.wrapColumn, + )); } else { - _status.write(wrapText(message, indent: indent, hangingIndent: hangingIndent, shouldWrap: wrap)); + _status.write(wrapText(message, + indent: indent, + hangingIndent: hangingIndent, + shouldWrap: wrap ?? _outputPreferences.wrapText, + columnWidth: _outputPreferences.wrapColumn, + )); } } @@ -341,7 +434,11 @@ }) { assert(progressIndicatorPadding != null); printStatus(message); - return SilentStatus(timeout: timeout)..start(); + return SilentStatus( + timeout: timeout, + timeoutConfiguration: _timeoutConfiguration, + + )..start(); } /// Clears all buffers. @@ -356,13 +453,23 @@ } class VerboseLogger extends Logger { - VerboseLogger(this.parent) : assert(globals.terminal != null) { + VerboseLogger(this.parent, { @required Stopwatch stopwatch }) : + _stopwatch = stopwatch ?? context.get<Stopwatch>() ?? Stopwatch() { _stopwatch.start(); } final Logger parent; - final Stopwatch _stopwatch = context.get<Stopwatch>() ?? Stopwatch(); + final Stopwatch _stopwatch; + + @override + AnsiTerminal get _terminal => parent._terminal; + + @override + OutputPreferences get _outputPreferences => parent._outputPreferences; + + @override + TimeoutConfiguration get _timeoutConfiguration => parent._timeoutConfiguration; @override bool get isVerbose => true; @@ -379,7 +486,12 @@ }) { _emit( _LogType.error, - wrapText(message, indent: indent, hangingIndent: hangingIndent, shouldWrap: wrap), + wrapText(message, + indent: indent, + hangingIndent: hangingIndent, + shouldWrap: wrap ?? _outputPreferences.wrapText, + columnWidth: _outputPreferences.wrapColumn, + ), stackTrace, ); } @@ -394,7 +506,12 @@ int hangingIndent, bool wrap, }) { - _emit(_LogType.status, wrapText(message, indent: indent, hangingIndent: hangingIndent, shouldWrap: wrap)); + _emit(_LogType.status, wrapText(message, + indent: indent, + hangingIndent: hangingIndent, + shouldWrap: wrap ?? _outputPreferences.wrapText, + columnWidth: _outputPreferences.wrapColumn, + )); } @override @@ -415,9 +532,10 @@ final Stopwatch timer = Stopwatch()..start(); return SilentStatus( timeout: timeout, + timeoutConfiguration: _timeoutConfiguration, onFinish: () { String time; - if (timeout == null || timeout > timeoutConfiguration.fastOperation) { + if (timeout == null || timeout > _timeoutConfiguration.fastOperation) { time = getElapsedAsSeconds(timer.elapsed); } else { time = getElapsedAsMilliseconds(timer.elapsed); @@ -446,7 +564,7 @@ } else { prefix = '+$millis ms'.padLeft(prefixWidth); if (millis >= 100) { - prefix = globals.terminal.bolden(prefix); + prefix = _terminal.bolden(prefix); } } prefix = '[$prefix] '; @@ -455,12 +573,12 @@ final String indentMessage = message.replaceAll('\n', '\n$indent'); if (type == _LogType.error) { - parent.printError(prefix + globals.terminal.bolden(indentMessage)); + parent.printError(prefix + _terminal.bolden(indentMessage)); if (stackTrace != null) { parent.printError(indent + stackTrace.toString().replaceAll('\n', '\n$indent')); } } else if (type == _LogType.status) { - parent.printStatus(prefix + globals.terminal.bolden(indentMessage)); + parent.printStatus(prefix + _terminal.bolden(indentMessage)); } else { parent.printStatus(prefix + indentMessage); } @@ -468,6 +586,12 @@ @override void sendEvent(String name, [Map<String, dynamic> args]) { } + + @override + bool get supportsColor => parent.supportsColor; + + @override + bool get hasTerminal => parent.hasTerminal; } enum _LogType { error, status, trace } @@ -495,12 +619,17 @@ /// Generally, consider `logger.startProgress` instead of directly creating /// a [Status] or one of its subclasses. abstract class Status { - Status({ @required this.timeout, this.onFinish }); + Status({ + @required this.timeout, + @required TimeoutConfiguration timeoutConfiguration, + this.onFinish, + }) : _timeoutConfiguration = timeoutConfiguration; /// A [SilentStatus] or an [AnsiSpinner] (depending on whether the /// terminal is fancy enough), already started. factory Status.withSpinner({ @required Duration timeout, + @required TimeoutConfiguration timeoutConfiguration, VoidCallback onFinish, SlowWarningCallback slowWarningCallback, }) { @@ -509,13 +638,19 @@ timeout: timeout, onFinish: onFinish, slowWarningCallback: slowWarningCallback, + timeoutConfiguration: timeoutConfiguration, )..start(); } - return SilentStatus(timeout: timeout, onFinish: onFinish)..start(); + return SilentStatus( + timeout: timeout, + onFinish: onFinish, + timeoutConfiguration: timeoutConfiguration, + )..start(); } final Duration timeout; final VoidCallback onFinish; + final TimeoutConfiguration _timeoutConfiguration; @protected final Stopwatch _stopwatch = context.get<Stopwatch>() ?? Stopwatch(); @@ -526,7 +661,7 @@ @protected String get elapsedTime { - if (timeout == null || timeout > timeoutConfiguration.fastOperation) { + if (timeout == null || timeout > _timeoutConfiguration.fastOperation) { return getElapsedAsSeconds(_stopwatch.elapsed); } return getElapsedAsMilliseconds(_stopwatch.elapsed); @@ -568,8 +703,13 @@ class SilentStatus extends Status { SilentStatus({ @required Duration timeout, + @required TimeoutConfiguration timeoutConfiguration, VoidCallback onFinish, - }) : super(timeout: timeout, onFinish: onFinish); + }) : super( + timeout: timeout, + onFinish: onFinish, + timeoutConfiguration: timeoutConfiguration, + ); } /// Constructor writes [message] to [stdout]. On [cancel] or [stop], will call @@ -580,12 +720,16 @@ @required Duration timeout, this.padding = kDefaultStatusPadding, VoidCallback onFinish, + Stdio stdio, + @required TimeoutConfiguration timeoutConfiguration, }) : assert(message != null), assert(padding != null), - super(timeout: timeout, onFinish: onFinish); + _stdio = stdio ?? globals.stdio, + super(timeout: timeout, onFinish: onFinish, timeoutConfiguration: timeoutConfiguration); final String message; final int padding; + final Stdio _stdio; bool _messageShowingOnCurrentLine = false; @@ -597,7 +741,7 @@ void _printMessage() { assert(!_messageShowingOnCurrentLine); - stdout.write('${message.padRight(padding)} '); + _stdio.stdout.write('${message.padRight(padding)} '); _messageShowingOnCurrentLine = true; } @@ -608,14 +752,14 @@ } super.stop(); writeSummaryInformation(); - stdout.write('\n'); + _stdio.stdout.write('\n'); } @override void cancel() { super.cancel(); if (_messageShowingOnCurrentLine) { - stdout.write('\n'); + _stdio.stdout.write('\n'); } } @@ -628,16 +772,16 @@ /// Examples: ` 0.5s`, ` 150ms`, ` 1,600ms`, ` 3.1s (!)` void writeSummaryInformation() { assert(_messageShowingOnCurrentLine); - stdout.write(elapsedTime.padLeft(_kTimePadding)); + _stdio.stdout.write(elapsedTime.padLeft(_kTimePadding)); if (seemsSlow) { - stdout.write(' (!)'); + _stdio.stdout.write(' (!)'); } } @override void pause() { super.pause(); - stdout.write('\n'); + _stdio.stdout.write('\n'); _messageShowingOnCurrentLine = false; } } @@ -652,10 +796,14 @@ @required Duration timeout, VoidCallback onFinish, this.slowWarningCallback, - }) : super(timeout: timeout, onFinish: onFinish); + Stdio stdio, + @required TimeoutConfiguration timeoutConfiguration, + }) : _stdio = stdio ?? globals.stdio, + super(timeout: timeout, onFinish: onFinish, timeoutConfiguration: timeoutConfiguration); final String _backspaceChar = '\b'; final String _clearChar = ' '; + final Stdio _stdio; bool timedOut = false; @@ -688,7 +836,7 @@ } void _startSpinner() { - stdout.write(_clear); // for _callback to backspace over + _stdio.stdout.write(_clear); // for _callback to backspace over timer = Timer.periodic(const Duration(milliseconds: 100), _callback); _callback(timer); } @@ -697,21 +845,21 @@ assert(this.timer == timer); assert(timer != null); assert(timer.isActive); - stdout.write(_backspace); + _stdio.stdout.write(_backspace); ticks += 1; if (seemsSlow) { if (!timedOut) { timedOut = true; - stdout.write('$_clear\n'); + _stdio.stdout.write('$_clear\n'); } if (slowWarningCallback != null) { _slowWarning = slowWarningCallback(); } else { _slowWarning = _defaultSlowWarning; } - stdout.write(_slowWarning); + _stdio.stdout.write(_slowWarning); } - stdout.write('${_clearChar * spinnerIndent}$_currentAnimationFrame'); + _stdio.stdout.write('${_clearChar * spinnerIndent}$_currentAnimationFrame'); } @override @@ -725,7 +873,7 @@ } void _clearSpinner() { - stdout.write('$_backspace$_clear$_backspace'); + _stdio.stdout.write('$_backspace$_clear$_backspace'); } @override @@ -759,10 +907,12 @@ this.multilineOutput = false, this.padding = kDefaultStatusPadding, VoidCallback onFinish, + Stdio stdio, + TimeoutConfiguration timeoutConfiguration, }) : assert(message != null), assert(multilineOutput != null), assert(padding != null), - super(timeout: timeout, onFinish: onFinish); + super(timeout: timeout, onFinish: onFinish, stdio: stdio, timeoutConfiguration: timeoutConfiguration); final String message; final bool multilineOutput; @@ -784,20 +934,20 @@ void _startStatus() { final String line = '${message.padRight(padding)}$_margin'; _totalMessageLength = line.length; - stdout.write(line); + _stdio.stdout.write(line); } @override void stop() { super.stop(); writeSummaryInformation(); - stdout.write('\n'); + _stdio.stdout.write('\n'); } @override void cancel() { super.cancel(); - stdout.write('\n'); + _stdio.stdout.write('\n'); } /// Print summary information when a task is done. @@ -808,16 +958,16 @@ /// line before writing the elapsed time. void writeSummaryInformation() { if (multilineOutput) { - stdout.write('\n${'$message Done'.padRight(padding)}$_margin'); + _stdio.stdout.write('\n${'$message Done'.padRight(padding)}$_margin'); } - stdout.write(elapsedTime.padLeft(_kTimePadding)); + _stdio.stdout.write(elapsedTime.padLeft(_kTimePadding)); if (seemsSlow) { - stdout.write(' (!)'); + _stdio.stdout.write(' (!)'); } } void _clearStatus() { - stdout.write('${_backspaceChar * _totalMessageLength}${_clearChar * _totalMessageLength}${_backspaceChar * _totalMessageLength}'); + _stdio.stdout.write('${_backspaceChar * _totalMessageLength}${_clearChar * _totalMessageLength}${_backspaceChar * _totalMessageLength}'); } @override
diff --git a/packages/flutter_tools/lib/src/base/terminal.dart b/packages/flutter_tools/lib/src/base/terminal.dart index e017556..5a0db58 100644 --- a/packages/flutter_tools/lib/src/base/terminal.dart +++ b/packages/flutter_tools/lib/src/base/terminal.dart
@@ -4,10 +4,14 @@ import 'dart:async'; +import 'package:meta/meta.dart'; +import 'package:platform/platform.dart'; + import '../convert.dart'; import '../globals.dart' as globals; import 'context.dart'; import 'io.dart' as io; +import 'logger.dart'; enum TerminalColor { red, @@ -41,12 +45,13 @@ bool wrapText, int wrapColumn, bool showColor, - }) : wrapText = wrapText ?? io.stdio.hasTerminal, + }) : wrapText = wrapText ?? globals.stdio.hasTerminal, _overrideWrapColumn = wrapColumn, showColor = showColor ?? globals.platform.stdoutSupportsAnsi ?? false; /// A version of this class for use in tests. - OutputPreferences.test() : wrapText = false, _overrideWrapColumn = null, showColor = false; + OutputPreferences.test({this.wrapText = false, int wrapColumn = kDefaultTerminalColumns, this.showColor = false}) + : _overrideWrapColumn = wrapColumn; /// If [wrapText] is true, then any text sent to the context's [Logger] /// instance (e.g. from the [printError] or [printStatus] functions) will be @@ -66,7 +71,7 @@ /// terminal, or to [kDefaultTerminalColumns] if not writing to a terminal. final int _overrideWrapColumn; int get wrapColumn { - return _overrideWrapColumn ?? io.stdio.terminalColumns ?? kDefaultTerminalColumns; + return _overrideWrapColumn ?? globals.stdio.terminalColumns ?? kDefaultTerminalColumns; } /// Whether or not to output ANSI color codes when writing to the output @@ -81,6 +86,13 @@ } class AnsiTerminal { + AnsiTerminal({@required io.Stdio stdio, @required Platform platform}) + : _stdio = stdio, + _platform = platform; + + final io.Stdio _stdio; + final Platform _platform; + static const String bold = '\u001B[1m'; static const String resetAll = '\u001B[0m'; static const String resetColor = '\u001B[39m'; @@ -107,7 +119,8 @@ static String colorCode(TerminalColor color) => _colorMap[color]; - bool get supportsColor => globals.platform.stdoutSupportsAnsi ?? false; + bool get supportsColor => _platform.stdoutSupportsAnsi ?? false; + final RegExp _boldControls = RegExp('(${RegExp.escape(resetBold)}|${RegExp.escape(bold)})'); /// Whether we are interacting with the flutter tool via the terminal. @@ -159,10 +172,10 @@ String clearScreen() => supportsColor ? clear : '\n\n'; set singleCharMode(bool value) { - if (!io.stdinHasTerminal) { + if (!_stdio.stdinHasTerminal) { return; } - final io.Stdin stdin = io.stdin as io.Stdin; + final io.Stdin stdin = _stdio.stdin as io.Stdin; // The order of setting lineMode and echoMode is important on Windows. if (value) { stdin.echoMode = false; @@ -179,7 +192,7 @@ /// /// Useful when the console is in [singleCharMode]. Stream<String> get keystrokes { - _broadcastStdInString ??= io.stdin.transform<String>(const AsciiDecoder(allowInvalid: true)).asBroadcastStream(); + _broadcastStdInString ??= _stdio.stdin.transform<String>(const AsciiDecoder(allowInvalid: true)).asBroadcastStream(); return _broadcastStdInString; } @@ -198,6 +211,7 @@ /// If [usesTerminalUi] is false, throws a [StateError]. Future<String> promptForCharInput( List<String> acceptedCharacters, { + @required Logger logger, String prompt, int defaultChoiceIndex, bool displayAcceptedCharacters = true, @@ -220,14 +234,14 @@ singleCharMode = true; while (choice == null || choice.length > 1 || !acceptedCharacters.contains(choice)) { if (prompt != null) { - globals.printStatus(prompt, emphasis: true, newline: false); + logger.printStatus(prompt, emphasis: true, newline: false); if (displayAcceptedCharacters) { - globals.printStatus(' [${charactersToDisplay.join("|")}]', newline: false); + logger.printStatus(' [${charactersToDisplay.join("|")}]', newline: false); } - globals.printStatus(': ', emphasis: true, newline: false); + logger.printStatus(': ', emphasis: true, newline: false); } choice = await keystrokes.first; - globals.printStatus(choice); + logger.printStatus(choice); } singleCharMode = false; if (defaultChoiceIndex != null && choice == '\n') {
diff --git a/packages/flutter_tools/lib/src/base/utils.dart b/packages/flutter_tools/lib/src/base/utils.dart index b246d10..7bb93c8 100644 --- a/packages/flutter_tools/lib/src/base/utils.dart +++ b/packages/flutter_tools/lib/src/base/utils.dart
@@ -6,6 +6,7 @@ import 'dart:math' show Random, max; import 'package:intl/intl.dart'; +import 'package:meta/meta.dart'; import '../convert.dart'; import '../globals.dart' as globals; @@ -395,7 +396,7 @@ /// If [outputPreferences.wrapText] is false, then the text will be returned /// simply split at the newlines, but not wrapped. If [shouldWrap] is specified, /// then it overrides the [outputPreferences.wrapText] setting. -List<String> _wrapTextAsLines(String text, { int start = 0, int columnWidth, bool shouldWrap }) { +List<String> _wrapTextAsLines(String text, { int start = 0, int columnWidth, @required bool shouldWrap }) { if (text == null || text.isEmpty) { return <String>['']; }
diff --git a/packages/flutter_tools/lib/src/commands/daemon.dart b/packages/flutter_tools/lib/src/commands/daemon.dart index 1b7cf43..b33a963 100644 --- a/packages/flutter_tools/lib/src/commands/daemon.dart +++ b/packages/flutter_tools/lib/src/commands/daemon.dart
@@ -974,7 +974,7 @@ }) { assert(timeout != null); printStatus(message); - return SilentStatus(timeout: timeout); + return SilentStatus(timeout: timeout, timeoutConfiguration: timeoutConfiguration); } void dispose() { @@ -983,6 +983,12 @@ @override void sendEvent(String name, [Map<String, dynamic> args]) { } + + @override + bool get supportsColor => throw UnimplementedError(); + + @override + bool get hasTerminal => false; } /// A running application, started by this daemon. @@ -1167,6 +1173,7 @@ _status = SilentStatus( timeout: timeout, + timeoutConfiguration: timeoutConfiguration, onFinish: () { _status = null; _sendProgressEvent(<String, dynamic>{ @@ -1206,6 +1213,12 @@ domain.sendEvent(name, args); } } + + @override + bool get supportsColor => throw UnimplementedError(); + + @override + bool get hasTerminal => false; } class LogMessage {
diff --git a/packages/flutter_tools/lib/src/context_runner.dart b/packages/flutter_tools/lib/src/context_runner.dart index e90cc72..a24d88d 100644 --- a/packages/flutter_tools/lib/src/context_runner.dart +++ b/packages/flutter_tools/lib/src/context_runner.dart
@@ -19,6 +19,7 @@ import 'base/os.dart'; import 'base/process.dart'; import 'base/signals.dart'; +import 'base/terminal.dart'; import 'base/time.dart'; import 'base/user_messages.dart'; import 'base/utils.dart'; @@ -101,7 +102,19 @@ IOSWorkflow: () => const IOSWorkflow(), KernelCompilerFactory: () => const KernelCompilerFactory(), LinuxWorkflow: () => const LinuxWorkflow(), - Logger: () => globals.platform.isWindows ? WindowsStdoutLogger() : StdoutLogger(), + Logger: () => globals.platform.isWindows + ? WindowsStdoutLogger( + terminal: globals.terminal, + stdio: globals.stdio, + outputPreferences: outputPreferences, + timeoutConfiguration: timeoutConfiguration, + ) + : StdoutLogger( + terminal: globals.terminal, + stdio: globals.stdio, + outputPreferences: outputPreferences, + timeoutConfiguration: timeoutConfiguration, + ), MacOSWorkflow: () => const MacOSWorkflow(), MDnsObservatoryDiscovery: () => MDnsObservatoryDiscovery(), OperatingSystemUtils: () => OperatingSystemUtils(),
diff --git a/packages/flutter_tools/lib/src/doctor.dart b/packages/flutter_tools/lib/src/doctor.dart index 366e2f1..a7cd3ec 100644 --- a/packages/flutter_tools/lib/src/doctor.dart +++ b/packages/flutter_tools/lib/src/doctor.dart
@@ -211,7 +211,12 @@ lineBuffer.write(' (${result.statusInfo})'); } - buffer.write(wrapText(lineBuffer.toString(), hangingIndent: result.leadingBox.length + 1)); + buffer.write(wrapText( + lineBuffer.toString(), + hangingIndent: result.leadingBox.length + 1, + columnWidth: outputPreferences.wrapColumn, + shouldWrap: outputPreferences.wrapText, + )); buffer.writeln(); if (result.type != ValidationType.installed) { @@ -253,6 +258,7 @@ final Status status = Status.withSpinner( timeout: timeoutConfiguration.fastOperation, slowWarningCallback: () => validator.slowWarning, + timeoutConfiguration: timeoutConfiguration, ); ValidationResult result; try {
diff --git a/packages/flutter_tools/lib/src/globals.dart b/packages/flutter_tools/lib/src/globals.dart index 777b844..f619882 100644 --- a/packages/flutter_tools/lib/src/globals.dart +++ b/packages/flutter_tools/lib/src/globals.dart
@@ -10,6 +10,7 @@ import 'base/context.dart'; import 'base/error_handling_file_system.dart'; import 'base/file_system.dart'; +import 'base/io.dart'; import 'base/logger.dart'; import 'base/terminal.dart'; import 'cache.dart'; @@ -103,4 +104,10 @@ return context?.get<AnsiTerminal>() ?? _defaultAnsiTerminal; } -final AnsiTerminal _defaultAnsiTerminal = AnsiTerminal(); +final AnsiTerminal _defaultAnsiTerminal = AnsiTerminal( + stdio: stdio, + platform: platform, +); + +/// The global Stdio wrapper. +Stdio get stdio => context.get<Stdio>() ?? const Stdio();
diff --git a/packages/flutter_tools/lib/src/ios/code_signing.dart b/packages/flutter_tools/lib/src/ios/code_signing.dart index fe375d4..992a0b7 100644 --- a/packages/flutter_tools/lib/src/ios/code_signing.dart +++ b/packages/flutter_tools/lib/src/ios/code_signing.dart
@@ -243,6 +243,7 @@ prompt: 'Please select a certificate for code signing', displayAcceptedCharacters: true, defaultChoiceIndex: 0, // Just pressing enter chooses the first one. + logger: globals.logger, ); if (choice == 'a') {
diff --git a/packages/flutter_tools/lib/src/ios/xcodeproj.dart b/packages/flutter_tools/lib/src/ios/xcodeproj.dart index 09b50ca..7b4203d 100644 --- a/packages/flutter_tools/lib/src/ios/xcodeproj.dart +++ b/packages/flutter_tools/lib/src/ios/xcodeproj.dart
@@ -284,6 +284,7 @@ }) async { final Status status = Status.withSpinner( timeout: timeoutConfiguration.fastOperation, + timeoutConfiguration: timeoutConfiguration, ); final List<String> showBuildSettingsCommand = <String>[ _executable,
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart index 7731bd0..ee6d56a 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
@@ -13,7 +13,6 @@ import '../base/common.dart'; import '../base/context.dart'; import '../base/file_system.dart'; -import '../base/io.dart' as io; import '../base/logger.dart'; import '../base/terminal.dart'; import '../base/user_messages.dart'; @@ -146,13 +145,20 @@ @override String get usageFooter { - return wrapText('Run "flutter help -v" for verbose help output, including less commonly used options.'); + return wrapText('Run "flutter help -v" for verbose help output, including less commonly used options.', + columnWidth: outputPreferences.wrapColumn, + shouldWrap: outputPreferences.wrapText, + ); } @override String get usage { final String usageWithoutDescription = super.usage.substring(description.length + 2); - return '${wrapText(description)}\n\n$usageWithoutDescription'; + final String prefix = wrapText(description, + shouldWrap: outputPreferences.wrapText, + columnWidth: outputPreferences.wrapColumn, + ); + return '$prefix\n\n$usageWithoutDescription'; } static String get defaultFlutterRoot { @@ -233,7 +239,7 @@ // Check for verbose. if (topLevelResults['verbose'] as bool) { // Override the logger. - contextOverrides[Logger] = VerboseLogger(globals.logger); + contextOverrides[Logger] = VerboseLogger(globals.logger, stopwatch: Stopwatch()); } // Don't set wrapColumns unless the user said to: if it's set, then all @@ -255,7 +261,7 @@ // anything, unless the user explicitly said to. final bool useWrapping = topLevelResults.wasParsed('wrap') ? topLevelResults['wrap'] as bool - : io.stdio.terminalColumns != null && topLevelResults['wrap'] as bool; + : globals.stdio.terminalColumns != null && topLevelResults['wrap'] as bool; contextOverrides[OutputPreferences] = OutputPreferences( wrapText: useWrapping, showColor: topLevelResults['color'] as bool,
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart index 7c1dec7..3ce4cd6 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart
@@ -699,7 +699,7 @@ int progressIndicatorPadding = kDefaultStatusPadding, }) { _log('[progress] $message'); - return SilentStatus(timeout: timeout)..start(); + return SilentStatus(timeout: timeout, timeoutConfiguration: timeoutConfiguration)..start(); } bool _interrupt = false; @@ -722,6 +722,12 @@ @override void sendEvent(String name, [Map<String, dynamic> args]) { } + + @override + bool get supportsColor => throw UnimplementedError(); + + @override + bool get hasTerminal => false; } class LoggerInterrupted implements Exception {
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/clean_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/clean_test.dart index 7145de8..eb7df8d 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/clean_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/clean_test.dart
@@ -7,7 +7,6 @@ import 'package:flutter_tools/src/base/context.dart'; import 'package:flutter_tools/src/base/file_system.dart'; -import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/commands/clean.dart'; import 'package:flutter_tools/src/ios/xcodeproj.dart'; import 'package:flutter_tools/src/macos/xcode.dart'; @@ -77,7 +76,6 @@ verify(mockFile.deleteSync(recursive: true)).called(1); }, overrides: <Type, Generator>{ Platform: () => windowsPlatform, - Logger: () => BufferLogger(), Xcode: () => mockXcode, }); @@ -94,7 +92,6 @@ verifyNever(mockFile.deleteSync(recursive: true)); }, overrides: <Type, Generator>{ Platform: () => windowsPlatform, - Logger: () => BufferLogger(), Xcode: () => mockXcode, }); }
diff --git a/packages/flutter_tools/test/general.shard/android/gradle_test.dart b/packages/flutter_tools/test/general.shard/android/gradle_test.dart index 83f69c7..347e626 100644 --- a/packages/flutter_tools/test/general.shard/android/gradle_test.dart +++ b/packages/flutter_tools/test/general.shard/android/gradle_test.dart
@@ -15,7 +15,6 @@ import 'package:flutter_tools/src/base/common.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/terminal.dart'; import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/cache.dart'; @@ -451,11 +450,9 @@ }); group('Config files', () { - BufferLogger mockLogger; Directory tempDir; setUp(() { - mockLogger = BufferLogger(); tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_settings_aar_test.'); }); @@ -498,13 +495,12 @@ createSettingsAarGradle(tempDir); - expect(mockLogger.statusText, contains('created successfully')); + expect(testLogger.statusText, contains('created successfully')); expect(tempDir.childFile('settings_aar.gradle').existsSync(), isTrue); }, overrides: <Type, Generator>{ FileSystem: () => MemoryFileSystem(), ProcessManager: () => FakeProcessManager.any(), - Logger: () => mockLogger, }); testUsingContext('create settings_aar.gradle when current settings.gradle doesn\'t load plugins', () { @@ -532,13 +528,12 @@ createSettingsAarGradle(tempDir); - expect(mockLogger.statusText, contains('created successfully')); + expect(testLogger.statusText, contains('created successfully')); expect(tempDir.childFile('settings_aar.gradle').existsSync(), isTrue); }, overrides: <Type, Generator>{ FileSystem: () => MemoryFileSystem(), ProcessManager: () => FakeProcessManager.any(), - Logger: () => mockLogger, }); });
diff --git a/packages/flutter_tools/test/general.shard/asset_bundle_test.dart b/packages/flutter_tools/test/general.shard/asset_bundle_test.dart index 39c8b02..dd616d2 100644 --- a/packages/flutter_tools/test/general.shard/asset_bundle_test.dart +++ b/packages/flutter_tools/test/general.shard/asset_bundle_test.dart
@@ -9,7 +9,6 @@ import 'package:flutter_tools/src/asset.dart'; import 'package:flutter_tools/src/base/file_system.dart'; -import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/bundle.dart'; import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/devfs.dart'; @@ -183,16 +182,15 @@ }); }); - test('Failed directory delete shows message', () async { + testUsingContext('Failed directory delete shows message', () async { final MockDirectory mockDirectory = MockDirectory(); - final BufferLogger bufferLogger = BufferLogger(); when(mockDirectory.existsSync()).thenReturn(true); when(mockDirectory.deleteSync(recursive: true)).thenThrow(const FileSystemException('ABCD')); - await writeBundle(mockDirectory, <String, DevFSContent>{}, loggerOverride: bufferLogger); + await writeBundle(mockDirectory, <String, DevFSContent>{}, loggerOverride: testLogger); verify(mockDirectory.createSync(recursive: true)).called(1); - expect(bufferLogger.errorText, contains('ABCD')); + expect(testLogger.errorText, contains('ABCD')); }); }
diff --git a/packages/flutter_tools/test/general.shard/base/build_test.dart b/packages/flutter_tools/test/general.shard/base/build_test.dart index 450e818..7a70c4d 100644 --- a/packages/flutter_tools/test/general.shard/base/build_test.dart +++ b/packages/flutter_tools/test/general.shard/base/build_test.dart
@@ -13,7 +13,6 @@ import 'package:flutter_tools/src/base/context.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/process.dart'; import 'package:flutter_tools/src/macos/xcode.dart'; import 'package:flutter_tools/src/version.dart'; @@ -225,7 +224,6 @@ MockAndroidSdk mockAndroidSdk; MockArtifacts mockArtifacts; MockXcode mockXcode; - BufferLogger bufferLogger; setUp(() async { fs = MemoryFileSystem(); @@ -247,7 +245,6 @@ mockXcode = MockXcode(); when(mockXcode.sdkLocation(any)).thenAnswer((_) => Future<String>.value(kSDKPath)); - bufferLogger = BufferLogger(); for (final BuildMode mode in BuildMode.values) { when(mockArtifacts.getArtifactPath(Artifact.snapshotDart, platform: anyNamed('platform'), mode: mode)).thenReturn(kSnapshotDart); @@ -261,7 +258,6 @@ ProcessManager: () => FakeProcessManager.any(), GenSnapshot: () => genSnapshot, Xcode: () => mockXcode, - Logger: () => bufferLogger, }; testUsingContext('iOS debug AOT snapshot is invalid', () async { @@ -658,7 +654,7 @@ expect(genSnapshotExitCode, 0); expect(genSnapshot.callCount, 1); - expect(bufferLogger.statusText, matches(RegExp(r'snapshot\(CompileTime\): \d+ ms.'))); + expect(testLogger.statusText, matches(RegExp(r'snapshot\(CompileTime\): \d+ ms.'))); }, overrides: contextOverrides); }); }
diff --git a/packages/flutter_tools/test/general.shard/base/logger_test.dart b/packages/flutter_tools/test/general.shard/base/logger_test.dart index 189464c..7095381 100644 --- a/packages/flutter_tools/test/general.shard/base/logger_test.dart +++ b/packages/flutter_tools/test/general.shard/base/logger_test.dart
@@ -6,7 +6,6 @@ import 'package:platform/platform.dart'; import 'package:flutter_tools/src/base/context.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/globals.dart' as globals; @@ -16,7 +15,7 @@ import '../../src/context.dart'; import '../../src/mocks.dart'; -final Generator _kNoAnsiPlatform = () => FakePlatform.fromPlatform(const LocalPlatform())..stdoutSupportsAnsi = false; +final Platform _kNoAnsiPlatform = FakePlatform.fromPlatform(const LocalPlatform())..stdoutSupportsAnsi = false; void main() { final String red = RegExp.escape(AnsiTerminal.red); @@ -30,9 +29,15 @@ setUp(() { fakeStopWatch = FakeStopwatch(); }); - testUsingContext('error', () async { - final BufferLogger mockLogger = BufferLogger(); - final VerboseLogger verboseLogger = VerboseLogger(mockLogger); + testWithoutContext('error', () async { + final BufferLogger mockLogger = BufferLogger( + terminal: AnsiTerminal( + stdio: MockStdio(), + platform: _kNoAnsiPlatform, + ), + outputPreferences: OutputPreferences.test(showColor: false), + ); + final VerboseLogger verboseLogger = VerboseLogger(mockLogger, stopwatch: fakeStopWatch); verboseLogger.printStatus('Hey Hey Hey Hey'); verboseLogger.printTrace('Oooh, I do I do I do'); @@ -42,15 +47,17 @@ r'\[ (?: {0,2}\+[0-9]{1,4} ms| )\] Oooh, I do I do I do\n$')); expect(mockLogger.traceText, ''); expect(mockLogger.errorText, matches( r'^\[ (?: {0,2}\+[0-9]{1,4} ms| )\] Helpless!\n$')); - }, overrides: <Type, Generator>{ - OutputPreferences: () => OutputPreferences(showColor: false), - Platform: _kNoAnsiPlatform, - Stopwatch: () => fakeStopWatch, }); - testUsingContext('ANSI colored errors', () async { - final BufferLogger mockLogger = BufferLogger(); - final VerboseLogger verboseLogger = VerboseLogger(mockLogger); + testWithoutContext('ANSI colored errors', () async { + final BufferLogger mockLogger = BufferLogger( + terminal: AnsiTerminal( + stdio: MockStdio(), + platform: FakePlatform()..stdoutSupportsAnsi = true, + ), + outputPreferences: OutputPreferences.test(showColor: true), + ); + final VerboseLogger verboseLogger = VerboseLogger(mockLogger, stopwatch: fakeStopWatch); verboseLogger.printStatus('Hey Hey Hey Hey'); verboseLogger.printTrace('Oooh, I do I do I do'); @@ -64,10 +71,6 @@ expect( mockLogger.errorText, matches('^$red' r'\[ (?: {0,2}\+[0-9]{1,4} ms| )\] ' '${bold}Helpless!$resetBold$resetColor' r'\n$')); - }, overrides: <Type, Generator>{ - OutputPreferences: () => OutputPreferences(showColor: true), - Platform: () => FakePlatform()..stdoutSupportsAnsi = true, - Stopwatch: () => fakeStopWatch, }); }); @@ -84,6 +87,8 @@ timeout: const Duration(seconds: 2), padding: 20, onFinish: () => called += 1, + stdio: mockStdio, + timeoutConfiguration: const TimeoutConfiguration(), ); } @@ -110,6 +115,8 @@ FakeAsync().run((FakeAsync time) { final AnsiSpinner ansiSpinner = AnsiSpinner( timeout: const Duration(hours: 10), + stdio: mockStdio, + timeoutConfiguration: const TimeoutConfiguration(), )..start(); doWhileAsync(time, () => ansiSpinner.ticks < 10); List<String> lines = outputStdout(); @@ -138,7 +145,6 @@ expect(done, isTrue); }, overrides: <Type, Generator>{ Platform: () => FakePlatform(operatingSystem: testOs), - Stdio: () => mockStdio, Stopwatch: () => mockStopwatch, }); @@ -148,6 +154,8 @@ FakeAsync().run((FakeAsync time) { final AnsiSpinner ansiSpinner = AnsiSpinner( timeout: const Duration(seconds: 2), + stdio: mockStdio, + timeoutConfiguration: const TimeoutConfiguration(), )..start(); mockStopwatch.elapsed = const Duration(seconds: 1); doWhileAsync(time, () => ansiSpinner.ticks < 10); // one second @@ -165,14 +173,22 @@ expect(done, isTrue); }, overrides: <Type, Generator>{ Platform: () => FakePlatform(operatingSystem: testOs), - Stdio: () => mockStdio, Stopwatch: () => mockStopwatch, }); + // Uses Stopwatch from context. testUsingContext('Stdout startProgress on colored terminal for $testOs', () async { bool done = false; FakeAsync().run((FakeAsync time) { - final Logger logger = context.get<Logger>(); + final Logger logger = StdoutLogger( + terminal: AnsiTerminal( + stdio: mockStdio, + platform: FakePlatform(operatingSystem: testOs)..stdoutSupportsAnsi = true, + ), + stdio: mockStdio, + outputPreferences: OutputPreferences.test(showColor: true), + timeoutConfiguration: const TimeoutConfiguration(), + ); final Status status = logger.startProgress( 'Hello', progressId: null, @@ -190,18 +206,21 @@ done = true; }); expect(done, isTrue); - }, overrides: <Type, Generator>{ - Logger: () => StdoutLogger(), - OutputPreferences: () => OutputPreferences(showColor: true), - Platform: () => FakePlatform(operatingSystem: testOs)..stdoutSupportsAnsi = true, - Stdio: () => mockStdio, }); testUsingContext('Stdout startProgress on colored terminal pauses on $testOs', () async { bool done = false; FakeAsync().run((FakeAsync time) { mockStopwatch.elapsed = const Duration(seconds: 5); - final Logger logger = context.get<Logger>(); + final Logger logger = StdoutLogger( + terminal: AnsiTerminal( + stdio: mockStdio, + platform: FakePlatform(operatingSystem: testOs)..stdoutSupportsAnsi = true, + ), + stdio: mockStdio, + outputPreferences: OutputPreferences.test(showColor: true), + timeoutConfiguration: const TimeoutConfiguration(), + ); final Status status = logger.startProgress( 'Knock Knock, Who\'s There', timeout: const Duration(days: 10), @@ -232,10 +251,6 @@ }); expect(done, isTrue); }, overrides: <Type, Generator>{ - Logger: () => StdoutLogger(), - OutputPreferences: () => OutputPreferences(showColor: true), - Platform: () => FakePlatform(operatingSystem: testOs)..stdoutSupportsAnsi = true, - Stdio: () => mockStdio, Stopwatch: () => mockStopwatch, }); @@ -270,7 +285,6 @@ expect(done, isTrue); }, overrides: <Type, Generator>{ Platform: () => FakePlatform(operatingSystem: testOs), - Stdio: () => mockStdio, Stopwatch: () => mockStopwatch, }); @@ -307,7 +321,6 @@ expect(done, isTrue); }, overrides: <Type, Generator>{ Platform: () => FakePlatform(operatingSystem: testOs), - Stdio: () => mockStdio, Stopwatch: () => mockStopwatch, }); @@ -353,7 +366,6 @@ expect(done, isTrue); }, overrides: <Type, Generator>{ Platform: () => FakePlatform(operatingSystem: testOs), - Stdio: () => mockStdio, Stopwatch: () => mockStopwatch, }); } @@ -372,33 +384,48 @@ timeout: timeoutConfiguration.slowOperation, padding: 20, onFinish: () => called++, + stdio: mockStdio, + timeoutConfiguration: const TimeoutConfiguration(), ); }); List<String> outputStdout() => mockStdio.writtenToStdout.join('').split('\n'); List<String> outputStderr() => mockStdio.writtenToStderr.join('').split('\n'); - testUsingContext('Error logs are wrapped', () async { - final Logger logger = context.get<Logger>(); + testWithoutContext('Error logs are wrapped', () async { + final Logger logger = StdoutLogger( + terminal: AnsiTerminal( + stdio: mockStdio, + platform: _kNoAnsiPlatform, + ), + stdio: mockStdio, + outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), + timeoutConfiguration: const TimeoutConfiguration(), + ); logger.printError('0123456789' * 15); final List<String> lines = outputStderr(); + expect(outputStdout().length, equals(1)); expect(outputStdout().first, isEmpty); expect(lines[0], equals('0123456789' * 4)); expect(lines[1], equals('0123456789' * 4)); expect(lines[2], equals('0123456789' * 4)); expect(lines[3], equals('0123456789' * 3)); - }, overrides: <Type, Generator>{ - Logger: () => StdoutLogger(), - OutputPreferences: () => OutputPreferences(wrapText: true, wrapColumn: 40, showColor: false), - Stdio: () => mockStdio, - Platform: _kNoAnsiPlatform, }); - testUsingContext('Error logs are wrapped and can be indented.', () async { - final Logger logger = context.get<Logger>(); + testWithoutContext('Error logs are wrapped and can be indented.', () async { + final Logger logger = StdoutLogger( + terminal: AnsiTerminal( + stdio: mockStdio, + platform: _kNoAnsiPlatform, + ), + stdio: mockStdio, + outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), + timeoutConfiguration: const TimeoutConfiguration(), + ); logger.printError('0123456789' * 15, indent: 5); final List<String> lines = outputStderr(); + expect(outputStdout().length, equals(1)); expect(outputStdout().first, isEmpty); expect(lines.length, equals(6)); @@ -408,17 +435,21 @@ expect(lines[3], equals(' 56789012345678901234567890123456789')); expect(lines[4], equals(' 0123456789')); expect(lines[5], isEmpty); - }, overrides: <Type, Generator>{ - Logger: () => StdoutLogger(), - OutputPreferences: () => OutputPreferences(wrapText: true, wrapColumn: 40, showColor: false), - Stdio: () => mockStdio, - Platform: _kNoAnsiPlatform, }); - testUsingContext('Error logs are wrapped and can have hanging indent.', () async { - final Logger logger = context.get<Logger>(); + testWithoutContext('Error logs are wrapped and can have hanging indent.', () async { + final Logger logger = StdoutLogger( + terminal: AnsiTerminal( + stdio: mockStdio, + platform: _kNoAnsiPlatform, + ), + stdio: mockStdio, + outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), + timeoutConfiguration: const TimeoutConfiguration(), + ); logger.printError('0123456789' * 15, hangingIndent: 5); final List<String> lines = outputStderr(); + expect(outputStdout().length, equals(1)); expect(outputStdout().first, isEmpty); expect(lines.length, equals(6)); @@ -428,17 +459,21 @@ expect(lines[3], equals(' 01234567890123456789012345678901234')); expect(lines[4], equals(' 56789')); expect(lines[5], isEmpty); - }, overrides: <Type, Generator>{ - Logger: () => StdoutLogger(), - OutputPreferences: () => OutputPreferences(wrapText: true, wrapColumn: 40, showColor: false), - Stdio: () => mockStdio, - Platform: _kNoAnsiPlatform, }); - testUsingContext('Error logs are wrapped, indented, and can have hanging indent.', () async { - final Logger logger = context.get<Logger>(); + testWithoutContext('Error logs are wrapped, indented, and can have hanging indent.', () async { + final Logger logger = StdoutLogger( + terminal: AnsiTerminal( + stdio: mockStdio, + platform: _kNoAnsiPlatform, + ), + stdio: mockStdio, + outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), + timeoutConfiguration: const TimeoutConfiguration(), + ); logger.printError('0123456789' * 15, indent: 4, hangingIndent: 5); final List<String> lines = outputStderr(); + expect(outputStdout().length, equals(1)); expect(outputStdout().first, isEmpty); expect(lines.length, equals(6)); @@ -448,34 +483,42 @@ expect(lines[3], equals(' 8901234567890123456789012345678')); expect(lines[4], equals(' 901234567890123456789')); expect(lines[5], isEmpty); - }, overrides: <Type, Generator>{ - Logger: () => StdoutLogger(), - OutputPreferences: () => OutputPreferences(wrapText: true, wrapColumn: 40, showColor: false), - Stdio: () => mockStdio, - Platform: _kNoAnsiPlatform, }); - testUsingContext('Stdout logs are wrapped', () async { - final Logger logger = context.get<Logger>(); + testWithoutContext('Stdout logs are wrapped', () async { + final Logger logger = StdoutLogger( + terminal: AnsiTerminal( + stdio: mockStdio, + platform: _kNoAnsiPlatform, + ), + stdio: mockStdio, + outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), + timeoutConfiguration: const TimeoutConfiguration(), + ); logger.printStatus('0123456789' * 15); final List<String> lines = outputStdout(); + expect(outputStderr().length, equals(1)); expect(outputStderr().first, isEmpty); expect(lines[0], equals('0123456789' * 4)); expect(lines[1], equals('0123456789' * 4)); expect(lines[2], equals('0123456789' * 4)); expect(lines[3], equals('0123456789' * 3)); - }, overrides: <Type, Generator>{ - Logger: () => StdoutLogger(), - OutputPreferences: () => OutputPreferences(wrapText: true, wrapColumn: 40, showColor: false), - Stdio: () => mockStdio, - Platform: _kNoAnsiPlatform, }); - testUsingContext('Stdout logs are wrapped and can be indented.', () async { - final Logger logger = context.get<Logger>(); + testWithoutContext('Stdout logs are wrapped and can be indented.', () async { + final Logger logger = StdoutLogger( + terminal: AnsiTerminal( + stdio: mockStdio, + platform: _kNoAnsiPlatform, + ), + stdio: mockStdio, + outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), + timeoutConfiguration: const TimeoutConfiguration(), + ); logger.printStatus('0123456789' * 15, indent: 5); final List<String> lines = outputStdout(); + expect(outputStderr().length, equals(1)); expect(outputStderr().first, isEmpty); expect(lines.length, equals(6)); @@ -485,17 +528,21 @@ expect(lines[3], equals(' 56789012345678901234567890123456789')); expect(lines[4], equals(' 0123456789')); expect(lines[5], isEmpty); - }, overrides: <Type, Generator>{ - Logger: () => StdoutLogger(), - OutputPreferences: () => OutputPreferences(wrapText: true, wrapColumn: 40, showColor: false), - Stdio: () => mockStdio, - Platform: _kNoAnsiPlatform, }); - testUsingContext('Stdout logs are wrapped and can have hanging indent.', () async { - final Logger logger = context.get<Logger>(); + testWithoutContext('Stdout logs are wrapped and can have hanging indent.', () async { + final Logger logger = StdoutLogger( + terminal: AnsiTerminal( + stdio: mockStdio, + platform: _kNoAnsiPlatform, + ), + stdio: mockStdio, + outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), + timeoutConfiguration: const TimeoutConfiguration(), + ); logger.printStatus('0123456789' * 15, hangingIndent: 5); final List<String> lines = outputStdout(); + expect(outputStderr().length, equals(1)); expect(outputStderr().first, isEmpty); expect(lines.length, equals(6)); @@ -505,17 +552,21 @@ expect(lines[3], equals(' 01234567890123456789012345678901234')); expect(lines[4], equals(' 56789')); expect(lines[5], isEmpty); - }, overrides: <Type, Generator>{ - Logger: () => StdoutLogger(), - OutputPreferences: () => OutputPreferences(wrapText: true, wrapColumn: 40, showColor: false), - Stdio: () => mockStdio, - Platform: _kNoAnsiPlatform, }); testUsingContext('Stdout logs are wrapped, indented, and can have hanging indent.', () async { - final Logger logger = context.get<Logger>(); + final Logger logger = StdoutLogger( + terminal: AnsiTerminal( + stdio: mockStdio, + platform: _kNoAnsiPlatform, + ), + stdio: mockStdio, + outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), + timeoutConfiguration: const TimeoutConfiguration(), + ); logger.printStatus('0123456789' * 15, indent: 4, hangingIndent: 5); final List<String> lines = outputStdout(); + expect(outputStderr().length, equals(1)); expect(outputStderr().first, isEmpty); expect(lines.length, equals(6)); @@ -525,42 +576,78 @@ expect(lines[3], equals(' 8901234567890123456789012345678')); expect(lines[4], equals(' 901234567890123456789')); expect(lines[5], isEmpty); - }, overrides: <Type, Generator>{ - Logger: () => StdoutLogger(), - OutputPreferences: () => OutputPreferences(wrapText: true, wrapColumn: 40, showColor: false), - Stdio: () => mockStdio, - Platform: _kNoAnsiPlatform, }); - testUsingContext('Error logs are red', () async { - final Logger logger = context.get<Logger>(); + testWithoutContext('Error logs are red', () async { + final Logger logger = StdoutLogger( + terminal: AnsiTerminal( + stdio: mockStdio, + platform: FakePlatform()..stdoutSupportsAnsi = true, + ), + stdio: mockStdio, + outputPreferences: OutputPreferences.test(showColor: true), + timeoutConfiguration: const TimeoutConfiguration(), + ); logger.printError('Pants on fire!'); final List<String> lines = outputStderr(); + expect(outputStdout().length, equals(1)); expect(outputStdout().first, isEmpty); expect(lines[0], equals('${AnsiTerminal.red}Pants on fire!${AnsiTerminal.resetColor}')); - }, overrides: <Type, Generator>{ - Logger: () => StdoutLogger(), - OutputPreferences: () => OutputPreferences(showColor: true), - Platform: () => FakePlatform()..stdoutSupportsAnsi = true, - Stdio: () => mockStdio, }); - testUsingContext('Stdout logs are not colored', () async { - final Logger logger = context.get<Logger>(); + testWithoutContext('Stdout logs are not colored', () async { + final Logger logger = StdoutLogger( + terminal: AnsiTerminal( + stdio: mockStdio, + platform: FakePlatform(), + ), + stdio: mockStdio, + outputPreferences: OutputPreferences.test(showColor: true), + timeoutConfiguration: const TimeoutConfiguration(), + ); logger.printStatus('All good.'); + final List<String> lines = outputStdout(); expect(outputStderr().length, equals(1)); expect(outputStderr().first, isEmpty); expect(lines[0], equals('All good.')); - }, overrides: <Type, Generator>{ - Logger: () => StdoutLogger(), - OutputPreferences: () => OutputPreferences(showColor: true), - Stdio: () => mockStdio, }); - testUsingContext('Stdout printStatus handle null inputs on colored terminal', () async { - final Logger logger = context.get<Logger>(); + testWithoutContext('Stdout printStatus handle null inputs on colored terminal', () async { + final Logger logger = StdoutLogger( + terminal: AnsiTerminal( + stdio: mockStdio, + platform: FakePlatform(), + ), + stdio: mockStdio, + outputPreferences: OutputPreferences.test(showColor: true), + timeoutConfiguration: const TimeoutConfiguration(), + ); + logger.printStatus( + null, + emphasis: null, + color: null, + newline: null, + indent: null, + ); + final List<String> lines = outputStdout(); + + expect(outputStderr().length, equals(1)); + expect(outputStderr().first, isEmpty); + expect(lines[0], equals('')); + }); + + testWithoutContext('Stdout printStatus handle null inputs on non-color terminal', () async { + final Logger logger = StdoutLogger( + terminal: AnsiTerminal( + stdio: mockStdio, + platform: _kNoAnsiPlatform, + ), + stdio: mockStdio, + outputPreferences: OutputPreferences.test(showColor: false), + timeoutConfiguration: const TimeoutConfiguration(), + ); logger.printStatus( null, emphasis: null, @@ -572,40 +659,25 @@ expect(outputStderr().length, equals(1)); expect(outputStderr().first, isEmpty); expect(lines[0], equals('')); - }, overrides: <Type, Generator>{ - Logger: () => StdoutLogger(), - OutputPreferences: () => OutputPreferences(showColor: true), - Stdio: () => mockStdio, }); - testUsingContext('Stdout printStatus handle null inputs on non-color terminal', () async { - final Logger logger = context.get<Logger>(); - logger.printStatus( - null, - emphasis: null, - color: null, - newline: null, - indent: null, - ); - final List<String> lines = outputStdout(); - expect(outputStderr().length, equals(1)); - expect(outputStderr().first, isEmpty); - expect(lines[0], equals('')); - }, overrides: <Type, Generator>{ - Logger: () => StdoutLogger(), - OutputPreferences: () => OutputPreferences(showColor: false), - Stdio: () => mockStdio, - Platform: _kNoAnsiPlatform, - }); - - testUsingContext('Stdout startProgress on non-color terminal', () async { + // Status uses Stopwatch from context. + test('Stdout startProgress on non-color terminal', () async { bool done = false; FakeAsync().run((FakeAsync time) { - final Logger logger = context.get<Logger>(); + final Logger logger = StdoutLogger( + terminal: AnsiTerminal( + stdio: mockStdio, + platform: _kNoAnsiPlatform, + ), + stdio: mockStdio, + outputPreferences: OutputPreferences.test(showColor: false), + timeoutConfiguration: const TimeoutConfiguration(), + ); final Status status = logger.startProgress( 'Hello', progressId: null, - timeout: timeoutConfiguration.slowOperation, + timeout: const TimeoutConfiguration().slowOperation, progressIndicatorPadding: 20, // this minus the "Hello" equals the 15 below. ); expect(outputStderr().length, equals(1)); @@ -619,11 +691,6 @@ done = true; }); expect(done, isTrue); - }, overrides: <Type, Generator>{ - Logger: () => StdoutLogger(), - OutputPreferences: () => OutputPreferences(showColor: false), - Stdio: () => mockStdio, - Platform: _kNoAnsiPlatform, }); testUsingContext('SummaryStatus works when canceled', () async { @@ -646,7 +713,9 @@ // Verify that stopping or canceling multiple times throws. expect(() { summaryStatus.cancel(); }, throwsA(isInstanceOf<AssertionError>())); expect(() { summaryStatus.stop(); }, throwsA(isInstanceOf<AssertionError>())); - }, overrides: <Type, Generator>{Stdio: () => mockStdio, Platform: _kNoAnsiPlatform}); + }, overrides: <Type, Generator>{ + Platform: () => _kNoAnsiPlatform, + }); testUsingContext('SummaryStatus works when stopped', () async { summaryStatus.start(); @@ -669,30 +738,53 @@ // Verify that stopping or canceling multiple times throws. expect(() { summaryStatus.stop(); }, throwsA(isInstanceOf<AssertionError>())); expect(() { summaryStatus.cancel(); }, throwsA(isInstanceOf<AssertionError>())); - }, overrides: <Type, Generator>{Stdio: () => mockStdio, Platform: _kNoAnsiPlatform}); + }, overrides: <Type, Generator>{ + Platform: () => _kNoAnsiPlatform, + }); - testUsingContext('sequential startProgress calls with StdoutLogger', () async { - final Logger logger = context.get<Logger>(); - logger.startProgress('AAA', timeout: timeoutConfiguration.fastOperation)..stop(); - logger.startProgress('BBB', timeout: timeoutConfiguration.fastOperation)..stop(); + // Status still uses Stopwatch from context. + // TODO(jonahwilliams): switch to testWithoutContext once logger uses a + // TimerFactory. + test('sequential startProgress calls with StdoutLogger', () async { + final Logger logger = StdoutLogger( + terminal: AnsiTerminal( + stdio: mockStdio, + platform: _kNoAnsiPlatform, + ), + stdio: mockStdio, + outputPreferences: OutputPreferences.test(showColor: false), + timeoutConfiguration: const TimeoutConfiguration(), + ); + logger.startProgress('AAA', timeout: const TimeoutConfiguration().fastOperation)..stop(); + logger.startProgress('BBB', timeout: const TimeoutConfiguration().fastOperation)..stop(); final List<String> output = outputStdout(); + expect(output.length, equals(3)); + // There's 61 spaces at the start: 59 (padding default) - 3 (length of AAA) + 5 (margin). // Then there's a left-padded "0ms" 8 characters wide, so 5 spaces then "0ms" // (except sometimes it's randomly slow so we handle up to "99,999ms"). expect(output[0], matches(RegExp(r'AAA[ ]{61}[\d, ]{5}[\d]ms'))); expect(output[1], matches(RegExp(r'BBB[ ]{61}[\d, ]{5}[\d]ms'))); - }, overrides: <Type, Generator>{ - Logger: () => StdoutLogger(), - OutputPreferences: () => OutputPreferences(showColor: false), - Stdio: () => mockStdio, - Platform: _kNoAnsiPlatform, }); - testUsingContext('sequential startProgress calls with VerboseLogger and StdoutLogger', () async { - final Logger logger = context.get<Logger>(); - logger.startProgress('AAA', timeout: timeoutConfiguration.fastOperation)..stop(); - logger.startProgress('BBB', timeout: timeoutConfiguration.fastOperation)..stop(); + // Status still uses Stopwatch from context. + test('sequential startProgress calls with VerboseLogger and StdoutLogger', () async { + final Logger logger = VerboseLogger( + StdoutLogger( + terminal: AnsiTerminal( + stdio: mockStdio, + platform: _kNoAnsiPlatform, + ), + stdio: mockStdio, + outputPreferences: OutputPreferences.test(), + timeoutConfiguration: const TimeoutConfiguration(), + ), + stopwatch: FakeStopwatch(), + ); + logger.startProgress('AAA', timeout: const TimeoutConfiguration().fastOperation)..stop(); + logger.startProgress('BBB', timeout: const TimeoutConfiguration().fastOperation)..stop(); + expect(outputStdout(), <Matcher>[ matches(r'^\[ (?: {0,2}\+[0-9]{1,4} ms| )\] AAA$'), matches(r'^\[ (?: {0,2}\+[0-9]{1,4} ms| )\] AAA \(completed.*\)$'), @@ -700,19 +792,21 @@ matches(r'^\[ (?: {0,2}\+[0-9]{1,4} ms| )\] BBB \(completed.*\)$'), matches(r'^$'), ]); - }, overrides: <Type, Generator>{ - Logger: () => VerboseLogger(StdoutLogger()), - Stdio: () => mockStdio, - Platform: _kNoAnsiPlatform, }); - testUsingContext('sequential startProgress calls with BufferLogger', () async { - testLogger.startProgress('AAA', timeout: timeoutConfiguration.fastOperation)..stop(); - testLogger.startProgress('BBB', timeout: timeoutConfiguration.fastOperation)..stop(); - expect(testLogger.statusText, 'AAA\nBBB\n'); - }, overrides: <Type, Generator>{ - Logger: () => BufferLogger(), - Platform: _kNoAnsiPlatform, + // Status still uses Stopwatch from context. + test('sequential startProgress calls with BufferLogger', () async { + final BufferLogger logger = BufferLogger( + terminal: AnsiTerminal( + stdio: mockStdio, + platform: _kNoAnsiPlatform, + ), + outputPreferences: OutputPreferences.test(), + ); + logger.startProgress('AAA', timeout: const TimeoutConfiguration().fastOperation)..stop(); + logger.startProgress('BBB', timeout: const TimeoutConfiguration().fastOperation)..stop(); + + expect(logger.statusText, 'AAA\nBBB\n'); }); }); }
diff --git a/packages/flutter_tools/test/general.shard/base/process_test.dart b/packages/flutter_tools/test/general.shard/base/process_test.dart index bc4383c..668310e 100644 --- a/packages/flutter_tools/test/general.shard/base/process_test.dart +++ b/packages/flutter_tools/test/general.shard/base/process_test.dart
@@ -6,7 +6,6 @@ import 'package:platform/platform.dart'; import 'package:flutter_tools/src/base/io.dart'; -import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/process.dart'; import 'package:flutter_tools/src/base/terminal.dart'; import 'package:mockito/mockito.dart'; @@ -69,11 +68,9 @@ group('output formatting', () { MockProcessManager mockProcessManager; - BufferLogger mockLogger; setUp(() { mockProcessManager = MockProcessManager(); - mockLogger = BufferLogger(); }); MockProcess Function(List<String>) processMetaFactory(List<String> stdout, { List<String> stderr = const <String>[] }) { @@ -88,10 +85,10 @@ final List<String> testString = <String>['0123456789' * 10]; mockProcessManager.processFactory = processMetaFactory(testString, stderr: testString); await processUtils.stream(<String>['command']); - expect(mockLogger.statusText, equals('${testString[0]}\n')); - expect(mockLogger.errorText, equals('${testString[0]}\n')); + + expect(testLogger.statusText, equals('${testString[0]}\n')); + expect(testLogger.errorText, equals('${testString[0]}\n')); }, overrides: <Type, Generator>{ - Logger: () => mockLogger, ProcessManager: () => mockProcessManager, OutputPreferences: () => OutputPreferences(wrapText: true, wrapColumn: 40), Platform: () => FakePlatform.fromPlatform(const LocalPlatform())..stdoutSupportsAnsi = false,
diff --git a/packages/flutter_tools/test/general.shard/base/terminal_test.dart b/packages/flutter_tools/test/general.shard/base/terminal_test.dart index ff62a6f..78bb1d4 100644 --- a/packages/flutter_tools/test/general.shard/base/terminal_test.dart +++ b/packages/flutter_tools/test/general.shard/base/terminal_test.dart
@@ -4,6 +4,7 @@ import 'dart:async'; +import 'package:flutter_tools/src/base/logger.dart'; import 'package:platform/platform.dart'; import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/base/terminal.dart'; @@ -11,24 +12,28 @@ import 'package:mockito/mockito.dart'; import '../../src/common.dart'; -import '../../src/context.dart'; void main() { group('output preferences', () { - testUsingContext('can wrap output', () async { - globals.printStatus('0123456789' * 8); - expect(testLogger.statusText, equals(('0123456789' * 4 + '\n') * 2)); - }, overrides: <Type, Generator>{ - OutputPreferences: () => OutputPreferences(wrapText: true, wrapColumn: 40), + testWithoutContext('can wrap output', () async { + final BufferLogger bufferLogger = BufferLogger( + outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40), + terminal: TestTerminal(platform: FakePlatform()..stdoutSupportsAnsi = true), + ); + bufferLogger.printStatus('0123456789' * 8); + + expect(bufferLogger.statusText, equals(('0123456789' * 4 + '\n') * 2)); }); - testUsingContext('can turn off wrapping', () async { + testWithoutContext('can turn off wrapping', () async { + final BufferLogger bufferLogger = BufferLogger( + outputPreferences: OutputPreferences.test(wrapText: false), + terminal: TestTerminal(platform: FakePlatform()..stdoutSupportsAnsi = true), + ); final String testString = '0123456789' * 20; - globals.printStatus(testString); - expect(testLogger.statusText, equals('$testString\n')); - }, overrides: <Type, Generator>{ - Platform: () => FakePlatform()..stdoutSupportsAnsi = true, - OutputPreferences: () => OutputPreferences(wrapText: false), + bufferLogger.printStatus(testString); + + expect(bufferLogger.statusText, equals('$testString\n')); }); }); @@ -36,32 +41,29 @@ AnsiTerminal terminal; setUp(() { - terminal = AnsiTerminal(); + terminal = AnsiTerminal( + stdio: globals.stdio, // Danger, using real stdio. + platform: FakePlatform()..stdoutSupportsAnsi = true, + ); }); - testUsingContext('adding colors works', () { + testWithoutContext('adding colors works', () { for (final TerminalColor color in TerminalColor.values) { expect( terminal.color('output', color), equals('${AnsiTerminal.colorCode(color)}output${AnsiTerminal.resetColor}'), ); } - }, overrides: <Type, Generator>{ - OutputPreferences: () => OutputPreferences(showColor: true), - Platform: () => FakePlatform()..stdoutSupportsAnsi = true, }); - testUsingContext('adding bold works', () { + testWithoutContext('adding bold works', () { expect( terminal.bolden('output'), equals('${AnsiTerminal.bold}output${AnsiTerminal.resetBold}'), ); - }, overrides: <Type, Generator>{ - OutputPreferences: () => OutputPreferences(showColor: true), - Platform: () => FakePlatform()..stdoutSupportsAnsi = true, }); - testUsingContext('nesting bold within color works', () { + testWithoutContext('nesting bold within color works', () { expect( terminal.color(terminal.bolden('output'), TerminalColor.blue), equals('${AnsiTerminal.blue}${AnsiTerminal.bold}output${AnsiTerminal.resetBold}${AnsiTerminal.resetColor}'), @@ -70,12 +72,9 @@ terminal.color('non-bold ${terminal.bolden('output')} also non-bold', TerminalColor.blue), equals('${AnsiTerminal.blue}non-bold ${AnsiTerminal.bold}output${AnsiTerminal.resetBold} also non-bold${AnsiTerminal.resetColor}'), ); - }, overrides: <Type, Generator>{ - OutputPreferences: () => OutputPreferences(showColor: true), - Platform: () => FakePlatform()..stdoutSupportsAnsi = true, }); - testUsingContext('nesting color within bold works', () { + testWithoutContext('nesting color within bold works', () { expect( terminal.bolden(terminal.color('output', TerminalColor.blue)), equals('${AnsiTerminal.bold}${AnsiTerminal.blue}output${AnsiTerminal.resetColor}${AnsiTerminal.resetBold}'), @@ -84,12 +83,9 @@ terminal.bolden('non-color ${terminal.color('output', TerminalColor.blue)} also non-color'), equals('${AnsiTerminal.bold}non-color ${AnsiTerminal.blue}output${AnsiTerminal.resetColor} also non-color${AnsiTerminal.resetBold}'), ); - }, overrides: <Type, Generator>{ - OutputPreferences: () => OutputPreferences(showColor: true), - Platform: () => FakePlatform()..stdoutSupportsAnsi = true, }); - testUsingContext('nesting color within color works', () { + testWithoutContext('nesting color within color works', () { expect( terminal.color(terminal.color('output', TerminalColor.blue), TerminalColor.magenta), equals('${AnsiTerminal.magenta}${AnsiTerminal.blue}output${AnsiTerminal.resetColor}${AnsiTerminal.magenta}${AnsiTerminal.resetColor}'), @@ -98,12 +94,9 @@ terminal.color('magenta ${terminal.color('output', TerminalColor.blue)} also magenta', TerminalColor.magenta), equals('${AnsiTerminal.magenta}magenta ${AnsiTerminal.blue}output${AnsiTerminal.resetColor}${AnsiTerminal.magenta} also magenta${AnsiTerminal.resetColor}'), ); - }, overrides: <Type, Generator>{ - OutputPreferences: () => OutputPreferences(showColor: true), - Platform: () => FakePlatform()..stdoutSupportsAnsi = true, }); - testUsingContext('nesting bold within bold works', () { + testWithoutContext('nesting bold within bold works', () { expect( terminal.bolden(terminal.bolden('output')), equals('${AnsiTerminal.bold}output${AnsiTerminal.resetBold}'), @@ -112,9 +105,6 @@ terminal.bolden('bold ${terminal.bolden('output')} still bold'), equals('${AnsiTerminal.bold}bold output still bold${AnsiTerminal.resetBold}'), ); - }, overrides: <Type, Generator>{ - OutputPreferences: () => OutputPreferences(showColor: true), - Platform: () => FakePlatform()..stdoutSupportsAnsi = true, }); }); @@ -122,17 +112,22 @@ AnsiTerminal terminalUnderTest; setUp(() { - terminalUnderTest = TestTerminal(); + terminalUnderTest = TestTerminal(stdio: MockStdio()); }); - testUsingContext('character prompt throws if usesTerminalUi is false', () async { + testWithoutContext('character prompt throws if usesTerminalUi is false', () async { expect(terminalUnderTest.promptForCharInput( <String>['a', 'b', 'c'], prompt: 'Please choose something', + logger: null, ), throwsA(isInstanceOf<StateError>())); }); - testUsingContext('character prompt', () async { + testWithoutContext('character prompt', () async { + final BufferLogger bufferLogger = BufferLogger( + terminal: terminalUnderTest, + outputPreferences: OutputPreferences.test(), + ); terminalUnderTest.usesTerminalUi = true; mockStdInStream = Stream<String>.fromFutures(<Future<String>>[ Future<String>.value('d'), // Not in accepted list. @@ -142,17 +137,22 @@ final String choice = await terminalUnderTest.promptForCharInput( <String>['a', 'b', 'c'], prompt: 'Please choose something', + logger: bufferLogger, ); expect(choice, 'b'); expect( - testLogger.statusText, + bufferLogger.statusText, 'Please choose something [a|b|c]: d\n' 'Please choose something [a|b|c]: \n' '\n' 'Please choose something [a|b|c]: b\n'); }); - testUsingContext('default character choice without displayAcceptedCharacters', () async { + testWithoutContext('default character choice without displayAcceptedCharacters', () async { + final BufferLogger bufferLogger = BufferLogger( + terminal: terminalUnderTest, + outputPreferences: OutputPreferences.test(), + ); terminalUnderTest.usesTerminalUi = true; mockStdInStream = Stream<String>.fromFutures(<Future<String>>[ Future<String>.value('\n'), // Not in accepted list @@ -162,21 +162,26 @@ prompt: 'Please choose something', displayAcceptedCharacters: false, defaultChoiceIndex: 1, // which is b. + logger: bufferLogger, ); + expect(choice, 'b'); expect( - testLogger.statusText, + bufferLogger.statusText, 'Please choose something: \n' '\n'); }); - testUsingContext('Does not set single char mode when a terminal is not attached', () { + testWithoutContext('Does not set single char mode when a terminal is not attached', () { + final Stdio stdio = MockStdio(); when(stdio.stdin).thenThrow(StateError('This should not be called')); when(stdio.stdinHasTerminal).thenReturn(false); + final AnsiTerminal ansiTerminal = AnsiTerminal( + stdio: stdio, + platform: const LocalPlatform() + ); - globals.terminal.singleCharMode = true; - }, overrides: <Type, Generator>{ - Stdio: () => MockStdio(), + expect(() => ansiTerminal.singleCharMode = true, returnsNormally); }); }); } @@ -184,10 +189,17 @@ Stream<String> mockStdInStream; class TestTerminal extends AnsiTerminal { + TestTerminal({ + Stdio stdio, + Platform platform = const LocalPlatform(), + }) : super(stdio: stdio, platform: platform); + @override Stream<String> get keystrokes { return mockStdInStream; } + + bool singleCharMode = false; } class MockStdio extends Mock implements Stdio {}
diff --git a/packages/flutter_tools/test/general.shard/cold_test.dart b/packages/flutter_tools/test/general.shard/cold_test.dart index 28df639..25ddc49 100644 --- a/packages/flutter_tools/test/general.shard/cold_test.dart +++ b/packages/flutter_tools/test/general.shard/cold_test.dart
@@ -7,6 +7,7 @@ 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/terminal.dart'; import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/compile.dart'; import 'package:flutter_tools/src/device.dart'; @@ -15,6 +16,7 @@ import 'package:flutter_tools/src/vmservice.dart'; import 'package:meta/meta.dart'; import 'package:mockito/mockito.dart'; +import 'package:platform/platform.dart'; import '../src/common.dart'; import '../src/context.dart'; @@ -26,7 +28,13 @@ BufferLogger mockLogger; setUp(() { - mockLogger = BufferLogger(); + mockLogger = BufferLogger( + terminal: AnsiTerminal( + stdio: null, + platform: const LocalPlatform(), + ), + outputPreferences: OutputPreferences.test(), + ); residentCompiler = MockResidentCompiler(); }); @@ -114,23 +122,16 @@ }); group('cold run', () { - BufferLogger mockLogger; - - setUp(() { - mockLogger = BufferLogger(); - }); - testUsingContext('returns 1 if not prebuilt mode & mainPath does not exist', () async { final MockDevice mockDevice = MockDevice(); final MockFlutterDevice mockFlutterDevice = MockFlutterDevice(); when(mockFlutterDevice.device).thenReturn(mockDevice); final List<FlutterDevice> devices = <FlutterDevice>[mockFlutterDevice]; final int result = await ColdRunner(devices).run(); + expect(result, 1); - expect(mockLogger.errorText, matches(r'Tried to run .*, but that file does not exist\.')); - expect(mockLogger.errorText, matches(r'Consider using the -t option to specify the Dart file to start\.')); - }, overrides: <Type, Generator>{ - Logger: () => mockLogger, + expect(testLogger.errorText, matches(r'Tried to run .*, but that file does not exist\.')); + expect(testLogger.errorText, matches(r'Consider using the -t option to specify the Dart file to start\.')); }); testUsingContext('calls runCold on attached device', () async { @@ -148,13 +149,12 @@ applicationBinary: applicationBinary, debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), ).run(); + expect(result, 1); verify(mockFlutterDevice.runCold( coldRunner: anyNamed('coldRunner'), route: anyNamed('route'), )); - }, overrides: <Type, Generator>{ - Logger: () => mockLogger, }); }); }
diff --git a/packages/flutter_tools/test/general.shard/commands/build_aot_test.dart b/packages/flutter_tools/test/general.shard/commands/build_aot_test.dart index 23e056f..de6b58c 100644 --- a/packages/flutter_tools/test/general.shard/commands/build_aot_test.dart +++ b/packages/flutter_tools/test/general.shard/commands/build_aot_test.dart
@@ -4,7 +4,6 @@ import 'package:file/memory.dart'; import 'package:flutter_tools/src/artifacts.dart'; -import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/process.dart'; import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/base/file_system.dart'; @@ -22,14 +21,12 @@ MockXcode mockXcode; MemoryFileSystem memoryFileSystem; MockProcessManager mockProcessManager; - BufferLogger bufferLogger; MockPlistUtils mockPlistUtils; setUp(() { mockXcode = MockXcode(); memoryFileSystem = MemoryFileSystem(style: FileSystemStyle.posix); mockProcessManager = MockProcessManager(); - bufferLogger = BufferLogger(); mockPlistUtils = MockPlistUtils(); }); @@ -67,7 +64,6 @@ FileSystem: () => memoryFileSystem, ProcessManager: () => mockProcessManager, Xcode: () => mockXcode, - Logger: () => bufferLogger, PlistParser: () => mockPlistUtils, }); @@ -91,7 +87,6 @@ FileSystem: () => memoryFileSystem, ProcessManager: () => mockProcessManager, Xcode: () => mockXcode, - Logger: () => bufferLogger, PlistParser: () => mockPlistUtils, }); @@ -114,7 +109,6 @@ FileSystem: () => memoryFileSystem, ProcessManager: () => mockProcessManager, Xcode: () => mockXcode, - Logger: () => bufferLogger, PlistParser: () => mockPlistUtils, }); @@ -143,7 +137,6 @@ FileSystem: () => memoryFileSystem, ProcessManager: () => mockProcessManager, Xcode: () => mockXcode, - Logger: () => bufferLogger, PlistParser: () => mockPlistUtils, }); @@ -162,13 +155,12 @@ await validateBitcode(BuildMode.release, TargetPlatform.ios); - expect(bufferLogger.statusText, ''); + expect(testLogger.statusText, ''); }, overrides: <Type, Generator>{ Artifacts: () => LocalEngineArtifacts('/engine', 'ios_profile', 'host_profile'), FileSystem: () => memoryFileSystem, ProcessManager: () => mockProcessManager, Xcode: () => mockXcode, - Logger: () => bufferLogger, PlistParser: () => mockPlistUtils, }); @@ -187,13 +179,12 @@ await validateBitcode(BuildMode.release, TargetPlatform.ios); - expect(bufferLogger.statusText, ''); + expect(testLogger.statusText, ''); }, overrides: <Type, Generator>{ Artifacts: () => LocalEngineArtifacts('/engine', 'ios_profile', 'host_profile'), FileSystem: () => memoryFileSystem, ProcessManager: () => mockProcessManager, Xcode: () => mockXcode, - Logger: () => bufferLogger, PlistParser: () => mockPlistUtils, }); }
diff --git a/packages/flutter_tools/test/general.shard/compile_expression_test.dart b/packages/flutter_tools/test/general.shard/compile_expression_test.dart index eaa7f25..9f28534 100644 --- a/packages/flutter_tools/test/general.shard/compile_expression_test.dart +++ b/packages/flutter_tools/test/general.shard/compile_expression_test.dart
@@ -6,7 +6,6 @@ import 'package:flutter_tools/src/base/common.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/build_info.dart'; import 'package:flutter_tools/src/compile.dart'; @@ -103,7 +102,6 @@ }, overrides: <Type, Generator>{ ProcessManager: () => mockProcessManager, OutputPreferences: () => OutputPreferences(showColor: false), - Logger: () => BufferLogger(), Platform: kNoColorTerminalPlatform, });
diff --git a/packages/flutter_tools/test/general.shard/config_test.dart b/packages/flutter_tools/test/general.shard/config_test.dart index 49d7ac7..5a437be 100644 --- a/packages/flutter_tools/test/general.shard/config_test.dart +++ b/packages/flutter_tools/test/general.shard/config_test.dart
@@ -6,6 +6,8 @@ import 'package:flutter_tools/src/base/config.dart'; import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/logger.dart'; +import 'package:flutter_tools/src/base/terminal.dart'; +import 'package:platform/platform.dart'; import '../src/common.dart'; @@ -49,7 +51,13 @@ }); test('Config parse error', () { - final BufferLogger bufferLogger =BufferLogger(); + final BufferLogger bufferLogger = BufferLogger( + terminal: AnsiTerminal( + stdio: null, + platform: const LocalPlatform(), + ), + outputPreferences: OutputPreferences.test(), + ); final File file = memoryFileSystem.file('example') ..writeAsStringSync('{"hello":"bar'); config = Config(file, bufferLogger);
diff --git a/packages/flutter_tools/test/general.shard/hot_test.dart b/packages/flutter_tools/test/general.shard/hot_test.dart index 47ac6c1..b12ef62 100644 --- a/packages/flutter_tools/test/general.shard/hot_test.dart +++ b/packages/flutter_tools/test/general.shard/hot_test.dart
@@ -6,7 +6,6 @@ import 'package:flutter_tools/src/artifacts.dart'; import 'package:flutter_tools/src/base/io.dart'; -import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/compile.dart'; import 'package:flutter_tools/src/devfs.dart'; @@ -269,12 +268,10 @@ group('hot attach', () { MockResidentCompiler residentCompiler = MockResidentCompiler(); - BufferLogger mockLogger; MockLocalEngineArtifacts mockArtifacts; setUp(() { residentCompiler = MockResidentCompiler(); - mockLogger = BufferLogger(); mockArtifacts = MockLocalEngineArtifacts(); }); @@ -298,13 +295,12 @@ debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), ).attach(); expect(exitCode, 2); - expect(mockLogger.statusText, contains('If you are using an emulator running Android Q Beta, ' + expect(testLogger.statusText, contains('If you are using an emulator running Android Q Beta, ' 'consider using an emulator running API level 29 or lower.')); - expect(mockLogger.statusText, contains('Learn more about the status of this issue on ' + expect(testLogger.statusText, contains('Learn more about the status of this issue on ' 'https://issuetracker.google.com/issues/132325318')); }, overrides: <Type, Generator>{ Artifacts: () => mockArtifacts, - Logger: () => mockLogger, HotRunnerConfig: () => TestHotRunnerConfig(successfulSetup: true), }); @@ -327,13 +323,12 @@ debuggingOptions: DebuggingOptions.enabled(BuildInfo.debug), ).attach(); expect(exitCode, 2); - expect(mockLogger.statusText, contains('If you are using an emulator running Android Q Beta, ' + expect(testLogger.statusText, contains('If you are using an emulator running Android Q Beta, ' 'consider using an emulator running API level 29 or lower.')); - expect(mockLogger.statusText, contains('Learn more about the status of this issue on ' + expect(testLogger.statusText, contains('Learn more about the status of this issue on ' 'https://issuetracker.google.com/issues/132325318')); }, overrides: <Type, Generator>{ Artifacts: () => mockArtifacts, - Logger: () => mockLogger, HotRunnerConfig: () => TestHotRunnerConfig(successfulSetup: true), }); });
diff --git a/packages/flutter_tools/test/general.shard/ios/code_signing_test.dart b/packages/flutter_tools/test/general.shard/ios/code_signing_test.dart index 973bfa1..7fc9fd0 100644 --- a/packages/flutter_tools/test/general.shard/ios/code_signing_test.dart +++ b/packages/flutter_tools/test/general.shard/ios/code_signing_test.dart
@@ -654,6 +654,8 @@ Stream<String> mockTerminalStdInStream; class TestTerminal extends AnsiTerminal { + TestTerminal() : super(stdio: globals.stdio, platform: globals.platform); + @override String bolden(String message) => '<bold>$message</bold>';
diff --git a/packages/flutter_tools/test/general.shard/project_file_invalidator_test.dart b/packages/flutter_tools/test/general.shard/project_file_invalidator_test.dart index d46e5629..70d50b80 100644 --- a/packages/flutter_tools/test/general.shard/project_file_invalidator_test.dart +++ b/packages/flutter_tools/test/general.shard/project_file_invalidator_test.dart
@@ -4,22 +4,36 @@ import 'package:file/memory.dart'; import 'package:flutter_tools/src/base/logger.dart'; +import 'package:flutter_tools/src/base/terminal.dart'; import 'package:flutter_tools/src/run_hot.dart'; import 'package:platform/platform.dart'; import '../src/common.dart'; +import '../src/mocks.dart'; // assumption: tests have a timeout less than 100 days final DateTime inFuture = DateTime.now().add(const Duration(days: 100)); void main() { + BufferLogger bufferLogger; + + setUp(() { + bufferLogger = BufferLogger( + terminal: AnsiTerminal( + stdio: MockStdio(), + platform: FakePlatform(), + ), + outputPreferences: OutputPreferences.test(), + ); + }); + for (final bool asyncScanning in <bool>[true, false]) { testWithoutContext('No last compile, asyncScanning: $asyncScanning', () async { final ProjectFileInvalidator projectFileInvalidator = ProjectFileInvalidator( fileSystem: MemoryFileSystem(), platform: FakePlatform(), - logger: BufferLogger(), + logger: bufferLogger, ); expect( @@ -37,7 +51,7 @@ final ProjectFileInvalidator projectFileInvalidator = ProjectFileInvalidator( fileSystem: MemoryFileSystem(), platform: FakePlatform(), - logger: BufferLogger(), + logger: bufferLogger, ); expect( @@ -55,7 +69,7 @@ final ProjectFileInvalidator projectFileInvalidator = ProjectFileInvalidator( fileSystem: MemoryFileSystem(), platform: FakePlatform(), - logger: BufferLogger(), + logger: bufferLogger, ); expect(
diff --git a/packages/flutter_tools/test/general.shard/resident_web_runner_cold_test.dart b/packages/flutter_tools/test/general.shard/resident_web_runner_cold_test.dart index 854c39f..0c15839 100644 --- a/packages/flutter_tools/test/general.shard/resident_web_runner_cold_test.dart +++ b/packages/flutter_tools/test/general.shard/resident_web_runner_cold_test.dart
@@ -7,6 +7,7 @@ import 'package:dwds/dwds.dart'; import 'package:flutter_tools/src/base/common.dart'; import 'package:flutter_tools/src/base/logger.dart'; +import 'package:flutter_tools/src/base/terminal.dart'; import 'package:flutter_tools/src/base/net.dart'; import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/device.dart'; @@ -17,6 +18,7 @@ import 'package:flutter_tools/src/build_runner/web_fs.dart'; import 'package:meta/meta.dart'; import 'package:mockito/mockito.dart'; +import 'package:platform/platform.dart'; import 'package:vm_service/vm_service.dart'; import '../src/common.dart'; @@ -84,7 +86,13 @@ expect(debugConnectionInfo.wsUri, null); verify(mockStatus.stop()).called(1); }, overrides: <Type, Generator>{ - Logger: () => DelegateLogger(BufferLogger()), + Logger: () => DelegateLogger(BufferLogger( + terminal: AnsiTerminal( + stdio: null, + platform: const LocalPlatform(), + ), + outputPreferences: OutputPreferences.test(), + )), })); test('Can full restart after attaching', () => testbed.run(() async {
diff --git a/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart b/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart index da322c4..96698bf 100644 --- a/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart +++ b/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart
@@ -11,6 +11,7 @@ import 'package:flutter_tools/src/base/io.dart'; import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/net.dart'; +import 'package:flutter_tools/src/base/terminal.dart'; import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/build_runner/resident_web_runner.dart'; import 'package:flutter_tools/src/build_runner/web_fs.dart'; @@ -26,6 +27,7 @@ import 'package:flutter_tools/src/web/web_device.dart'; import 'package:meta/meta.dart'; import 'package:mockito/mockito.dart'; +import 'package:platform/platform.dart'; import 'package:vm_service/vm_service.dart'; import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'; @@ -257,7 +259,13 @@ expect(bufferLogger.statusText, contains('Debug service listening on ws://127.0.0.1/abcd/')); expect(debugConnectionInfo.wsUri.toString(), 'ws://127.0.0.1/abcd/'); }, overrides: <Type, Generator>{ - Logger: () => DelegateLogger(BufferLogger()), + Logger: () => DelegateLogger(BufferLogger( + terminal: AnsiTerminal( + stdio: null, + platform: const LocalPlatform(), + ), + outputPreferences: OutputPreferences.test(), + )), })); test('Can successfully run and disconnect with --no-resident', () => testbed.run(() async { @@ -1080,7 +1088,13 @@ await expectation; verify(mockStatus.stop()).called(2); }, overrides: <Type, Generator>{ - Logger: () => DelegateLogger(BufferLogger()) + Logger: () => DelegateLogger(BufferLogger( + terminal: AnsiTerminal( + stdio: null, + platform: const LocalPlatform(), + ), + outputPreferences: OutputPreferences.test(), + )) })); }
diff --git a/packages/flutter_tools/test/general.shard/vmservice_test.dart b/packages/flutter_tools/test/general.shard/vmservice_test.dart index 138ac83..5e4fb07 100644 --- a/packages/flutter_tools/test/general.shard/vmservice_test.dart +++ b/packages/flutter_tools/test/general.shard/vmservice_test.dart
@@ -7,10 +7,12 @@ 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/device.dart'; import 'package:flutter_tools/src/vmservice.dart'; import 'package:json_rpc_2/json_rpc_2.dart' as rpc; import 'package:mockito/mockito.dart'; +import 'package:platform/platform.dart'; import 'package:quiver/testing/async.dart'; import '../src/common.dart'; @@ -167,6 +169,7 @@ void main() { MockStdio mockStdio; group('VMService', () { + setUp(() { mockStdio = MockStdio(); }); @@ -188,8 +191,12 @@ expect(mockStdio.writtenToStderr.join(''), ''); }); }, overrides: <Type, Generator>{ - Logger: () => StdoutLogger(), - Stdio: () => mockStdio, + Logger: () => StdoutLogger( + outputPreferences: OutputPreferences.test(), + stdio: mockStdio, + terminal: AnsiTerminal(stdio: mockStdio, platform: const LocalPlatform()), + timeoutConfiguration: const TimeoutConfiguration(), + ), WebSocketConnector: () => (String url, {CompressionOptions compression}) async => throw const SocketException('test'), }); @@ -263,8 +270,12 @@ expect(mockStdio.writtenToStderr.join(''), ''); }); }, overrides: <Type, Generator>{ - Logger: () => StdoutLogger(), - Stdio: () => mockStdio, + Logger: () => StdoutLogger( + outputPreferences: outputPreferences, + terminal: AnsiTerminal(stdio: mockStdio, platform: const LocalPlatform()), + stdio: mockStdio, + timeoutConfiguration: const TimeoutConfiguration(), + ), }); testUsingContext('registers hot UI method', () { @@ -276,8 +287,12 @@ expect(mockPeer.registeredMethods, contains('reloadMethod')); }); }, overrides: <Type, Generator>{ - Logger: () => StdoutLogger(), - Stdio: () => mockStdio, + Logger: () => StdoutLogger( + outputPreferences: outputPreferences, + terminal: AnsiTerminal(stdio: mockStdio, platform: const LocalPlatform()), + stdio: mockStdio, + timeoutConfiguration: const TimeoutConfiguration(), + ), }); testUsingContext('registers flutterMemoryInfo service', () { @@ -290,8 +305,12 @@ expect(mockPeer.registeredMethods, contains('flutterMemoryInfo')); }); }, overrides: <Type, Generator>{ - Logger: () => StdoutLogger(), - Stdio: () => mockStdio, + Logger: () => StdoutLogger( + outputPreferences: outputPreferences, + terminal: AnsiTerminal(stdio: mockStdio, platform: const LocalPlatform()), + stdio: mockStdio, + timeoutConfiguration: const TimeoutConfiguration(), + ), }); }); }
diff --git a/packages/flutter_tools/test/src/context.dart b/packages/flutter_tools/test/src/context.dart index 8c29688..80d2d30 100644 --- a/packages/flutter_tools/test/src/context.dart +++ b/packages/flutter_tools/test/src/context.dart
@@ -92,6 +92,7 @@ return context.run<dynamic>( name: 'mocks', overrides: <Type, Generator>{ + AnsiTerminal: () => AnsiTerminal(platform: globals.platform, stdio: globals.stdio), Config: () => buildConfig(globals.fs), DeviceManager: () => FakeDeviceManager(), Doctor: () => FakeDoctor(), @@ -103,7 +104,10 @@ return mock; }, OutputPreferences: () => OutputPreferences.test(), - Logger: () => BufferLogger(), + Logger: () => BufferLogger( + terminal: globals.terminal, + outputPreferences: outputPreferences, + ), OperatingSystemUtils: () => FakeOperatingSystemUtils(), PersistentToolState: () => buildPersistentToolState(globals.fs), SimControl: () => MockSimControl(),
diff --git a/packages/flutter_tools/test/src/testbed.dart b/packages/flutter_tools/test/src/testbed.dart index ab68e92..5934d28 100644 --- a/packages/flutter_tools/test/src/testbed.dart +++ b/packages/flutter_tools/test/src/testbed.dart
@@ -38,7 +38,10 @@ // Keeps tests fast by avoiding the actual file system. FileSystem: () => MemoryFileSystem(style: globals.platform.isWindows ? FileSystemStyle.windows : FileSystemStyle.posix), ProcessManager: () => FakeProcessManager.any(), - Logger: () => BufferLogger(), // Allows reading logs and prevents stdout. + Logger: () => BufferLogger( + terminal: AnsiTerminal(stdio: globals.stdio, platform: globals.platform), // Danger, using real stdio. + outputPreferences: OutputPreferences.test(), + ), // Allows reading logs and prevents stdout. OperatingSystemUtils: () => FakeOperatingSystemUtils(), OutputPreferences: () => OutputPreferences.test(), // configures BufferLogger to avoid color codes. Usage: () => NoOpUsage(), // prevent addition of analytics from burdening test mocks