Unverified Commit db5c71f4 authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Fix analyze --watch command iterator (#96264)

parent 7ab50d64
...@@ -110,27 +110,29 @@ class AnalyzeContinuously extends AnalyzeBase { ...@@ -110,27 +110,29 @@ class AnalyzeContinuously extends AnalyzeBase {
logger.printStatus(terminal.clearScreen(), newline: false); logger.printStatus(terminal.clearScreen(), newline: false);
// Remove errors for deleted files, sort, and print errors. // Remove errors for deleted files, sort, and print errors.
final List<AnalysisError> errors = <AnalysisError>[]; final List<AnalysisError> sortedErrors = <AnalysisError>[];
final List<String> pathsToRemove = <String>[];
analysisErrors.forEach((String path, List<AnalysisError> errors) { analysisErrors.forEach((String path, List<AnalysisError> errors) {
if (fileSystem.isFileSync(path)) { if (fileSystem.isFileSync(path)) {
errors.addAll(errors); sortedErrors.addAll(errors);
} else { } else {
analysisErrors.remove(path); pathsToRemove.add(path);
} }
}); });
analysisErrors.removeWhere((String path, _) => pathsToRemove.contains(path));
errors.sort(); sortedErrors.sort();
for (final AnalysisError error in errors) { for (final AnalysisError error in sortedErrors) {
logger.printStatus(error.toString()); logger.printStatus(error.toString());
if (error.code != null) { if (error.code != null) {
logger.printTrace('error code: ${error.code}'); logger.printTrace('error code: ${error.code}');
} }
} }
dumpErrors(errors.map<String>((AnalysisError error) => error.toLegacyString())); dumpErrors(sortedErrors.map<String>((AnalysisError error) => error.toLegacyString()));
final int issueCount = errors.length; final int issueCount = sortedErrors.length;
final int issueDiff = issueCount - lastErrorCount; final int issueDiff = issueCount - lastErrorCount;
lastErrorCount = issueCount; lastErrorCount = issueCount;
final String seconds = (analysisTimer.elapsedMilliseconds / 1000.0).toStringAsFixed(2); final String seconds = (analysisTimer.elapsedMilliseconds / 1000.0).toStringAsFixed(2);
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
import 'dart:async'; import 'dart:async';
import 'package:fake_async/fake_async.dart';
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:flutter_tools/src/artifacts.dart'; import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/common.dart'; import 'package:flutter_tools/src/base/common.dart';
...@@ -174,7 +175,6 @@ void main() { ...@@ -174,7 +175,6 @@ void main() {
}); });
testUsingContext('Can run AnalysisService with customized cache location', () async { testUsingContext('Can run AnalysisService with customized cache location', () async {
final Completer<void> completer = Completer<void>();
final StreamController<List<int>> stdin = StreamController<List<int>>(); final StreamController<List<int>> stdin = StreamController<List<int>>();
final FakeProcessManager processManager = FakeProcessManager.list( final FakeProcessManager processManager = FakeProcessManager.list(
<FakeCommand>[ <FakeCommand>[
...@@ -188,7 +188,6 @@ void main() { ...@@ -188,7 +188,6 @@ void main() {
'--sdk', '--sdk',
'HostArtifact.engineDartSdkPath', 'HostArtifact.engineDartSdkPath',
], ],
completer: completer,
stdin: IOSink(stdin.sink), stdin: IOSink(stdin.sink),
), ),
]); ]);
...@@ -212,6 +211,11 @@ void main() { ...@@ -212,6 +211,11 @@ void main() {
}); });
testUsingContext('Can run AnalysisService with customized cache location --watch', () async { testUsingContext('Can run AnalysisService with customized cache location --watch', () async {
final MemoryFileSystem fileSystem = MemoryFileSystem.test();
fileSystem.directory('directoryA').childFile('foo').createSync(recursive: true);
final BufferLogger logger = BufferLogger.test();
final Completer<void> completer = Completer<void>(); final Completer<void> completer = Completer<void>();
final StreamController<List<int>> stdin = StreamController<List<int>>(); final StreamController<List<int>> stdin = StreamController<List<int>>();
final FakeProcessManager processManager = FakeProcessManager.list( final FakeProcessManager processManager = FakeProcessManager.list(
...@@ -226,8 +230,12 @@ void main() { ...@@ -226,8 +230,12 @@ void main() {
'--sdk', '--sdk',
'HostArtifact.engineDartSdkPath', 'HostArtifact.engineDartSdkPath',
], ],
completer: completer,
stdin: IOSink(stdin.sink), stdin: IOSink(stdin.sink),
stdout: '''
{"event":"server.status","params":{"analysis":{"isAnalyzing":true}}}
{"event":"analysis.errors","params":{"file":"/directoryA/foo","errors":[{"type":"TestError","message":"It's an error.","severity":"warning","code":"500","location":{"file":"/directoryA/foo","startLine": 100,"startColumn":5,"offset":0}}]}}
{"event":"server.status","params":{"analysis":{"isAnalyzing":false}}}
'''
), ),
]); ]);
...@@ -235,17 +243,78 @@ void main() { ...@@ -235,17 +243,78 @@ void main() {
final AnalyzeCommand command = AnalyzeCommand( final AnalyzeCommand command = AnalyzeCommand(
terminal: Terminal.test(), terminal: Terminal.test(),
artifacts: artifacts, artifacts: artifacts,
logger: BufferLogger.test(), logger: logger,
platform: FakePlatform(),
fileSystem: fileSystem,
processManager: processManager,
);
await FakeAsync().run((FakeAsync time) async {
final TestFlutterCommandRunner commandRunner = TestFlutterCommandRunner();
commandRunner.addCommand(command);
unawaited(commandRunner.run(<String>['analyze', '--watch']));
while (!logger.statusText.contains('analyzed 1 file')) {
time.flushMicrotasks();
}
completer.complete();
return completer.future;
});
expect(logger.statusText, contains("warning It's an error • directoryA/foo:100:5 • 500"));
expect(logger.statusText, contains('1 issue found. (1 new)'));
expect(logger.errorText, isEmpty);
expect(processManager, hasNoRemainingExpectations);
});
testUsingContext('AnalysisService --watch skips errors from non-files', () async {
final BufferLogger logger = BufferLogger.test();
final Completer<void> completer = Completer<void>();
final StreamController<List<int>> stdin = StreamController<List<int>>();
final FakeProcessManager processManager = FakeProcessManager.list(
<FakeCommand>[
FakeCommand(
command: const <String>[
'HostArtifact.engineDartSdkPath/bin/dart',
'--disable-dart-dev',
'HostArtifact.engineDartSdkPath/bin/snapshots/analysis_server.dart.snapshot',
'--disable-server-feature-completion',
'--disable-server-feature-search',
'--sdk',
'HostArtifact.engineDartSdkPath',
],
stdin: IOSink(stdin.sink),
stdout: '''
{"event":"server.status","params":{"analysis":{"isAnalyzing":true}}}
{"event":"analysis.errors","params":{"file":"/directoryA/bar","errors":[{"type":"TestError","message":"It's an error.","severity":"warning","code":"500","location":{"file":"/directoryA/bar","startLine":100,"startColumn":5,"offset":0}}]}}
{"event":"server.status","params":{"analysis":{"isAnalyzing":false}}}
'''
),
]);
final Artifacts artifacts = Artifacts.test();
final AnalyzeCommand command = AnalyzeCommand(
terminal: Terminal.test(),
artifacts: artifacts,
logger: logger,
platform: FakePlatform(), platform: FakePlatform(),
fileSystem: MemoryFileSystem.test(), fileSystem: MemoryFileSystem.test(),
processManager: processManager, processManager: processManager,
); );
final TestFlutterCommandRunner commandRunner = TestFlutterCommandRunner(); await FakeAsync().run((FakeAsync time) async {
commandRunner.addCommand(command); final TestFlutterCommandRunner commandRunner = TestFlutterCommandRunner();
unawaited(commandRunner.run(<String>['analyze', '--watch'])); commandRunner.addCommand(command);
await stdin.stream.first; unawaited(commandRunner.run(<String>['analyze', '--watch']));
while (!logger.statusText.contains('analyzed 1 file')) {
time.flushMicrotasks();
}
completer.complete();
return completer.future;
});
expect(logger.statusText, contains('No issues found!'));
expect(logger.errorText, isEmpty);
expect(processManager, hasNoRemainingExpectations); expect(processManager, hasNoRemainingExpectations);
}); });
} }
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