| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library engine.test_support; | 5 library analyzer.test.generated.test_support; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/src/generated/ast.dart' show AstNode, NodeLocator; | 9 import 'package:analyzer/dart/ast/ast.dart' show AstNode, SimpleIdentifier; |
| 10 import 'package:analyzer/src/generated/element.dart'; | 10 import 'package:analyzer/dart/element/element.dart'; |
| 11 import 'package:analyzer/dart/element/type.dart'; |
| 12 import 'package:analyzer/error/error.dart'; |
| 13 import 'package:analyzer/error/listener.dart'; |
| 14 import 'package:analyzer/exception/exception.dart'; |
| 15 import 'package:analyzer/src/dart/ast/utilities.dart'; |
| 11 import 'package:analyzer/src/generated/engine.dart'; | 16 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'; | 17 import 'package:analyzer/src/generated/java_engine.dart'; |
| 15 import 'package:analyzer/src/generated/source.dart'; | 18 import 'package:analyzer/src/generated/source.dart'; |
| 19 import 'package:plugin/manager.dart'; |
| 20 import 'package:plugin/plugin.dart'; |
| 16 import 'package:unittest/unittest.dart'; | 21 import 'package:unittest/unittest.dart'; |
| 17 | 22 |
| 18 import 'resolver_test.dart'; | 23 import 'analysis_context_factory.dart'; |
| 19 | 24 |
| 20 /** | 25 /** |
| 21 * The class `EngineTestCase` defines utility methods for making assertions. | 26 * The class `EngineTestCase` defines utility methods for making assertions. |
| 22 */ | 27 */ |
| 23 class EngineTestCase { | 28 class EngineTestCase { |
| 24 /** | 29 /** |
| 25 * Assert that the given collection has the same number of elements as the num
ber of specified | 30 * 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 | 31 * names, and that for each specified name, a corresponding element can be fou
nd in the given |
| 27 * collection with that name. | 32 * collection with that name. |
| 28 * | 33 * |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 MethodElement getMethod(InterfaceType type, String methodName) { | 89 MethodElement getMethod(InterfaceType type, String methodName) { |
| 85 for (MethodElement method in type.element.methods) { | 90 for (MethodElement method in type.element.methods) { |
| 86 if (method.name == methodName) { | 91 if (method.name == methodName) { |
| 87 return method; | 92 return method; |
| 88 } | 93 } |
| 89 } | 94 } |
| 90 fail("Could not find method named $methodName in ${type.displayName}"); | 95 fail("Could not find method named $methodName in ${type.displayName}"); |
| 91 return null; | 96 return null; |
| 92 } | 97 } |
| 93 | 98 |
| 94 void setUp() {} | 99 void setUp() { |
| 100 List<Plugin> plugins = <Plugin>[]; |
| 101 plugins.addAll(AnalysisEngine.instance.requiredPlugins); |
| 102 plugins.add(AnalysisEngine.instance.commandLinePlugin); |
| 103 plugins.add(AnalysisEngine.instance.optionsPlugin); |
| 104 new ExtensionManager().processPlugins(plugins); |
| 105 } |
| 95 | 106 |
| 96 void tearDown() {} | 107 void tearDown() {} |
| 97 | 108 |
| 98 /** | 109 /** |
| 99 * Assert that the given object is an instance of the expected class. | 110 * Assert that the given object is an instance of the expected class. |
| 100 * | 111 * |
| 101 * @param expectedClass the class that the object is expected to be an instanc
e of | 112 * @param expectedClass the class that the object is expected to be an instanc
e of |
| 102 * @param object the object being tested | 113 * @param object the object being tested |
| 103 * @return the object that was being tested | 114 * @return the object that was being tested |
| 104 * @throws Exception if the object is not an instance of the expected class | 115 * @throws Exception if the object is not an instance of the expected class |
| 105 */ | 116 */ |
| 106 static Object assertInstanceOf( | 117 static Object assertInstanceOf( |
| 107 Predicate<Object> predicate, Type expectedClass, Object object) { | 118 Predicate<Object> predicate, Type expectedClass, Object object) { |
| 108 if (!predicate(object)) { | 119 if (!predicate(object)) { |
| 109 fail( | 120 fail( |
| 110 "Expected instance of $expectedClass, found ${object == null ? "null"
: object.runtimeType}"); | 121 "Expected instance of $expectedClass, found ${object == null ? "null"
: object.runtimeType}"); |
| 111 } | 122 } |
| 112 return object; | 123 return object; |
| 113 } | 124 } |
| 114 | 125 |
| 115 /** | 126 /** |
| 116 * @return the [AstNode] with requested type at offset of the "prefix". | 127 * @return the [AstNode] with requested type at offset of the "prefix". |
| 117 */ | 128 */ |
| 118 static AstNode findNode( | 129 static AstNode findNode( |
| 119 AstNode root, String code, String prefix, Predicate<AstNode> predicate) { | 130 AstNode root, String code, String prefix, Predicate<AstNode> predicate) { |
| 120 int offset = code.indexOf(prefix); | 131 int offset = code.indexOf(prefix); |
| 121 if (offset == -1) { | 132 if (offset == -1) { |
| 122 throw new IllegalArgumentException("Not found '$prefix'."); | 133 throw new ArgumentError("Not found '$prefix'."); |
| 123 } | 134 } |
| 124 AstNode node = new NodeLocator(offset).searchWithin(root); | 135 AstNode node = new NodeLocator(offset).searchWithin(root); |
| 125 return node.getAncestor(predicate); | 136 return node.getAncestor(predicate); |
| 126 } | 137 } |
| 138 |
| 139 /** |
| 140 * Find the [SimpleIdentifier] with at offset of the "prefix". |
| 141 */ |
| 142 static SimpleIdentifier findSimpleIdentifier( |
| 143 AstNode root, String code, String prefix) { |
| 144 int offset = code.indexOf(prefix); |
| 145 if (offset == -1) { |
| 146 throw new ArgumentError("Not found '$prefix'."); |
| 147 } |
| 148 return new NodeLocator(offset).searchWithin(root); |
| 149 } |
| 127 } | 150 } |
| 128 | 151 |
| 129 /** | 152 /** |
| 130 * Instances of the class `GatheringErrorListener` implement an error listener t
hat collects | 153 * Instances of the class `GatheringErrorListener` implement an error listener t
hat collects |
| 131 * all of the errors passed to it for later examination. | 154 * all of the errors passed to it for later examination. |
| 132 */ | 155 */ |
| 133 class GatheringErrorListener implements AnalysisErrorListener { | 156 class GatheringErrorListener implements AnalysisErrorListener { |
| 134 /** | 157 /** |
| 135 * An empty array of errors used when no errors are expected. | 158 * An empty array of errors used when no errors are expected. |
| 136 */ | 159 */ |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 * Set the line information associated with the given source to the given info
rmation. | 409 * Set the line information associated with the given source to the given info
rmation. |
| 387 * | 410 * |
| 388 * @param source the source with which the line information is associated | 411 * @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 | 412 * @param lineStarts the line start information to be associated with the sour
ce |
| 390 */ | 413 */ |
| 391 void setLineInfo(Source source, List<int> lineStarts) { | 414 void setLineInfo(Source source, List<int> lineStarts) { |
| 392 _lineInfoMap[source] = new LineInfo(lineStarts); | 415 _lineInfoMap[source] = new LineInfo(lineStarts); |
| 393 } | 416 } |
| 394 | 417 |
| 395 /** | 418 /** |
| 396 * Return `true` if the two errors are equivalent. | 419 * Return `true` if the [actualError] matches the [expectedError]. |
| 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 */ | 420 */ |
| 402 bool _equalErrors(AnalysisError firstError, AnalysisError secondError) => | 421 bool _equalErrors(AnalysisError expectedError, AnalysisError actualError) { |
| 403 identical(firstError.errorCode, secondError.errorCode) && | 422 Source expectedSource = expectedError.source; |
| 404 firstError.offset == secondError.offset && | 423 return identical(expectedError.errorCode, actualError.errorCode) && |
| 405 firstError.length == secondError.length && | 424 expectedError.offset == actualError.offset && |
| 406 _equalSources(firstError.source, secondError.source); | 425 expectedError.length == actualError.length && |
| 426 (expectedSource == null || |
| 427 _equalSources(expectedSource, actualError.source)); |
| 428 } |
| 407 | 429 |
| 408 /** | 430 /** |
| 409 * Return `true` if the two sources are equivalent. | 431 * Return `true` if the two sources are equivalent. |
| 410 * | 432 * |
| 411 * @param firstSource the first source being compared | 433 * @param firstSource the first source being compared |
| 412 * @param secondSource the second source being compared | 434 * @param secondSource the second source being compared |
| 413 * @return `true` if the two sources are equivalent | 435 * @return `true` if the two sources are equivalent |
| 414 */ | 436 */ |
| 415 bool _equalSources(Source firstSource, Source secondSource) { | 437 bool _equalSources(Source firstSource, Source secondSource) { |
| 416 if (firstSource == null) { | 438 if (firstSource == null) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 431 */ | 453 */ |
| 432 void _fail(List<AnalysisError> expectedErrors) { | 454 void _fail(List<AnalysisError> expectedErrors) { |
| 433 StringBuffer buffer = new StringBuffer(); | 455 StringBuffer buffer = new StringBuffer(); |
| 434 buffer.write("Expected "); | 456 buffer.write("Expected "); |
| 435 buffer.write(expectedErrors.length); | 457 buffer.write(expectedErrors.length); |
| 436 buffer.write(" errors:"); | 458 buffer.write(" errors:"); |
| 437 for (AnalysisError error in expectedErrors) { | 459 for (AnalysisError error in expectedErrors) { |
| 438 Source source = error.source; | 460 Source source = error.source; |
| 439 LineInfo lineInfo = _lineInfoMap[source]; | 461 LineInfo lineInfo = _lineInfoMap[source]; |
| 440 buffer.writeln(); | 462 buffer.writeln(); |
| 463 String sourceName = source == null ? '' : source.shortName; |
| 441 if (lineInfo == null) { | 464 if (lineInfo == null) { |
| 442 int offset = error.offset; | 465 int offset = error.offset; |
| 443 StringUtils.printf(buffer, " %s %s (%d..%d)", [ | 466 buffer.write(' $sourceName ${error.errorCode} ' |
| 444 source == null ? "" : source.shortName, | 467 '($offset..${offset + error.length})'); |
| 445 error.errorCode, | |
| 446 offset, | |
| 447 offset + error.length | |
| 448 ]); | |
| 449 } else { | 468 } else { |
| 450 LineInfo_Location location = lineInfo.getLocation(error.offset); | 469 LineInfo_Location location = lineInfo.getLocation(error.offset); |
| 451 StringUtils.printf(buffer, " %s %s (%d, %d/%d)", [ | 470 int lineNumber = location.lineNumber; |
| 452 source == null ? "" : source.shortName, | 471 int columnNumber = location.columnNumber; |
| 453 error.errorCode, | 472 buffer.write(' $sourceName ${error.errorCode} ' |
| 454 location.lineNumber, | 473 '($lineNumber, $columnNumber/${error.length})'); |
| 455 location.columnNumber, | |
| 456 error.length | |
| 457 ]); | |
| 458 } | 474 } |
| 459 } | 475 } |
| 460 buffer.writeln(); | 476 buffer.writeln(); |
| 461 buffer.write("found "); | 477 buffer.write("found "); |
| 462 buffer.write(_errors.length); | 478 buffer.write(_errors.length); |
| 463 buffer.write(" errors:"); | 479 buffer.write(" errors:"); |
| 464 for (AnalysisError error in _errors) { | 480 for (AnalysisError error in _errors) { |
| 465 Source source = error.source; | 481 Source source = error.source; |
| 466 LineInfo lineInfo = _lineInfoMap[source]; | 482 LineInfo lineInfo = _lineInfoMap[source]; |
| 467 buffer.writeln(); | 483 buffer.writeln(); |
| 484 String sourceName = source == null ? '' : source.shortName; |
| 468 if (lineInfo == null) { | 485 if (lineInfo == null) { |
| 469 int offset = error.offset; | 486 int offset = error.offset; |
| 470 StringUtils.printf(buffer, " %s %s (%d..%d): %s", [ | 487 buffer.write(' $sourceName ${error.errorCode} ' |
| 471 source == null ? "" : source.shortName, | 488 '($offset..${offset + error.length}): ${error.message}'); |
| 472 error.errorCode, | |
| 473 offset, | |
| 474 offset + error.length, | |
| 475 error.message | |
| 476 ]); | |
| 477 } else { | 489 } else { |
| 478 LineInfo_Location location = lineInfo.getLocation(error.offset); | 490 LineInfo_Location location = lineInfo.getLocation(error.offset); |
| 479 StringUtils.printf(buffer, " %s %s (%d, %d/%d): %s", [ | 491 int lineNumber = location.lineNumber; |
| 480 source == null ? "" : source.shortName, | 492 int columnNumber = location.columnNumber; |
| 481 error.errorCode, | 493 buffer.write(' $sourceName ${error.errorCode} ' |
| 482 location.lineNumber, | 494 '($lineNumber, $columnNumber/${error.length}): ${error.message}'); |
| 483 location.columnNumber, | |
| 484 error.length, | |
| 485 error.message | |
| 486 ]); | |
| 487 } | 495 } |
| 488 } | 496 } |
| 489 fail(buffer.toString()); | 497 fail(buffer.toString()); |
| 490 } | 498 } |
| 491 | 499 |
| 492 /** | 500 /** |
| 493 * Search through the given list of errors for an error that is equal to the t
arget error. If one | 501 * 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` | 502 * is found, remove it from the list and return `true`, otherwise return `fals
e` |
| 495 * without modifying the list. | 503 * without modifying the list. |
| 496 * | 504 * |
| (...skipping 11 matching lines...) Expand all Loading... |
| 508 return false; | 516 return false; |
| 509 } | 517 } |
| 510 } | 518 } |
| 511 | 519 |
| 512 /** | 520 /** |
| 513 * Instances of the class [TestLogger] implement a logger that can be used by | 521 * Instances of the class [TestLogger] implement a logger that can be used by |
| 514 * tests. | 522 * tests. |
| 515 */ | 523 */ |
| 516 class TestLogger implements Logger { | 524 class TestLogger implements Logger { |
| 517 /** | 525 /** |
| 518 * The number of error messages that were logged. | 526 * All logged messages. |
| 519 */ | 527 */ |
| 520 int errorCount = 0; | 528 List<String> log = []; |
| 521 | |
| 522 /** | |
| 523 * The number of informational messages that were logged. | |
| 524 */ | |
| 525 int infoCount = 0; | |
| 526 | 529 |
| 527 @override | 530 @override |
| 528 void logError(String message, [CaughtException exception]) { | 531 void logError(String message, [CaughtException exception]) { |
| 529 errorCount++; | 532 log.add("error: $message"); |
| 530 } | |
| 531 | |
| 532 @override | |
| 533 void logError2(String message, Object exception) { | |
| 534 errorCount++; | |
| 535 } | 533 } |
| 536 | 534 |
| 537 @override | 535 @override |
| 538 void logInformation(String message, [CaughtException exception]) { | 536 void logInformation(String message, [CaughtException exception]) { |
| 539 infoCount++; | 537 log.add("info: $message"); |
| 540 } | |
| 541 | |
| 542 @override | |
| 543 void logInformation2(String message, Object exception) { | |
| 544 infoCount++; | |
| 545 } | 538 } |
| 546 } | 539 } |
| 547 | 540 |
| 548 class TestSource extends Source { | 541 class TestSource extends Source { |
| 549 String _name; | 542 String _name; |
| 550 String _contents; | 543 String _contents; |
| 551 int _modificationStamp = 0; | 544 int _modificationStamp = 0; |
| 552 bool exists2 = true; | 545 bool exists2 = true; |
| 553 | 546 |
| 554 /** | 547 /** |
| 555 * A flag indicating whether an exception should be generated when an attempt | 548 * A flag indicating whether an exception should be generated when an attempt |
| 556 * is made to access the contents of this source. | 549 * is made to access the contents of this source. |
| 557 */ | 550 */ |
| 558 bool generateExceptionOnRead = false; | 551 bool generateExceptionOnRead = false; |
| 559 | 552 |
| 560 @override | |
| 561 int get modificationStamp => | |
| 562 generateExceptionOnRead ? -1 : _modificationStamp; | |
| 563 | |
| 564 /** | 553 /** |
| 565 * The number of times that the contents of this source have been requested. | 554 * The number of times that the contents of this source have been requested. |
| 566 */ | 555 */ |
| 567 int readCount = 0; | 556 int readCount = 0; |
| 568 | 557 |
| 569 TestSource([this._name = '/test.dart', this._contents]); | 558 TestSource([this._name = '/test.dart', this._contents]); |
| 570 | 559 |
| 571 TimestampedData<String> get contents { | 560 TimestampedData<String> get contents { |
| 572 readCount++; | 561 readCount++; |
| 573 if (generateExceptionOnRead) { | 562 if (generateExceptionOnRead) { |
| 574 String msg = "I/O Exception while getting the contents of " + _name; | 563 String msg = "I/O Exception while getting the contents of " + _name; |
| 575 throw new Exception(msg); | 564 throw new Exception(msg); |
| 576 } | 565 } |
| 577 return new TimestampedData<String>(0, _contents); | 566 return new TimestampedData<String>(0, _contents); |
| 578 } | 567 } |
| 579 | 568 |
| 580 String get encoding { | 569 String get encoding => _name; |
| 581 throw new UnsupportedOperationException(); | |
| 582 } | |
| 583 | 570 |
| 584 String get fullName { | 571 String get fullName { |
| 585 return _name; | 572 return _name; |
| 586 } | 573 } |
| 587 | 574 |
| 588 int get hashCode => 0; | 575 int get hashCode => 0; |
| 576 |
| 589 bool get isInSystemLibrary { | 577 bool get isInSystemLibrary { |
| 590 return false; | 578 return false; |
| 591 } | 579 } |
| 592 | 580 |
| 581 @override |
| 582 int get modificationStamp => |
| 583 generateExceptionOnRead ? -1 : _modificationStamp; |
| 584 |
| 593 String get shortName { | 585 String get shortName { |
| 594 return _name; | 586 return _name; |
| 595 } | 587 } |
| 596 | 588 |
| 597 Uri get uri { | 589 Uri get uri => new Uri.file(_name); |
| 598 throw new UnsupportedOperationException(); | |
| 599 } | |
| 600 | 590 |
| 601 UriKind get uriKind { | 591 UriKind get uriKind { |
| 602 throw new UnsupportedOperationException(); | 592 throw new UnsupportedError('uriKind'); |
| 603 } | 593 } |
| 604 | 594 |
| 605 bool operator ==(Object other) { | 595 bool operator ==(Object other) { |
| 606 if (other is TestSource) { | 596 if (other is TestSource) { |
| 607 return other._name == _name; | 597 return other._name == _name; |
| 608 } | 598 } |
| 609 return false; | 599 return false; |
| 610 } | 600 } |
| 611 | 601 |
| 612 bool exists() => exists2; | 602 bool exists() => exists2; |
| 613 void getContentsToReceiver(Source_ContentReceiver receiver) { | 603 void getContentsToReceiver(Source_ContentReceiver receiver) { |
| 614 throw new UnsupportedOperationException(); | 604 throw new UnsupportedError('getContentsToReceiver'); |
| 615 } | 605 } |
| 616 | 606 |
| 617 Source resolve(String uri) { | 607 Source resolve(String uri) { |
| 618 throw new UnsupportedOperationException(); | 608 throw new UnsupportedError('resolve'); |
| 619 } | |
| 620 | |
| 621 Uri resolveRelativeUri(Uri uri) { | |
| 622 return new Uri(scheme: 'file', path: _name).resolveUri(uri); | |
| 623 } | 609 } |
| 624 | 610 |
| 625 void setContents(String value) { | 611 void setContents(String value) { |
| 626 generateExceptionOnRead = false; | 612 generateExceptionOnRead = false; |
| 627 _modificationStamp = new DateTime.now().millisecondsSinceEpoch; | 613 _modificationStamp = new DateTime.now().millisecondsSinceEpoch; |
| 628 _contents = value; | 614 _contents = value; |
| 629 } | 615 } |
| 630 | 616 |
| 631 @override | 617 @override |
| 632 String toString() => '$_name'; | 618 String toString() => '$_name'; |
| 633 } | 619 } |
| 634 | 620 |
| 635 class TestSourceWithUri extends TestSource { | 621 class TestSourceWithUri extends TestSource { |
| 636 final Uri uri; | 622 final Uri uri; |
| 637 | 623 |
| 638 TestSourceWithUri(String path, this.uri, [String content]) | 624 TestSourceWithUri(String path, this.uri, [String content]) |
| 639 : super(path, content); | 625 : super(path, content); |
| 640 | 626 |
| 627 String get encoding => uri.toString(); |
| 628 |
| 641 UriKind get uriKind { | 629 UriKind get uriKind { |
| 642 if (uri == null) { | 630 if (uri == null) { |
| 643 return UriKind.FILE_URI; | 631 return UriKind.FILE_URI; |
| 644 } else if (uri.scheme == 'dart') { | 632 } else if (uri.scheme == 'dart') { |
| 645 return UriKind.DART_URI; | 633 return UriKind.DART_URI; |
| 646 } else if (uri.scheme == 'package') { | 634 } else if (uri.scheme == 'package') { |
| 647 return UriKind.PACKAGE_URI; | 635 return UriKind.PACKAGE_URI; |
| 648 } | 636 } |
| 649 return UriKind.FILE_URI; | 637 return UriKind.FILE_URI; |
| 650 } | 638 } |
| 651 | 639 |
| 652 bool operator ==(Object other) { | 640 bool operator ==(Object other) { |
| 653 if (other is TestSource) { | 641 if (other is TestSource) { |
| 654 return other.uri == uri; | 642 return other.uri == uri; |
| 655 } | 643 } |
| 656 return false; | 644 return false; |
| 657 } | 645 } |
| 658 | |
| 659 Uri resolveRelativeUri(Uri uri) { | |
| 660 return this.uri.resolveUri(uri); | |
| 661 } | |
| 662 } | 646 } |
| OLD | NEW |