From c23d9cd4ce85aff95360ac0b61cd93344e123f92 Mon Sep 17 00:00:00 2001 From: Zachary Anderson Date: Mon, 10 Feb 2020 10:23:35 -0800 Subject: [PATCH] [flutter_tools] Print emojis in Windows Terminal (#50446) --- .../lib/src/base/command_help.dart | 141 +++-- .../flutter_tools/lib/src/base/logger.dart | 37 +- .../flutter_tools/lib/src/base/terminal.dart | 16 +- .../flutter_tools/lib/src/context_runner.dart | 2 - packages/flutter_tools/lib/src/doctor.dart | 3 +- .../flutter_tools/lib/src/ios/xcodeproj.dart | 3 +- .../test/general.shard/base/logger_test.dart | 545 +++++++++--------- .../test/general.shard/vmservice_test.dart | 24 +- 8 files changed, 440 insertions(+), 331 deletions(-) diff --git a/packages/flutter_tools/lib/src/base/command_help.dart b/packages/flutter_tools/lib/src/base/command_help.dart index 0b52404c6b5..4a1434cd72e 100644 --- a/packages/flutter_tools/lib/src/base/command_help.dart +++ b/packages/flutter_tools/lib/src/base/command_help.dart @@ -36,58 +36,122 @@ class CommandHelp { final OutputPreferences _outputPreferences; CommandHelpOption _L; - CommandHelpOption get L => _L ??= _makeOption('L', 'Dump layer tree to the console.', 'debugDumpLayerTree'); + CommandHelpOption get L => _L ??= _makeOption( + 'L', + 'Dump layer tree to the console.', + 'debugDumpLayerTree', + ); CommandHelpOption _P; - CommandHelpOption get P => _P ??= _makeOption('P', 'Toggle performance overlay.', 'WidgetsApp.showPerformanceOverlay'); + CommandHelpOption get P => _P ??= _makeOption( + 'P', + 'Toggle performance overlay.', + 'WidgetsApp.showPerformanceOverlay', + ); CommandHelpOption _R; - CommandHelpOption get R => _R ??= _makeOption('R', 'Hot restart.'); + CommandHelpOption get R => _R ??= _makeOption( + 'R', + 'Hot restart.', + ); CommandHelpOption _S; - CommandHelpOption get S => _S ??= _makeOption('S', 'Dump accessibility tree in traversal order.', 'debugDumpSemantics'); + CommandHelpOption get S => _S ??= _makeOption( + 'S', + 'Dump accessibility tree in traversal order.', + 'debugDumpSemantics', + ); CommandHelpOption _U; - CommandHelpOption get U => _U ??= _makeOption('U', 'Dump accessibility tree in inverse hit test order.', 'debugDumpSemantics'); + CommandHelpOption get U => _U ??= _makeOption( + 'U', + 'Dump accessibility tree in inverse hit test order.', + 'debugDumpSemantics', + ); CommandHelpOption _a; - CommandHelpOption get a => _a ??= _makeOption('a', 'Toggle timeline events for all widget build methods.', 'debugProfileWidgetBuilds'); + CommandHelpOption get a => _a ??= _makeOption( + 'a', + 'Toggle timeline events for all widget build methods.', + 'debugProfileWidgetBuilds', + ); CommandHelpOption _c; - CommandHelpOption get c => _c ??= _makeOption('c', 'Clear the screen'); + CommandHelpOption get c => _c ??= _makeOption( + 'c', + 'Clear the screen', + ); CommandHelpOption _d; - CommandHelpOption get d => _d ??= _makeOption('d', 'Detach (terminate "flutter run" but leave application running).'); + CommandHelpOption get d => _d ??= _makeOption( + 'd', + 'Detach (terminate "flutter run" but leave application running).', + ); CommandHelpOption _h; - CommandHelpOption get h => _h ??= _makeOption('h', 'Repeat this help message.'); + CommandHelpOption get h => _h ??= _makeOption( + 'h', + 'Repeat this help message.', + ); CommandHelpOption _i; - CommandHelpOption get i => _i ??= _makeOption('i', 'Toggle widget inspector.', 'WidgetsApp.showWidgetInspectorOverride'); + CommandHelpOption get i => _i ??= _makeOption( + 'i', + 'Toggle widget inspector.', + 'WidgetsApp.showWidgetInspectorOverride', + ); CommandHelpOption _o; - CommandHelpOption get o => _o ??= _makeOption('o', 'Simulate different operating systems.', 'defaultTargetPlatform'); + CommandHelpOption get o => _o ??= _makeOption( + 'o', + 'Simulate different operating systems.', + 'defaultTargetPlatform', + ); CommandHelpOption _p; - CommandHelpOption get p => _p ??= _makeOption('p', 'Toggle the display of construction lines.', 'debugPaintSizeEnabled'); + CommandHelpOption get p => _p ??= _makeOption( + 'p', + 'Toggle the display of construction lines.', + 'debugPaintSizeEnabled', + ); CommandHelpOption _q; - CommandHelpOption get q => _q ??= _makeOption('q', 'Quit (terminate the application on the device).'); + CommandHelpOption get q => _q ??= _makeOption( + 'q', + 'Quit (terminate the application on the device).', + ); CommandHelpOption _r; - CommandHelpOption get r => _r ??= _makeOption('r', 'Hot reload. $fire$fire$fire'); + CommandHelpOption get r => _r ??= _makeOption( + 'r', + 'Hot reload. $fire$fire$fire', + ); CommandHelpOption _s; - CommandHelpOption get s => _s ??= _makeOption('s', 'Save a screenshot to flutter.png.'); + CommandHelpOption get s => _s ??= _makeOption( + 's', + 'Save a screenshot to flutter.png.', + ); CommandHelpOption _t; - CommandHelpOption get t => _t ??= _makeOption('t', 'Dump rendering tree to the console.', 'debugDumpRenderTree'); + CommandHelpOption get t => _t ??= _makeOption( + 't', + 'Dump rendering tree to the console.', + 'debugDumpRenderTree', + ); CommandHelpOption _w; - CommandHelpOption get w => _w ??= _makeOption('w', 'Dump widget hierarchy to the console.', 'debugDumpApp'); + CommandHelpOption get w => _w ??= _makeOption( + 'w', + 'Dump widget hierarchy to the console.', + 'debugDumpApp', + ); CommandHelpOption _z; - CommandHelpOption get z => _z ??= _makeOption('z', 'Toggle elevation checker.'); + CommandHelpOption get z => _z ??= _makeOption( + 'z', + 'Toggle elevation checker.', + ); CommandHelpOption _makeOption(String key, String description, [ String inParenthesis = '', @@ -142,25 +206,30 @@ class CommandHelpOption { String toString() { final StringBuffer message = StringBuffer(); message.writeAll([_terminal.bolden(key), description], ' '); - - if (_hasTextInParenthesis) { - bool wrap = false; - final int maxWidth = math.max(_outputPreferences.wrapColumn ?? 0, maxLineWidth); - int width = maxWidth - (_platform.stdoutSupportsAnsi ? _rawMessageLength + 1 : message.length); - final String parentheticalText = '($inParenthesis)'; - if (width < parentheticalText.length) { - width = maxWidth; - wrap = true; - } - - if (wrap) { - message.write('\n'); - } - // pad according to the raw text - message.write(''.padLeft(width - parentheticalText.length)); - - message.write(_terminal.color(parentheticalText, TerminalColor.grey)); + if (!_hasTextInParenthesis) { + return message.toString(); } + + bool wrap = false; + final int maxWidth = math.max( + _outputPreferences.wrapColumn ?? 0, + maxLineWidth, + ); + final int adjustedMessageLength = _platform.stdoutSupportsAnsi + ? _rawMessageLength + 1 + : message.length; + int width = maxWidth - adjustedMessageLength; + final String parentheticalText = '($inParenthesis)'; + if (width < parentheticalText.length) { + width = maxWidth; + wrap = true; + } + if (wrap) { + message.write('\n'); + } + // pad according to the raw text + message.write(''.padLeft(width - parentheticalText.length)); + message.write(_terminal.color(parentheticalText, TerminalColor.grey)); return message.toString(); } diff --git a/packages/flutter_tools/lib/src/base/logger.dart b/packages/flutter_tools/lib/src/base/logger.dart index fbe9d7685f7..0f523516200 100644 --- a/packages/flutter_tools/lib/src/base/logger.dart +++ b/packages/flutter_tools/lib/src/base/logger.dart @@ -5,7 +5,6 @@ import 'dart:async'; import 'package:meta/meta.dart'; -import 'package:platform/platform.dart'; import '../base/context.dart'; import '../globals.dart' as globals; @@ -179,15 +178,13 @@ class StdoutLogger extends Logger { @required Stdio stdio, @required OutputPreferences outputPreferences, @required TimeoutConfiguration timeoutConfiguration, - @required Platform platform, StopwatchFactory stopwatchFactory = const StopwatchFactory(), }) : _stdio = stdio, _terminal = terminal, _timeoutConfiguration = timeoutConfiguration, _outputPreferences = outputPreferences, - _stopwatchFactory = stopwatchFactory, - _platform = platform; + _stopwatchFactory = stopwatchFactory; @override final AnsiTerminal _terminal; @@ -197,7 +194,6 @@ class StdoutLogger extends Logger { final TimeoutConfiguration _timeoutConfiguration; final Stdio _stdio; final StopwatchFactory _stopwatchFactory; - final Platform _platform; Status _status; @@ -306,8 +302,8 @@ class StdoutLogger extends Logger { onFinish: _clearStatus, stdio: _stdio, timeoutConfiguration: _timeoutConfiguration, - platform: _platform, stopwatch: _stopwatchFactory.createStopwatch(), + terminal: _terminal, )..start(); } else { _status = SummaryStatus( @@ -352,7 +348,6 @@ class WindowsStdoutLogger extends StdoutLogger { @required Stdio stdio, @required OutputPreferences outputPreferences, @required TimeoutConfiguration timeoutConfiguration, - @required Platform platform, StopwatchFactory stopwatchFactory = const StopwatchFactory(), }) : super( terminal: terminal, @@ -360,15 +355,16 @@ class WindowsStdoutLogger extends StdoutLogger { outputPreferences: outputPreferences, timeoutConfiguration: timeoutConfiguration, stopwatchFactory: stopwatchFactory, - platform: platform, ); @override void writeToStdOut(String message) { // TODO(jcollins-g): wrong abstraction layer for this, move to [Stdio]. - final String windowsMessage = message - .replaceAll('✗', 'X') - .replaceAll('✓', '√'); + final String windowsMessage = _terminal.supportsEmoji + ? message + : message.replaceAll('🔥', '') + .replaceAll('✗', 'X') + .replaceAll('✓', '√'); _stdio.stdoutWrite(windowsMessage); } } @@ -681,19 +677,18 @@ abstract class Status { @required Duration timeout, @required TimeoutConfiguration timeoutConfiguration, @required Stopwatch stopwatch, - @required bool supportsColor, - @required Platform platform, + @required AnsiTerminal terminal, VoidCallback onFinish, SlowWarningCallback slowWarningCallback, }) { - if (supportsColor) { + if (terminal.supportsColor) { return AnsiSpinner( timeout: timeout, onFinish: onFinish, slowWarningCallback: slowWarningCallback, timeoutConfiguration: timeoutConfiguration, stopwatch: stopwatch, - platform: platform, + terminal: terminal, )..start(); } return SilentStatus( @@ -862,12 +857,12 @@ class AnsiSpinner extends Status { @required Duration timeout, @required TimeoutConfiguration timeoutConfiguration, @required Stopwatch stopwatch, - @required Platform platform, + @required AnsiTerminal terminal, VoidCallback onFinish, this.slowWarningCallback, Stdio stdio, }) : _stdio = stdio ?? globals.stdio, - _isWindows = platform.isWindows, + _terminal = terminal, super( timeout: timeout, onFinish: onFinish, @@ -878,7 +873,7 @@ class AnsiSpinner extends Status { final String _backspaceChar = '\b'; final String _clearChar = ' '; final Stdio _stdio; - final bool _isWindows; + final AnsiTerminal _terminal; bool timedOut = false; @@ -886,7 +881,7 @@ class AnsiSpinner extends Status { Timer timer; // Windows console font has a limited set of Unicode characters. - List get _animation => _isWindows + List get _animation => !_terminal.supportsEmoji ? const [r'-', r'\', r'|', r'/'] : const ['⣾', '⣽', '⣻', '⢿', '⡿', '⣟', '⣯', '⣷']; @@ -984,7 +979,7 @@ class AnsiStatus extends AnsiSpinner { this.padding = kDefaultStatusPadding, @required Duration timeout, @required Stopwatch stopwatch, - @required Platform platform, + @required AnsiTerminal terminal, VoidCallback onFinish, Stdio stdio, TimeoutConfiguration timeoutConfiguration, @@ -997,7 +992,7 @@ class AnsiStatus extends AnsiSpinner { stdio: stdio, timeoutConfiguration: timeoutConfiguration, stopwatch: stopwatch, - platform: platform, + terminal: terminal, ); final String message; diff --git a/packages/flutter_tools/lib/src/base/terminal.dart b/packages/flutter_tools/lib/src/base/terminal.dart index 5a0db58a4f6..448da611805 100644 --- a/packages/flutter_tools/lib/src/base/terminal.dart +++ b/packages/flutter_tools/lib/src/base/terminal.dart @@ -86,7 +86,10 @@ class OutputPreferences { } class AnsiTerminal { - AnsiTerminal({@required io.Stdio stdio, @required Platform platform}) + AnsiTerminal({ + @required io.Stdio stdio, + @required Platform platform, + }) : _stdio = stdio, _platform = platform; @@ -121,7 +124,16 @@ class AnsiTerminal { bool get supportsColor => _platform.stdoutSupportsAnsi ?? false; - final RegExp _boldControls = RegExp('(${RegExp.escape(resetBold)}|${RegExp.escape(bold)})'); + // Assume unicode emojis are supported when not on Windows. + // If we are on Windows, unicode emojis are supported in Windows Terminal, + // which sets the WT_SESSION environment variable. See: + // https://github.com/microsoft/terminal/blob/master/doc/user-docs/index.md#tips-and-tricks + bool get supportsEmoji => !_platform.isWindows + || _platform.environment.containsKey('WT_SESSION'); + + final RegExp _boldControls = RegExp( + '(${RegExp.escape(resetBold)}|${RegExp.escape(bold)})', + ); /// Whether we are interacting with the flutter tool via the terminal. /// diff --git a/packages/flutter_tools/lib/src/context_runner.dart b/packages/flutter_tools/lib/src/context_runner.dart index d0f3f543756..78b4754d209 100644 --- a/packages/flutter_tools/lib/src/context_runner.dart +++ b/packages/flutter_tools/lib/src/context_runner.dart @@ -127,14 +127,12 @@ Future runInContext( stdio: globals.stdio, outputPreferences: outputPreferences, timeoutConfiguration: timeoutConfiguration, - platform: globals.platform, ) : StdoutLogger( terminal: globals.terminal, stdio: globals.stdio, outputPreferences: outputPreferences, timeoutConfiguration: timeoutConfiguration, - platform: globals.platform, ), MacOSWorkflow: () => const MacOSWorkflow(), MDnsObservatoryDiscovery: () => MDnsObservatoryDiscovery(), diff --git a/packages/flutter_tools/lib/src/doctor.dart b/packages/flutter_tools/lib/src/doctor.dart index e6e40170200..d2a39a7c1b4 100644 --- a/packages/flutter_tools/lib/src/doctor.dart +++ b/packages/flutter_tools/lib/src/doctor.dart @@ -258,8 +258,7 @@ class Doctor { slowWarningCallback: () => validator.slowWarning, timeoutConfiguration: timeoutConfiguration, stopwatch: Stopwatch(), - supportsColor: globals.terminal.supportsColor, - platform: globals.platform, + terminal: globals.terminal, ); ValidationResult result; try { diff --git a/packages/flutter_tools/lib/src/ios/xcodeproj.dart b/packages/flutter_tools/lib/src/ios/xcodeproj.dart index f4c857d9de9..4cca408198b 100644 --- a/packages/flutter_tools/lib/src/ios/xcodeproj.dart +++ b/packages/flutter_tools/lib/src/ios/xcodeproj.dart @@ -314,9 +314,8 @@ class XcodeProjectInterpreter { final Status status = Status.withSpinner( timeout: const TimeoutConfiguration().fastOperation, timeoutConfiguration: const TimeoutConfiguration(), - platform: _platform, stopwatch: Stopwatch(), - supportsColor: _terminal.supportsColor, + terminal: _terminal, ); final List showBuildSettingsCommand = [ _executable, diff --git a/packages/flutter_tools/test/general.shard/base/logger_test.dart b/packages/flutter_tools/test/general.shard/base/logger_test.dart index aedfd5e95d4..05bb6976a9b 100644 --- a/packages/flutter_tools/test/general.shard/base/logger_test.dart +++ b/packages/flutter_tools/test/general.shard/base/logger_test.dart @@ -112,7 +112,6 @@ void main() { stdio: stdio, outputPreferences: OutputPreferences.test(), timeoutConfiguration: const TimeoutConfiguration(), - platform: FakePlatform(), ); logger.printStatus('message'); logger.printError('error message'); @@ -125,7 +124,33 @@ void main() { FakeStopwatch mockStopwatch; FakeStopwatchFactory stopwatchFactory; int called; - const List testPlatforms = ['linux', 'macos', 'windows', 'fuchsia']; + final List testPlatforms = [ + FakePlatform( + operatingSystem: 'linux', + environment: {}, + executableArguments: [], + ), + FakePlatform( + operatingSystem: 'macos', + environment: {}, + executableArguments: [], + ), + FakePlatform( + operatingSystem: 'windows', + environment: {}, + executableArguments: [], + ), + FakePlatform( + operatingSystem: 'windows', + environment: {'WT_SESSION': ''}, + executableArguments: [], + ), + FakePlatform( + operatingSystem: 'fuchsia', + environment: {}, + executableArguments: [], + ), + ]; final RegExp secondDigits = RegExp(r'[0-9,.]*[0-9]m?s'); setUp(() { @@ -145,278 +170,297 @@ void main() { } while (doThis()); } - for (final String testOs in testPlatforms) { - Platform currentPlatform() => FakePlatform(operatingSystem: testOs); + for (final Platform testPlatform in testPlatforms) { + group('(${testPlatform.operatingSystem})', () { + Platform platform; + Platform ansiPlatform; + AnsiTerminal terminal; + AnsiTerminal coloredTerminal; + AnsiStatus ansiStatus; - 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; - mockStopwatch = FakeStopwatch(); - FakeAsync().run((FakeAsync time) { - final AnsiSpinner ansiSpinner = AnsiSpinner( - timeout: const Duration(hours: 10), + setUp(() { + platform = FakePlatform.fromPlatform(testPlatform)..stdoutSupportsAnsi = false; + ansiPlatform = FakePlatform.fromPlatform(testPlatform)..stdoutSupportsAnsi = true; + + terminal = AnsiTerminal( + stdio: mockStdio, + platform: platform, + ); + coloredTerminal = AnsiTerminal( + stdio: mockStdio, + platform: ansiPlatform, + ); + + ansiStatus = AnsiStatus( + message: 'Hello world', + timeout: const Duration(seconds: 2), + padding: 20, + onFinish: () => called += 1, stdio: mockStdio, timeoutConfiguration: const TimeoutConfiguration(), stopwatch: stopwatchFactory.createStopwatch(), - platform: currentPlatform(), - )..start(); - doWhileAsync(time, () => ansiSpinner.ticks < 10); - List lines = outputStdout(); - expect(lines[0], startsWith( - currentPlatform().isWindows - ? ' \b\\\b|\b/\b-\b\\\b|\b/\b-' - : ' \b⣽\b⣻\b⢿\b⡿\b⣟\b⣯\b⣷\b⣾\b⣽\b⣻' - ), + terminal: terminal, ); - expect(lines[0].endsWith('\n'), isFalse); - expect(lines.length, equals(1)); - - ansiSpinner.stop(); - lines = outputStdout(); - - expect(lines[0], endsWith('\b \b')); - expect(lines.length, equals(1)); - - // Verify that stopping or canceling multiple times throws. - expect(ansiSpinner.stop, throwsAssertionError); - expect(ansiSpinner.cancel, throwsAssertionError); - done = true; }); - expect(done, isTrue); - }); - testWithoutContext('AnsiSpinner works for $testOs (2)', () async { - bool done = false; - mockStopwatch = FakeStopwatch(); - FakeAsync().run((FakeAsync time) { - final AnsiSpinner ansiSpinner = AnsiSpinner( - timeout: const Duration(seconds: 2), - stdio: mockStdio, - timeoutConfiguration: const TimeoutConfiguration(), - stopwatch: mockStopwatch, - platform: FakePlatform(operatingSystem: testOs), - )..start(); - mockStopwatch.elapsed = const Duration(seconds: 1); - doWhileAsync(time, () => ansiSpinner.ticks < 10); // one second - - expect(ansiSpinner.seemsSlow, isFalse); - expect(outputStdout().join('\n'), isNot(contains('This is taking an unexpectedly long time.'))); - mockStopwatch.elapsed = const Duration(seconds: 3); - doWhileAsync(time, () => ansiSpinner.ticks < 30); // three seconds - - expect(ansiSpinner.seemsSlow, isTrue); - // Check the 2nd line to verify there's a newline before the warning - expect(outputStdout()[1], contains('This is taking an unexpectedly long time.')); - ansiSpinner.stop(); - expect(outputStdout().join('\n'), isNot(contains('(!)'))); - done = true; - }); - expect(done, isTrue); - }); - - testWithoutContext('Stdout startProgress on colored terminal for $testOs', () async { - bool done = false; - FakeAsync().run((FakeAsync time) { - final Logger logger = StdoutLogger( - terminal: AnsiTerminal( + testWithoutContext('AnsiSpinner works (1)', () async { + bool done = false; + mockStopwatch = FakeStopwatch(); + FakeAsync().run((FakeAsync time) { + final AnsiSpinner ansiSpinner = AnsiSpinner( + timeout: const Duration(hours: 10), stdio: mockStdio, - platform: FakePlatform(operatingSystem: testOs)..stdoutSupportsAnsi = true, - ), - stdio: mockStdio, - outputPreferences: OutputPreferences.test(showColor: true), - timeoutConfiguration: const TimeoutConfiguration(), - stopwatchFactory: stopwatchFactory, - platform: currentPlatform(), - ); - final Status status = logger.startProgress( - 'Hello', - progressId: null, - timeout: const TimeoutConfiguration().slowOperation, - progressIndicatorPadding: 20, // this minus the "Hello" equals the 15 below. - ); - expect(outputStderr().length, equals(1)); - expect(outputStderr().first, isEmpty); - // the 5 below is the margin that is always included between the message and the time. - expect(outputStdout().join('\n'), - matches(currentPlatform().isWindows ? r'^Hello {15} {5} {8}[\b]{8} {7}\\$' : - r'^Hello {15} {5} {8}[\b]{8} {7}⣽$')); - status.stop(); - 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]$')); - done = true; - }); - expect(done, isTrue); - }); + timeoutConfiguration: const TimeoutConfiguration(), + stopwatch: stopwatchFactory.createStopwatch(), + terminal: terminal, + )..start(); + doWhileAsync(time, () => ansiSpinner.ticks < 10); + List lines = outputStdout(); + expect(lines[0], startsWith( + terminal.supportsEmoji + ? ' \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.length, equals(1)); - testWithoutContext('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 = StdoutLogger( - terminal: AnsiTerminal( + ansiSpinner.stop(); + lines = outputStdout(); + + expect(lines[0], endsWith('\b \b')); + expect(lines.length, equals(1)); + + // Verify that stopping or canceling multiple times throws. + expect(ansiSpinner.stop, throwsAssertionError); + expect(ansiSpinner.cancel, throwsAssertionError); + done = true; + }); + expect(done, isTrue); + }); + + testWithoutContext('AnsiSpinner works (2)', () async { + bool done = false; + mockStopwatch = FakeStopwatch(); + FakeAsync().run((FakeAsync time) { + final AnsiSpinner ansiSpinner = AnsiSpinner( + timeout: const Duration(seconds: 2), stdio: mockStdio, - platform: FakePlatform(operatingSystem: testOs)..stdoutSupportsAnsi = true, - ), - stdio: mockStdio, - outputPreferences: OutputPreferences.test(showColor: true), - timeoutConfiguration: const TimeoutConfiguration(), - stopwatchFactory: stopwatchFactory, - platform: currentPlatform(), - ); - final Status status = logger.startProgress( - 'Knock Knock, Who\'s There', - timeout: const Duration(days: 10), - progressIndicatorPadding: 10, - ); - logger.printStatus('Rude Interrupting Cow'); - status.stop(); - final String a = currentPlatform().isWindows ? r'\' : '⣽'; - final String b = currentPlatform().isWindows ? '|' : '⣻'; + timeoutConfiguration: const TimeoutConfiguration(), + stopwatch: mockStopwatch, + terminal: terminal, + )..start(); + mockStopwatch.elapsed = const Duration(seconds: 1); + doWhileAsync(time, () => ansiSpinner.ticks < 10); // one second - expect( - outputStdout().join('\n'), - 'Knock Knock, Who\'s There ' // initial message - ' ' // placeholder so that spinner can backspace on its first tick - '\b\b\b\b\b\b\b\b $a' // first tick - '\b\b\b\b\b\b\b\b ' // clearing the spinner - '\b\b\b\b\b\b\b\b' // clearing the clearing of the spinner - '\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b ' // clearing the message - '\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b' // clearing the clearing of the message - 'Rude Interrupting Cow\n' // message - 'Knock Knock, Who\'s There ' // message restoration - ' ' // placeholder so that spinner can backspace on its second tick - '\b\b\b\b\b\b\b\b $b' // second tick - '\b\b\b\b\b\b\b\b ' // clearing the spinner to put the time - '\b\b\b\b\b\b\b\b' // clearing the clearing of the spinner - ' 5.0s\n', // replacing it with the time - ); - done = true; + expect(ansiSpinner.seemsSlow, isFalse); + expect(outputStdout().join('\n'), isNot(contains('This is taking an unexpectedly long time.'))); + mockStopwatch.elapsed = const Duration(seconds: 3); + doWhileAsync(time, () => ansiSpinner.ticks < 30); // three seconds + + expect(ansiSpinner.seemsSlow, isTrue); + // Check the 2nd line to verify there's a newline before the warning + expect(outputStdout()[1], contains('This is taking an unexpectedly long time.')); + ansiSpinner.stop(); + expect(outputStdout().join('\n'), isNot(contains('(!)'))); + done = true; + }); + expect(done, isTrue); }); - expect(done, isTrue); - }); - testWithoutContext('AnsiStatus works for $testOs', () { - final AnsiStatus ansiStatus = createAnsiStatus(); - bool done = false; - FakeAsync().run((FakeAsync time) { - ansiStatus.start(); - mockStopwatch.elapsed = const Duration(seconds: 1); - doWhileAsync(time, () => ansiStatus.ticks < 10); // one second + testWithoutContext('Stdout startProgress on colored terminal', () async { + bool done = false; + FakeAsync().run((FakeAsync time) { + final Logger logger = StdoutLogger( + terminal: coloredTerminal, + stdio: mockStdio, + outputPreferences: OutputPreferences.test(showColor: true), + timeoutConfiguration: const TimeoutConfiguration(), + stopwatchFactory: stopwatchFactory, + ); + final Status status = logger.startProgress( + 'Hello', + progressId: null, + timeout: const TimeoutConfiguration().slowOperation, + progressIndicatorPadding: 20, // this minus the "Hello" equals the 15 below. + ); + expect(outputStderr().length, equals(1)); + expect(outputStderr().first, isEmpty); + // the 5 below is the margin that is always included between the message and the time. + expect( + outputStdout().join('\n'), + matches(terminal.supportsEmoji + ? r'^Hello {15} {5} {8}[\b]{8} {7}⣽$' + : r'^Hello {15} {5} {8}[\b]{8} {7}\\$'), + ); + status.stop(); + expect( + outputStdout().join('\n'), + matches( + terminal.supportsEmoji + ? 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; + }); + expect(done, isTrue); + }); - expect(ansiStatus.seemsSlow, isFalse); - expect(outputStdout().join('\n'), isNot(contains('This is taking an unexpectedly long time.'))); - expect(outputStdout().join('\n'), isNot(contains('(!)'))); - mockStopwatch.elapsed = const Duration(seconds: 3); - doWhileAsync(time, () => ansiStatus.ticks < 30); // three seconds + testWithoutContext('Stdout startProgress on colored terminal pauses', () async { + bool done = false; + FakeAsync().run((FakeAsync time) { + mockStopwatch.elapsed = const Duration(seconds: 5); + final Logger logger = StdoutLogger( + terminal: coloredTerminal, + stdio: mockStdio, + outputPreferences: OutputPreferences.test(showColor: true), + timeoutConfiguration: const TimeoutConfiguration(), + stopwatchFactory: stopwatchFactory, + ); + final Status status = logger.startProgress( + 'Knock Knock, Who\'s There', + timeout: const Duration(days: 10), + progressIndicatorPadding: 10, + ); + logger.printStatus('Rude Interrupting Cow'); + status.stop(); + final String a = terminal.supportsEmoji ? '⣽' : r'\'; + final String b = terminal.supportsEmoji ? '⣻' : '|'; - expect(ansiStatus.seemsSlow, isTrue); - expect(outputStdout().join('\n'), contains('This is taking an unexpectedly long time.')); + expect( + outputStdout().join('\n'), + 'Knock Knock, Who\'s There ' // initial message + ' ' // placeholder so that spinner can backspace on its first tick + '\b\b\b\b\b\b\b\b $a' // first tick + '\b\b\b\b\b\b\b\b ' // clearing the spinner + '\b\b\b\b\b\b\b\b' // clearing the clearing of the spinner + '\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b ' // clearing the message + '\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b' // clearing the clearing of the message + 'Rude Interrupting Cow\n' // message + 'Knock Knock, Who\'s There ' // message restoration + ' ' // placeholder so that spinner can backspace on its second tick + '\b\b\b\b\b\b\b\b $b' // second tick + '\b\b\b\b\b\b\b\b ' // clearing the spinner to put the time + '\b\b\b\b\b\b\b\b' // clearing the clearing of the spinner + ' 5.0s\n', // replacing it with the time + ); + done = true; + }); + expect(done, isTrue); + }); - // Test that the number of '\b' is correct. - for (final String line in outputStdout()) { - int currLength = 0; - for (int i = 0; i < line.length; i += 1) { - currLength += line[i] == '\b' ? -1 : 1; - expect(currLength, isNonNegative, reason: 'The following line has overflow backtraces:\n' + jsonEncode(line)); + testWithoutContext('AnsiStatus works', () { + bool done = false; + FakeAsync().run((FakeAsync time) { + ansiStatus.start(); + mockStopwatch.elapsed = const Duration(seconds: 1); + doWhileAsync(time, () => ansiStatus.ticks < 10); // one second + + expect(ansiStatus.seemsSlow, isFalse); + expect(outputStdout().join('\n'), isNot(contains('This is taking an unexpectedly long time.'))); + expect(outputStdout().join('\n'), isNot(contains('(!)'))); + mockStopwatch.elapsed = const Duration(seconds: 3); + doWhileAsync(time, () => ansiStatus.ticks < 30); // three seconds + + expect(ansiStatus.seemsSlow, isTrue); + expect(outputStdout().join('\n'), contains('This is taking an unexpectedly long time.')); + + // Test that the number of '\b' is correct. + for (final String line in outputStdout()) { + int currLength = 0; + for (int i = 0; i < line.length; i += 1) { + currLength += line[i] == '\b' ? -1 : 1; + expect(currLength, isNonNegative, reason: 'The following line has overflow backtraces:\n' + jsonEncode(line)); + } } - } - ansiStatus.stop(); - expect(outputStdout().join('\n'), contains('(!)')); - done = true; + ansiStatus.stop(); + expect(outputStdout().join('\n'), contains('(!)')); + done = true; + }); + expect(done, isTrue); }); - expect(done, isTrue); - }); - testWithoutContext('AnsiStatus works when canceled for $testOs', () async { - final AnsiStatus ansiStatus = createAnsiStatus(); - bool done = false; - FakeAsync().run((FakeAsync time) { - ansiStatus.start(); - mockStopwatch.elapsed = const Duration(seconds: 1); - doWhileAsync(time, () => ansiStatus.ticks < 10); - List lines = outputStdout(); + testWithoutContext('AnsiStatus works when canceled', () async { + bool done = false; + FakeAsync().run((FakeAsync time) { + ansiStatus.start(); + mockStopwatch.elapsed = const Duration(seconds: 1); + doWhileAsync(time, () => ansiStatus.ticks < 10); + List lines = outputStdout(); - 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 ⣻')); - expect(lines.length, equals(1)); - expect(lines[0].endsWith('\n'), isFalse); + expect(lines[0], startsWith( + terminal.supportsEmoji + ? '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[0].endsWith('\n'), isFalse); - // Verify a cancel does _not_ print the time and prints a newline. - ansiStatus.cancel(); - lines = outputStdout(); - final List matches = secondDigits.allMatches(lines[0]).toList(); - expect(matches, isEmpty); - final String leading = currentPlatform().isWindows ? '|' : '⣻'; + // Verify a cancel does _not_ print the time and prints a newline. + ansiStatus.cancel(); + lines = outputStdout(); + final List matches = secondDigits.allMatches(lines[0]).toList(); + expect(matches, isEmpty); + final String leading = terminal.supportsEmoji ? '⣻' : '|'; - 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(lines.length, equals(2)); - expect(lines[1], equals('')); + 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(lines.length, equals(2)); + expect(lines[1], equals('')); - // Verify that stopping or canceling multiple times throws. - expect(() { ansiStatus.cancel(); }, throwsAssertionError); - expect(() { ansiStatus.stop(); }, throwsAssertionError); - done = true; + // Verify that stopping or canceling multiple times throws. + expect(() { ansiStatus.cancel(); }, throwsAssertionError); + expect(() { ansiStatus.stop(); }, throwsAssertionError); + done = true; + }); + expect(done, isTrue); }); - expect(done, isTrue); - }); - testWithoutContext('AnsiStatus works when stopped for $testOs', () async { - final AnsiStatus ansiStatus = createAnsiStatus(); - bool done = false; - FakeAsync().run((FakeAsync time) { - ansiStatus.start(); - mockStopwatch.elapsed = const Duration(seconds: 1); - doWhileAsync(time, () => ansiStatus.ticks < 10); - List lines = outputStdout(); + testWithoutContext('AnsiStatus works when stopped', () async { + bool done = false; + FakeAsync().run((FakeAsync time) { + ansiStatus.start(); + mockStopwatch.elapsed = const Duration(seconds: 1); + doWhileAsync(time, () => ansiStatus.ticks < 10); + List lines = outputStdout(); - expect(lines, hasLength(1)); - expect(lines[0], - 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 ⣻', - ); + expect(lines, hasLength(1)); + expect( + lines[0], + terminal.supportsEmoji + ? '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 |', + ); - // Verify a stop prints the time. - ansiStatus.stop(); - lines = outputStdout(); - expect(lines, hasLength(2)); - expect(lines[0], matches( - 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., ]{5}[\d]ms$' - )); - expect(lines[1], isEmpty); - final List times = secondDigits.allMatches(lines[0]).toList(); - expect(times, isNotNull); - expect(times, hasLength(1)); - final Match match = times.single; + // Verify a stop prints the time. + ansiStatus.stop(); + lines = outputStdout(); + expect(lines, hasLength(2)); + expect(lines[0], matches( + terminal.supportsEmoji + ? 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., ]{6}[\d]ms$', + )); + expect(lines[1], isEmpty); + final List times = secondDigits.allMatches(lines[0]).toList(); + expect(times, isNotNull); + expect(times, hasLength(1)); + final Match match = times.single; - expect(lines[0], endsWith(match.group(0))); - expect(called, equals(1)); - expect(lines.length, equals(2)); - expect(lines[1], equals('')); + expect(lines[0], endsWith(match.group(0))); + expect(called, equals(1)); + expect(lines.length, equals(2)); + expect(lines[1], equals('')); - // Verify that stopping or canceling multiple times throws. - expect(ansiStatus.stop, throwsAssertionError); - expect(ansiStatus.cancel, throwsAssertionError); - done = true; + // Verify that stopping or canceling multiple times throws. + expect(ansiStatus.stop, throwsAssertionError); + expect(ansiStatus.cancel, throwsAssertionError); + done = true; + }); + expect(done, isTrue); }); - expect(done, isTrue); }); } }); @@ -453,7 +497,6 @@ void main() { stdio: mockStdio, outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), timeoutConfiguration: const TimeoutConfiguration(), - platform: FakePlatform(), ); logger.printError('0123456789' * 15); final List lines = outputStderr(); @@ -475,7 +518,6 @@ void main() { stdio: mockStdio, outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), timeoutConfiguration: const TimeoutConfiguration(), - platform: FakePlatform(), ); logger.printError('0123456789' * 15, indent: 5); final List lines = outputStderr(); @@ -500,7 +542,6 @@ void main() { stdio: mockStdio, outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), timeoutConfiguration: const TimeoutConfiguration(), - platform: FakePlatform(), ); logger.printError('0123456789' * 15, hangingIndent: 5); final List lines = outputStderr(); @@ -525,7 +566,6 @@ void main() { stdio: mockStdio, outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), timeoutConfiguration: const TimeoutConfiguration(), - platform: FakePlatform(), ); logger.printError('0123456789' * 15, indent: 4, hangingIndent: 5); final List lines = outputStderr(); @@ -550,7 +590,6 @@ void main() { stdio: mockStdio, outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), timeoutConfiguration: const TimeoutConfiguration(), - platform: FakePlatform(), ); logger.printStatus('0123456789' * 15); final List lines = outputStdout(); @@ -572,7 +611,6 @@ void main() { stdio: mockStdio, outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), timeoutConfiguration: const TimeoutConfiguration(), - platform: FakePlatform(), ); logger.printStatus('0123456789' * 15, indent: 5); final List lines = outputStdout(); @@ -597,7 +635,6 @@ void main() { stdio: mockStdio, outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), timeoutConfiguration: const TimeoutConfiguration(), - platform: FakePlatform(), ); logger.printStatus('0123456789' * 15, hangingIndent: 5); final List lines = outputStdout(); @@ -622,7 +659,6 @@ void main() { stdio: mockStdio, outputPreferences: OutputPreferences.test(wrapText: true, wrapColumn: 40, showColor: false), timeoutConfiguration: const TimeoutConfiguration(), - platform: FakePlatform(), ); logger.printStatus('0123456789' * 15, indent: 4, hangingIndent: 5); final List lines = outputStdout(); @@ -647,7 +683,6 @@ void main() { stdio: mockStdio, outputPreferences: OutputPreferences.test(showColor: true), timeoutConfiguration: const TimeoutConfiguration(), - platform: FakePlatform(), ); logger.printError('Pants on fire!'); final List lines = outputStderr(); @@ -666,7 +701,6 @@ void main() { stdio: mockStdio, outputPreferences: OutputPreferences.test(showColor: true), timeoutConfiguration: const TimeoutConfiguration(), - platform: FakePlatform(), ); logger.printStatus('All good.'); @@ -685,7 +719,6 @@ void main() { stdio: mockStdio, outputPreferences: OutputPreferences.test(showColor: true), timeoutConfiguration: const TimeoutConfiguration(), - platform: FakePlatform(), ); logger.printStatus( null, @@ -710,7 +743,6 @@ void main() { stdio: mockStdio, outputPreferences: OutputPreferences.test(showColor: false), timeoutConfiguration: const TimeoutConfiguration(), - platform: FakePlatform(), ); logger.printStatus( null, @@ -736,7 +768,6 @@ void main() { stdio: mockStdio, outputPreferences: OutputPreferences.test(showColor: false), timeoutConfiguration: const TimeoutConfiguration(), - platform: FakePlatform(), ); final Status status = logger.startProgress( 'Hello', @@ -818,7 +849,6 @@ void main() { stdio: mockStdio, outputPreferences: OutputPreferences.test(showColor: false), timeoutConfiguration: const TimeoutConfiguration(), - platform: FakePlatform(), ); logger.startProgress('AAA', timeout: const TimeoutConfiguration().fastOperation)..stop(); logger.startProgress('BBB', timeout: const TimeoutConfiguration().fastOperation)..stop(); @@ -843,7 +873,6 @@ void main() { stdio: mockStdio, outputPreferences: OutputPreferences.test(), timeoutConfiguration: const TimeoutConfiguration(), - platform: FakePlatform(), ), stopwatchFactory: FakeStopwatchFactory(), ); diff --git a/packages/flutter_tools/test/general.shard/vmservice_test.dart b/packages/flutter_tools/test/general.shard/vmservice_test.dart index f5217838443..a0830c02b1d 100644 --- a/packages/flutter_tools/test/general.shard/vmservice_test.dart +++ b/packages/flutter_tools/test/general.shard/vmservice_test.dart @@ -204,9 +204,11 @@ void main() { Logger: () => StdoutLogger( outputPreferences: OutputPreferences.test(), stdio: mockStdio, - terminal: AnsiTerminal(stdio: mockStdio, platform: const LocalPlatform()), + terminal: AnsiTerminal( + stdio: mockStdio, + platform: const LocalPlatform(), + ), timeoutConfiguration: const TimeoutConfiguration(), - platform: FakePlatform(), ), WebSocketConnector: () => (String url, {CompressionOptions compression}) async => throw const SocketException('test'), }); @@ -283,10 +285,12 @@ void main() { }, overrides: { Logger: () => StdoutLogger( outputPreferences: outputPreferences, - terminal: AnsiTerminal(stdio: mockStdio, platform: const LocalPlatform()), + terminal: AnsiTerminal( + stdio: mockStdio, + platform: const LocalPlatform(), + ), stdio: mockStdio, timeoutConfiguration: const TimeoutConfiguration(), - platform: FakePlatform(), ), }); @@ -301,10 +305,12 @@ void main() { }, overrides: { Logger: () => StdoutLogger( outputPreferences: outputPreferences, - terminal: AnsiTerminal(stdio: mockStdio, platform: const LocalPlatform()), + terminal: AnsiTerminal( + stdio: mockStdio, + platform: const LocalPlatform(), + ), stdio: mockStdio, timeoutConfiguration: const TimeoutConfiguration(), - platform: FakePlatform(), ), }); @@ -320,10 +326,12 @@ void main() { }, overrides: { Logger: () => StdoutLogger( outputPreferences: outputPreferences, - terminal: AnsiTerminal(stdio: mockStdio, platform: const LocalPlatform()), + terminal: AnsiTerminal( + stdio: mockStdio, + platform: const LocalPlatform(), + ), stdio: mockStdio, timeoutConfiguration: const TimeoutConfiguration(), - platform: FakePlatform(), ), });