Unverified Commit 749589d8 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] Remove context usage from status and clean up test cases (#48446)

parent 5f4e4a3f
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import 'dart:async'; import 'dart:async';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:platform/platform.dart';
import '../base/context.dart'; import '../base/context.dart';
import '../globals.dart' as globals; import '../globals.dart' as globals;
...@@ -21,6 +22,15 @@ const Duration _kSlowOperation = Duration(minutes: 2); ...@@ -21,6 +22,15 @@ const Duration _kSlowOperation = Duration(minutes: 2);
/// If not provided via injection, a default instance is provided. /// If not provided via injection, a default instance is provided.
TimeoutConfiguration get timeoutConfiguration => context.get<TimeoutConfiguration>() ?? const TimeoutConfiguration(); TimeoutConfiguration get timeoutConfiguration => context.get<TimeoutConfiguration>() ?? const TimeoutConfiguration();
/// A factory for generating [Stopwatch] instances for [Status] instances.
class StopwatchFactory {
/// const constructor so that subclasses may be const.
const StopwatchFactory();
/// Create a new [Stopwatch] instance.
Stopwatch createStopwatch() => Stopwatch();
}
class TimeoutConfiguration { class TimeoutConfiguration {
const TimeoutConfiguration(); const TimeoutConfiguration();
...@@ -166,11 +176,15 @@ class StdoutLogger extends Logger { ...@@ -166,11 +176,15 @@ class StdoutLogger extends Logger {
@required Stdio stdio, @required Stdio stdio,
@required OutputPreferences outputPreferences, @required OutputPreferences outputPreferences,
@required TimeoutConfiguration timeoutConfiguration, @required TimeoutConfiguration timeoutConfiguration,
@required Platform platform,
StopwatchFactory stopwatchFactory = const StopwatchFactory(),
}) })
: _stdio = stdio, : _stdio = stdio,
_terminal = terminal, _terminal = terminal,
_timeoutConfiguration = timeoutConfiguration, _timeoutConfiguration = timeoutConfiguration,
_outputPreferences = outputPreferences; _outputPreferences = outputPreferences,
_stopwatchFactory = stopwatchFactory,
_platform = platform;
@override @override
final AnsiTerminal _terminal; final AnsiTerminal _terminal;
...@@ -179,6 +193,8 @@ class StdoutLogger extends Logger { ...@@ -179,6 +193,8 @@ class StdoutLogger extends Logger {
@override @override
final TimeoutConfiguration _timeoutConfiguration; final TimeoutConfiguration _timeoutConfiguration;
final Stdio _stdio; final Stdio _stdio;
final StopwatchFactory _stopwatchFactory;
final Platform _platform;
Status _status; Status _status;
...@@ -273,7 +289,8 @@ class StdoutLogger extends Logger { ...@@ -273,7 +289,8 @@ class StdoutLogger extends Logger {
return SilentStatus( return SilentStatus(
timeout: timeout, timeout: timeout,
onFinish: _clearStatus, onFinish: _clearStatus,
timeoutConfiguration: _timeoutConfiguration timeoutConfiguration: _timeoutConfiguration,
stopwatch: _stopwatchFactory.createStopwatch(),
)..start(); )..start();
} }
if (supportsColor) { if (supportsColor) {
...@@ -285,6 +302,8 @@ class StdoutLogger extends Logger { ...@@ -285,6 +302,8 @@ class StdoutLogger extends Logger {
onFinish: _clearStatus, onFinish: _clearStatus,
stdio: _stdio, stdio: _stdio,
timeoutConfiguration: _timeoutConfiguration, timeoutConfiguration: _timeoutConfiguration,
platform: _platform,
stopwatch: _stopwatchFactory.createStopwatch(),
)..start(); )..start();
} else { } else {
_status = SummaryStatus( _status = SummaryStatus(
...@@ -294,6 +313,7 @@ class StdoutLogger extends Logger { ...@@ -294,6 +313,7 @@ class StdoutLogger extends Logger {
onFinish: _clearStatus, onFinish: _clearStatus,
stdio: _stdio, stdio: _stdio,
timeoutConfiguration: _timeoutConfiguration, timeoutConfiguration: _timeoutConfiguration,
stopwatch: _stopwatchFactory.createStopwatch(),
)..start(); )..start();
} }
return _status; return _status;
...@@ -321,11 +341,15 @@ class WindowsStdoutLogger extends StdoutLogger { ...@@ -321,11 +341,15 @@ class WindowsStdoutLogger extends StdoutLogger {
@required Stdio stdio, @required Stdio stdio,
@required OutputPreferences outputPreferences, @required OutputPreferences outputPreferences,
@required TimeoutConfiguration timeoutConfiguration, @required TimeoutConfiguration timeoutConfiguration,
@required Platform platform,
StopwatchFactory stopwatchFactory = const StopwatchFactory(),
}) : super( }) : super(
terminal: terminal, terminal: terminal,
stdio: stdio, stdio: stdio,
outputPreferences: outputPreferences, outputPreferences: outputPreferences,
timeoutConfiguration: timeoutConfiguration, timeoutConfiguration: timeoutConfiguration,
stopwatchFactory: stopwatchFactory,
platform: platform,
); );
@override @override
...@@ -342,10 +366,12 @@ class BufferLogger extends Logger { ...@@ -342,10 +366,12 @@ class BufferLogger extends Logger {
BufferLogger({ BufferLogger({
@required AnsiTerminal terminal, @required AnsiTerminal terminal,
@required OutputPreferences outputPreferences, @required OutputPreferences outputPreferences,
TimeoutConfiguration timeoutConfiguration = const TimeoutConfiguration() TimeoutConfiguration timeoutConfiguration = const TimeoutConfiguration(),
StopwatchFactory stopwatchFactory = const StopwatchFactory(),
}) : _outputPreferences = outputPreferences, }) : _outputPreferences = outputPreferences,
_terminal = terminal, _terminal = terminal,
_timeoutConfiguration = timeoutConfiguration; _timeoutConfiguration = timeoutConfiguration,
_stopwatchFactory = stopwatchFactory;
@override @override
final OutputPreferences _outputPreferences; final OutputPreferences _outputPreferences;
...@@ -356,6 +382,8 @@ class BufferLogger extends Logger { ...@@ -356,6 +382,8 @@ class BufferLogger extends Logger {
@override @override
final TimeoutConfiguration _timeoutConfiguration; final TimeoutConfiguration _timeoutConfiguration;
final StopwatchFactory _stopwatchFactory;
@override @override
bool get isVerbose => false; bool get isVerbose => false;
...@@ -437,7 +465,7 @@ class BufferLogger extends Logger { ...@@ -437,7 +465,7 @@ class BufferLogger extends Logger {
return SilentStatus( return SilentStatus(
timeout: timeout, timeout: timeout,
timeoutConfiguration: _timeoutConfiguration, timeoutConfiguration: _timeoutConfiguration,
stopwatch: _stopwatchFactory.createStopwatch(),
)..start(); )..start();
} }
...@@ -453,8 +481,10 @@ class BufferLogger extends Logger { ...@@ -453,8 +481,10 @@ class BufferLogger extends Logger {
} }
class VerboseLogger extends Logger { class VerboseLogger extends Logger {
VerboseLogger(this.parent, { @required Stopwatch stopwatch }) : VerboseLogger(this.parent, {
_stopwatch = stopwatch ?? context.get<Stopwatch>() ?? Stopwatch() { StopwatchFactory stopwatchFactory = const StopwatchFactory()
}) : _stopwatch = stopwatchFactory.createStopwatch(),
_stopwatchFactory = stopwatchFactory {
_stopwatch.start(); _stopwatch.start();
} }
...@@ -471,6 +501,8 @@ class VerboseLogger extends Logger { ...@@ -471,6 +501,8 @@ class VerboseLogger extends Logger {
@override @override
TimeoutConfiguration get _timeoutConfiguration => parent._timeoutConfiguration; TimeoutConfiguration get _timeoutConfiguration => parent._timeoutConfiguration;
final StopwatchFactory _stopwatchFactory;
@override @override
bool get isVerbose => true; bool get isVerbose => true;
...@@ -529,10 +561,12 @@ class VerboseLogger extends Logger { ...@@ -529,10 +561,12 @@ class VerboseLogger extends Logger {
}) { }) {
assert(progressIndicatorPadding != null); assert(progressIndicatorPadding != null);
printStatus(message); printStatus(message);
final Stopwatch timer = Stopwatch()..start(); final Stopwatch timer = _stopwatchFactory.createStopwatch()..start();
return SilentStatus( return SilentStatus(
timeout: timeout, timeout: timeout,
timeoutConfiguration: _timeoutConfiguration, timeoutConfiguration: _timeoutConfiguration,
// This is intentionally a different stopwatch than above.
stopwatch: _stopwatchFactory.createStopwatch(),
onFinish: () { onFinish: () {
String time; String time;
if (timeout == null || timeout > _timeoutConfiguration.fastOperation) { if (timeout == null || timeout > _timeoutConfiguration.fastOperation) {
...@@ -623,28 +657,36 @@ abstract class Status { ...@@ -623,28 +657,36 @@ abstract class Status {
@required this.timeout, @required this.timeout,
@required TimeoutConfiguration timeoutConfiguration, @required TimeoutConfiguration timeoutConfiguration,
this.onFinish, this.onFinish,
}) : _timeoutConfiguration = timeoutConfiguration; @required Stopwatch stopwatch,
}) : _timeoutConfiguration = timeoutConfiguration,
_stopwatch = stopwatch;
/// A [SilentStatus] or an [AnsiSpinner] (depending on whether the /// A [SilentStatus] or an [AnsiSpinner] (depending on whether the
/// terminal is fancy enough), already started. /// terminal is fancy enough), already started.
factory Status.withSpinner({ factory Status.withSpinner({
@required Duration timeout, @required Duration timeout,
@required TimeoutConfiguration timeoutConfiguration, @required TimeoutConfiguration timeoutConfiguration,
@required Stopwatch stopwatch,
@required bool supportsColor,
@required Platform platform,
VoidCallback onFinish, VoidCallback onFinish,
SlowWarningCallback slowWarningCallback, SlowWarningCallback slowWarningCallback,
}) { }) {
if (globals.terminal.supportsColor) { if (supportsColor) {
return AnsiSpinner( return AnsiSpinner(
timeout: timeout, timeout: timeout,
onFinish: onFinish, onFinish: onFinish,
slowWarningCallback: slowWarningCallback, slowWarningCallback: slowWarningCallback,
timeoutConfiguration: timeoutConfiguration, timeoutConfiguration: timeoutConfiguration,
stopwatch: stopwatch,
platform: platform,
)..start(); )..start();
} }
return SilentStatus( return SilentStatus(
timeout: timeout, timeout: timeout,
onFinish: onFinish, onFinish: onFinish,
timeoutConfiguration: timeoutConfiguration, timeoutConfiguration: timeoutConfiguration,
stopwatch: stopwatch,
)..start(); )..start();
} }
...@@ -653,7 +695,7 @@ abstract class Status { ...@@ -653,7 +695,7 @@ abstract class Status {
final TimeoutConfiguration _timeoutConfiguration; final TimeoutConfiguration _timeoutConfiguration;
@protected @protected
final Stopwatch _stopwatch = context.get<Stopwatch>() ?? Stopwatch(); final Stopwatch _stopwatch;
@protected @protected
@visibleForTesting @visibleForTesting
...@@ -704,11 +746,13 @@ class SilentStatus extends Status { ...@@ -704,11 +746,13 @@ class SilentStatus extends Status {
SilentStatus({ SilentStatus({
@required Duration timeout, @required Duration timeout,
@required TimeoutConfiguration timeoutConfiguration, @required TimeoutConfiguration timeoutConfiguration,
@required Stopwatch stopwatch,
VoidCallback onFinish, VoidCallback onFinish,
}) : super( }) : super(
timeout: timeout, timeout: timeout,
onFinish: onFinish, onFinish: onFinish,
timeoutConfiguration: timeoutConfiguration, timeoutConfiguration: timeoutConfiguration,
stopwatch: stopwatch,
); );
} }
...@@ -718,14 +762,20 @@ class SummaryStatus extends Status { ...@@ -718,14 +762,20 @@ class SummaryStatus extends Status {
SummaryStatus({ SummaryStatus({
this.message = '', this.message = '',
@required Duration timeout, @required Duration timeout,
@required TimeoutConfiguration timeoutConfiguration,
@required Stopwatch stopwatch,
this.padding = kDefaultStatusPadding, this.padding = kDefaultStatusPadding,
VoidCallback onFinish, VoidCallback onFinish,
Stdio stdio, Stdio stdio,
@required TimeoutConfiguration timeoutConfiguration,
}) : assert(message != null), }) : assert(message != null),
assert(padding != null), assert(padding != null),
_stdio = stdio ?? globals.stdio, _stdio = stdio ?? globals.stdio,
super(timeout: timeout, onFinish: onFinish, timeoutConfiguration: timeoutConfiguration); super(
timeout: timeout,
onFinish: onFinish,
timeoutConfiguration: timeoutConfiguration,
stopwatch: stopwatch,
);
final String message; final String message;
final int padding; final int padding;
...@@ -794,16 +844,25 @@ class SummaryStatus extends Status { ...@@ -794,16 +844,25 @@ class SummaryStatus extends Status {
class AnsiSpinner extends Status { class AnsiSpinner extends Status {
AnsiSpinner({ AnsiSpinner({
@required Duration timeout, @required Duration timeout,
@required TimeoutConfiguration timeoutConfiguration,
@required Stopwatch stopwatch,
@required Platform platform,
VoidCallback onFinish, VoidCallback onFinish,
this.slowWarningCallback, this.slowWarningCallback,
Stdio stdio, Stdio stdio,
@required TimeoutConfiguration timeoutConfiguration,
}) : _stdio = stdio ?? globals.stdio, }) : _stdio = stdio ?? globals.stdio,
super(timeout: timeout, onFinish: onFinish, timeoutConfiguration: timeoutConfiguration); _isWindows = platform.isWindows,
super(
timeout: timeout,
onFinish: onFinish,
timeoutConfiguration: timeoutConfiguration,
stopwatch: stopwatch,
);
final String _backspaceChar = '\b'; final String _backspaceChar = '\b';
final String _clearChar = ' '; final String _clearChar = ' ';
final Stdio _stdio; final Stdio _stdio;
final bool _isWindows;
bool timedOut = false; bool timedOut = false;
...@@ -811,9 +870,9 @@ class AnsiSpinner extends Status { ...@@ -811,9 +870,9 @@ class AnsiSpinner extends Status {
Timer timer; Timer timer;
// Windows console font has a limited set of Unicode characters. // Windows console font has a limited set of Unicode characters.
List<String> get _animation => globals.platform.isWindows List<String> get _animation => _isWindows
? <String>[r'-', r'\', r'|', r'/'] ? const <String>[r'-', r'\', r'|', r'/']
: <String>['⣾', '⣽', '⣻', '⢿', '⡿', '⣟', '⣯', '⣷']; : const <String>['⣾', '⣽', '⣻', '⢿', '⡿', '⣟', '⣯', '⣷'];
static const String _defaultSlowWarning = '(This is taking an unexpectedly long time.)'; static const String _defaultSlowWarning = '(This is taking an unexpectedly long time.)';
final SlowWarningCallback slowWarningCallback; final SlowWarningCallback slowWarningCallback;
...@@ -903,16 +962,25 @@ const int _kTimePadding = 8; // should fit "99,999ms" ...@@ -903,16 +962,25 @@ const int _kTimePadding = 8; // should fit "99,999ms"
class AnsiStatus extends AnsiSpinner { class AnsiStatus extends AnsiSpinner {
AnsiStatus({ AnsiStatus({
this.message = '', this.message = '',
@required Duration timeout,
this.multilineOutput = false, this.multilineOutput = false,
this.padding = kDefaultStatusPadding, this.padding = kDefaultStatusPadding,
@required Duration timeout,
@required Stopwatch stopwatch,
@required Platform platform,
VoidCallback onFinish, VoidCallback onFinish,
Stdio stdio, Stdio stdio,
TimeoutConfiguration timeoutConfiguration, TimeoutConfiguration timeoutConfiguration,
}) : assert(message != null), }) : assert(message != null),
assert(multilineOutput != null), assert(multilineOutput != null),
assert(padding != null), assert(padding != null),
super(timeout: timeout, onFinish: onFinish, stdio: stdio, timeoutConfiguration: timeoutConfiguration); super(
timeout: timeout,
onFinish: onFinish,
stdio: stdio,
timeoutConfiguration: timeoutConfiguration,
stopwatch: stopwatch,
platform: platform,
);
final String message; final String message;
final bool multilineOutput; final bool multilineOutput;
......
...@@ -974,7 +974,11 @@ class NotifyingLogger extends Logger { ...@@ -974,7 +974,11 @@ class NotifyingLogger extends Logger {
}) { }) {
assert(timeout != null); assert(timeout != null);
printStatus(message); printStatus(message);
return SilentStatus(timeout: timeout, timeoutConfiguration: timeoutConfiguration); return SilentStatus(
timeout: timeout,
timeoutConfiguration: timeoutConfiguration,
stopwatch: Stopwatch(),
);
} }
void dispose() { void dispose() {
...@@ -1181,7 +1185,7 @@ class _AppRunLogger extends Logger { ...@@ -1181,7 +1185,7 @@ class _AppRunLogger extends Logger {
'progressId': progressId, 'progressId': progressId,
'finished': true, 'finished': true,
}); });
})..start(); }, stopwatch: Stopwatch())..start();
return _status; return _status;
} }
......
...@@ -108,12 +108,14 @@ Future<T> runInContext<T>( ...@@ -108,12 +108,14 @@ Future<T> runInContext<T>(
stdio: globals.stdio, stdio: globals.stdio,
outputPreferences: outputPreferences, outputPreferences: outputPreferences,
timeoutConfiguration: timeoutConfiguration, timeoutConfiguration: timeoutConfiguration,
platform: globals.platform,
) )
: StdoutLogger( : StdoutLogger(
terminal: globals.terminal, terminal: globals.terminal,
stdio: globals.stdio, stdio: globals.stdio,
outputPreferences: outputPreferences, outputPreferences: outputPreferences,
timeoutConfiguration: timeoutConfiguration, timeoutConfiguration: timeoutConfiguration,
platform: globals.platform,
), ),
MacOSWorkflow: () => const MacOSWorkflow(), MacOSWorkflow: () => const MacOSWorkflow(),
MDnsObservatoryDiscovery: () => MDnsObservatoryDiscovery(), MDnsObservatoryDiscovery: () => MDnsObservatoryDiscovery(),
......
...@@ -259,6 +259,9 @@ class Doctor { ...@@ -259,6 +259,9 @@ class Doctor {
timeout: timeoutConfiguration.fastOperation, timeout: timeoutConfiguration.fastOperation,
slowWarningCallback: () => validator.slowWarning, slowWarningCallback: () => validator.slowWarning,
timeoutConfiguration: timeoutConfiguration, timeoutConfiguration: timeoutConfiguration,
stopwatch: Stopwatch(),
supportsColor: globals.terminal.supportsColor,
platform: globals.platform,
); );
ValidationResult result; ValidationResult result;
try { try {
......
...@@ -285,6 +285,9 @@ class XcodeProjectInterpreter { ...@@ -285,6 +285,9 @@ class XcodeProjectInterpreter {
final Status status = Status.withSpinner( final Status status = Status.withSpinner(
timeout: timeoutConfiguration.fastOperation, timeout: timeoutConfiguration.fastOperation,
timeoutConfiguration: timeoutConfiguration, timeoutConfiguration: timeoutConfiguration,
platform: globals.platform,
stopwatch: Stopwatch(),
supportsColor: globals.terminal.supportsColor,
); );
final List<String> showBuildSettingsCommand = <String>[ final List<String> showBuildSettingsCommand = <String>[
_executable, _executable,
......
...@@ -239,7 +239,7 @@ class FlutterCommandRunner extends CommandRunner<void> { ...@@ -239,7 +239,7 @@ class FlutterCommandRunner extends CommandRunner<void> {
// Check for verbose. // Check for verbose.
if (topLevelResults['verbose'] as bool) { if (topLevelResults['verbose'] as bool) {
// Override the logger. // Override the logger.
contextOverrides[Logger] = VerboseLogger(globals.logger, stopwatch: Stopwatch()); contextOverrides[Logger] = VerboseLogger(globals.logger);
} }
// Don't set wrapColumns unless the user said to: if it's set, then all // Don't set wrapColumns unless the user said to: if it's set, then all
......
...@@ -704,7 +704,11 @@ class StreamLogger extends Logger { ...@@ -704,7 +704,11 @@ class StreamLogger extends Logger {
int progressIndicatorPadding = kDefaultStatusPadding, int progressIndicatorPadding = kDefaultStatusPadding,
}) { }) {
_log('[progress] $message'); _log('[progress] $message');
return SilentStatus(timeout: timeout, timeoutConfiguration: timeoutConfiguration)..start(); return SilentStatus(
timeout: timeout,
timeoutConfiguration: timeoutConfiguration,
stopwatch: Stopwatch(),
)..start();
} }
bool _interrupt = false; bool _interrupt = false;
......
...@@ -5,24 +5,20 @@ ...@@ -5,24 +5,20 @@
import 'dart:convert' show jsonEncode; import 'dart:convert' show jsonEncode;
import 'package:platform/platform.dart'; import 'package:platform/platform.dart';
import 'package:flutter_tools/src/base/context.dart';
import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/terminal.dart'; import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:quiver/testing/async.dart'; import 'package:quiver/testing/async.dart';
import '../../src/common.dart'; import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/mocks.dart'; import '../../src/mocks.dart';
final Platform _kNoAnsiPlatform = FakePlatform.fromPlatform(const LocalPlatform())..stdoutSupportsAnsi = false; final Platform _kNoAnsiPlatform = FakePlatform.fromPlatform(const LocalPlatform())..stdoutSupportsAnsi = false;
final String red = RegExp.escape(AnsiTerminal.red);
final String bold = RegExp.escape(AnsiTerminal.bold);
final String resetBold = RegExp.escape(AnsiTerminal.resetBold);
final String resetColor = RegExp.escape(AnsiTerminal.resetColor);
void main() { void main() {
final String red = RegExp.escape(AnsiTerminal.red);
final String bold = RegExp.escape(AnsiTerminal.bold);
final String resetBold = RegExp.escape(AnsiTerminal.resetBold);
final String resetColor = RegExp.escape(AnsiTerminal.resetColor);
group('AppContext', () { group('AppContext', () {
FakeStopwatch fakeStopWatch; FakeStopwatch fakeStopWatch;
...@@ -37,7 +33,10 @@ void main() { ...@@ -37,7 +33,10 @@ void main() {
), ),
outputPreferences: OutputPreferences.test(showColor: false), outputPreferences: OutputPreferences.test(showColor: false),
); );
final VerboseLogger verboseLogger = VerboseLogger(mockLogger, stopwatch: fakeStopWatch); final VerboseLogger verboseLogger = VerboseLogger(
mockLogger,
stopwatchFactory: FakeStopwatchFactory(fakeStopWatch),
);
verboseLogger.printStatus('Hey Hey Hey Hey'); verboseLogger.printStatus('Hey Hey Hey Hey');
verboseLogger.printTrace('Oooh, I do I do I do'); verboseLogger.printTrace('Oooh, I do I do I do');
...@@ -57,7 +56,9 @@ void main() { ...@@ -57,7 +56,9 @@ void main() {
), ),
outputPreferences: OutputPreferences.test(showColor: true), outputPreferences: OutputPreferences.test(showColor: true),
); );
final VerboseLogger verboseLogger = VerboseLogger(mockLogger, stopwatch: fakeStopWatch); final VerboseLogger verboseLogger = VerboseLogger(
mockLogger, stopwatchFactory: FakeStopwatchFactory(fakeStopWatch),
);
verboseLogger.printStatus('Hey Hey Hey Hey'); verboseLogger.printStatus('Hey Hey Hey Hey');
verboseLogger.printTrace('Oooh, I do I do I do'); verboseLogger.printTrace('Oooh, I do I do I do');
...@@ -77,25 +78,16 @@ void main() { ...@@ -77,25 +78,16 @@ void main() {
group('Spinners', () { group('Spinners', () {
MockStdio mockStdio; MockStdio mockStdio;
FakeStopwatch mockStopwatch; FakeStopwatch mockStopwatch;
FakeStopwatchFactory stopwatchFactory;
int called; int called;
const List<String> testPlatforms = <String>['linux', 'macos', 'windows', 'fuchsia']; const List<String> testPlatforms = <String>['linux', 'macos', 'windows', 'fuchsia'];
final RegExp secondDigits = RegExp(r'[0-9,.]*[0-9]m?s'); final RegExp secondDigits = RegExp(r'[0-9,.]*[0-9]m?s');
AnsiStatus _createAnsiStatus() {
return AnsiStatus(
message: 'Hello world',
timeout: const Duration(seconds: 2),
padding: 20,
onFinish: () => called += 1,
stdio: mockStdio,
timeoutConfiguration: const TimeoutConfiguration(),
);
}
setUp(() { setUp(() {
mockStopwatch = FakeStopwatch(); mockStopwatch = FakeStopwatch();
mockStdio = MockStdio(); mockStdio = MockStdio();
called = 0; called = 0;
stopwatchFactory = FakeStopwatchFactory(mockStopwatch);
}); });
List<String> outputStdout() => mockStdio.writtenToStdout.join('').split('\n'); List<String> outputStdout() => mockStdio.writtenToStdout.join('').split('\n');
...@@ -109,7 +101,21 @@ void main() { ...@@ -109,7 +101,21 @@ void main() {
} }
for (final String testOs in testPlatforms) { for (final String testOs in testPlatforms) {
testUsingContext('AnsiSpinner works for $testOs (1)', () async { Platform currentPlatform() => FakePlatform(operatingSystem: testOs);
AnsiStatus createAnsiStatus() {
return AnsiStatus(
message: 'Hello world',
timeout: const Duration(seconds: 2),
padding: 20,
onFinish: () => called += 1,
stdio: mockStdio,
timeoutConfiguration: const TimeoutConfiguration(),
stopwatch: stopwatchFactory.createStopwatch(),
platform: currentPlatform(),
);
}
testWithoutContext('AnsiSpinner works for $testOs (1)', () async {
bool done = false; bool done = false;
mockStopwatch = FakeStopwatch(); mockStopwatch = FakeStopwatch();
FakeAsync().run((FakeAsync time) { FakeAsync().run((FakeAsync time) {
...@@ -117,38 +123,35 @@ void main() { ...@@ -117,38 +123,35 @@ void main() {
timeout: const Duration(hours: 10), timeout: const Duration(hours: 10),
stdio: mockStdio, stdio: mockStdio,
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
stopwatch: stopwatchFactory.createStopwatch(),
platform: currentPlatform(),
)..start(); )..start();
doWhileAsync(time, () => ansiSpinner.ticks < 10); doWhileAsync(time, () => ansiSpinner.ticks < 10);
List<String> lines = outputStdout(); List<String> lines = outputStdout();
expect(lines[0], startsWith( expect(lines[0], startsWith(
globals.platform.isWindows currentPlatform().isWindows
? ' \b\\\b|\b/\b-\b\\\b|\b/\b-' ? ' \b\\\b|\b/\b-\b\\\b|\b/\b-'
: ' \b⣽\b⣻\b⢿\b⡿\b⣟\b⣯\b⣷\b⣾\b⣽\b⣻' : ' \b⣽\b⣻\b⢿\b⡿\b⣟\b⣯\b⣷\b⣾\b⣽\b⣻'
), ),
); );
expect(lines[0].endsWith('\n'), isFalse); expect(lines[0].endsWith('\n'), isFalse);
expect(lines.length, equals(1)); expect(lines.length, equals(1));
ansiSpinner.stop(); ansiSpinner.stop();
lines = outputStdout(); lines = outputStdout();
expect(lines[0], endsWith('\b \b')); expect(lines[0], endsWith('\b \b'));
expect(lines.length, equals(1)); expect(lines.length, equals(1));
// Verify that stopping or canceling multiple times throws. // Verify that stopping or canceling multiple times throws.
expect(() { expect(ansiSpinner.stop, throwsA(isInstanceOf<AssertionError>()));
ansiSpinner.stop(); expect(ansiSpinner.cancel, throwsA(isInstanceOf<AssertionError>()));
}, throwsA(isInstanceOf<AssertionError>()));
expect(() {
ansiSpinner.cancel();
}, throwsA(isInstanceOf<AssertionError>()));
done = true; done = true;
}); });
expect(done, isTrue); expect(done, isTrue);
}, overrides: <Type, Generator>{
Platform: () => FakePlatform(operatingSystem: testOs),
Stopwatch: () => mockStopwatch,
}); });
testUsingContext('AnsiSpinner works for $testOs (2)', () async { testWithoutContext('AnsiSpinner works for $testOs (2)', () async {
bool done = false; bool done = false;
mockStopwatch = FakeStopwatch(); mockStopwatch = FakeStopwatch();
FakeAsync().run((FakeAsync time) { FakeAsync().run((FakeAsync time) {
...@@ -156,13 +159,17 @@ void main() { ...@@ -156,13 +159,17 @@ void main() {
timeout: const Duration(seconds: 2), timeout: const Duration(seconds: 2),
stdio: mockStdio, stdio: mockStdio,
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
stopwatch: mockStopwatch,
platform: FakePlatform(operatingSystem: testOs),
)..start(); )..start();
mockStopwatch.elapsed = const Duration(seconds: 1); mockStopwatch.elapsed = const Duration(seconds: 1);
doWhileAsync(time, () => ansiSpinner.ticks < 10); // one second doWhileAsync(time, () => ansiSpinner.ticks < 10); // one second
expect(ansiSpinner.seemsSlow, isFalse); expect(ansiSpinner.seemsSlow, isFalse);
expect(outputStdout().join('\n'), isNot(contains('This is taking an unexpectedly long time.'))); expect(outputStdout().join('\n'), isNot(contains('This is taking an unexpectedly long time.')));
mockStopwatch.elapsed = const Duration(seconds: 3); mockStopwatch.elapsed = const Duration(seconds: 3);
doWhileAsync(time, () => ansiSpinner.ticks < 30); // three seconds doWhileAsync(time, () => ansiSpinner.ticks < 30); // three seconds
expect(ansiSpinner.seemsSlow, isTrue); expect(ansiSpinner.seemsSlow, isTrue);
// Check the 2nd line to verify there's a newline before the warning // Check the 2nd line to verify there's a newline before the warning
expect(outputStdout()[1], contains('This is taking an unexpectedly long time.')); expect(outputStdout()[1], contains('This is taking an unexpectedly long time.'));
...@@ -171,13 +178,9 @@ void main() { ...@@ -171,13 +178,9 @@ void main() {
done = true; done = true;
}); });
expect(done, isTrue); expect(done, isTrue);
}, overrides: <Type, Generator>{
Platform: () => FakePlatform(operatingSystem: testOs),
Stopwatch: () => mockStopwatch,
}); });
// Uses Stopwatch from context. testWithoutContext('Stdout startProgress on colored terminal for $testOs', () async {
testUsingContext('Stdout startProgress on colored terminal for $testOs', () async {
bool done = false; bool done = false;
FakeAsync().run((FakeAsync time) { FakeAsync().run((FakeAsync time) {
final Logger logger = StdoutLogger( final Logger logger = StdoutLogger(
...@@ -188,27 +191,31 @@ void main() { ...@@ -188,27 +191,31 @@ void main() {
stdio: mockStdio, stdio: mockStdio,
outputPreferences: OutputPreferences.test(showColor: true), outputPreferences: OutputPreferences.test(showColor: true),
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
stopwatchFactory: stopwatchFactory,
platform: currentPlatform(),
); );
final Status status = logger.startProgress( final Status status = logger.startProgress(
'Hello', 'Hello',
progressId: null, progressId: null,
timeout: timeoutConfiguration.slowOperation, timeout: const TimeoutConfiguration().slowOperation,
progressIndicatorPadding: 20, // this minus the "Hello" equals the 15 below. progressIndicatorPadding: 20, // this minus the "Hello" equals the 15 below.
); );
expect(outputStderr().length, equals(1)); expect(outputStderr().length, equals(1));
expect(outputStderr().first, isEmpty); expect(outputStderr().first, isEmpty);
// the 5 below is the margin that is always included between the message and the time. // the 5 below is the margin that is always included between the message and the time.
expect(outputStdout().join('\n'), matches(globals.platform.isWindows ? r'^Hello {15} {5} {8}[\b]{8} {7}\\$' : expect(outputStdout().join('\n'),
matches(currentPlatform().isWindows ? r'^Hello {15} {5} {8}[\b]{8} {7}\\$' :
r'^Hello {15} {5} {8}[\b]{8} {7}⣽$')); r'^Hello {15} {5} {8}[\b]{8} {7}⣽$'));
status.stop(); status.stop();
expect(outputStdout().join('\n'), matches(globals.platform.isWindows ? r'^Hello {15} {5} {8}[\b]{8} {7}\\[\b]{8} {8}[\b]{8}[\d, ]{4}[\d]\.[\d]s[\n]$' : expect(outputStdout().join('\n'),
matches(currentPlatform().isWindows ? r'^Hello {15} {5} {8}[\b]{8} {7}\\[\b]{8} {8}[\b]{8}[\d, ]{4}[\d]\.[\d]s[\n]$' :
r'^Hello {15} {5} {8}[\b]{8} {7}⣽[\b]{8} {8}[\b]{8}[\d, ]{4}[\d]\.[\d]s[\n]$')); r'^Hello {15} {5} {8}[\b]{8} {7}⣽[\b]{8} {8}[\b]{8}[\d, ]{4}[\d]\.[\d]s[\n]$'));
done = true; done = true;
}); });
expect(done, isTrue); expect(done, isTrue);
}); });
testUsingContext('Stdout startProgress on colored terminal pauses on $testOs', () async { testWithoutContext('Stdout startProgress on colored terminal pauses on $testOs', () async {
bool done = false; bool done = false;
FakeAsync().run((FakeAsync time) { FakeAsync().run((FakeAsync time) {
mockStopwatch.elapsed = const Duration(seconds: 5); mockStopwatch.elapsed = const Duration(seconds: 5);
...@@ -220,6 +227,8 @@ void main() { ...@@ -220,6 +227,8 @@ void main() {
stdio: mockStdio, stdio: mockStdio,
outputPreferences: OutputPreferences.test(showColor: true), outputPreferences: OutputPreferences.test(showColor: true),
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
stopwatchFactory: stopwatchFactory,
platform: currentPlatform(),
); );
final Status status = logger.startProgress( final Status status = logger.startProgress(
'Knock Knock, Who\'s There', 'Knock Knock, Who\'s There',
...@@ -228,8 +237,9 @@ void main() { ...@@ -228,8 +237,9 @@ void main() {
); );
logger.printStatus('Rude Interrupting Cow'); logger.printStatus('Rude Interrupting Cow');
status.stop(); status.stop();
final String a = globals.platform.isWindows ? '\\' : '⣽'; final String a = currentPlatform().isWindows ? '\\' : '⣽';
final String b = globals.platform.isWindows ? '|' : '⣻'; final String b = currentPlatform().isWindows ? '|' : '⣻';
expect( expect(
outputStdout().join('\n'), outputStdout().join('\n'),
'Knock Knock, Who\'s There ' // initial message 'Knock Knock, Who\'s There ' // initial message
...@@ -250,22 +260,22 @@ void main() { ...@@ -250,22 +260,22 @@ void main() {
done = true; done = true;
}); });
expect(done, isTrue); expect(done, isTrue);
}, overrides: <Type, Generator>{
Stopwatch: () => mockStopwatch,
}); });
testUsingContext('AnsiStatus works for $testOs', () { testWithoutContext('AnsiStatus works for $testOs', () {
final AnsiStatus ansiStatus = _createAnsiStatus(); final AnsiStatus ansiStatus = createAnsiStatus();
bool done = false; bool done = false;
FakeAsync().run((FakeAsync time) { FakeAsync().run((FakeAsync time) {
ansiStatus.start(); ansiStatus.start();
mockStopwatch.elapsed = const Duration(seconds: 1); mockStopwatch.elapsed = const Duration(seconds: 1);
doWhileAsync(time, () => ansiStatus.ticks < 10); // one second doWhileAsync(time, () => ansiStatus.ticks < 10); // one second
expect(ansiStatus.seemsSlow, isFalse); expect(ansiStatus.seemsSlow, isFalse);
expect(outputStdout().join('\n'), isNot(contains('This is taking an unexpectedly long time.'))); expect(outputStdout().join('\n'), isNot(contains('This is taking an unexpectedly long time.')));
expect(outputStdout().join('\n'), isNot(contains('(!)'))); expect(outputStdout().join('\n'), isNot(contains('(!)')));
mockStopwatch.elapsed = const Duration(seconds: 3); mockStopwatch.elapsed = const Duration(seconds: 3);
doWhileAsync(time, () => ansiStatus.ticks < 30); // three seconds doWhileAsync(time, () => ansiStatus.ticks < 30); // three seconds
expect(ansiStatus.seemsSlow, isTrue); expect(ansiStatus.seemsSlow, isTrue);
expect(outputStdout().join('\n'), contains('This is taking an unexpectedly long time.')); expect(outputStdout().join('\n'), contains('This is taking an unexpectedly long time.'));
...@@ -283,20 +293,18 @@ void main() { ...@@ -283,20 +293,18 @@ void main() {
done = true; done = true;
}); });
expect(done, isTrue); expect(done, isTrue);
}, overrides: <Type, Generator>{
Platform: () => FakePlatform(operatingSystem: testOs),
Stopwatch: () => mockStopwatch,
}); });
testUsingContext('AnsiStatus works when canceled for $testOs', () async { testWithoutContext('AnsiStatus works when canceled for $testOs', () async {
final AnsiStatus ansiStatus = _createAnsiStatus(); final AnsiStatus ansiStatus = createAnsiStatus();
bool done = false; bool done = false;
FakeAsync().run((FakeAsync time) { FakeAsync().run((FakeAsync time) {
ansiStatus.start(); ansiStatus.start();
mockStopwatch.elapsed = const Duration(seconds: 1); mockStopwatch.elapsed = const Duration(seconds: 1);
doWhileAsync(time, () => ansiStatus.ticks < 10); doWhileAsync(time, () => ansiStatus.ticks < 10);
List<String> lines = outputStdout(); List<String> lines = outputStdout();
expect(lines[0], startsWith(globals.platform.isWindows
expect(lines[0], startsWith(testOs == 'windows'
? 'Hello world \b\b\b\b\b\b\b\b \\\b\b\b\b\b\b\b\b |\b\b\b\b\b\b\b\b /\b\b\b\b\b\b\b\b -\b\b\b\b\b\b\b\b \\\b\b\b\b\b\b\b\b |\b\b\b\b\b\b\b\b /\b\b\b\b\b\b\b\b -\b\b\b\b\b\b\b\b \\\b\b\b\b\b\b\b\b |' ? 'Hello world \b\b\b\b\b\b\b\b \\\b\b\b\b\b\b\b\b |\b\b\b\b\b\b\b\b /\b\b\b\b\b\b\b\b -\b\b\b\b\b\b\b\b \\\b\b\b\b\b\b\b\b |\b\b\b\b\b\b\b\b /\b\b\b\b\b\b\b\b -\b\b\b\b\b\b\b\b \\\b\b\b\b\b\b\b\b |'
: 'Hello world \b\b\b\b\b\b\b\b ⣽\b\b\b\b\b\b\b\b ⣻\b\b\b\b\b\b\b\b ⢿\b\b\b\b\b\b\b\b ⡿\b\b\b\b\b\b\b\b ⣟\b\b\b\b\b\b\b\b ⣯\b\b\b\b\b\b\b\b ⣷\b\b\b\b\b\b\b\b ⣾\b\b\b\b\b\b\b\b ⣽\b\b\b\b\b\b\b\b ⣻')); : 'Hello world \b\b\b\b\b\b\b\b ⣽\b\b\b\b\b\b\b\b ⣻\b\b\b\b\b\b\b\b ⢿\b\b\b\b\b\b\b\b ⡿\b\b\b\b\b\b\b\b ⣟\b\b\b\b\b\b\b\b ⣯\b\b\b\b\b\b\b\b ⣷\b\b\b\b\b\b\b\b ⣾\b\b\b\b\b\b\b\b ⣽\b\b\b\b\b\b\b\b ⣻'));
expect(lines.length, equals(1)); expect(lines.length, equals(1));
...@@ -307,8 +315,9 @@ void main() { ...@@ -307,8 +315,9 @@ void main() {
lines = outputStdout(); lines = outputStdout();
final List<Match> matches = secondDigits.allMatches(lines[0]).toList(); final List<Match> matches = secondDigits.allMatches(lines[0]).toList();
expect(matches, isEmpty); expect(matches, isEmpty);
final String x = globals.platform.isWindows ? '|' : '⣻'; final String leading = currentPlatform().isWindows ? '|' : '⣻';
expect(lines[0], endsWith('$x\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b'));
expect(lines[0], endsWith('$leading\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b'));
expect(called, equals(1)); expect(called, equals(1));
expect(lines.length, equals(2)); expect(lines.length, equals(2));
expect(lines[1], equals('')); expect(lines[1], equals(''));
...@@ -319,22 +328,20 @@ void main() { ...@@ -319,22 +328,20 @@ void main() {
done = true; done = true;
}); });
expect(done, isTrue); expect(done, isTrue);
}, overrides: <Type, Generator>{
Platform: () => FakePlatform(operatingSystem: testOs),
Stopwatch: () => mockStopwatch,
}); });
testUsingContext('AnsiStatus works when stopped for $testOs', () async { testWithoutContext('AnsiStatus works when stopped for $testOs', () async {
final AnsiStatus ansiStatus = _createAnsiStatus(); final AnsiStatus ansiStatus = createAnsiStatus();
bool done = false; bool done = false;
FakeAsync().run((FakeAsync time) { FakeAsync().run((FakeAsync time) {
ansiStatus.start(); ansiStatus.start();
mockStopwatch.elapsed = const Duration(seconds: 1); mockStopwatch.elapsed = const Duration(seconds: 1);
doWhileAsync(time, () => ansiStatus.ticks < 10); doWhileAsync(time, () => ansiStatus.ticks < 10);
List<String> lines = outputStdout(); List<String> lines = outputStdout();
expect(lines, hasLength(1)); expect(lines, hasLength(1));
expect(lines[0], expect(lines[0],
globals.platform.isWindows currentPlatform().isWindows
? 'Hello world \b\b\b\b\b\b\b\b \\\b\b\b\b\b\b\b\b |\b\b\b\b\b\b\b\b /\b\b\b\b\b\b\b\b -\b\b\b\b\b\b\b\b \\\b\b\b\b\b\b\b\b |\b\b\b\b\b\b\b\b /\b\b\b\b\b\b\b\b -\b\b\b\b\b\b\b\b \\\b\b\b\b\b\b\b\b |' ? 'Hello world \b\b\b\b\b\b\b\b \\\b\b\b\b\b\b\b\b |\b\b\b\b\b\b\b\b /\b\b\b\b\b\b\b\b -\b\b\b\b\b\b\b\b \\\b\b\b\b\b\b\b\b |\b\b\b\b\b\b\b\b /\b\b\b\b\b\b\b\b -\b\b\b\b\b\b\b\b \\\b\b\b\b\b\b\b\b |'
: 'Hello world \b\b\b\b\b\b\b\b ⣽\b\b\b\b\b\b\b\b ⣻\b\b\b\b\b\b\b\b ⢿\b\b\b\b\b\b\b\b ⡿\b\b\b\b\b\b\b\b ⣟\b\b\b\b\b\b\b\b ⣯\b\b\b\b\b\b\b\b ⣷\b\b\b\b\b\b\b\b ⣾\b\b\b\b\b\b\b\b ⣽\b\b\b\b\b\b\b\b ⣻', : 'Hello world \b\b\b\b\b\b\b\b ⣽\b\b\b\b\b\b\b\b ⣻\b\b\b\b\b\b\b\b ⢿\b\b\b\b\b\b\b\b ⡿\b\b\b\b\b\b\b\b ⣟\b\b\b\b\b\b\b\b ⣯\b\b\b\b\b\b\b\b ⣷\b\b\b\b\b\b\b\b ⣾\b\b\b\b\b\b\b\b ⣽\b\b\b\b\b\b\b\b ⣻',
); );
...@@ -344,7 +351,7 @@ void main() { ...@@ -344,7 +351,7 @@ void main() {
lines = outputStdout(); lines = outputStdout();
expect(lines, hasLength(2)); expect(lines, hasLength(2));
expect(lines[0], matches( expect(lines[0], matches(
globals.platform.isWindows currentPlatform().isWindows
? r'Hello world {8}[\b]{8} {7}\\[\b]{8} {7}|[\b]{8} {7}/[\b]{8} {7}-[\b]{8} {7}\\[\b]{8} {7}|[\b]{8} {7}/[\b]{8} {7}-[\b]{8} {7}\\[\b]{8} {7}|[\b]{8} {7} [\b]{8}[\d., ]{6}[\d]ms$' ? r'Hello world {8}[\b]{8} {7}\\[\b]{8} {7}|[\b]{8} {7}/[\b]{8} {7}-[\b]{8} {7}\\[\b]{8} {7}|[\b]{8} {7}/[\b]{8} {7}-[\b]{8} {7}\\[\b]{8} {7}|[\b]{8} {7} [\b]{8}[\d., ]{6}[\d]ms$'
: r'Hello world {8}[\b]{8} {7}⣽[\b]{8} {7}⣻[\b]{8} {7}⢿[\b]{8} {7}⡿[\b]{8} {7}⣟[\b]{8} {7}⣯[\b]{8} {7}⣷[\b]{8} {7}⣾[\b]{8} {7}⣽[\b]{8} {7}⣻[\b]{8} {7} [\b]{8}[\d., ]{5}[\d]ms$' : r'Hello world {8}[\b]{8} {7}⣽[\b]{8} {7}⣻[\b]{8} {7}⢿[\b]{8} {7}⡿[\b]{8} {7}⣟[\b]{8} {7}⣯[\b]{8} {7}⣷[\b]{8} {7}⣾[\b]{8} {7}⣽[\b]{8} {7}⣻[\b]{8} {7} [\b]{8}[\d., ]{5}[\d]ms$'
)); ));
...@@ -353,20 +360,18 @@ void main() { ...@@ -353,20 +360,18 @@ void main() {
expect(times, isNotNull); expect(times, isNotNull);
expect(times, hasLength(1)); expect(times, hasLength(1));
final Match match = times.single; final Match match = times.single;
expect(lines[0], endsWith(match.group(0))); expect(lines[0], endsWith(match.group(0)));
expect(called, equals(1)); expect(called, equals(1));
expect(lines.length, equals(2)); expect(lines.length, equals(2));
expect(lines[1], equals('')); expect(lines[1], equals(''));
// Verify that stopping or canceling multiple times throws. // Verify that stopping or canceling multiple times throws.
expect(() { ansiStatus.stop(); }, throwsA(isInstanceOf<AssertionError>())); expect(ansiStatus.stop, throwsA(isInstanceOf<AssertionError>()));
expect(() { ansiStatus.cancel(); }, throwsA(isInstanceOf<AssertionError>())); expect(ansiStatus.cancel, throwsA(isInstanceOf<AssertionError>()));
done = true; done = true;
}); });
expect(done, isTrue); expect(done, isTrue);
}, overrides: <Type, Generator>{
Platform: () => FakePlatform(operatingSystem: testOs),
Stopwatch: () => mockStopwatch,
}); });
} }
}); });
...@@ -381,11 +386,12 @@ void main() { ...@@ -381,11 +386,12 @@ void main() {
called = 0; called = 0;
summaryStatus = SummaryStatus( summaryStatus = SummaryStatus(
message: 'Hello world', message: 'Hello world',
timeout: timeoutConfiguration.slowOperation, timeout: const TimeoutConfiguration().slowOperation,
padding: 20, padding: 20,
onFinish: () => called++, onFinish: () => called++,
stdio: mockStdio, stdio: mockStdio,
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
stopwatch: FakeStopwatch(),
); );
}); });
...@@ -401,6 +407,7 @@ void main() { ...@@ -401,6 +407,7 @@ void main() {
stdio: mockStdio, stdio: mockStdio,
outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false),
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
platform: FakePlatform(),
); );
logger.printError('0123456789' * 15); logger.printError('0123456789' * 15);
final List<String> lines = outputStderr(); final List<String> lines = outputStderr();
...@@ -422,6 +429,7 @@ void main() { ...@@ -422,6 +429,7 @@ void main() {
stdio: mockStdio, stdio: mockStdio,
outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false),
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
platform: FakePlatform(),
); );
logger.printError('0123456789' * 15, indent: 5); logger.printError('0123456789' * 15, indent: 5);
final List<String> lines = outputStderr(); final List<String> lines = outputStderr();
...@@ -446,6 +454,7 @@ void main() { ...@@ -446,6 +454,7 @@ void main() {
stdio: mockStdio, stdio: mockStdio,
outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false),
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
platform: FakePlatform(),
); );
logger.printError('0123456789' * 15, hangingIndent: 5); logger.printError('0123456789' * 15, hangingIndent: 5);
final List<String> lines = outputStderr(); final List<String> lines = outputStderr();
...@@ -470,6 +479,7 @@ void main() { ...@@ -470,6 +479,7 @@ void main() {
stdio: mockStdio, stdio: mockStdio,
outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false),
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
platform: FakePlatform(),
); );
logger.printError('0123456789' * 15, indent: 4, hangingIndent: 5); logger.printError('0123456789' * 15, indent: 4, hangingIndent: 5);
final List<String> lines = outputStderr(); final List<String> lines = outputStderr();
...@@ -494,6 +504,7 @@ void main() { ...@@ -494,6 +504,7 @@ void main() {
stdio: mockStdio, stdio: mockStdio,
outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false),
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
platform: FakePlatform(),
); );
logger.printStatus('0123456789' * 15); logger.printStatus('0123456789' * 15);
final List<String> lines = outputStdout(); final List<String> lines = outputStdout();
...@@ -515,6 +526,7 @@ void main() { ...@@ -515,6 +526,7 @@ void main() {
stdio: mockStdio, stdio: mockStdio,
outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false),
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
platform: FakePlatform(),
); );
logger.printStatus('0123456789' * 15, indent: 5); logger.printStatus('0123456789' * 15, indent: 5);
final List<String> lines = outputStdout(); final List<String> lines = outputStdout();
...@@ -539,6 +551,7 @@ void main() { ...@@ -539,6 +551,7 @@ void main() {
stdio: mockStdio, stdio: mockStdio,
outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false),
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
platform: FakePlatform(),
); );
logger.printStatus('0123456789' * 15, hangingIndent: 5); logger.printStatus('0123456789' * 15, hangingIndent: 5);
final List<String> lines = outputStdout(); final List<String> lines = outputStdout();
...@@ -554,7 +567,7 @@ void main() { ...@@ -554,7 +567,7 @@ void main() {
expect(lines[5], isEmpty); expect(lines[5], isEmpty);
}); });
testUsingContext('Stdout logs are wrapped, indented, and can have hanging indent.', () async { testWithoutContext('Stdout logs are wrapped, indented, and can have hanging indent.', () async {
final Logger logger = StdoutLogger( final Logger logger = StdoutLogger(
terminal: AnsiTerminal( terminal: AnsiTerminal(
stdio: mockStdio, stdio: mockStdio,
...@@ -563,6 +576,7 @@ void main() { ...@@ -563,6 +576,7 @@ void main() {
stdio: mockStdio, stdio: mockStdio,
outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false),
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
platform: FakePlatform(),
); );
logger.printStatus('0123456789' * 15, indent: 4, hangingIndent: 5); logger.printStatus('0123456789' * 15, indent: 4, hangingIndent: 5);
final List<String> lines = outputStdout(); final List<String> lines = outputStdout();
...@@ -587,6 +601,7 @@ void main() { ...@@ -587,6 +601,7 @@ void main() {
stdio: mockStdio, stdio: mockStdio,
outputPreferences: OutputPreferences.test(showColor: true), outputPreferences: OutputPreferences.test(showColor: true),
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
platform: FakePlatform(),
); );
logger.printError('Pants on fire!'); logger.printError('Pants on fire!');
final List<String> lines = outputStderr(); final List<String> lines = outputStderr();
...@@ -605,6 +620,7 @@ void main() { ...@@ -605,6 +620,7 @@ void main() {
stdio: mockStdio, stdio: mockStdio,
outputPreferences: OutputPreferences.test(showColor: true), outputPreferences: OutputPreferences.test(showColor: true),
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
platform: FakePlatform(),
); );
logger.printStatus('All good.'); logger.printStatus('All good.');
...@@ -623,6 +639,7 @@ void main() { ...@@ -623,6 +639,7 @@ void main() {
stdio: mockStdio, stdio: mockStdio,
outputPreferences: OutputPreferences.test(showColor: true), outputPreferences: OutputPreferences.test(showColor: true),
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
platform: FakePlatform(),
); );
logger.printStatus( logger.printStatus(
null, null,
...@@ -647,6 +664,7 @@ void main() { ...@@ -647,6 +664,7 @@ void main() {
stdio: mockStdio, stdio: mockStdio,
outputPreferences: OutputPreferences.test(showColor: false), outputPreferences: OutputPreferences.test(showColor: false),
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
platform: FakePlatform(),
); );
logger.printStatus( logger.printStatus(
null, null,
...@@ -661,8 +679,7 @@ void main() { ...@@ -661,8 +679,7 @@ void main() {
expect(lines[0], equals('')); expect(lines[0], equals(''));
}); });
// Status uses Stopwatch from context. testWithoutContext('Stdout startProgress on non-color terminal', () async {
test('Stdout startProgress on non-color terminal', () async {
bool done = false; bool done = false;
FakeAsync().run((FakeAsync time) { FakeAsync().run((FakeAsync time) {
final Logger logger = StdoutLogger( final Logger logger = StdoutLogger(
...@@ -673,6 +690,7 @@ void main() { ...@@ -673,6 +690,7 @@ void main() {
stdio: mockStdio, stdio: mockStdio,
outputPreferences: OutputPreferences.test(showColor: false), outputPreferences: OutputPreferences.test(showColor: false),
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
platform: FakePlatform(),
); );
final Status status = logger.startProgress( final Status status = logger.startProgress(
'Hello', 'Hello',
...@@ -683,17 +701,24 @@ void main() { ...@@ -683,17 +701,24 @@ void main() {
expect(outputStderr().length, equals(1)); expect(outputStderr().length, equals(1));
expect(outputStderr().first, isEmpty); expect(outputStderr().first, isEmpty);
// the 5 below is the margin that is always included between the message and the time. // the 5 below is the margin that is always included between the message and the time.
expect(outputStdout().join('\n'), matches(globals.platform.isWindows ? r'^Hello {15} {5}$' : expect(outputStdout().join('\n'), matches(r'^Hello {15} {5}$'));
r'^Hello {15} {5}$'));
status.stop(); status.stop();
expect(outputStdout().join('\n'), matches(globals.platform.isWindows ? r'^Hello {15} {5}[\d, ]{4}[\d]\.[\d]s[\n]$' : expect(outputStdout().join('\n'), matches(r'^Hello {15} {5}[\d, ]{4}[\d]\.[\d]s[\n]$'));
r'^Hello {15} {5}[\d, ]{4}[\d]\.[\d]s[\n]$'));
done = true; done = true;
}); });
expect(done, isTrue); expect(done, isTrue);
}); });
testUsingContext('SummaryStatus works when canceled', () async { testWithoutContext('SummaryStatus works when canceled', () async {
final SummaryStatus summaryStatus = SummaryStatus(
message: 'Hello world',
timeout: const TimeoutConfiguration().slowOperation,
padding: 20,
onFinish: () => called++,
stdio: mockStdio,
timeoutConfiguration: const TimeoutConfiguration(),
stopwatch: FakeStopwatch(),
);
summaryStatus.start(); summaryStatus.start();
List<String> lines = outputStdout(); List<String> lines = outputStdout();
expect(lines[0], startsWith('Hello world ')); expect(lines[0], startsWith('Hello world '));
...@@ -711,13 +736,11 @@ void main() { ...@@ -711,13 +736,11 @@ void main() {
expect(lines[1], equals('')); expect(lines[1], equals(''));
// Verify that stopping or canceling multiple times throws. // Verify that stopping or canceling multiple times throws.
expect(() { summaryStatus.cancel(); }, throwsA(isInstanceOf<AssertionError>())); expect(summaryStatus.cancel, throwsA(isInstanceOf<AssertionError>()));
expect(() { summaryStatus.stop(); }, throwsA(isInstanceOf<AssertionError>())); expect(summaryStatus.stop, throwsA(isInstanceOf<AssertionError>()));
}, overrides: <Type, Generator>{
Platform: () => _kNoAnsiPlatform,
}); });
testUsingContext('SummaryStatus works when stopped', () async { testWithoutContext('SummaryStatus works when stopped', () async {
summaryStatus.start(); summaryStatus.start();
List<String> lines = outputStdout(); List<String> lines = outputStdout();
expect(lines[0], startsWith('Hello world ')); expect(lines[0], startsWith('Hello world '));
...@@ -736,16 +759,11 @@ void main() { ...@@ -736,16 +759,11 @@ void main() {
expect(lines[1], equals('')); expect(lines[1], equals(''));
// Verify that stopping or canceling multiple times throws. // Verify that stopping or canceling multiple times throws.
expect(() { summaryStatus.stop(); }, throwsA(isInstanceOf<AssertionError>())); expect(summaryStatus.stop, throwsA(isInstanceOf<AssertionError>()));
expect(() { summaryStatus.cancel(); }, throwsA(isInstanceOf<AssertionError>())); expect(summaryStatus.cancel, throwsA(isInstanceOf<AssertionError>()));
}, overrides: <Type, Generator>{
Platform: () => _kNoAnsiPlatform,
}); });
// Status still uses Stopwatch from context. testWithoutContext('sequential startProgress calls with StdoutLogger', () async {
// TODO(jonahwilliams): switch to testWithoutContext once logger uses a
// TimerFactory.
test('sequential startProgress calls with StdoutLogger', () async {
final Logger logger = StdoutLogger( final Logger logger = StdoutLogger(
terminal: AnsiTerminal( terminal: AnsiTerminal(
stdio: mockStdio, stdio: mockStdio,
...@@ -754,6 +772,7 @@ void main() { ...@@ -754,6 +772,7 @@ void main() {
stdio: mockStdio, stdio: mockStdio,
outputPreferences: OutputPreferences.test(showColor: false), outputPreferences: OutputPreferences.test(showColor: false),
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
platform: FakePlatform(),
); );
logger.startProgress('AAA', timeout: const TimeoutConfiguration().fastOperation)..stop(); logger.startProgress('AAA', timeout: const TimeoutConfiguration().fastOperation)..stop();
logger.startProgress('BBB', timeout: const TimeoutConfiguration().fastOperation)..stop(); logger.startProgress('BBB', timeout: const TimeoutConfiguration().fastOperation)..stop();
...@@ -768,8 +787,7 @@ void main() { ...@@ -768,8 +787,7 @@ void main() {
expect(output[1], matches(RegExp(r'BBB[ ]{61}[\d, ]{5}[\d]ms'))); expect(output[1], matches(RegExp(r'BBB[ ]{61}[\d, ]{5}[\d]ms')));
}); });
// Status still uses Stopwatch from context. testWithoutContext('sequential startProgress calls with VerboseLogger and StdoutLogger', () async {
test('sequential startProgress calls with VerboseLogger and StdoutLogger', () async {
final Logger logger = VerboseLogger( final Logger logger = VerboseLogger(
StdoutLogger( StdoutLogger(
terminal: AnsiTerminal( terminal: AnsiTerminal(
...@@ -779,8 +797,9 @@ void main() { ...@@ -779,8 +797,9 @@ void main() {
stdio: mockStdio, stdio: mockStdio,
outputPreferences: OutputPreferences.test(), outputPreferences: OutputPreferences.test(),
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
platform: FakePlatform(),
), ),
stopwatch: FakeStopwatch(), stopwatchFactory: FakeStopwatchFactory(),
); );
logger.startProgress('AAA', timeout: const TimeoutConfiguration().fastOperation)..stop(); logger.startProgress('AAA', timeout: const TimeoutConfiguration().fastOperation)..stop();
logger.startProgress('BBB', timeout: const TimeoutConfiguration().fastOperation)..stop(); logger.startProgress('BBB', timeout: const TimeoutConfiguration().fastOperation)..stop();
...@@ -794,8 +813,7 @@ void main() { ...@@ -794,8 +813,7 @@ void main() {
]); ]);
}); });
// Status still uses Stopwatch from context. testWithoutContext('sequential startProgress calls with BufferLogger', () async {
test('sequential startProgress calls with BufferLogger', () async {
final BufferLogger logger = BufferLogger( final BufferLogger logger = BufferLogger(
terminal: AnsiTerminal( terminal: AnsiTerminal(
stdio: mockStdio, stdio: mockStdio,
...@@ -846,3 +864,14 @@ class FakeStopwatch implements Stopwatch { ...@@ -846,3 +864,14 @@ class FakeStopwatch implements Stopwatch {
@override @override
String toString() => '$runtimeType $elapsed $isRunning'; String toString() => '$runtimeType $elapsed $isRunning';
} }
class FakeStopwatchFactory implements StopwatchFactory {
FakeStopwatchFactory([this.stopwatch]);
Stopwatch stopwatch;
@override
Stopwatch createStopwatch() {
return stopwatch ?? FakeStopwatch();
}
}
...@@ -196,6 +196,7 @@ void main() { ...@@ -196,6 +196,7 @@ void main() {
stdio: mockStdio, stdio: mockStdio,
terminal: AnsiTerminal(stdio: mockStdio, platform: const LocalPlatform()), terminal: AnsiTerminal(stdio: mockStdio, platform: const LocalPlatform()),
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
platform: FakePlatform(),
), ),
WebSocketConnector: () => (String url, {CompressionOptions compression}) async => throw const SocketException('test'), WebSocketConnector: () => (String url, {CompressionOptions compression}) async => throw const SocketException('test'),
}); });
...@@ -275,6 +276,7 @@ void main() { ...@@ -275,6 +276,7 @@ void main() {
terminal: AnsiTerminal(stdio: mockStdio, platform: const LocalPlatform()), terminal: AnsiTerminal(stdio: mockStdio, platform: const LocalPlatform()),
stdio: mockStdio, stdio: mockStdio,
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
platform: FakePlatform(),
), ),
}); });
...@@ -292,6 +294,7 @@ void main() { ...@@ -292,6 +294,7 @@ void main() {
terminal: AnsiTerminal(stdio: mockStdio, platform: const LocalPlatform()), terminal: AnsiTerminal(stdio: mockStdio, platform: const LocalPlatform()),
stdio: mockStdio, stdio: mockStdio,
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
platform: FakePlatform(),
), ),
}); });
...@@ -310,6 +313,7 @@ void main() { ...@@ -310,6 +313,7 @@ void main() {
terminal: AnsiTerminal(stdio: mockStdio, platform: const LocalPlatform()), terminal: AnsiTerminal(stdio: mockStdio, platform: const LocalPlatform()),
stdio: mockStdio, stdio: mockStdio,
timeoutConfiguration: const TimeoutConfiguration(), timeoutConfiguration: const TimeoutConfiguration(),
platform: FakePlatform(),
), ),
}); });
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment