Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Unified Diff: packages/analyzer/test/generated/test_support.dart

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: packages/analyzer/test/generated/test_support.dart
diff --git a/packages/analyzer/test/generated/test_support.dart b/packages/analyzer/test/generated/test_support.dart
new file mode 100644
index 0000000000000000000000000000000000000000..20cc0e2633937cf63bf8b7beb51ac0a9090b6df7
--- /dev/null
+++ b/packages/analyzer/test/generated/test_support.dart
@@ -0,0 +1,662 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library engine.test_support;
+
+import 'dart:collection';
+
+import 'package:analyzer/src/generated/ast.dart' show AstNode, NodeLocator;
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:unittest/unittest.dart';
+
+import 'resolver_test.dart';
+
+/**
+ * The class `EngineTestCase` defines utility methods for making assertions.
+ */
+class EngineTestCase {
+ /**
+ * Assert that the given collection has the same number of elements as the number of specified
+ * names, and that for each specified name, a corresponding element can be found in the given
+ * collection with that name.
+ *
+ * @param elements the elements
+ * @param names the names
+ */
+ void assertNamedElements(List<Element> elements, List<String> names) {
+ for (String elemName in names) {
+ bool found = false;
+ for (Element elem in elements) {
+ if (elem.name == elemName) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.write("Expected element named: ");
+ buffer.write(elemName);
+ buffer.write("\n but found: ");
+ for (Element elem in elements) {
+ buffer.write(elem.name);
+ buffer.write(", ");
+ }
+ fail(buffer.toString());
+ }
+ }
+ expect(elements, hasLength(names.length));
+ }
+
+ AnalysisContext createAnalysisContext() {
+ return AnalysisContextFactory.contextWithCore();
+ }
+
+ /**
+ * Return the getter in the given type with the given name. Inherited getters are ignored.
+ *
+ * @param type the type in which the getter is declared
+ * @param getterName the name of the getter to be returned
+ * @return the property accessor element representing the getter with the given name
+ */
+ PropertyAccessorElement getGetter(InterfaceType type, String getterName) {
+ for (PropertyAccessorElement accessor in type.element.accessors) {
+ if (accessor.isGetter && accessor.name == getterName) {
+ return accessor;
+ }
+ }
+ fail("Could not find getter named $getterName in ${type.displayName}");
+ return null;
+ }
+
+ /**
+ * Return the method in the given type with the given name. Inherited methods are ignored.
+ *
+ * @param type the type in which the method is declared
+ * @param methodName the name of the method to be returned
+ * @return the method element representing the method with the given name
+ */
+ MethodElement getMethod(InterfaceType type, String methodName) {
+ for (MethodElement method in type.element.methods) {
+ if (method.name == methodName) {
+ return method;
+ }
+ }
+ fail("Could not find method named $methodName in ${type.displayName}");
+ return null;
+ }
+
+ void setUp() {}
+
+ void tearDown() {}
+
+ /**
+ * Assert that the given object is an instance of the expected class.
+ *
+ * @param expectedClass the class that the object is expected to be an instance of
+ * @param object the object being tested
+ * @return the object that was being tested
+ * @throws Exception if the object is not an instance of the expected class
+ */
+ static Object assertInstanceOf(
+ Predicate<Object> predicate, Type expectedClass, Object object) {
+ if (!predicate(object)) {
+ fail(
+ "Expected instance of $expectedClass, found ${object == null ? "null" : object.runtimeType}");
+ }
+ return object;
+ }
+
+ /**
+ * @return the [AstNode] with requested type at offset of the "prefix".
+ */
+ static AstNode findNode(
+ AstNode root, String code, String prefix, Predicate<AstNode> predicate) {
+ int offset = code.indexOf(prefix);
+ if (offset == -1) {
+ throw new IllegalArgumentException("Not found '$prefix'.");
+ }
+ AstNode node = new NodeLocator(offset).searchWithin(root);
+ return node.getAncestor(predicate);
+ }
+}
+
+/**
+ * Instances of the class `GatheringErrorListener` implement an error listener that collects
+ * all of the errors passed to it for later examination.
+ */
+class GatheringErrorListener implements AnalysisErrorListener {
+ /**
+ * An empty array of errors used when no errors are expected.
+ */
+ static List<AnalysisError> _NO_ERRORS = new List<AnalysisError>(0);
+
+ /**
+ * A list containing the errors that were collected.
+ */
+ List<AnalysisError> _errors = new List<AnalysisError>();
+
+ /**
+ * A table mapping sources to the line information for the source.
+ */
+ HashMap<Source, LineInfo> _lineInfoMap = new HashMap<Source, LineInfo>();
+
+ /**
+ * Initialize a newly created error listener to collect errors.
+ */
+ GatheringErrorListener();
+
+ /**
+ * Return the errors that were collected.
+ *
+ * @return the errors that were collected
+ */
+ List<AnalysisError> get errors => _errors;
+
+ /**
+ * Return `true` if at least one error has been gathered.
+ *
+ * @return `true` if at least one error has been gathered
+ */
+ bool get hasErrors => _errors.length > 0;
+
+ /**
+ * Add all of the given errors to this listener.
+ *
+ * @param the errors to be added
+ */
+ void addAll(List<AnalysisError> errors) {
+ for (AnalysisError error in errors) {
+ onError(error);
+ }
+ }
+
+ /**
+ * Add all of the errors recorded by the given listener to this listener.
+ *
+ * @param listener the listener that has recorded the errors to be added
+ */
+ void addAll2(RecordingErrorListener listener) {
+ addAll(listener.errors);
+ }
+
+ /**
+ * Assert that the number of errors that have been gathered matches the number of errors that are
+ * given and that they have the expected error codes and locations. The order in which the errors
+ * were gathered is ignored.
+ *
+ * @param errorCodes the errors that should have been gathered
+ * @throws AssertionFailedError if a different number of errors have been gathered than were
+ * expected or if they do not have the same codes and locations
+ */
+ void assertErrors(List<AnalysisError> expectedErrors) {
+ if (_errors.length != expectedErrors.length) {
+ _fail(expectedErrors);
+ }
+ List<AnalysisError> remainingErrors = new List<AnalysisError>();
+ for (AnalysisError error in expectedErrors) {
+ remainingErrors.add(error);
+ }
+ for (AnalysisError error in _errors) {
+ if (!_foundAndRemoved(remainingErrors, error)) {
+ _fail(expectedErrors);
+ }
+ }
+ }
+
+ /**
+ * Assert that the number of errors that have been gathered matches the number of errors that are
+ * given and that they have the expected error codes. The order in which the errors were gathered
+ * is ignored.
+ *
+ * @param expectedErrorCodes the error codes of the errors that should have been gathered
+ * @throws AssertionFailedError if a different number of errors have been gathered than were
+ * expected
+ */
+ void assertErrorsWithCodes(
+ [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) {
+ StringBuffer buffer = new StringBuffer();
+ //
+ // Verify that the expected error codes have a non-empty message.
+ //
+ for (ErrorCode errorCode in expectedErrorCodes) {
+ expect(errorCode.message.isEmpty, isFalse,
+ reason: "Empty error code message");
+ }
+ //
+ // Compute the expected number of each type of error.
+ //
+ HashMap<ErrorCode, int> expectedCounts = new HashMap<ErrorCode, int>();
+ for (ErrorCode code in expectedErrorCodes) {
+ int count = expectedCounts[code];
+ if (count == null) {
+ count = 1;
+ } else {
+ count = count + 1;
+ }
+ expectedCounts[code] = count;
+ }
+ //
+ // Compute the actual number of each type of error.
+ //
+ HashMap<ErrorCode, List<AnalysisError>> errorsByCode =
+ new HashMap<ErrorCode, List<AnalysisError>>();
+ for (AnalysisError error in _errors) {
+ ErrorCode code = error.errorCode;
+ List<AnalysisError> list = errorsByCode[code];
+ if (list == null) {
+ list = new List<AnalysisError>();
+ errorsByCode[code] = list;
+ }
+ list.add(error);
+ }
+ //
+ // Compare the expected and actual number of each type of error.
+ //
+ expectedCounts.forEach((ErrorCode code, int expectedCount) {
+ int actualCount;
+ List<AnalysisError> list = errorsByCode.remove(code);
+ if (list == null) {
+ actualCount = 0;
+ } else {
+ actualCount = list.length;
+ }
+ if (actualCount != expectedCount) {
+ if (buffer.length == 0) {
+ buffer.write("Expected ");
+ } else {
+ buffer.write("; ");
+ }
+ buffer.write(expectedCount);
+ buffer.write(" errors of type ");
+ buffer.write(code.uniqueName);
+ buffer.write(", found ");
+ buffer.write(actualCount);
+ }
+ });
+ //
+ // Check that there are no more errors in the actual-errors map,
+ // otherwise record message.
+ //
+ errorsByCode.forEach((ErrorCode code, List<AnalysisError> actualErrors) {
+ int actualCount = actualErrors.length;
+ if (buffer.length == 0) {
+ buffer.write("Expected ");
+ } else {
+ buffer.write("; ");
+ }
+ buffer.write("0 errors of type ");
+ buffer.write(code.uniqueName);
+ buffer.write(", found ");
+ buffer.write(actualCount);
+ buffer.write(" (");
+ for (int i = 0; i < actualErrors.length; i++) {
+ AnalysisError error = actualErrors[i];
+ if (i > 0) {
+ buffer.write(", ");
+ }
+ buffer.write(error.offset);
+ }
+ buffer.write(")");
+ });
+ if (buffer.length > 0) {
+ fail(buffer.toString());
+ }
+ }
+
+ /**
+ * Assert that the number of errors that have been gathered matches the number of severities that
+ * are given and that there are the same number of errors and warnings as specified by the
+ * argument. The order in which the errors were gathered is ignored.
+ *
+ * @param expectedSeverities the severities of the errors that should have been gathered
+ * @throws AssertionFailedError if a different number of errors have been gathered than were
+ * expected
+ */
+ void assertErrorsWithSeverities(List<ErrorSeverity> expectedSeverities) {
+ int expectedErrorCount = 0;
+ int expectedWarningCount = 0;
+ for (ErrorSeverity severity in expectedSeverities) {
+ if (severity == ErrorSeverity.ERROR) {
+ expectedErrorCount++;
+ } else {
+ expectedWarningCount++;
+ }
+ }
+ int actualErrorCount = 0;
+ int actualWarningCount = 0;
+ for (AnalysisError error in _errors) {
+ if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) {
+ actualErrorCount++;
+ } else {
+ actualWarningCount++;
+ }
+ }
+ if (expectedErrorCount != actualErrorCount ||
+ expectedWarningCount != actualWarningCount) {
+ fail(
+ "Expected $expectedErrorCount errors and $expectedWarningCount warnings, found $actualErrorCount errors and $actualWarningCount warnings");
+ }
+ }
+
+ /**
+ * Assert that no errors have been gathered.
+ *
+ * @throws AssertionFailedError if any errors have been gathered
+ */
+ void assertNoErrors() {
+ assertErrors(_NO_ERRORS);
+ }
+
+ /**
+ * Return the line information associated with the given source, or `null` if no line
+ * information has been associated with the source.
+ *
+ * @param source the source with which the line information is associated
+ * @return the line information associated with the source
+ */
+ LineInfo getLineInfo(Source source) => _lineInfoMap[source];
+
+ /**
+ * Return `true` if an error with the given error code has been gathered.
+ *
+ * @param errorCode the error code being searched for
+ * @return `true` if an error with the given error code has been gathered
+ */
+ bool hasError(ErrorCode errorCode) {
+ for (AnalysisError error in _errors) {
+ if (identical(error.errorCode, errorCode)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @override
+ void onError(AnalysisError error) {
+ _errors.add(error);
+ }
+
+ /**
+ * Set the line information associated with the given source to the given information.
+ *
+ * @param source the source with which the line information is associated
+ * @param lineStarts the line start information to be associated with the source
+ */
+ void setLineInfo(Source source, List<int> lineStarts) {
+ _lineInfoMap[source] = new LineInfo(lineStarts);
+ }
+
+ /**
+ * Return `true` if the two errors are equivalent.
+ *
+ * @param firstError the first error being compared
+ * @param secondError the second error being compared
+ * @return `true` if the two errors are equivalent
+ */
+ bool _equalErrors(AnalysisError firstError, AnalysisError secondError) =>
+ identical(firstError.errorCode, secondError.errorCode) &&
+ firstError.offset == secondError.offset &&
+ firstError.length == secondError.length &&
+ _equalSources(firstError.source, secondError.source);
+
+ /**
+ * Return `true` if the two sources are equivalent.
+ *
+ * @param firstSource the first source being compared
+ * @param secondSource the second source being compared
+ * @return `true` if the two sources are equivalent
+ */
+ bool _equalSources(Source firstSource, Source secondSource) {
+ if (firstSource == null) {
+ return secondSource == null;
+ } else if (secondSource == null) {
+ return false;
+ }
+ return firstSource == secondSource;
+ }
+
+ /**
+ * Assert that the number of errors that have been gathered matches the number of errors that are
+ * given and that they have the expected error codes. The order in which the errors were gathered
+ * is ignored.
+ *
+ * @param errorCodes the errors that should have been gathered
+ * @throws AssertionFailedError with
+ */
+ void _fail(List<AnalysisError> expectedErrors) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.write("Expected ");
+ buffer.write(expectedErrors.length);
+ buffer.write(" errors:");
+ for (AnalysisError error in expectedErrors) {
+ Source source = error.source;
+ LineInfo lineInfo = _lineInfoMap[source];
+ buffer.writeln();
+ if (lineInfo == null) {
+ int offset = error.offset;
+ StringUtils.printf(buffer, " %s %s (%d..%d)", [
+ source == null ? "" : source.shortName,
+ error.errorCode,
+ offset,
+ offset + error.length
+ ]);
+ } else {
+ LineInfo_Location location = lineInfo.getLocation(error.offset);
+ StringUtils.printf(buffer, " %s %s (%d, %d/%d)", [
+ source == null ? "" : source.shortName,
+ error.errorCode,
+ location.lineNumber,
+ location.columnNumber,
+ error.length
+ ]);
+ }
+ }
+ buffer.writeln();
+ buffer.write("found ");
+ buffer.write(_errors.length);
+ buffer.write(" errors:");
+ for (AnalysisError error in _errors) {
+ Source source = error.source;
+ LineInfo lineInfo = _lineInfoMap[source];
+ buffer.writeln();
+ if (lineInfo == null) {
+ int offset = error.offset;
+ StringUtils.printf(buffer, " %s %s (%d..%d): %s", [
+ source == null ? "" : source.shortName,
+ error.errorCode,
+ offset,
+ offset + error.length,
+ error.message
+ ]);
+ } else {
+ LineInfo_Location location = lineInfo.getLocation(error.offset);
+ StringUtils.printf(buffer, " %s %s (%d, %d/%d): %s", [
+ source == null ? "" : source.shortName,
+ error.errorCode,
+ location.lineNumber,
+ location.columnNumber,
+ error.length,
+ error.message
+ ]);
+ }
+ }
+ fail(buffer.toString());
+ }
+
+ /**
+ * Search through the given list of errors for an error that is equal to the target error. If one
+ * is found, remove it from the list and return `true`, otherwise return `false`
+ * without modifying the list.
+ *
+ * @param errors the errors through which we are searching
+ * @param targetError the error being searched for
+ * @return `true` if the error is found and removed from the list
+ */
+ bool _foundAndRemoved(List<AnalysisError> errors, AnalysisError targetError) {
+ for (AnalysisError error in errors) {
+ if (_equalErrors(error, targetError)) {
+ errors.remove(error);
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+/**
+ * Instances of the class [TestLogger] implement a logger that can be used by
+ * tests.
+ */
+class TestLogger implements Logger {
+ /**
+ * The number of error messages that were logged.
+ */
+ int errorCount = 0;
+
+ /**
+ * The number of informational messages that were logged.
+ */
+ int infoCount = 0;
+
+ @override
+ void logError(String message, [CaughtException exception]) {
+ errorCount++;
+ }
+
+ @override
+ void logError2(String message, Object exception) {
+ errorCount++;
+ }
+
+ @override
+ void logInformation(String message, [CaughtException exception]) {
+ infoCount++;
+ }
+
+ @override
+ void logInformation2(String message, Object exception) {
+ infoCount++;
+ }
+}
+
+class TestSource extends Source {
+ String _name;
+ String _contents;
+ int _modificationStamp = 0;
+ bool exists2 = true;
+
+ /**
+ * A flag indicating whether an exception should be generated when an attempt
+ * is made to access the contents of this source.
+ */
+ bool generateExceptionOnRead = false;
+
+ @override
+ int get modificationStamp =>
+ generateExceptionOnRead ? -1 : _modificationStamp;
+
+ /**
+ * The number of times that the contents of this source have been requested.
+ */
+ int readCount = 0;
+
+ TestSource([this._name = '/test.dart', this._contents]);
+
+ TimestampedData<String> get contents {
+ readCount++;
+ if (generateExceptionOnRead) {
+ String msg = "I/O Exception while getting the contents of " + _name;
+ throw new Exception(msg);
+ }
+ return new TimestampedData<String>(0, _contents);
+ }
+
+ String get encoding {
+ throw new UnsupportedOperationException();
+ }
+
+ String get fullName {
+ return _name;
+ }
+
+ int get hashCode => 0;
+ bool get isInSystemLibrary {
+ return false;
+ }
+
+ String get shortName {
+ return _name;
+ }
+
+ Uri get uri {
+ throw new UnsupportedOperationException();
+ }
+
+ UriKind get uriKind {
+ throw new UnsupportedOperationException();
+ }
+
+ bool operator ==(Object other) {
+ if (other is TestSource) {
+ return other._name == _name;
+ }
+ return false;
+ }
+
+ bool exists() => exists2;
+ void getContentsToReceiver(Source_ContentReceiver receiver) {
+ throw new UnsupportedOperationException();
+ }
+
+ Source resolve(String uri) {
+ throw new UnsupportedOperationException();
+ }
+
+ Uri resolveRelativeUri(Uri uri) {
+ return new Uri(scheme: 'file', path: _name).resolveUri(uri);
+ }
+
+ void setContents(String value) {
+ generateExceptionOnRead = false;
+ _modificationStamp = new DateTime.now().millisecondsSinceEpoch;
+ _contents = value;
+ }
+
+ @override
+ String toString() => '$_name';
+}
+
+class TestSourceWithUri extends TestSource {
+ final Uri uri;
+
+ TestSourceWithUri(String path, this.uri, [String content])
+ : super(path, content);
+
+ UriKind get uriKind {
+ if (uri == null) {
+ return UriKind.FILE_URI;
+ } else if (uri.scheme == 'dart') {
+ return UriKind.DART_URI;
+ } else if (uri.scheme == 'package') {
+ return UriKind.PACKAGE_URI;
+ }
+ return UriKind.FILE_URI;
+ }
+
+ bool operator ==(Object other) {
+ if (other is TestSource) {
+ return other.uri == uri;
+ }
+ return false;
+ }
+
+ Uri resolveRelativeUri(Uri uri) {
+ return this.uri.resolveUri(uri);
+ }
+}
« no previous file with comments | « packages/analyzer/test/generated/test_all.dart ('k') | packages/analyzer/test/generated/type_system_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698