| Index: pkg/analysis_server/test/stress/utilities/server.dart
|
| diff --git a/pkg/analysis_server/test/stress/utilities/server.dart b/pkg/analysis_server/test/stress/utilities/server.dart
|
| index 149dcdf7b7bbb9ae224f933637fe7f3b3051858d..ee52fdd6551ecd7369699b19ed6de443218225d6 100644
|
| --- a/pkg/analysis_server/test/stress/utilities/server.dart
|
| +++ b/pkg/analysis_server/test/stress/utilities/server.dart
|
| @@ -17,6 +17,48 @@ import '../../integration/integration_test_methods.dart';
|
| import '../../integration/integration_tests.dart' as base;
|
|
|
| /**
|
| + * ???
|
| + */
|
| +class ErrorMap {
|
| + /**
|
| + * A table mapping file paths to the errors associated with that file.
|
| + */
|
| + final Map<String, List<AnalysisError>> pathMap =
|
| + new HashMap<String, List<AnalysisError>>();
|
| +
|
| + /**
|
| + * Initialize a newly created error map.
|
| + */
|
| + ErrorMap();
|
| +
|
| + /**
|
| + * Initialize a newly created error map to contain the same mapping as the
|
| + * given [errorMap].
|
| + */
|
| + ErrorMap.from(ErrorMap errorMap) {
|
| + pathMap.addAll(errorMap.pathMap);
|
| + }
|
| +
|
| + void operator []=(String filePath, List<AnalysisError> errors) {
|
| + pathMap[filePath] = errors;
|
| + }
|
| +
|
| + /**
|
| + * Compare the this error map with the state captured in the given [errorMap].
|
| + * Throw an exception if the two maps do not agree.
|
| + */
|
| + String expectErrorMap(ErrorMap errorMap) {
|
| + StringBuffer buffer = new StringBuffer();
|
| + _ErrorComparator comparator = new _ErrorComparator(buffer);
|
| + comparator.compare(pathMap, errorMap.pathMap);
|
| + if (buffer.length > 0) {
|
| + return buffer.toString();
|
| + }
|
| + return null;
|
| + }
|
| +}
|
| +
|
| +/**
|
| * An interface for starting and communicating with an analysis server running
|
| * in a separate process.
|
| */
|
| @@ -27,11 +69,10 @@ class Server extends base.Server with IntegrationTestMixin {
|
| List<String> filesWithOverlays = <String>[];
|
|
|
| /**
|
| - * A table mapping the absolute paths of files to the most recent set of
|
| - * errors received for that file.
|
| + * A mapping from the absolute paths of files to the most recent set of errors
|
| + * received for that file.
|
| */
|
| - Map<String, List<AnalysisError>> _errorMap =
|
| - new HashMap<String, List<AnalysisError>>();
|
| + ErrorMap _errorMap = new ErrorMap();
|
|
|
| /**
|
| * Initialize a new analysis server. The analysis server is not running and
|
| @@ -43,17 +84,41 @@ class Server extends base.Server with IntegrationTestMixin {
|
| }
|
|
|
| /**
|
| + * Return a list of the paths of files that are currently being analyzed.
|
| + */
|
| + List<String> get analyzedDartFiles {
|
| + // TODO(brianwilkerson) Implement this.
|
| + return <String>[];
|
| + }
|
| +
|
| + /**
|
| * Return a table mapping the absolute paths of files to the most recent set
|
| * of errors received for that file. The content of the map will not change
|
| * when new sets of errors are received.
|
| */
|
| - Map<String, List<AnalysisError>> get errorMap =>
|
| - new HashMap<String, List<AnalysisError>>.from(_errorMap);
|
| + ErrorMap get errorMap => new ErrorMap.from(_errorMap);
|
|
|
| @override
|
| base.Server get server => this;
|
|
|
| /**
|
| + * Compute a mapping from each of the file paths in the given list of
|
| + * [filePaths] to the list of errors in the file at that path.
|
| + */
|
| + Future<ErrorMap> computeErrorMap(List<String> filePaths) async {
|
| + ErrorMap errorMap = new ErrorMap();
|
| + List<Future> futures = <Future>[];
|
| + for (String filePath in filePaths) {
|
| + futures.add(sendAnalysisGetErrors(filePath)
|
| + .then((AnalysisGetErrorsResult result) {
|
| + errorMap[filePath] = result.errors;
|
| + }));
|
| + }
|
| + await Future.wait(futures);
|
| + return errorMap;
|
| + }
|
| +
|
| + /**
|
| * Remove any existing overlays.
|
| */
|
| Future<AnalysisUpdateContentResult> removeAllOverlays() {
|
| @@ -84,3 +149,141 @@ class Server extends base.Server with IntegrationTestMixin {
|
| _errorMap[params.file] = params.errors;
|
| }
|
| }
|
| +
|
| +/**
|
| + * A utility class used to compare two sets of errors.
|
| + */
|
| +class _ErrorComparator {
|
| + /**
|
| + * An empty list of analysis errors.
|
| + */
|
| + static final List<AnalysisError> NO_ERRORS = <AnalysisError>[];
|
| +
|
| + /**
|
| + * The buffer to which an error description will be written if any of the
|
| + * files have different errors than are expected.
|
| + */
|
| + final StringBuffer buffer;
|
| +
|
| + /**
|
| + * Initialize a newly created comparator to write to the given [buffer].
|
| + */
|
| + _ErrorComparator(this.buffer);
|
| +
|
| + /**
|
| + * Compare the [actualErrorMap] and the [expectedErrorMap], writing a
|
| + * description to the [buffer] if they are not the same. The error maps are
|
| + * expected to be maps from absolute file paths to the list of actual or
|
| + * expected errors.
|
| + */
|
| + void compare(Map<String, List<AnalysisError>> actualErrorMap,
|
| + Map<String, List<AnalysisError>> expectedErrorMap) {
|
| + Set<String> allFiles = new HashSet();
|
| + allFiles.addAll(actualErrorMap.keys);
|
| + allFiles.addAll(expectedErrorMap.keys);
|
| + List<String> sortedFiles = allFiles.toList()..sort();
|
| + for (String filePath in sortedFiles) {
|
| + List<AnalysisError> actualErrors = actualErrorMap[filePath];
|
| + List<AnalysisError> expectedErrors = expectedErrorMap[filePath];
|
| + _compareLists(
|
| + filePath, actualErrors ?? NO_ERRORS, expectedErrors ?? NO_ERRORS);
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Compare the [actualErrors] and [expectedErrors], writing a description to
|
| + * the [buffer] if they are not the same.
|
| + */
|
| + void _compareLists(String filePath, List<AnalysisError> actualErrors,
|
| + List<AnalysisError> expectedErrors) {
|
| + List<AnalysisError> remainingExpected =
|
| + new List<AnalysisError>.from(expectedErrors);
|
| + for (AnalysisError actualError in actualErrors) {
|
| + AnalysisError expectedError = _findError(remainingExpected, actualError);
|
| + if (expectedError == null) {
|
| + _writeReport(filePath, actualErrors, expectedErrors);
|
| + return;
|
| + }
|
| + remainingExpected.remove(expectedError);
|
| + }
|
| + if (remainingExpected.isNotEmpty) {
|
| + _writeReport(filePath, actualErrors, expectedErrors);
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Return `true` if the [firstError] and the [secondError] are equivalent.
|
| + */
|
| + bool _equalErrors(AnalysisError firstError, AnalysisError secondError) =>
|
| + firstError.severity == secondError.severity &&
|
| + firstError.type == secondError.type &&
|
| + _equalLocations(firstError.location, secondError.location) &&
|
| + firstError.message == secondError.message;
|
| +
|
| + /**
|
| + * Return `true` if the [firstLocation] and the [secondLocation] are
|
| + * equivalent.
|
| + */
|
| + bool _equalLocations(Location firstLocation, Location secondLocation) =>
|
| + firstLocation.file == secondLocation.file &&
|
| + firstLocation.offset == secondLocation.offset &&
|
| + firstLocation.length == secondLocation.length;
|
| +
|
| + /**
|
| + * Search through the given list of [errors] for an error that is equal to the
|
| + * [targetError]. If one is found, return it, otherwise return `null`.
|
| + */
|
| + AnalysisError _findError(
|
| + List<AnalysisError> errors, AnalysisError targetError) {
|
| + for (AnalysisError error in errors) {
|
| + if (_equalErrors(error, targetError)) {
|
| + return error;
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + /**
|
| + * Write the given list of [errors], preceded by a header beginning with the
|
| + * given [prefix].
|
| + */
|
| + void _writeErrors(String prefix, List<AnalysisError> errors) {
|
| + buffer.write(prefix);
|
| + buffer.write(errors.length);
|
| + buffer.write(' errors:');
|
| + for (AnalysisError error in errors) {
|
| + buffer.writeln();
|
| + Location location = error.location;
|
| + int offset = location.offset;
|
| + buffer.write(' ');
|
| + buffer.write(location.file);
|
| + buffer.write(' (');
|
| + buffer.write(offset);
|
| + buffer.write('..');
|
| + buffer.write(offset + location.length);
|
| + buffer.write(') ');
|
| + buffer.write(error.severity);
|
| + buffer.write(', ');
|
| + buffer.write(error.type);
|
| + buffer.write(' : ');
|
| + buffer.write(error.message);
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Write a report of the differences between the [actualErrors] and the
|
| + * [expectedErrors]. The errors are reported as being from the file at the
|
| + * given [filePath].
|
| + */
|
| + void _writeReport(String filePath, List<AnalysisError> actualErrors,
|
| + List<AnalysisError> expectedErrors) {
|
| + if (buffer.length > 0) {
|
| + buffer.writeln();
|
| + buffer.writeln();
|
| + }
|
| + buffer.writeln(filePath);
|
| + _writeErrors(' Expected ', expectedErrors);
|
| + buffer.writeln();
|
| + _writeErrors(' Found ', expectedErrors);
|
| + }
|
| +}
|
|
|