Unverified Commit 1328997b authored by Andrew Kolos's avatar Andrew Kolos Committed by GitHub

give `throwsToolExit` a more useful description (#136694)

Fixes https://github.com/flutter/flutter/issues/136698.

Alters how `throwToolExit` creates its matcher. This results is an improved description of the matcher.

The mismatch description isn't improved by this, but I writing an entirely custom matcher to fix this isn't ideal either. We can instead mitigate the issue by augmenting the `toString` implementation of `ToolExit` to include the exit code, if it is non-null.

With these changes, the first few lines of output from a test would look like this:

```
Expected: throws <Instance of 'ToolExit'> with `exitCode`: <42> and `message`: contains 'message'
  Actual: <Closure: () => Never>
   Which: threw ToolExit:<Exit code: 41232. Error: message>
```
parent 37da62a6
......@@ -21,5 +21,5 @@ class ToolExit implements Exception {
final int? exitCode;
@override
String toString() => 'Exception: $message'; // TODO(ianh): Really this should say "Error".
String toString() => 'Error: $message';
}
......@@ -1298,7 +1298,7 @@ flutter:
await residentRunner.runSourceGenerators();
expect(testLogger.errorText, allOf(contains('Exception')));
expect(testLogger.errorText, contains('Error'));
expect(testLogger.statusText, isEmpty);
}));
......
......@@ -184,7 +184,7 @@ void main() {
final String output = _uniqueOutputLines(outputEvents);
expect(output, contains('this code does not compile'));
expect(output, contains('Exception: Failed to build'));
expect(output, contains('Error: Failed to build'));
expect(output, contains('Exited (1)'));
});
......
......@@ -93,19 +93,20 @@ Future<StringBuffer> capturedConsolePrint(Future<void> Function() body) async {
final Matcher throwsAssertionError = throwsA(isA<AssertionError>());
/// Matcher for functions that throw [ToolExit].
///
/// [message] is matched using the [contains] matcher.
Matcher throwsToolExit({ int? exitCode, Pattern? message }) {
Matcher matcher = _isToolExit;
TypeMatcher<ToolExit> result = const TypeMatcher<ToolExit>();
if (exitCode != null) {
matcher = allOf(matcher, (ToolExit e) => e.exitCode == exitCode);
result = result.having((ToolExit e) => e.exitCode, 'exitCode', equals(exitCode));
}
if (message != null) {
matcher = allOf(matcher, (ToolExit e) => e.message?.contains(message) ?? false);
result = result.having((ToolExit e) => e.message, 'message', contains(message));
}
return throwsA(matcher);
}
/// Matcher for [ToolExit]s.
final TypeMatcher<ToolExit> _isToolExit = isA<ToolExit>();
return throwsA(result);
}
/// Matcher for functions that throw [UsageException].
Matcher throwsUsageException({Pattern? message }) {
......
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