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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library engine.test_support;
6
7 import 'dart:collection';
8
9 import 'package:analyzer/src/generated/ast.dart' show AstNode, NodeLocator;
10 import 'package:analyzer/src/generated/element.dart';
11 import 'package:analyzer/src/generated/engine.dart';
12 import 'package:analyzer/src/generated/error.dart';
13 import 'package:analyzer/src/generated/java_core.dart';
14 import 'package:analyzer/src/generated/java_engine.dart';
15 import 'package:analyzer/src/generated/source.dart';
16 import 'package:unittest/unittest.dart';
17
18 import 'resolver_test.dart';
19
20 /**
21 * The class `EngineTestCase` defines utility methods for making assertions.
22 */
23 class EngineTestCase {
24 /**
25 * Assert that the given collection has the same number of elements as the num ber of specified
26 * names, and that for each specified name, a corresponding element can be fou nd in the given
27 * collection with that name.
28 *
29 * @param elements the elements
30 * @param names the names
31 */
32 void assertNamedElements(List<Element> elements, List<String> names) {
33 for (String elemName in names) {
34 bool found = false;
35 for (Element elem in elements) {
36 if (elem.name == elemName) {
37 found = true;
38 break;
39 }
40 }
41 if (!found) {
42 StringBuffer buffer = new StringBuffer();
43 buffer.write("Expected element named: ");
44 buffer.write(elemName);
45 buffer.write("\n but found: ");
46 for (Element elem in elements) {
47 buffer.write(elem.name);
48 buffer.write(", ");
49 }
50 fail(buffer.toString());
51 }
52 }
53 expect(elements, hasLength(names.length));
54 }
55
56 AnalysisContext createAnalysisContext() {
57 return AnalysisContextFactory.contextWithCore();
58 }
59
60 /**
61 * Return the getter in the given type with the given name. Inherited getters are ignored.
62 *
63 * @param type the type in which the getter is declared
64 * @param getterName the name of the getter to be returned
65 * @return the property accessor element representing the getter with the give n name
66 */
67 PropertyAccessorElement getGetter(InterfaceType type, String getterName) {
68 for (PropertyAccessorElement accessor in type.element.accessors) {
69 if (accessor.isGetter && accessor.name == getterName) {
70 return accessor;
71 }
72 }
73 fail("Could not find getter named $getterName in ${type.displayName}");
74 return null;
75 }
76
77 /**
78 * Return the method in the given type with the given name. Inherited methods are ignored.
79 *
80 * @param type the type in which the method is declared
81 * @param methodName the name of the method to be returned
82 * @return the method element representing the method with the given name
83 */
84 MethodElement getMethod(InterfaceType type, String methodName) {
85 for (MethodElement method in type.element.methods) {
86 if (method.name == methodName) {
87 return method;
88 }
89 }
90 fail("Could not find method named $methodName in ${type.displayName}");
91 return null;
92 }
93
94 void setUp() {}
95
96 void tearDown() {}
97
98 /**
99 * Assert that the given object is an instance of the expected class.
100 *
101 * @param expectedClass the class that the object is expected to be an instanc e of
102 * @param object the object being tested
103 * @return the object that was being tested
104 * @throws Exception if the object is not an instance of the expected class
105 */
106 static Object assertInstanceOf(
107 Predicate<Object> predicate, Type expectedClass, Object object) {
108 if (!predicate(object)) {
109 fail(
110 "Expected instance of $expectedClass, found ${object == null ? "null" : object.runtimeType}");
111 }
112 return object;
113 }
114
115 /**
116 * @return the [AstNode] with requested type at offset of the "prefix".
117 */
118 static AstNode findNode(
119 AstNode root, String code, String prefix, Predicate<AstNode> predicate) {
120 int offset = code.indexOf(prefix);
121 if (offset == -1) {
122 throw new IllegalArgumentException("Not found '$prefix'.");
123 }
124 AstNode node = new NodeLocator(offset).searchWithin(root);
125 return node.getAncestor(predicate);
126 }
127 }
128
129 /**
130 * Instances of the class `GatheringErrorListener` implement an error listener t hat collects
131 * all of the errors passed to it for later examination.
132 */
133 class GatheringErrorListener implements AnalysisErrorListener {
134 /**
135 * An empty array of errors used when no errors are expected.
136 */
137 static List<AnalysisError> _NO_ERRORS = new List<AnalysisError>(0);
138
139 /**
140 * A list containing the errors that were collected.
141 */
142 List<AnalysisError> _errors = new List<AnalysisError>();
143
144 /**
145 * A table mapping sources to the line information for the source.
146 */
147 HashMap<Source, LineInfo> _lineInfoMap = new HashMap<Source, LineInfo>();
148
149 /**
150 * Initialize a newly created error listener to collect errors.
151 */
152 GatheringErrorListener();
153
154 /**
155 * Return the errors that were collected.
156 *
157 * @return the errors that were collected
158 */
159 List<AnalysisError> get errors => _errors;
160
161 /**
162 * Return `true` if at least one error has been gathered.
163 *
164 * @return `true` if at least one error has been gathered
165 */
166 bool get hasErrors => _errors.length > 0;
167
168 /**
169 * Add all of the given errors to this listener.
170 *
171 * @param the errors to be added
172 */
173 void addAll(List<AnalysisError> errors) {
174 for (AnalysisError error in errors) {
175 onError(error);
176 }
177 }
178
179 /**
180 * Add all of the errors recorded by the given listener to this listener.
181 *
182 * @param listener the listener that has recorded the errors to be added
183 */
184 void addAll2(RecordingErrorListener listener) {
185 addAll(listener.errors);
186 }
187
188 /**
189 * Assert that the number of errors that have been gathered matches the number of errors that are
190 * given and that they have the expected error codes and locations. The order in which the errors
191 * were gathered is ignored.
192 *
193 * @param errorCodes the errors that should have been gathered
194 * @throws AssertionFailedError if a different number of errors have been gath ered than were
195 * expected or if they do not have the same codes and locations
196 */
197 void assertErrors(List<AnalysisError> expectedErrors) {
198 if (_errors.length != expectedErrors.length) {
199 _fail(expectedErrors);
200 }
201 List<AnalysisError> remainingErrors = new List<AnalysisError>();
202 for (AnalysisError error in expectedErrors) {
203 remainingErrors.add(error);
204 }
205 for (AnalysisError error in _errors) {
206 if (!_foundAndRemoved(remainingErrors, error)) {
207 _fail(expectedErrors);
208 }
209 }
210 }
211
212 /**
213 * Assert that the number of errors that have been gathered matches the number of errors that are
214 * given and that they have the expected error codes. The order in which the e rrors were gathered
215 * is ignored.
216 *
217 * @param expectedErrorCodes the error codes of the errors that should have be en gathered
218 * @throws AssertionFailedError if a different number of errors have been gath ered than were
219 * expected
220 */
221 void assertErrorsWithCodes(
222 [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) {
223 StringBuffer buffer = new StringBuffer();
224 //
225 // Verify that the expected error codes have a non-empty message.
226 //
227 for (ErrorCode errorCode in expectedErrorCodes) {
228 expect(errorCode.message.isEmpty, isFalse,
229 reason: "Empty error code message");
230 }
231 //
232 // Compute the expected number of each type of error.
233 //
234 HashMap<ErrorCode, int> expectedCounts = new HashMap<ErrorCode, int>();
235 for (ErrorCode code in expectedErrorCodes) {
236 int count = expectedCounts[code];
237 if (count == null) {
238 count = 1;
239 } else {
240 count = count + 1;
241 }
242 expectedCounts[code] = count;
243 }
244 //
245 // Compute the actual number of each type of error.
246 //
247 HashMap<ErrorCode, List<AnalysisError>> errorsByCode =
248 new HashMap<ErrorCode, List<AnalysisError>>();
249 for (AnalysisError error in _errors) {
250 ErrorCode code = error.errorCode;
251 List<AnalysisError> list = errorsByCode[code];
252 if (list == null) {
253 list = new List<AnalysisError>();
254 errorsByCode[code] = list;
255 }
256 list.add(error);
257 }
258 //
259 // Compare the expected and actual number of each type of error.
260 //
261 expectedCounts.forEach((ErrorCode code, int expectedCount) {
262 int actualCount;
263 List<AnalysisError> list = errorsByCode.remove(code);
264 if (list == null) {
265 actualCount = 0;
266 } else {
267 actualCount = list.length;
268 }
269 if (actualCount != expectedCount) {
270 if (buffer.length == 0) {
271 buffer.write("Expected ");
272 } else {
273 buffer.write("; ");
274 }
275 buffer.write(expectedCount);
276 buffer.write(" errors of type ");
277 buffer.write(code.uniqueName);
278 buffer.write(", found ");
279 buffer.write(actualCount);
280 }
281 });
282 //
283 // Check that there are no more errors in the actual-errors map,
284 // otherwise record message.
285 //
286 errorsByCode.forEach((ErrorCode code, List<AnalysisError> actualErrors) {
287 int actualCount = actualErrors.length;
288 if (buffer.length == 0) {
289 buffer.write("Expected ");
290 } else {
291 buffer.write("; ");
292 }
293 buffer.write("0 errors of type ");
294 buffer.write(code.uniqueName);
295 buffer.write(", found ");
296 buffer.write(actualCount);
297 buffer.write(" (");
298 for (int i = 0; i < actualErrors.length; i++) {
299 AnalysisError error = actualErrors[i];
300 if (i > 0) {
301 buffer.write(", ");
302 }
303 buffer.write(error.offset);
304 }
305 buffer.write(")");
306 });
307 if (buffer.length > 0) {
308 fail(buffer.toString());
309 }
310 }
311
312 /**
313 * Assert that the number of errors that have been gathered matches the number of severities that
314 * are given and that there are the same number of errors and warnings as spec ified by the
315 * argument. The order in which the errors were gathered is ignored.
316 *
317 * @param expectedSeverities the severities of the errors that should have bee n gathered
318 * @throws AssertionFailedError if a different number of errors have been gath ered than were
319 * expected
320 */
321 void assertErrorsWithSeverities(List<ErrorSeverity> expectedSeverities) {
322 int expectedErrorCount = 0;
323 int expectedWarningCount = 0;
324 for (ErrorSeverity severity in expectedSeverities) {
325 if (severity == ErrorSeverity.ERROR) {
326 expectedErrorCount++;
327 } else {
328 expectedWarningCount++;
329 }
330 }
331 int actualErrorCount = 0;
332 int actualWarningCount = 0;
333 for (AnalysisError error in _errors) {
334 if (error.errorCode.errorSeverity == ErrorSeverity.ERROR) {
335 actualErrorCount++;
336 } else {
337 actualWarningCount++;
338 }
339 }
340 if (expectedErrorCount != actualErrorCount ||
341 expectedWarningCount != actualWarningCount) {
342 fail(
343 "Expected $expectedErrorCount errors and $expectedWarningCount warning s, found $actualErrorCount errors and $actualWarningCount warnings");
344 }
345 }
346
347 /**
348 * Assert that no errors have been gathered.
349 *
350 * @throws AssertionFailedError if any errors have been gathered
351 */
352 void assertNoErrors() {
353 assertErrors(_NO_ERRORS);
354 }
355
356 /**
357 * Return the line information associated with the given source, or `null` if no line
358 * information has been associated with the source.
359 *
360 * @param source the source with which the line information is associated
361 * @return the line information associated with the source
362 */
363 LineInfo getLineInfo(Source source) => _lineInfoMap[source];
364
365 /**
366 * Return `true` if an error with the given error code has been gathered.
367 *
368 * @param errorCode the error code being searched for
369 * @return `true` if an error with the given error code has been gathered
370 */
371 bool hasError(ErrorCode errorCode) {
372 for (AnalysisError error in _errors) {
373 if (identical(error.errorCode, errorCode)) {
374 return true;
375 }
376 }
377 return false;
378 }
379
380 @override
381 void onError(AnalysisError error) {
382 _errors.add(error);
383 }
384
385 /**
386 * Set the line information associated with the given source to the given info rmation.
387 *
388 * @param source the source with which the line information is associated
389 * @param lineStarts the line start information to be associated with the sour ce
390 */
391 void setLineInfo(Source source, List<int> lineStarts) {
392 _lineInfoMap[source] = new LineInfo(lineStarts);
393 }
394
395 /**
396 * Return `true` if the two errors are equivalent.
397 *
398 * @param firstError the first error being compared
399 * @param secondError the second error being compared
400 * @return `true` if the two errors are equivalent
401 */
402 bool _equalErrors(AnalysisError firstError, AnalysisError secondError) =>
403 identical(firstError.errorCode, secondError.errorCode) &&
404 firstError.offset == secondError.offset &&
405 firstError.length == secondError.length &&
406 _equalSources(firstError.source, secondError.source);
407
408 /**
409 * Return `true` if the two sources are equivalent.
410 *
411 * @param firstSource the first source being compared
412 * @param secondSource the second source being compared
413 * @return `true` if the two sources are equivalent
414 */
415 bool _equalSources(Source firstSource, Source secondSource) {
416 if (firstSource == null) {
417 return secondSource == null;
418 } else if (secondSource == null) {
419 return false;
420 }
421 return firstSource == secondSource;
422 }
423
424 /**
425 * Assert that the number of errors that have been gathered matches the number of errors that are
426 * given and that they have the expected error codes. The order in which the e rrors were gathered
427 * is ignored.
428 *
429 * @param errorCodes the errors that should have been gathered
430 * @throws AssertionFailedError with
431 */
432 void _fail(List<AnalysisError> expectedErrors) {
433 StringBuffer buffer = new StringBuffer();
434 buffer.write("Expected ");
435 buffer.write(expectedErrors.length);
436 buffer.write(" errors:");
437 for (AnalysisError error in expectedErrors) {
438 Source source = error.source;
439 LineInfo lineInfo = _lineInfoMap[source];
440 buffer.writeln();
441 if (lineInfo == null) {
442 int offset = error.offset;
443 StringUtils.printf(buffer, " %s %s (%d..%d)", [
444 source == null ? "" : source.shortName,
445 error.errorCode,
446 offset,
447 offset + error.length
448 ]);
449 } else {
450 LineInfo_Location location = lineInfo.getLocation(error.offset);
451 StringUtils.printf(buffer, " %s %s (%d, %d/%d)", [
452 source == null ? "" : source.shortName,
453 error.errorCode,
454 location.lineNumber,
455 location.columnNumber,
456 error.length
457 ]);
458 }
459 }
460 buffer.writeln();
461 buffer.write("found ");
462 buffer.write(_errors.length);
463 buffer.write(" errors:");
464 for (AnalysisError error in _errors) {
465 Source source = error.source;
466 LineInfo lineInfo = _lineInfoMap[source];
467 buffer.writeln();
468 if (lineInfo == null) {
469 int offset = error.offset;
470 StringUtils.printf(buffer, " %s %s (%d..%d): %s", [
471 source == null ? "" : source.shortName,
472 error.errorCode,
473 offset,
474 offset + error.length,
475 error.message
476 ]);
477 } else {
478 LineInfo_Location location = lineInfo.getLocation(error.offset);
479 StringUtils.printf(buffer, " %s %s (%d, %d/%d): %s", [
480 source == null ? "" : source.shortName,
481 error.errorCode,
482 location.lineNumber,
483 location.columnNumber,
484 error.length,
485 error.message
486 ]);
487 }
488 }
489 fail(buffer.toString());
490 }
491
492 /**
493 * Search through the given list of errors for an error that is equal to the t arget error. If one
494 * is found, remove it from the list and return `true`, otherwise return `fals e`
495 * without modifying the list.
496 *
497 * @param errors the errors through which we are searching
498 * @param targetError the error being searched for
499 * @return `true` if the error is found and removed from the list
500 */
501 bool _foundAndRemoved(List<AnalysisError> errors, AnalysisError targetError) {
502 for (AnalysisError error in errors) {
503 if (_equalErrors(error, targetError)) {
504 errors.remove(error);
505 return true;
506 }
507 }
508 return false;
509 }
510 }
511
512 /**
513 * Instances of the class [TestLogger] implement a logger that can be used by
514 * tests.
515 */
516 class TestLogger implements Logger {
517 /**
518 * The number of error messages that were logged.
519 */
520 int errorCount = 0;
521
522 /**
523 * The number of informational messages that were logged.
524 */
525 int infoCount = 0;
526
527 @override
528 void logError(String message, [CaughtException exception]) {
529 errorCount++;
530 }
531
532 @override
533 void logError2(String message, Object exception) {
534 errorCount++;
535 }
536
537 @override
538 void logInformation(String message, [CaughtException exception]) {
539 infoCount++;
540 }
541
542 @override
543 void logInformation2(String message, Object exception) {
544 infoCount++;
545 }
546 }
547
548 class TestSource extends Source {
549 String _name;
550 String _contents;
551 int _modificationStamp = 0;
552 bool exists2 = true;
553
554 /**
555 * A flag indicating whether an exception should be generated when an attempt
556 * is made to access the contents of this source.
557 */
558 bool generateExceptionOnRead = false;
559
560 @override
561 int get modificationStamp =>
562 generateExceptionOnRead ? -1 : _modificationStamp;
563
564 /**
565 * The number of times that the contents of this source have been requested.
566 */
567 int readCount = 0;
568
569 TestSource([this._name = '/test.dart', this._contents]);
570
571 TimestampedData<String> get contents {
572 readCount++;
573 if (generateExceptionOnRead) {
574 String msg = "I/O Exception while getting the contents of " + _name;
575 throw new Exception(msg);
576 }
577 return new TimestampedData<String>(0, _contents);
578 }
579
580 String get encoding {
581 throw new UnsupportedOperationException();
582 }
583
584 String get fullName {
585 return _name;
586 }
587
588 int get hashCode => 0;
589 bool get isInSystemLibrary {
590 return false;
591 }
592
593 String get shortName {
594 return _name;
595 }
596
597 Uri get uri {
598 throw new UnsupportedOperationException();
599 }
600
601 UriKind get uriKind {
602 throw new UnsupportedOperationException();
603 }
604
605 bool operator ==(Object other) {
606 if (other is TestSource) {
607 return other._name == _name;
608 }
609 return false;
610 }
611
612 bool exists() => exists2;
613 void getContentsToReceiver(Source_ContentReceiver receiver) {
614 throw new UnsupportedOperationException();
615 }
616
617 Source resolve(String uri) {
618 throw new UnsupportedOperationException();
619 }
620
621 Uri resolveRelativeUri(Uri uri) {
622 return new Uri(scheme: 'file', path: _name).resolveUri(uri);
623 }
624
625 void setContents(String value) {
626 generateExceptionOnRead = false;
627 _modificationStamp = new DateTime.now().millisecondsSinceEpoch;
628 _contents = value;
629 }
630
631 @override
632 String toString() => '$_name';
633 }
634
635 class TestSourceWithUri extends TestSource {
636 final Uri uri;
637
638 TestSourceWithUri(String path, this.uri, [String content])
639 : super(path, content);
640
641 UriKind get uriKind {
642 if (uri == null) {
643 return UriKind.FILE_URI;
644 } else if (uri.scheme == 'dart') {
645 return UriKind.DART_URI;
646 } else if (uri.scheme == 'package') {
647 return UriKind.PACKAGE_URI;
648 }
649 return UriKind.FILE_URI;
650 }
651
652 bool operator ==(Object other) {
653 if (other is TestSource) {
654 return other.uri == uri;
655 }
656 return false;
657 }
658
659 Uri resolveRelativeUri(Uri uri) {
660 return this.uri.resolveUri(uri);
661 }
662 }
OLDNEW
« 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