[flutter_tool] Make CommandHelp context free (#48584)

diff --git a/packages/flutter_tools/lib/src/base/command_help.dart b/packages/flutter_tools/lib/src/base/command_help.dart
index c8797f4..5194a25 100644
--- a/packages/flutter_tools/lib/src/base/command_help.dart
+++ b/packages/flutter_tools/lib/src/base/command_help.dart
@@ -4,34 +4,125 @@
 
 import 'dart:math' as math;
 
-import '../globals.dart' as globals;
+import 'package:meta/meta.dart';
+import 'package:platform/platform.dart';
+
+import 'logger.dart';
 import 'terminal.dart';
 
+// ignore_for_file: non_constant_identifier_names
+
 const String fire = '🔥';
 const int maxLineWidth = 84;
 
-/// Encapsulates the help text construction and printing
+/// Encapsulates the help text construction and printing.
 class CommandHelp {
+  CommandHelp({
+    @required Logger logger,
+    @required AnsiTerminal terminal,
+    @required Platform platform,
+    @required OutputPreferences outputPreferences,
+  }) : _logger = logger,
+       _terminal = terminal,
+       _platform = platform,
+       _outputPreferences = outputPreferences;
 
-  const CommandHelp._(this.key, this.description, [this.inParenthesis = '']);
+  final Logger _logger;
 
-  static const CommandHelp L = CommandHelp._('L', 'Dump layer tree to the console.', 'debugDumpLayerTree');
-  static const CommandHelp P = CommandHelp._('P', 'Toggle performance overlay.', 'WidgetsApp.showPerformanceOverlay');
-  static const CommandHelp R = CommandHelp._('R', 'Hot restart.');
-  static const CommandHelp S = CommandHelp._('S', 'Dump accessibility tree in traversal order.', 'debugDumpSemantics');
-  static const CommandHelp U = CommandHelp._('U', 'Dump accessibility tree in inverse hit test order.', 'debugDumpSemantics');
-  static const CommandHelp a = CommandHelp._('a', 'Toggle timeline events for all widget build methods.', 'debugProfileWidgetBuilds');
-  static const CommandHelp d = CommandHelp._('d', 'Detach (terminate "flutter run" but leave application running).');
-  static const CommandHelp h = CommandHelp._('h', 'Repeat this help message.');
-  static const CommandHelp i = CommandHelp._('i', 'Toggle widget inspector.', 'WidgetsApp.showWidgetInspectorOverride');
-  static const CommandHelp o = CommandHelp._('o', 'Simulate different operating systems.', 'defaultTargetPlatform');
-  static const CommandHelp p = CommandHelp._('p', 'Toggle the display of construction lines.', 'debugPaintSizeEnabled');
-  static const CommandHelp q = CommandHelp._('q', 'Quit (terminate the application on the device).');
-  static const CommandHelp r = CommandHelp._('r', 'Hot reload. $fire$fire$fire');
-  static const CommandHelp s = CommandHelp._('s', 'Save a screenshot to flutter.png.');
-  static const CommandHelp t = CommandHelp._('t', 'Dump rendering tree to the console.', 'debugDumpRenderTree');
-  static const CommandHelp w = CommandHelp._('w', 'Dump widget hierarchy to the console.', 'debugDumpApp');
-  static const CommandHelp z = CommandHelp._('z', 'Toggle elevation checker.');
+  final AnsiTerminal _terminal;
+
+  final Platform _platform;
+
+  final OutputPreferences _outputPreferences;
+
+  CommandHelpOption _L;
+  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 _R;
+  CommandHelpOption get R => _R ??= _makeOption('R', 'Hot restart.');
+
+  CommandHelpOption _S;
+  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 _a;
+  CommandHelpOption get a => _a ??= _makeOption('a', 'Toggle timeline events for all widget build methods.', 'debugProfileWidgetBuilds');
+
+  CommandHelpOption _d;
+  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 _i;
+  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 _p;
+  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 _r;
+  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 _t;
+  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 _z;
+  CommandHelpOption get z => _z ??= _makeOption('z', 'Toggle elevation checker.');
+
+  CommandHelpOption _makeOption(String key, String description, [
+    String inParenthesis = '',
+  ]) {
+    return CommandHelpOption(
+      key,
+      description,
+      inParenthesis: inParenthesis,
+      logger: _logger,
+      terminal: _terminal,
+      platform: _platform,
+      outputPreferences: _outputPreferences,
+    );
+  }
+}
+
+/// Encapsulates printing help text for a single option.
+class CommandHelpOption {
+  CommandHelpOption(
+    this.key,
+    this.description, {
+    this.inParenthesis = '',
+    @required Logger logger,
+    @required AnsiTerminal terminal,
+    @required Platform platform,
+    @required OutputPreferences outputPreferences,
+  }) : _logger = logger,
+       _terminal = terminal,
+       _platform = platform,
+       _outputPreferences = outputPreferences;
+
+  final Logger _logger;
+
+  final AnsiTerminal _terminal;
+
+  final Platform _platform;
+
+  final OutputPreferences _outputPreferences;
 
   /// The key associated with this command
   final String key;
@@ -47,12 +138,12 @@
   @override
   String toString() {
     final StringBuffer message = StringBuffer();
-    message.writeAll(<String>[globals.terminal.bolden(key), description], ' ');
+    message.writeAll(<String>[_terminal.bolden(key), description], ' ');
 
     if (_hasTextInParenthesis) {
       bool wrap = false;
-      final int maxWidth = math.max(outputPreferences.wrapColumn ?? 0,  maxLineWidth);
-      int width = maxWidth - (globals.platform.stdoutSupportsAnsi ? _rawMessageLength + 1 : message.length);
+      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;
@@ -65,12 +156,12 @@
       // pad according to the raw text
       message.write(''.padLeft(width - parentheticalText.length));
 
-      message.write(globals.terminal.color(parentheticalText, TerminalColor.grey));
+      message.write(_terminal.color(parentheticalText, TerminalColor.grey));
     }
     return message.toString();
   }
 
   void print() {
-    globals.printStatus(toString());
+    _logger.printStatus(toString());
   }
 }
diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart
index 1ce14f4..c7f314e 100644
--- a/packages/flutter_tools/lib/src/resident_runner.dart
+++ b/packages/flutter_tools/lib/src/resident_runner.dart
@@ -15,6 +15,7 @@
 import 'base/io.dart' as io;
 import 'base/logger.dart';
 import 'base/signals.dart';
+import 'base/terminal.dart' show outputPreferences;
 import 'base/utils.dart';
 import 'build_info.dart';
 import 'codegen.dart';
@@ -607,7 +608,13 @@
        artifactDirectory = dillOutputPath == null
           ? globals.fs.systemTempDirectory.createTempSync('flutter_tool.')
           : globals.fs.file(dillOutputPath).parent,
-       assetBundle = AssetBundleFactory.instance.createBundle() {
+       assetBundle = AssetBundleFactory.instance.createBundle(),
+       commandHelp = CommandHelp(
+         logger: globals.logger,
+         terminal: globals.terminal,
+         platform: globals.platform,
+         outputPreferences: outputPreferences,
+       ) {
     if (!artifactDirectory.existsSync()) {
       artifactDirectory.createSync(recursive: true);
     }
@@ -640,6 +647,8 @@
   final String mainPath;
   final AssetBundle assetBundle;
 
+  final CommandHelp commandHelp;
+
   bool _exited = false;
   Completer<int> _finished = Completer<int>();
   bool hotMode;
@@ -1005,29 +1014,29 @@
 
   void printHelpDetails() {
     if (flutterDevices.any((FlutterDevice d) => d.device.supportsScreenshot)) {
-      CommandHelp.s.print();
+      commandHelp.s.print();
     }
     if (supportsServiceProtocol) {
-      CommandHelp.w.print();
-      CommandHelp.t.print();
+      commandHelp.w.print();
+      commandHelp.t.print();
       if (isRunningDebug) {
-        CommandHelp.L.print();
-        CommandHelp.S.print();
-        CommandHelp.U.print();
-        CommandHelp.i.print();
-        CommandHelp.p.print();
-        CommandHelp.o.print();
-        CommandHelp.z.print();
+        commandHelp.L.print();
+        commandHelp.S.print();
+        commandHelp.U.print();
+        commandHelp.i.print();
+        commandHelp.p.print();
+        commandHelp.o.print();
+        commandHelp.z.print();
       } else {
-        CommandHelp.S.print();
-        CommandHelp.U.print();
+        commandHelp.S.print();
+        commandHelp.U.print();
       }
       // `P` should precede `a`
-      CommandHelp.P.print();
-      CommandHelp.a.print();
+      commandHelp.P.print();
+      commandHelp.a.print();
     }
     if (flutterDevices.any((FlutterDevice d) => d.device.supportsScreenshot)) {
-      CommandHelp.s.print();
+      commandHelp.s.print();
     }
   }
 
diff --git a/packages/flutter_tools/lib/src/run_cold.dart b/packages/flutter_tools/lib/src/run_cold.dart
index 26405b3..b4a74ce 100644
--- a/packages/flutter_tools/lib/src/run_cold.dart
+++ b/packages/flutter_tools/lib/src/run_cold.dart
@@ -6,7 +6,6 @@
 
 import 'package:meta/meta.dart';
 
-import 'base/command_help.dart';
 import 'base/file_system.dart';
 import 'device.dart';
 import 'globals.dart' as globals;
@@ -186,11 +185,11 @@
         printHelpDetails();
       }
     }
-    CommandHelp.h.print();
+    commandHelp.h.print();
     if (_didAttach) {
-      CommandHelp.d.print();
+      commandHelp.d.print();
     }
-    CommandHelp.q.print();
+    commandHelp.q.print();
     for (final FlutterDevice device in flutterDevices) {
       final String dname = device.device.name;
       if (device.vmService != null) {
diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart
index a5dd209..111918e 100644
--- a/packages/flutter_tools/lib/src/run_hot.dart
+++ b/packages/flutter_tools/lib/src/run_hot.dart
@@ -11,7 +11,6 @@
 import 'package:pool/pool.dart';
 import 'base/async_guard.dart';
 
-import 'base/command_help.dart';
 import 'base/context.dart';
 import 'base/file_system.dart';
 import 'base/logger.dart';
@@ -1046,15 +1045,15 @@
   @override
   void printHelp({ @required bool details }) {
     globals.printStatus('Flutter run key commands.');
-    CommandHelp.r.print();
+    commandHelp.r.print();
     if (canHotRestart) {
-      CommandHelp.R.print();
+      commandHelp.R.print();
     }
-    CommandHelp.h.print();
+    commandHelp.h.print();
     if (_didAttach) {
-      CommandHelp.d.print();
+      commandHelp.d.print();
     }
-    CommandHelp.q.print();
+    commandHelp.q.print();
     if (details) {
       printHelpDetails();
     }
diff --git a/packages/flutter_tools/test/general.shard/base/command_help_test.dart b/packages/flutter_tools/test/general.shard/base/command_help_test.dart
index 5fdbc84..b04c9df 100644
--- a/packages/flutter_tools/test/general.shard/base/command_help_test.dart
+++ b/packages/flutter_tools/test/general.shard/base/command_help_test.dart
@@ -3,17 +3,47 @@
 // found in the LICENSE file.
 
 import 'package:flutter_tools/src/base/command_help.dart';
-import 'package:flutter_tools/src/base/terminal.dart' show OutputPreferences, outputPreferences;
-import 'package:flutter_tools/src/globals.dart' as globals;
+import 'package:flutter_tools/src/base/logger.dart';
+import 'package:flutter_tools/src/base/terminal.dart' show AnsiTerminal, OutputPreferences;
+import 'package:meta/meta.dart';
 import 'package:mockito/mockito.dart';
 import 'package:platform/platform.dart';
 
 import '../../src/common.dart';
-import '../../src/context.dart';
+import '../../src/mocks.dart' show MockStdio;
+
+class MockLogger extends Mock implements Logger {}
+
+CommandHelp _createCommandHelp({
+  @required bool ansi,
+  @required int wrapColumn,
+}) {
+  final MockPlatform mockPlatform = MockPlatform();
+  when(mockPlatform.stdoutSupportsAnsi).thenReturn(ansi);
+  return CommandHelp(
+    logger: MockLogger(),
+    terminal: AnsiTerminal(
+      stdio:  MockStdio(),
+      platform: mockPlatform,
+    ),
+    platform: mockPlatform,
+    outputPreferences: OutputPreferences.test(
+      showColor: ansi,
+      wrapColumn: wrapColumn,
+    ),
+  );
+}
 
 // Used to use the message length in different scenarios in a DRY way
-Future<void> Function() _testMessageLength(bool stdoutSupportsAnsi, int maxTestLineLength) => () async {
-  when(globals.platform.stdoutSupportsAnsi).thenReturn(stdoutSupportsAnsi);
+void _testMessageLength({
+  @required bool stdoutSupportsAnsi,
+  @required int maxTestLineLength,
+  @required int wrapColumn,
+}) {
+  final CommandHelp commandHelp = _createCommandHelp(
+    ansi: stdoutSupportsAnsi,
+    wrapColumn: wrapColumn,
+  );
 
   int expectedWidth = maxTestLineLength;
 
@@ -22,148 +52,153 @@
     expectedWidth += ansiMetaCharactersLength;
   }
 
-  expect(CommandHelp.L.toString().length, lessThanOrEqualTo(expectedWidth));
-  expect(CommandHelp.P.toString().length, lessThanOrEqualTo(expectedWidth));
-  expect(CommandHelp.R.toString().length, lessThanOrEqualTo(expectedWidth));
-  expect(CommandHelp.S.toString().length, lessThanOrEqualTo(expectedWidth));
-  expect(CommandHelp.U.toString().length, lessThanOrEqualTo(expectedWidth));
-  expect(CommandHelp.a.toString().length, lessThanOrEqualTo(expectedWidth));
-  expect(CommandHelp.d.toString().length, lessThanOrEqualTo(expectedWidth));
-  expect(CommandHelp.h.toString().length, lessThanOrEqualTo(expectedWidth));
-  expect(CommandHelp.i.toString().length, lessThanOrEqualTo(expectedWidth));
-  expect(CommandHelp.o.toString().length, lessThanOrEqualTo(expectedWidth));
-  expect(CommandHelp.p.toString().length, lessThanOrEqualTo(expectedWidth));
-  expect(CommandHelp.q.toString().length, lessThanOrEqualTo(expectedWidth));
-  expect(CommandHelp.r.toString().length, lessThanOrEqualTo(expectedWidth));
-  expect(CommandHelp.s.toString().length, lessThanOrEqualTo(expectedWidth));
-  expect(CommandHelp.t.toString().length, lessThanOrEqualTo(expectedWidth));
-  expect(CommandHelp.w.toString().length, lessThanOrEqualTo(expectedWidth));
-  expect(CommandHelp.z.toString().length, lessThanOrEqualTo(expectedWidth));
-};
+  expect(commandHelp.L.toString().length, lessThanOrEqualTo(expectedWidth));
+  expect(commandHelp.P.toString().length, lessThanOrEqualTo(expectedWidth));
+  expect(commandHelp.R.toString().length, lessThanOrEqualTo(expectedWidth));
+  expect(commandHelp.S.toString().length, lessThanOrEqualTo(expectedWidth));
+  expect(commandHelp.U.toString().length, lessThanOrEqualTo(expectedWidth));
+  expect(commandHelp.a.toString().length, lessThanOrEqualTo(expectedWidth));
+  expect(commandHelp.d.toString().length, lessThanOrEqualTo(expectedWidth));
+  expect(commandHelp.h.toString().length, lessThanOrEqualTo(expectedWidth));
+  expect(commandHelp.i.toString().length, lessThanOrEqualTo(expectedWidth));
+  expect(commandHelp.o.toString().length, lessThanOrEqualTo(expectedWidth));
+  expect(commandHelp.p.toString().length, lessThanOrEqualTo(expectedWidth));
+  expect(commandHelp.q.toString().length, lessThanOrEqualTo(expectedWidth));
+  expect(commandHelp.r.toString().length, lessThanOrEqualTo(expectedWidth));
+  expect(commandHelp.s.toString().length, lessThanOrEqualTo(expectedWidth));
+  expect(commandHelp.t.toString().length, lessThanOrEqualTo(expectedWidth));
+  expect(commandHelp.w.toString().length, lessThanOrEqualTo(expectedWidth));
+  expect(commandHelp.z.toString().length, lessThanOrEqualTo(expectedWidth));
+}
 
 void main() {
   group('CommandHelp', () {
     group('toString', () {
 
-      testUsingContext('should have a bold command key', () async {
-        when(globals.platform.stdoutSupportsAnsi).thenReturn(true);
+      testWithoutContext('should have a bold command key', () {
+        final CommandHelp commandHelp = _createCommandHelp(
+          ansi: true,
+          wrapColumn: maxLineWidth,
+        );
 
-        expect(CommandHelp.L.toString(), startsWith('\x1B[1mL\x1B[22m'));
-        expect(CommandHelp.P.toString(), startsWith('\x1B[1mP\x1B[22m'));
-        expect(CommandHelp.R.toString(), startsWith('\x1B[1mR\x1B[22m'));
-        expect(CommandHelp.S.toString(), startsWith('\x1B[1mS\x1B[22m'));
-        expect(CommandHelp.U.toString(), startsWith('\x1B[1mU\x1B[22m'));
-        expect(CommandHelp.a.toString(), startsWith('\x1B[1ma\x1B[22m'));
-        expect(CommandHelp.d.toString(), startsWith('\x1B[1md\x1B[22m'));
-        expect(CommandHelp.h.toString(), startsWith('\x1B[1mh\x1B[22m'));
-        expect(CommandHelp.i.toString(), startsWith('\x1B[1mi\x1B[22m'));
-        expect(CommandHelp.o.toString(), startsWith('\x1B[1mo\x1B[22m'));
-        expect(CommandHelp.p.toString(), startsWith('\x1B[1mp\x1B[22m'));
-        expect(CommandHelp.q.toString(), startsWith('\x1B[1mq\x1B[22m'));
-        expect(CommandHelp.r.toString(), startsWith('\x1B[1mr\x1B[22m'));
-        expect(CommandHelp.s.toString(), startsWith('\x1B[1ms\x1B[22m'));
-        expect(CommandHelp.t.toString(), startsWith('\x1B[1mt\x1B[22m'));
-        expect(CommandHelp.w.toString(), startsWith('\x1B[1mw\x1B[22m'));
-        expect(CommandHelp.z.toString(), startsWith('\x1B[1mz\x1B[22m'));
-      }, overrides: <Type, Generator>{
-        OutputPreferences: () => OutputPreferences(wrapColumn: maxLineWidth),
-        Platform: () => MockPlatform(),
+        expect(commandHelp.L.toString(), startsWith('\x1B[1mL\x1B[22m'));
+        expect(commandHelp.P.toString(), startsWith('\x1B[1mP\x1B[22m'));
+        expect(commandHelp.R.toString(), startsWith('\x1B[1mR\x1B[22m'));
+        expect(commandHelp.S.toString(), startsWith('\x1B[1mS\x1B[22m'));
+        expect(commandHelp.U.toString(), startsWith('\x1B[1mU\x1B[22m'));
+        expect(commandHelp.a.toString(), startsWith('\x1B[1ma\x1B[22m'));
+        expect(commandHelp.d.toString(), startsWith('\x1B[1md\x1B[22m'));
+        expect(commandHelp.h.toString(), startsWith('\x1B[1mh\x1B[22m'));
+        expect(commandHelp.i.toString(), startsWith('\x1B[1mi\x1B[22m'));
+        expect(commandHelp.o.toString(), startsWith('\x1B[1mo\x1B[22m'));
+        expect(commandHelp.p.toString(), startsWith('\x1B[1mp\x1B[22m'));
+        expect(commandHelp.q.toString(), startsWith('\x1B[1mq\x1B[22m'));
+        expect(commandHelp.r.toString(), startsWith('\x1B[1mr\x1B[22m'));
+        expect(commandHelp.s.toString(), startsWith('\x1B[1ms\x1B[22m'));
+        expect(commandHelp.t.toString(), startsWith('\x1B[1mt\x1B[22m'));
+        expect(commandHelp.w.toString(), startsWith('\x1B[1mw\x1B[22m'));
+        expect(commandHelp.z.toString(), startsWith('\x1B[1mz\x1B[22m'));
       });
 
-      testUsingContext('commands L,P,S,U,a,i,o,p,t,w should have a grey bolden parenthetical text', () async {
-        when(globals.platform.stdoutSupportsAnsi).thenReturn(true);
+      testWithoutContext('commands L,P,S,U,a,i,o,p,t,w should have a grey bolden parenthetical text', () {
+        final CommandHelp commandHelp = _createCommandHelp(
+          ansi: true,
+          wrapColumn: maxLineWidth,
+        );
 
-        expect(CommandHelp.L.toString(), endsWith('\x1B[1;30m(debugDumpLayerTree)\x1B[39m'));
-        expect(CommandHelp.P.toString(), endsWith('\x1B[1;30m(WidgetsApp.showPerformanceOverlay)\x1B[39m'));
-        expect(CommandHelp.S.toString(), endsWith('\x1B[1;30m(debugDumpSemantics)\x1B[39m'));
-        expect(CommandHelp.U.toString(), endsWith('\x1B[1;30m(debugDumpSemantics)\x1B[39m'));
-        expect(CommandHelp.a.toString(), endsWith('\x1B[1;30m(debugProfileWidgetBuilds)\x1B[39m'));
-        expect(CommandHelp.i.toString(), endsWith('\x1B[1;30m(WidgetsApp.showWidgetInspectorOverride)\x1B[39m'));
-        expect(CommandHelp.o.toString(), endsWith('\x1B[1;30m(defaultTargetPlatform)\x1B[39m'));
-        expect(CommandHelp.p.toString(), endsWith('\x1B[1;30m(debugPaintSizeEnabled)\x1B[39m'));
-        expect(CommandHelp.t.toString(), endsWith('\x1B[1;30m(debugDumpRenderTree)\x1B[39m'));
-        expect(CommandHelp.w.toString(), endsWith('\x1B[1;30m(debugDumpApp)\x1B[39m'));
-      }, overrides: <Type, Generator>{
-        OutputPreferences: () => OutputPreferences(wrapColumn: maxLineWidth),
-        Platform: () => MockPlatform(),
+        expect(commandHelp.L.toString(), endsWith('\x1B[1;30m(debugDumpLayerTree)\x1B[39m'));
+        expect(commandHelp.P.toString(), endsWith('\x1B[1;30m(WidgetsApp.showPerformanceOverlay)\x1B[39m'));
+        expect(commandHelp.S.toString(), endsWith('\x1B[1;30m(debugDumpSemantics)\x1B[39m'));
+        expect(commandHelp.U.toString(), endsWith('\x1B[1;30m(debugDumpSemantics)\x1B[39m'));
+        expect(commandHelp.a.toString(), endsWith('\x1B[1;30m(debugProfileWidgetBuilds)\x1B[39m'));
+        expect(commandHelp.i.toString(), endsWith('\x1B[1;30m(WidgetsApp.showWidgetInspectorOverride)\x1B[39m'));
+        expect(commandHelp.o.toString(), endsWith('\x1B[1;30m(defaultTargetPlatform)\x1B[39m'));
+        expect(commandHelp.p.toString(), endsWith('\x1B[1;30m(debugPaintSizeEnabled)\x1B[39m'));
+        expect(commandHelp.t.toString(), endsWith('\x1B[1;30m(debugDumpRenderTree)\x1B[39m'));
+        expect(commandHelp.w.toString(), endsWith('\x1B[1;30m(debugDumpApp)\x1B[39m'));
       });
 
-      testUsingContext('should not create a help text longer than maxLineWidth without ansi support',
-        _testMessageLength(false, maxLineWidth),
-        overrides: <Type, Generator>{
-          OutputPreferences: () => OutputPreferences(wrapColumn: 0),
-          Platform: () => MockPlatform(),
+      testWithoutContext('should not create a help text longer than maxLineWidth without ansi support', () {
+        _testMessageLength(
+          stdoutSupportsAnsi: false,
+          wrapColumn: 0,
+          maxTestLineLength: maxLineWidth,
+        );
       });
 
-      testUsingContext('should not create a help text longer than maxLineWidth with ansi support',
-        _testMessageLength(true, maxLineWidth),
-        overrides: <Type, Generator>{
-          OutputPreferences: () => OutputPreferences(wrapColumn: 0),
-          Platform: () => MockPlatform(),
+      testWithoutContext('should not create a help text longer than maxLineWidth with ansi support', () {
+        _testMessageLength(
+          stdoutSupportsAnsi: true,
+          wrapColumn: 0,
+          maxTestLineLength: maxLineWidth,
+        );
       });
 
-      testUsingContext('should not create a help text longer than outputPreferences.wrapColumn without ansi support',
-        _testMessageLength(false, outputPreferences.wrapColumn),
-          overrides: <Type, Generator>{
-          Platform: () => MockPlatform(),
+      testWithoutContext('should not create a help text longer than outputPreferences.wrapColumn without ansi support', () {
+        _testMessageLength(
+          stdoutSupportsAnsi: false,
+          wrapColumn: OutputPreferences.kDefaultTerminalColumns,
+          maxTestLineLength: OutputPreferences.kDefaultTerminalColumns,
+        );
       });
 
-      testUsingContext('should not create a help text longer than outputPreferences.wrapColumn with ansi support',
-        _testMessageLength(true, outputPreferences.wrapColumn),
-        overrides: <Type, Generator>{
-          Platform: () => MockPlatform(),
-        });
-
-      testUsingContext('should create the correct help text with ansi support', () async {
-        when(globals.platform.stdoutSupportsAnsi).thenReturn(true);
-
-        expect(CommandHelp.L.toString(), equals('\x1B[1mL\x1B[22m Dump layer tree to the console.                               \x1B[1;30m(debugDumpLayerTree)\x1B[39m'));
-        expect(CommandHelp.P.toString(), equals('\x1B[1mP\x1B[22m Toggle performance overlay.                    \x1B[1;30m(WidgetsApp.showPerformanceOverlay)\x1B[39m'));
-        expect(CommandHelp.R.toString(), equals('\x1B[1mR\x1B[22m Hot restart.'));
-        expect(CommandHelp.S.toString(), equals('\x1B[1mS\x1B[22m Dump accessibility tree in traversal order.                   \x1B[1;30m(debugDumpSemantics)\x1B[39m'));
-        expect(CommandHelp.U.toString(), equals('\x1B[1mU\x1B[22m Dump accessibility tree in inverse hit test order.            \x1B[1;30m(debugDumpSemantics)\x1B[39m'));
-        expect(CommandHelp.a.toString(), equals('\x1B[1ma\x1B[22m Toggle timeline events for all widget build methods.    \x1B[1;30m(debugProfileWidgetBuilds)\x1B[39m'));
-        expect(CommandHelp.d.toString(), equals('\x1B[1md\x1B[22m Detach (terminate "flutter run" but leave application running).'));
-        expect(CommandHelp.h.toString(), equals('\x1B[1mh\x1B[22m Repeat this help message.'));
-        expect(CommandHelp.i.toString(), equals('\x1B[1mi\x1B[22m Toggle widget inspector.                  \x1B[1;30m(WidgetsApp.showWidgetInspectorOverride)\x1B[39m'));
-        expect(CommandHelp.o.toString(), equals('\x1B[1mo\x1B[22m Simulate different operating systems.                      \x1B[1;30m(defaultTargetPlatform)\x1B[39m'));
-        expect(CommandHelp.p.toString(), equals('\x1B[1mp\x1B[22m Toggle the display of construction lines.                  \x1B[1;30m(debugPaintSizeEnabled)\x1B[39m'));
-        expect(CommandHelp.q.toString(), equals('\x1B[1mq\x1B[22m Quit (terminate the application on the device).'));
-        expect(CommandHelp.r.toString(), equals('\x1B[1mr\x1B[22m Hot reload. $fire$fire$fire'));
-        expect(CommandHelp.s.toString(), equals('\x1B[1ms\x1B[22m Save a screenshot to flutter.png.'));
-        expect(CommandHelp.t.toString(), equals('\x1B[1mt\x1B[22m Dump rendering tree to the console.                          \x1B[1;30m(debugDumpRenderTree)\x1B[39m'));
-        expect(CommandHelp.w.toString(), equals('\x1B[1mw\x1B[22m Dump widget hierarchy to the console.                               \x1B[1;30m(debugDumpApp)\x1B[39m'));
-        expect(CommandHelp.z.toString(), equals('\x1B[1mz\x1B[22m Toggle elevation checker.'));
-      }, overrides: <Type, Generator>{
-        OutputPreferences: () => OutputPreferences(wrapColumn: maxLineWidth),
-        Platform: () => MockPlatform(),
+      testWithoutContext('should not create a help text longer than outputPreferences.wrapColumn with ansi support', () {
+        _testMessageLength(
+          stdoutSupportsAnsi: true,
+          wrapColumn: OutputPreferences.kDefaultTerminalColumns,
+          maxTestLineLength: OutputPreferences.kDefaultTerminalColumns,
+        );
       });
 
-      testUsingContext('should create the correct help text without ansi support', () async {
-        when(globals.platform.stdoutSupportsAnsi).thenReturn(false);
+      testWithoutContext('should create the correct help text with ansi support', () {
+        final CommandHelp commandHelp = _createCommandHelp(
+          ansi: true,
+          wrapColumn: maxLineWidth,
+        );
 
-        expect(CommandHelp.L.toString(), equals('L Dump layer tree to the console.                               (debugDumpLayerTree)'));
-        expect(CommandHelp.P.toString(), equals('P Toggle performance overlay.                    (WidgetsApp.showPerformanceOverlay)'));
-        expect(CommandHelp.R.toString(), equals('R Hot restart.'));
-        expect(CommandHelp.S.toString(), equals('S Dump accessibility tree in traversal order.                   (debugDumpSemantics)'));
-        expect(CommandHelp.U.toString(), equals('U Dump accessibility tree in inverse hit test order.            (debugDumpSemantics)'));
-        expect(CommandHelp.a.toString(), equals('a Toggle timeline events for all widget build methods.    (debugProfileWidgetBuilds)'));
-        expect(CommandHelp.d.toString(), equals('d Detach (terminate "flutter run" but leave application running).'));
-        expect(CommandHelp.h.toString(), equals('h Repeat this help message.'));
-        expect(CommandHelp.i.toString(), equals('i Toggle widget inspector.                  (WidgetsApp.showWidgetInspectorOverride)'));
-        expect(CommandHelp.o.toString(), equals('o Simulate different operating systems.                      (defaultTargetPlatform)'));
-        expect(CommandHelp.p.toString(), equals('p Toggle the display of construction lines.                  (debugPaintSizeEnabled)'));
-        expect(CommandHelp.q.toString(), equals('q Quit (terminate the application on the device).'));
-        expect(CommandHelp.r.toString(), equals('r Hot reload. $fire$fire$fire'));
-        expect(CommandHelp.s.toString(), equals('s Save a screenshot to flutter.png.'));
-        expect(CommandHelp.t.toString(), equals('t Dump rendering tree to the console.                          (debugDumpRenderTree)'));
-        expect(CommandHelp.w.toString(), equals('w Dump widget hierarchy to the console.                               (debugDumpApp)'));
-        expect(CommandHelp.z.toString(), equals('z Toggle elevation checker.'));
-      }, overrides: <Type, Generator>{
-        OutputPreferences: () => OutputPreferences(wrapColumn: maxLineWidth),
-        Platform: () => MockPlatform(),
+        expect(commandHelp.L.toString(), equals('\x1B[1mL\x1B[22m Dump layer tree to the console.                               \x1B[1;30m(debugDumpLayerTree)\x1B[39m'));
+        expect(commandHelp.P.toString(), equals('\x1B[1mP\x1B[22m Toggle performance overlay.                    \x1B[1;30m(WidgetsApp.showPerformanceOverlay)\x1B[39m'));
+        expect(commandHelp.R.toString(), equals('\x1B[1mR\x1B[22m Hot restart.'));
+        expect(commandHelp.S.toString(), equals('\x1B[1mS\x1B[22m Dump accessibility tree in traversal order.                   \x1B[1;30m(debugDumpSemantics)\x1B[39m'));
+        expect(commandHelp.U.toString(), equals('\x1B[1mU\x1B[22m Dump accessibility tree in inverse hit test order.            \x1B[1;30m(debugDumpSemantics)\x1B[39m'));
+        expect(commandHelp.a.toString(), equals('\x1B[1ma\x1B[22m Toggle timeline events for all widget build methods.    \x1B[1;30m(debugProfileWidgetBuilds)\x1B[39m'));
+        expect(commandHelp.d.toString(), equals('\x1B[1md\x1B[22m Detach (terminate "flutter run" but leave application running).'));
+        expect(commandHelp.h.toString(), equals('\x1B[1mh\x1B[22m Repeat this help message.'));
+        expect(commandHelp.i.toString(), equals('\x1B[1mi\x1B[22m Toggle widget inspector.                  \x1B[1;30m(WidgetsApp.showWidgetInspectorOverride)\x1B[39m'));
+        expect(commandHelp.o.toString(), equals('\x1B[1mo\x1B[22m Simulate different operating systems.                      \x1B[1;30m(defaultTargetPlatform)\x1B[39m'));
+        expect(commandHelp.p.toString(), equals('\x1B[1mp\x1B[22m Toggle the display of construction lines.                  \x1B[1;30m(debugPaintSizeEnabled)\x1B[39m'));
+        expect(commandHelp.q.toString(), equals('\x1B[1mq\x1B[22m Quit (terminate the application on the device).'));
+        expect(commandHelp.r.toString(), equals('\x1B[1mr\x1B[22m Hot reload. $fire$fire$fire'));
+        expect(commandHelp.s.toString(), equals('\x1B[1ms\x1B[22m Save a screenshot to flutter.png.'));
+        expect(commandHelp.t.toString(), equals('\x1B[1mt\x1B[22m Dump rendering tree to the console.                          \x1B[1;30m(debugDumpRenderTree)\x1B[39m'));
+        expect(commandHelp.w.toString(), equals('\x1B[1mw\x1B[22m Dump widget hierarchy to the console.                               \x1B[1;30m(debugDumpApp)\x1B[39m'));
+        expect(commandHelp.z.toString(), equals('\x1B[1mz\x1B[22m Toggle elevation checker.'));
       });
 
+      testWithoutContext('should create the correct help text without ansi support', () {
+        final CommandHelp commandHelp = _createCommandHelp(
+          ansi: false,
+          wrapColumn: maxLineWidth,
+        );
+
+        expect(commandHelp.L.toString(), equals('L Dump layer tree to the console.                               (debugDumpLayerTree)'));
+        expect(commandHelp.P.toString(), equals('P Toggle performance overlay.                    (WidgetsApp.showPerformanceOverlay)'));
+        expect(commandHelp.R.toString(), equals('R Hot restart.'));
+        expect(commandHelp.S.toString(), equals('S Dump accessibility tree in traversal order.                   (debugDumpSemantics)'));
+        expect(commandHelp.U.toString(), equals('U Dump accessibility tree in inverse hit test order.            (debugDumpSemantics)'));
+        expect(commandHelp.a.toString(), equals('a Toggle timeline events for all widget build methods.    (debugProfileWidgetBuilds)'));
+        expect(commandHelp.d.toString(), equals('d Detach (terminate "flutter run" but leave application running).'));
+        expect(commandHelp.h.toString(), equals('h Repeat this help message.'));
+        expect(commandHelp.i.toString(), equals('i Toggle widget inspector.                  (WidgetsApp.showWidgetInspectorOverride)'));
+        expect(commandHelp.o.toString(), equals('o Simulate different operating systems.                      (defaultTargetPlatform)'));
+        expect(commandHelp.p.toString(), equals('p Toggle the display of construction lines.                  (debugPaintSizeEnabled)'));
+        expect(commandHelp.q.toString(), equals('q Quit (terminate the application on the device).'));
+        expect(commandHelp.r.toString(), equals('r Hot reload. $fire$fire$fire'));
+        expect(commandHelp.s.toString(), equals('s Save a screenshot to flutter.png.'));
+        expect(commandHelp.t.toString(), equals('t Dump rendering tree to the console.                          (debugDumpRenderTree)'));
+        expect(commandHelp.w.toString(), equals('w Dump widget hierarchy to the console.                               (debugDumpApp)'));
+        expect(commandHelp.z.toString(), equals('z Toggle elevation checker.'));
+      });
     });
   });
 }
diff --git a/packages/flutter_tools/test/general.shard/resident_runner_test.dart b/packages/flutter_tools/test/general.shard/resident_runner_test.dart
index 1e33692..ef835f1 100644
--- a/packages/flutter_tools/test/general.shard/resident_runner_test.dart
+++ b/packages/flutter_tools/test/general.shard/resident_runner_test.dart
@@ -364,6 +364,8 @@
 
     residentRunner.printHelp(details: true);
 
+    final CommandHelp commandHelp = residentRunner.commandHelp;
+
     // supports service protocol
     expect(residentRunner.supportsServiceProtocol, true);
     // isRunningDebug
@@ -372,23 +374,23 @@
     expect(testLogger.statusText, equals(
         <dynamic>[
           'Flutter run key commands.',
-          CommandHelp.r,
-          CommandHelp.R,
-          CommandHelp.h,
-          CommandHelp.q,
-          CommandHelp.s,
-          CommandHelp.w,
-          CommandHelp.t,
-          CommandHelp.L,
-          CommandHelp.S,
-          CommandHelp.U,
-          CommandHelp.i,
-          CommandHelp.p,
-          CommandHelp.o,
-          CommandHelp.z,
-          CommandHelp.P,
-          CommandHelp.a,
-          CommandHelp.s,
+          commandHelp.r,
+          commandHelp.R,
+          commandHelp.h,
+          commandHelp.q,
+          commandHelp.s,
+          commandHelp.w,
+          commandHelp.t,
+          commandHelp.L,
+          commandHelp.S,
+          commandHelp.U,
+          commandHelp.i,
+          commandHelp.p,
+          commandHelp.o,
+          commandHelp.z,
+          commandHelp.P,
+          commandHelp.a,
+          commandHelp.s,
           'An Observatory debugger and profiler on null is available at: null',
           ''
         ].join('\n')