@@ -2,6 +2,59 @@ part of 'cli.dart';
22
33const _testOptimizerFileName = '.test_optimizer.dart' ;
44
5+ /// This class facilitates overriding `ProcessSignal` related behavior.
6+ /// It should be extended by another class in client code with overrides
7+ /// that construct a custom implementation.
8+ @visibleForTesting
9+ abstract class ProcessSignalOverrides {
10+ static final _token = Object ();
11+ StreamController <ProcessSignal >? _sigintStreamController;
12+
13+ /// Returns the current [ProcessSignalOverrides] instance.
14+ ///
15+ /// This will return `null` if the current [Zone] does not contain
16+ /// any [ProcessSignalOverrides] .
17+ ///
18+ /// See also:
19+ /// * [ProcessSignalOverrides.runZoned] to provide [ProcessSignalOverrides]
20+ /// in a fresh [Zone] .
21+ static ProcessSignalOverrides ? get current {
22+ return Zone .current[_token] as ProcessSignalOverrides ? ;
23+ }
24+
25+ /// Runs [body] in a fresh [Zone] using the provided overrides.
26+ static R runZoned <R >(
27+ R Function () body, {
28+ Stream <ProcessSignal >? sigintStream,
29+ }) {
30+ final overrides = _ProcessSignalOverridesScope (sigintStream);
31+ return _asyncRunZoned (body, zoneValues: {_token: overrides});
32+ }
33+
34+ /// Provides a custom [Stream] of [ProcessSignal.sigint] events.
35+ Stream <ProcessSignal >? get sigintWatch;
36+
37+ /// Emits a [ProcessSignal.sigint] event on the [sigintWatch] stream.
38+ ///
39+ /// If no custom [sigintWatch] stream is provided, this method does nothing.
40+ void addSIGINT () {
41+ _sigintStreamController? .add (ProcessSignal .sigint);
42+ }
43+ }
44+
45+ class _ProcessSignalOverridesScope extends ProcessSignalOverrides {
46+ _ProcessSignalOverridesScope (Stream <ProcessSignal >? mockSigintStream) {
47+ if (mockSigintStream != null ) {
48+ _sigintStreamController = StreamController <ProcessSignal >();
49+ }
50+ }
51+
52+ @override
53+ Stream <ProcessSignal >? get sigintWatch {
54+ return _sigintStreamController? .stream;
55+ }
56+ }
57+
558/// Thrown when `flutter pub get` is executed without a `pubspec.yaml` .
659class PubspecNotFound implements Exception {}
760
@@ -211,9 +264,7 @@ class Flutter {
211264 stderr: stderr ?? noop,
212265 ).whenComplete (() async {
213266 if (optimizePerformance) {
214- File (p.join (cwd, 'test' , _testOptimizerFileName))
215- .delete ()
216- .ignore ();
267+ await _cleanupOptimizerFile (cwd);
217268 }
218269
219270 if (collectCoverage) {
@@ -325,6 +376,8 @@ Future<int> _flutterTest({
325376 final groups = < int , TestGroup > {};
326377 final tests = < int , Test > {};
327378 final failedTestErrorMessages = < String , List <String >> {};
379+ final sigintWatch = ProcessSignalOverrides .current? .sigintWatch ??
380+ ProcessSignal .sigint.watch ();
328381
329382 var successCount = 0 ;
330383 var skipCount = 0 ;
@@ -351,6 +404,15 @@ Future<int> _flutterTest({
351404 );
352405
353406 late final StreamSubscription <TestEvent > subscription;
407+ late final StreamSubscription <ProcessSignal > sigintWatchSubscription;
408+
409+ sigintWatchSubscription = sigintWatch.listen ((_) async {
410+ await _cleanupOptimizerFile (cwd);
411+ await subscription.cancel ();
412+ await sigintWatchSubscription.cancel ();
413+ return completer.complete (ExitCode .success.code);
414+ });
415+
354416 subscription = testRunner (
355417 workingDirectory: cwd,
356418 arguments: [
@@ -483,6 +545,8 @@ Future<int> _flutterTest({
483545 if (event is ExitTestEvent ) {
484546 if (completer.isCompleted) return ;
485547 subscription.cancel ();
548+ sigintWatchSubscription.cancel ();
549+
486550 completer.complete (
487551 event.exitCode == ExitCode .success.code
488552 ? ExitCode .success.code
@@ -506,6 +570,10 @@ String? _topGroupName(Test test, Map<int, TestGroup> groups) => test.groupIDs
506570 .map ((groupID) => groups[groupID]? .name)
507571 .firstWhereOrNull ((groupName) => groupName? .isNotEmpty ?? false );
508572
573+ Future <void > _cleanupOptimizerFile (String cwd) async => File (
574+ p.join (cwd, 'test' , _testOptimizerFileName),
575+ ).delete ().ignore ();
576+
509577final int _lineLength = () {
510578 try {
511579 return stdout.terminalColumns;
0 commit comments