mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[flutter_tool] Refactor Logger and Terminal to (mostly) no longer depend directly on context (#47269)
This commit is contained in:
parent
0384c8c482
commit
f7b8d62cbc
@ -15,6 +15,7 @@ import 'src/base/file_system.dart';
|
||||
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<File> _createLocalCrashReport(List<String> args, dynamic error, StackTrac
|
||||
|
||||
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),
|
||||
|
||||
@ -247,11 +247,10 @@ class Stdio {
|
||||
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 {
|
||||
|
||||
@ -8,8 +8,8 @@ import 'package:meta/meta.dart';
|
||||
|
||||
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 @@ abstract class Logger {
|
||||
|
||||
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,11 +161,36 @@ abstract class Logger {
|
||||
}
|
||||
|
||||
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, {
|
||||
@ -172,14 +203,19 @@ class StdoutLogger extends Logger {
|
||||
}) {
|
||||
_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 @@ class StdoutLogger extends Logger {
|
||||
}) {
|
||||
_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 @@ class StdoutLogger extends Logger {
|
||||
|
||||
@protected
|
||||
void writeToStdOut(String message) {
|
||||
stdout.write(message);
|
||||
_stdio.stdout.write(message);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -232,15 +273,18 @@ class StdoutLogger extends Logger {
|
||||
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 @@ class StdoutLogger extends Logger {
|
||||
timeout: timeout,
|
||||
padding: progressIndicatorPadding,
|
||||
onFinish: _clearStatus,
|
||||
stdio: _stdio,
|
||||
timeoutConfiguration: _timeoutConfiguration,
|
||||
)..start();
|
||||
}
|
||||
return _status;
|
||||
@ -270,10 +316,22 @@ class StdoutLogger extends Logger {
|
||||
/// fonts, should be replaced by this class with printable symbols. Otherwise,
|
||||
/// they will show up as the unrepresentable character symbol '<EFBFBD>'.
|
||||
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 WindowsStdoutLogger extends StdoutLogger {
|
||||
}
|
||||
|
||||
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 @@ class BufferLogger extends Logger {
|
||||
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 @@ class BufferLogger extends Logger {
|
||||
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 @@ class BufferLogger extends Logger {
|
||||
}) {
|
||||
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 BufferLogger extends Logger {
|
||||
}
|
||||
|
||||
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 @@ class VerboseLogger extends Logger {
|
||||
}) {
|
||||
_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 @@ class VerboseLogger extends Logger {
|
||||
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 @@ class VerboseLogger extends Logger {
|
||||
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 @@ class VerboseLogger extends Logger {
|
||||
} else {
|
||||
prefix = '+$millis ms'.padLeft(prefixWidth);
|
||||
if (millis >= 100) {
|
||||
prefix = globals.terminal.bolden(prefix);
|
||||
prefix = _terminal.bolden(prefix);
|
||||
}
|
||||
}
|
||||
prefix = '[$prefix] ';
|
||||
@ -455,12 +573,12 @@ class VerboseLogger extends Logger {
|
||||
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 @@ class VerboseLogger extends Logger {
|
||||
|
||||
@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 @@ typedef SlowWarningCallback = String Function();
|
||||
/// 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 @@ abstract class Status {
|
||||
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 @@ abstract class Status {
|
||||
|
||||
@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 @@ abstract class Status {
|
||||
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 @@ class SummaryStatus extends Status {
|
||||
@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 @@ class SummaryStatus extends Status {
|
||||
|
||||
void _printMessage() {
|
||||
assert(!_messageShowingOnCurrentLine);
|
||||
stdout.write('${message.padRight(padding)} ');
|
||||
_stdio.stdout.write('${message.padRight(padding)} ');
|
||||
_messageShowingOnCurrentLine = true;
|
||||
}
|
||||
|
||||
@ -608,14 +752,14 @@ class SummaryStatus extends Status {
|
||||
}
|
||||
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 @@ class SummaryStatus extends Status {
|
||||
/// 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 @@ class AnsiSpinner extends Status {
|
||||
@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 @@ class AnsiSpinner extends Status {
|
||||
}
|
||||
|
||||
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 @@ class AnsiSpinner extends Status {
|
||||
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 @@ class AnsiSpinner extends Status {
|
||||
}
|
||||
|
||||
void _clearSpinner() {
|
||||
stdout.write('$_backspace$_clear$_backspace');
|
||||
_stdio.stdout.write('$_backspace$_clear$_backspace');
|
||||
}
|
||||
|
||||
@override
|
||||
@ -759,10 +907,12 @@ class AnsiStatus extends AnsiSpinner {
|
||||
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 @@ class AnsiStatus extends AnsiSpinner {
|
||||
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 @@ class AnsiStatus extends AnsiSpinner {
|
||||
/// 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
|
||||
|
||||
@ -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 @@ class OutputPreferences {
|
||||
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 @@ class OutputPreferences {
|
||||
/// 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 OutputPreferences {
|
||||
}
|
||||
|
||||
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 @@ class AnsiTerminal {
|
||||
|
||||
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 @@ class AnsiTerminal {
|
||||
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 @@ class AnsiTerminal {
|
||||
///
|
||||
/// 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 @@ class AnsiTerminal {
|
||||
/// 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 @@ class AnsiTerminal {
|
||||
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') {
|
||||
|
||||
@ -6,6 +6,7 @@ import 'dart:async';
|
||||
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 @@ class _AnsiRun {
|
||||
/// 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>[''];
|
||||
}
|
||||
|
||||
@ -974,7 +974,7 @@ class NotifyingLogger extends Logger {
|
||||
}) {
|
||||
assert(timeout != null);
|
||||
printStatus(message);
|
||||
return SilentStatus(timeout: timeout);
|
||||
return SilentStatus(timeout: timeout, timeoutConfiguration: timeoutConfiguration);
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
@ -983,6 +983,12 @@ class NotifyingLogger extends Logger {
|
||||
|
||||
@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 @@ class _AppRunLogger extends Logger {
|
||||
|
||||
_status = SilentStatus(
|
||||
timeout: timeout,
|
||||
timeoutConfiguration: timeoutConfiguration,
|
||||
onFinish: () {
|
||||
_status = null;
|
||||
_sendProgressEvent(<String, dynamic>{
|
||||
@ -1206,6 +1213,12 @@ class _AppRunLogger extends Logger {
|
||||
domain.sendEvent(name, args);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
bool get supportsColor => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
bool get hasTerminal => false;
|
||||
}
|
||||
|
||||
class LogMessage {
|
||||
|
||||
@ -19,6 +19,7 @@ import 'base/logger.dart';
|
||||
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 @@ Future<T> runInContext<T>(
|
||||
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(),
|
||||
|
||||
@ -211,7 +211,12 @@ class Doctor {
|
||||
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 @@ class Doctor {
|
||||
final Status status = Status.withSpinner(
|
||||
timeout: timeoutConfiguration.fastOperation,
|
||||
slowWarningCallback: () => validator.slowWarning,
|
||||
timeoutConfiguration: timeoutConfiguration,
|
||||
);
|
||||
ValidationResult result;
|
||||
try {
|
||||
|
||||
@ -10,6 +10,7 @@ import 'base/config.dart';
|
||||
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 @@ AnsiTerminal get terminal {
|
||||
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();
|
||||
|
||||
@ -243,6 +243,7 @@ Future<String> _chooseSigningIdentity(List<String> validCodeSigningIdentities) a
|
||||
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') {
|
||||
|
||||
@ -284,6 +284,7 @@ class XcodeProjectInterpreter {
|
||||
}) async {
|
||||
final Status status = Status.withSpinner(
|
||||
timeout: timeoutConfiguration.fastOperation,
|
||||
timeoutConfiguration: timeoutConfiguration,
|
||||
);
|
||||
final List<String> showBuildSettingsCommand = <String>[
|
||||
_executable,
|
||||
|
||||
@ -13,7 +13,6 @@ import '../artifacts.dart';
|
||||
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 @@ class FlutterCommandRunner extends CommandRunner<void> {
|
||||
|
||||
@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 @@ class FlutterCommandRunner extends CommandRunner<void> {
|
||||
// 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 @@ class FlutterCommandRunner extends CommandRunner<void> {
|
||||
// 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,
|
||||
|
||||
@ -699,7 +699,7 @@ class StreamLogger extends Logger {
|
||||
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 @@ class StreamLogger extends Logger {
|
||||
|
||||
@override
|
||||
void sendEvent(String name, [Map<String, dynamic> args]) { }
|
||||
|
||||
@override
|
||||
bool get supportsColor => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
bool get hasTerminal => false;
|
||||
}
|
||||
|
||||
class LoggerInterrupted implements Exception {
|
||||
|
||||
@ -7,7 +7,6 @@ import 'package:platform/platform.dart';
|
||||
|
||||
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 @@ void main() {
|
||||
verify(mockFile.deleteSync(recursive: true)).called(1);
|
||||
}, overrides: <Type, Generator>{
|
||||
Platform: () => windowsPlatform,
|
||||
Logger: () => BufferLogger(),
|
||||
Xcode: () => mockXcode,
|
||||
});
|
||||
|
||||
@ -94,7 +92,6 @@ void main() {
|
||||
verifyNever(mockFile.deleteSync(recursive: true));
|
||||
}, overrides: <Type, Generator>{
|
||||
Platform: () => windowsPlatform,
|
||||
Logger: () => BufferLogger(),
|
||||
Xcode: () => mockXcode,
|
||||
});
|
||||
}
|
||||
|
||||
@ -15,7 +15,6 @@ import 'package:flutter_tools/src/base/context.dart';
|
||||
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 @@ void main() {
|
||||
});
|
||||
|
||||
group('Config files', () {
|
||||
BufferLogger mockLogger;
|
||||
Directory tempDir;
|
||||
|
||||
setUp(() {
|
||||
mockLogger = BufferLogger();
|
||||
tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_settings_aar_test.');
|
||||
});
|
||||
|
||||
@ -498,13 +495,12 @@ include ':app'
|
||||
|
||||
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 @@ include ':app'
|
||||
|
||||
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,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -9,7 +9,6 @@ import 'package:file/memory.dart';
|
||||
|
||||
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 @@ flutter:
|
||||
});
|
||||
});
|
||||
|
||||
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'));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -13,7 +13,6 @@ import 'package:flutter_tools/src/base/build.dart';
|
||||
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 @@ void main() {
|
||||
MockAndroidSdk mockAndroidSdk;
|
||||
MockArtifacts mockArtifacts;
|
||||
MockXcode mockXcode;
|
||||
BufferLogger bufferLogger;
|
||||
|
||||
setUp(() async {
|
||||
fs = MemoryFileSystem();
|
||||
@ -247,7 +245,6 @@ void main() {
|
||||
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 @@ void main() {
|
||||
ProcessManager: () => FakeProcessManager.any(),
|
||||
GenSnapshot: () => genSnapshot,
|
||||
Xcode: () => mockXcode,
|
||||
Logger: () => bufferLogger,
|
||||
};
|
||||
|
||||
testUsingContext('iOS debug AOT snapshot is invalid', () async {
|
||||
@ -658,7 +654,7 @@ void main() {
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@ import 'dart:convert' show jsonEncode;
|
||||
|
||||
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/common.dart';
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
timeout: const Duration(seconds: 2),
|
||||
padding: 20,
|
||||
onFinish: () => called += 1,
|
||||
stdio: mockStdio,
|
||||
timeoutConfiguration: const TimeoutConfiguration(),
|
||||
);
|
||||
}
|
||||
|
||||
@ -110,6 +115,8 @@ void main() {
|
||||
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 @@ void main() {
|
||||
expect(done, isTrue);
|
||||
}, overrides: <Type, Generator>{
|
||||
Platform: () => FakePlatform(operatingSystem: testOs),
|
||||
Stdio: () => mockStdio,
|
||||
Stopwatch: () => mockStopwatch,
|
||||
});
|
||||
|
||||
@ -148,6 +154,8 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
});
|
||||
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 @@ void main() {
|
||||
expect(done, isTrue);
|
||||
}, overrides: <Type, Generator>{
|
||||
Platform: () => FakePlatform(operatingSystem: testOs),
|
||||
Stdio: () => mockStdio,
|
||||
Stopwatch: () => mockStopwatch,
|
||||
});
|
||||
|
||||
@ -307,7 +321,6 @@ void main() {
|
||||
expect(done, isTrue);
|
||||
}, overrides: <Type, Generator>{
|
||||
Platform: () => FakePlatform(operatingSystem: testOs),
|
||||
Stdio: () => mockStdio,
|
||||
Stopwatch: () => mockStopwatch,
|
||||
});
|
||||
|
||||
@ -353,7 +366,6 @@ void main() {
|
||||
expect(done, isTrue);
|
||||
}, overrides: <Type, Generator>{
|
||||
Platform: () => FakePlatform(operatingSystem: testOs),
|
||||
Stdio: () => mockStdio,
|
||||
Stopwatch: () => mockStopwatch,
|
||||
});
|
||||
}
|
||||
@ -372,33 +384,48 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
// 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 @@ void main() {
|
||||
// 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 @@ void main() {
|
||||
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');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@ import 'dart:async';
|
||||
|
||||
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 @@ void main() {
|
||||
|
||||
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 @@ void main() {
|
||||
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,
|
||||
|
||||
@ -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:flutter_tools/src/globals.dart' as globals;
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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 {}
|
||||
|
||||
@ -7,6 +7,7 @@ import 'dart:async';
|
||||
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/run_cold.dart';
|
||||
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 @@ void main() {
|
||||
BufferLogger mockLogger;
|
||||
|
||||
setUp(() {
|
||||
mockLogger = BufferLogger();
|
||||
mockLogger = BufferLogger(
|
||||
terminal: AnsiTerminal(
|
||||
stdio: null,
|
||||
platform: const LocalPlatform(),
|
||||
),
|
||||
outputPreferences: OutputPreferences.test(),
|
||||
);
|
||||
residentCompiler = MockResidentCompiler();
|
||||
});
|
||||
|
||||
@ -114,23 +122,16 @@ void main() {
|
||||
});
|
||||
|
||||
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 @@ void main() {
|
||||
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,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
FileSystem: () => memoryFileSystem,
|
||||
ProcessManager: () => mockProcessManager,
|
||||
Xcode: () => mockXcode,
|
||||
Logger: () => bufferLogger,
|
||||
PlistParser: () => mockPlistUtils,
|
||||
});
|
||||
|
||||
@ -91,7 +87,6 @@ void main() {
|
||||
FileSystem: () => memoryFileSystem,
|
||||
ProcessManager: () => mockProcessManager,
|
||||
Xcode: () => mockXcode,
|
||||
Logger: () => bufferLogger,
|
||||
PlistParser: () => mockPlistUtils,
|
||||
});
|
||||
|
||||
@ -114,7 +109,6 @@ void main() {
|
||||
FileSystem: () => memoryFileSystem,
|
||||
ProcessManager: () => mockProcessManager,
|
||||
Xcode: () => mockXcode,
|
||||
Logger: () => bufferLogger,
|
||||
PlistParser: () => mockPlistUtils,
|
||||
});
|
||||
|
||||
@ -143,7 +137,6 @@ void main() {
|
||||
FileSystem: () => memoryFileSystem,
|
||||
ProcessManager: () => mockProcessManager,
|
||||
Xcode: () => mockXcode,
|
||||
Logger: () => bufferLogger,
|
||||
PlistParser: () => mockPlistUtils,
|
||||
});
|
||||
|
||||
@ -162,13 +155,12 @@ void main() {
|
||||
|
||||
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 @@ void main() {
|
||||
|
||||
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,
|
||||
});
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@ import 'dart:async';
|
||||
|
||||
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 @@ void main() {
|
||||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => mockProcessManager,
|
||||
OutputPreferences: () => OutputPreferences(showColor: false),
|
||||
Logger: () => BufferLogger(),
|
||||
Platform: kNoColorTerminalPlatform,
|
||||
});
|
||||
|
||||
|
||||
@ -6,6 +6,8 @@ import 'package:file/memory.dart';
|
||||
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 @@ void main() {
|
||||
});
|
||||
|
||||
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);
|
||||
|
||||
@ -6,7 +6,6 @@ import 'dart:async';
|
||||
|
||||
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 @@ void main() {
|
||||
|
||||
group('hot attach', () {
|
||||
MockResidentCompiler residentCompiler = MockResidentCompiler();
|
||||
BufferLogger mockLogger;
|
||||
MockLocalEngineArtifacts mockArtifacts;
|
||||
|
||||
setUp(() {
|
||||
residentCompiler = MockResidentCompiler();
|
||||
mockLogger = BufferLogger();
|
||||
mockArtifacts = MockLocalEngineArtifacts();
|
||||
});
|
||||
|
||||
@ -298,13 +295,12 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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),
|
||||
});
|
||||
});
|
||||
|
||||
@ -654,6 +654,8 @@ class MockConfig extends Mock implements Config {}
|
||||
Stream<String> mockTerminalStdInStream;
|
||||
|
||||
class TestTerminal extends AnsiTerminal {
|
||||
TestTerminal() : super(stdio: globals.stdio, platform: globals.platform);
|
||||
|
||||
@override
|
||||
String bolden(String message) => '<bold>$message</bold>';
|
||||
|
||||
|
||||
@ -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 @@ void main() {
|
||||
final ProjectFileInvalidator projectFileInvalidator = ProjectFileInvalidator(
|
||||
fileSystem: MemoryFileSystem(),
|
||||
platform: FakePlatform(),
|
||||
logger: BufferLogger(),
|
||||
logger: bufferLogger,
|
||||
);
|
||||
|
||||
expect(
|
||||
@ -55,7 +69,7 @@ void main() {
|
||||
final ProjectFileInvalidator projectFileInvalidator = ProjectFileInvalidator(
|
||||
fileSystem: MemoryFileSystem(),
|
||||
platform: FakePlatform(),
|
||||
logger: BufferLogger(),
|
||||
logger: bufferLogger,
|
||||
);
|
||||
|
||||
expect(
|
||||
|
||||
@ -7,6 +7,7 @@ import 'dart:async';
|
||||
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/resident_web_runner.dart';
|
||||
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 @@ void main() {
|
||||
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 {
|
||||
|
||||
@ -11,6 +11,7 @@ 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/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/chrome.dart';
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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(),
|
||||
))
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@ -7,10 +7,12 @@ import 'dart:io';
|
||||
|
||||
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 @@ class MockPeer implements rpc.Peer {
|
||||
void main() {
|
||||
MockStdio mockStdio;
|
||||
group('VMService', () {
|
||||
|
||||
setUp(() {
|
||||
mockStdio = MockStdio();
|
||||
});
|
||||
@ -188,8 +191,12 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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 @@ void main() {
|
||||
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(),
|
||||
),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -92,6 +92,7 @@ void testUsingContext(
|
||||
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 @@ void testUsingContext(
|
||||
return mock;
|
||||
},
|
||||
OutputPreferences: () => OutputPreferences.test(),
|
||||
Logger: () => BufferLogger(),
|
||||
Logger: () => BufferLogger(
|
||||
terminal: globals.terminal,
|
||||
outputPreferences: outputPreferences,
|
||||
),
|
||||
OperatingSystemUtils: () => FakeOperatingSystemUtils(),
|
||||
PersistentToolState: () => buildPersistentToolState(globals.fs),
|
||||
SimControl: () => MockSimControl(),
|
||||
|
||||
@ -38,7 +38,10 @@ final Map<Type, Generator> _testbedDefaults = <Type, Generator>{
|
||||
// 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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user