Unverified Commit d0526d3f authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tool] Prevent accidental calls to io.exit in unit tests (#46639)

parent 14145a4e
......@@ -30,6 +30,7 @@ import 'dart:io' as io show exit, IOSink, Process, ProcessInfo, ProcessSignal,
stderr, stdin, Stdin, StdinException, Stdout, stdout;
import 'package:meta/meta.dart';
import 'package:test_api/test_api.dart'; // ignore: deprecated_member_use
import 'context.dart';
import 'platform.dart';
......@@ -92,12 +93,33 @@ ExitFunction _exitFunction = _defaultExitFunction;
/// Exits the process.
///
/// Throws [AssertionError] if assertions are enabled and the dart:io exit
/// is still active when called. This may indicate exit was called in
/// a test without being configured correctly.
///
/// This is analogous to the `exit` function in `dart:io`, except that this
/// function may be set to a testing-friendly value by calling
/// [setExitFunctionForTests] (and then restored to its default implementation
/// with [restoreExitFunction]). The default implementation delegates to
/// `dart:io`.
ExitFunction get exit => _exitFunction;
ExitFunction get exit {
assert(
_exitFunction != io.exit || !_inUnitTest(),
'io.exit was called with assertions active in a unit test',
);
return _exitFunction;
}
// Whether the tool is executing in a unit test.
bool _inUnitTest() {
try {
expect(true, true);
} on StateError {
// If a StateError is caught, then this is not a unit test.
return false;
}
return true;
}
/// Sets the [exit] function to a function that throws an exception rather
/// than exiting the process; this is intended for testing purposes.
......
......@@ -68,6 +68,16 @@ void main() {
testUsingContext('ProcessSignal toString() works', () async {
expect(io.ProcessSignal.sigint.toString(), ProcessSignal.SIGINT.toString());
});
test('exit throws a StateError if called without being overriden', () {
expect(() => exit(0), throwsA(isInstanceOf<AssertionError>()));
});
test('exit does not throw a StateError if overriden', () {
setExitFunctionForTests((int value) {});
expect(() => exit(0), returnsNormally);
});
}
class MockIoProcessSignal extends Mock implements io.ProcessSignal {}
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