| OLD | NEW |
| (Empty) |
| 1 // This code was auto-generated, is not intended to be edited, and is subject to | |
| 2 // significant change. Please see the README file for more information. | |
| 3 library engine.test_support; | |
| 4 import 'package:analyzer_experimental/src/generated/java_core.dart'; | |
| 5 import 'package:analyzer_experimental/src/generated/java_junit.dart'; | |
| 6 import 'package:analyzer_experimental/src/generated/source.dart'; | |
| 7 import 'package:analyzer_experimental/src/generated/error.dart'; | |
| 8 import 'package:analyzer_experimental/src/generated/scanner.dart'; | |
| 9 import 'package:analyzer_experimental/src/generated/ast.dart' show ASTNode, Node
Locator; | |
| 10 import 'package:analyzer_experimental/src/generated/element.dart' show Interface
Type, MethodElement, PropertyAccessorElement; | |
| 11 import 'package:analyzer_experimental/src/generated/engine.dart' show AnalysisCo
ntext, AnalysisContextImpl, RecordingErrorListener; | |
| 12 import 'package:unittest/unittest.dart' as _ut; | |
| 13 /** | |
| 14 * Instances of the class `GatheringErrorListener` implement an error listener t
hat collects | |
| 15 * all of the errors passed to it for later examination. | |
| 16 */ | |
| 17 class GatheringErrorListener implements AnalysisErrorListener { | |
| 18 | |
| 19 /** | |
| 20 * The source being parsed. | |
| 21 */ | |
| 22 String _rawSource; | |
| 23 | |
| 24 /** | |
| 25 * The source being parsed after inserting a marker at the beginning and end o
f the range of the | |
| 26 * most recent error. | |
| 27 */ | |
| 28 String _markedSource; | |
| 29 | |
| 30 /** | |
| 31 * A list containing the errors that were collected. | |
| 32 */ | |
| 33 final List<AnalysisError> errors = new List<AnalysisError>(); | |
| 34 | |
| 35 /** | |
| 36 * A table mapping sources to the line information for the source. | |
| 37 */ | |
| 38 Map<Source, LineInfo> _lineInfoMap = new Map<Source, LineInfo>(); | |
| 39 | |
| 40 /** | |
| 41 * An empty array of errors used when no errors are expected. | |
| 42 */ | |
| 43 static List<AnalysisError> _NO_ERRORS = new List<AnalysisError>(0); | |
| 44 | |
| 45 /** | |
| 46 * Initialize a newly created error listener to collect errors. | |
| 47 */ | |
| 48 GatheringErrorListener() : super(); | |
| 49 | |
| 50 /** | |
| 51 * Initialize a newly created error listener to collect errors. | |
| 52 */ | |
| 53 GatheringErrorListener.con1(String rawSource) { | |
| 54 this._rawSource = rawSource; | |
| 55 this._markedSource = rawSource; | |
| 56 } | |
| 57 | |
| 58 /** | |
| 59 * Add all of the errors recorded by the given listener to this listener. | |
| 60 * | |
| 61 * @param listener the listener that has recorded the errors to be added | |
| 62 */ | |
| 63 void addAll(RecordingErrorListener listener) { | |
| 64 for (AnalysisError error in listener.errors) { | |
| 65 onError(error); | |
| 66 } | |
| 67 } | |
| 68 | |
| 69 /** | |
| 70 * Assert that the number of errors that have been gathered matches the number
of errors that are | |
| 71 * given and that they have the expected error codes and locations. The order
in which the errors | |
| 72 * were gathered is ignored. | |
| 73 * | |
| 74 * @param errorCodes the errors that should have been gathered | |
| 75 * @throws AssertionFailedError if a different number of errors have been gath
ered than were | |
| 76 * expected or if they do not have the same codes and locations | |
| 77 */ | |
| 78 void assertErrors(List<AnalysisError> expectedErrors) { | |
| 79 if (errors.length != expectedErrors.length) { | |
| 80 fail(expectedErrors); | |
| 81 } | |
| 82 List<AnalysisError> remainingErrors = new List<AnalysisError>(); | |
| 83 for (AnalysisError error in expectedErrors) { | |
| 84 remainingErrors.add(error); | |
| 85 } | |
| 86 for (AnalysisError error in errors) { | |
| 87 if (!foundAndRemoved(remainingErrors, error)) { | |
| 88 fail(expectedErrors); | |
| 89 } | |
| 90 } | |
| 91 } | |
| 92 | |
| 93 /** | |
| 94 * Assert that the number of errors that have been gathered matches the number
of errors that are | |
| 95 * given and that they have the expected error codes. The order in which the e
rrors were gathered | |
| 96 * is ignored. | |
| 97 * | |
| 98 * @param expectedErrorCodes the error codes of the errors that should have be
en gathered | |
| 99 * @throws AssertionFailedError if a different number of errors have been gath
ered than were | |
| 100 * expected | |
| 101 */ | |
| 102 void assertErrors2(List<ErrorCode> expectedErrorCodes) { | |
| 103 JavaStringBuilder builder = new JavaStringBuilder(); | |
| 104 for (ErrorCode errorCode in expectedErrorCodes) { | |
| 105 JUnitTestCase.assertFalseMsg("Empty error code message", errorCode.message
.isEmpty); | |
| 106 } | |
| 107 Map<ErrorCode, int> expectedCounts = new Map<ErrorCode, int>(); | |
| 108 for (ErrorCode code in expectedErrorCodes) { | |
| 109 int count = expectedCounts[code]; | |
| 110 if (count == null) { | |
| 111 count = 1; | |
| 112 } else { | |
| 113 count = count + 1; | |
| 114 } | |
| 115 expectedCounts[code] = count; | |
| 116 } | |
| 117 Map<ErrorCode, List<AnalysisError>> errorsByCode = new Map<ErrorCode, List<A
nalysisError>>(); | |
| 118 for (AnalysisError error in errors) { | |
| 119 ErrorCode code = error.errorCode; | |
| 120 List<AnalysisError> list = errorsByCode[code]; | |
| 121 if (list == null) { | |
| 122 list = new List<AnalysisError>(); | |
| 123 errorsByCode[code] = list; | |
| 124 } | |
| 125 list.add(error); | |
| 126 } | |
| 127 for (MapEntry<ErrorCode, int> entry in getMapEntrySet(expectedCounts)) { | |
| 128 ErrorCode code = entry.getKey(); | |
| 129 int expectedCount = entry.getValue(); | |
| 130 int actualCount; | |
| 131 List<AnalysisError> list = errorsByCode.remove(code); | |
| 132 if (list == null) { | |
| 133 actualCount = 0; | |
| 134 } else { | |
| 135 actualCount = list.length; | |
| 136 } | |
| 137 if (actualCount != expectedCount) { | |
| 138 if (builder.length == 0) { | |
| 139 builder.append("Expected "); | |
| 140 } else { | |
| 141 builder.append("; "); | |
| 142 } | |
| 143 builder.append(expectedCount); | |
| 144 builder.append(" errors of type "); | |
| 145 builder.append("${code.runtimeType.toString()}.${code}"); | |
| 146 builder.append(", found "); | |
| 147 builder.append(actualCount); | |
| 148 } | |
| 149 } | |
| 150 for (MapEntry<ErrorCode, List<AnalysisError>> entry in getMapEntrySet(errors
ByCode)) { | |
| 151 ErrorCode code = entry.getKey(); | |
| 152 List<AnalysisError> actualErrors = entry.getValue(); | |
| 153 int actualCount = actualErrors.length; | |
| 154 if (builder.length == 0) { | |
| 155 builder.append("Expected "); | |
| 156 } else { | |
| 157 builder.append("; "); | |
| 158 } | |
| 159 builder.append("0 errors of type "); | |
| 160 builder.append("${code.runtimeType.toString()}.${code}"); | |
| 161 builder.append(", found "); | |
| 162 builder.append(actualCount); | |
| 163 builder.append(" ("); | |
| 164 for (int i = 0; i < actualErrors.length; i++) { | |
| 165 AnalysisError error = actualErrors[i]; | |
| 166 if (i > 0) { | |
| 167 builder.append(", "); | |
| 168 } | |
| 169 builder.append(error.offset); | |
| 170 } | |
| 171 builder.append(")"); | |
| 172 } | |
| 173 if (builder.length > 0) { | |
| 174 JUnitTestCase.fail(builder.toString()); | |
| 175 } | |
| 176 } | |
| 177 | |
| 178 /** | |
| 179 * Assert that the number of errors that have been gathered matches the number
of severities that | |
| 180 * are given and that there are the same number of errors and warnings as spec
ified by the | |
| 181 * argument. The order in which the errors were gathered is ignored. | |
| 182 * | |
| 183 * @param expectedSeverities the severities of the errors that should have bee
n gathered | |
| 184 * @throws AssertionFailedError if a different number of errors have been gath
ered than were | |
| 185 * expected | |
| 186 */ | |
| 187 void assertErrors3(List<ErrorSeverity> expectedSeverities) { | |
| 188 int expectedErrorCount = 0; | |
| 189 int expectedWarningCount = 0; | |
| 190 for (ErrorSeverity severity in expectedSeverities) { | |
| 191 if (identical(severity, ErrorSeverity.ERROR)) { | |
| 192 expectedErrorCount++; | |
| 193 } else { | |
| 194 expectedWarningCount++; | |
| 195 } | |
| 196 } | |
| 197 int actualErrorCount = 0; | |
| 198 int actualWarningCount = 0; | |
| 199 for (AnalysisError error in errors) { | |
| 200 if (identical(error.errorCode.errorSeverity, ErrorSeverity.ERROR)) { | |
| 201 actualErrorCount++; | |
| 202 } else { | |
| 203 actualWarningCount++; | |
| 204 } | |
| 205 } | |
| 206 if (expectedErrorCount != actualErrorCount || expectedWarningCount != actual
WarningCount) { | |
| 207 JUnitTestCase.fail("Expected ${expectedErrorCount} errors and ${expectedWa
rningCount} warnings, found ${actualErrorCount} errors and ${actualWarningCount}
warnings"); | |
| 208 } | |
| 209 } | |
| 210 | |
| 211 /** | |
| 212 * Assert that no errors have been gathered. | |
| 213 * | |
| 214 * @throws AssertionFailedError if any errors have been gathered | |
| 215 */ | |
| 216 void assertNoErrors() { | |
| 217 assertErrors(_NO_ERRORS); | |
| 218 } | |
| 219 | |
| 220 /** | |
| 221 * Return the line information associated with the given source, or `null` if
no line | |
| 222 * information has been associated with the source. | |
| 223 * | |
| 224 * @param source the source with which the line information is associated | |
| 225 * @return the line information associated with the source | |
| 226 */ | |
| 227 LineInfo getLineInfo(Source source) => _lineInfoMap[source]; | |
| 228 | |
| 229 /** | |
| 230 * Return `true` if an error with the given error code has been gathered. | |
| 231 * | |
| 232 * @param errorCode the error code being searched for | |
| 233 * @return `true` if an error with the given error code has been gathered | |
| 234 */ | |
| 235 bool hasError(ErrorCode errorCode) { | |
| 236 for (AnalysisError error in errors) { | |
| 237 if (identical(error.errorCode, errorCode)) { | |
| 238 return true; | |
| 239 } | |
| 240 } | |
| 241 return false; | |
| 242 } | |
| 243 | |
| 244 /** | |
| 245 * Return `true` if at least one error has been gathered. | |
| 246 * | |
| 247 * @return `true` if at least one error has been gathered | |
| 248 */ | |
| 249 bool hasErrors() => errors.length > 0; | |
| 250 void onError(AnalysisError error) { | |
| 251 if (_rawSource != null) { | |
| 252 int left = error.offset; | |
| 253 int right = left + error.length - 1; | |
| 254 _markedSource = "${_rawSource.substring(0, left)}^${_rawSource.substring(l
eft, right)}^${_rawSource.substring(right)}"; | |
| 255 } | |
| 256 errors.add(error); | |
| 257 } | |
| 258 | |
| 259 /** | |
| 260 * Set the line information associated with the given source to the given info
rmation. | |
| 261 * | |
| 262 * @param source the source with which the line information is associated | |
| 263 * @param lineStarts the line start information to be associated with the sour
ce | |
| 264 */ | |
| 265 void setLineInfo(Source source, List<int> lineStarts) { | |
| 266 _lineInfoMap[source] = new LineInfo(lineStarts); | |
| 267 } | |
| 268 | |
| 269 /** | |
| 270 * Set the line information associated with the given source to the given info
rmation. | |
| 271 * | |
| 272 * @param source the source with which the line information is associated | |
| 273 * @param lineInfo the line information to be associated with the source | |
| 274 */ | |
| 275 void setLineInfo2(Source source, LineInfo lineInfo) { | |
| 276 _lineInfoMap[source] = lineInfo; | |
| 277 } | |
| 278 | |
| 279 /** | |
| 280 * Return `true` if the two errors are equivalent. | |
| 281 * | |
| 282 * @param firstError the first error being compared | |
| 283 * @param secondError the second error being compared | |
| 284 * @return `true` if the two errors are equivalent | |
| 285 */ | |
| 286 bool equals3(AnalysisError firstError, AnalysisError secondError) => identical
(firstError.errorCode, secondError.errorCode) && firstError.offset == secondErro
r.offset && firstError.length == secondError.length && equals4(firstError.source
, secondError.source); | |
| 287 | |
| 288 /** | |
| 289 * Return `true` if the two sources are equivalent. | |
| 290 * | |
| 291 * @param firstSource the first source being compared | |
| 292 * @param secondSource the second source being compared | |
| 293 * @return `true` if the two sources are equivalent | |
| 294 */ | |
| 295 bool equals4(Source firstSource, Source secondSource) { | |
| 296 if (firstSource == null) { | |
| 297 return secondSource == null; | |
| 298 } else if (secondSource == null) { | |
| 299 return false; | |
| 300 } | |
| 301 return firstSource == secondSource; | |
| 302 } | |
| 303 | |
| 304 /** | |
| 305 * Assert that the number of errors that have been gathered matches the number
of errors that are | |
| 306 * given and that they have the expected error codes. The order in which the e
rrors were gathered | |
| 307 * is ignored. | |
| 308 * | |
| 309 * @param errorCodes the errors that should have been gathered | |
| 310 * @throws AssertionFailedError with | |
| 311 */ | |
| 312 void fail(List<AnalysisError> expectedErrors) { | |
| 313 PrintStringWriter writer = new PrintStringWriter(); | |
| 314 writer.print("Expected "); | |
| 315 writer.print(expectedErrors.length); | |
| 316 writer.print(" errors:"); | |
| 317 for (AnalysisError error in expectedErrors) { | |
| 318 Source source = error.source; | |
| 319 LineInfo lineInfo = _lineInfoMap[source]; | |
| 320 writer.newLine(); | |
| 321 if (lineInfo == null) { | |
| 322 int offset = error.offset; | |
| 323 writer.printf(" %s %s (%d..%d)", [ | |
| 324 source == null ? "" : source.shortName, | |
| 325 error.errorCode, | |
| 326 offset, | |
| 327 offset + error.length]); | |
| 328 } else { | |
| 329 LineInfo_Location location = lineInfo.getLocation(error.offset); | |
| 330 writer.printf(" %s %s (%d, %d/%d)", [ | |
| 331 source == null ? "" : source.shortName, | |
| 332 error.errorCode, | |
| 333 location.lineNumber, | |
| 334 location.columnNumber, | |
| 335 error.length]); | |
| 336 } | |
| 337 } | |
| 338 writer.newLine(); | |
| 339 writer.print("found "); | |
| 340 writer.print(errors.length); | |
| 341 writer.print(" errors:"); | |
| 342 for (AnalysisError error in errors) { | |
| 343 Source source = error.source; | |
| 344 LineInfo lineInfo = _lineInfoMap[source]; | |
| 345 writer.newLine(); | |
| 346 if (lineInfo == null) { | |
| 347 int offset = error.offset; | |
| 348 writer.printf(" %s %s (%d..%d): %s", [ | |
| 349 source == null ? "" : source.shortName, | |
| 350 error.errorCode, | |
| 351 offset, | |
| 352 offset + error.length, | |
| 353 error.message]); | |
| 354 } else { | |
| 355 LineInfo_Location location = lineInfo.getLocation(error.offset); | |
| 356 writer.printf(" %s %s (%d, %d/%d): %s", [ | |
| 357 source == null ? "" : source.shortName, | |
| 358 error.errorCode, | |
| 359 location.lineNumber, | |
| 360 location.columnNumber, | |
| 361 error.length, | |
| 362 error.message]); | |
| 363 } | |
| 364 } | |
| 365 JUnitTestCase.fail(writer.toString()); | |
| 366 } | |
| 367 | |
| 368 /** | |
| 369 * Search through the given list of errors for an error that is equal to the t
arget error. If one | |
| 370 * is found, remove it from the list and return `true`, otherwise return `fals
e` | |
| 371 * without modifying the list. | |
| 372 * | |
| 373 * @param errors the errors through which we are searching | |
| 374 * @param targetError the error being searched for | |
| 375 * @return `true` if the error is found and removed from the list | |
| 376 */ | |
| 377 bool foundAndRemoved(List<AnalysisError> errors, AnalysisError targetError) { | |
| 378 for (AnalysisError error in errors) { | |
| 379 if (equals3(error, targetError)) { | |
| 380 errors.remove(error); | |
| 381 return true; | |
| 382 } | |
| 383 } | |
| 384 return true; | |
| 385 } | |
| 386 } | |
| 387 /** | |
| 388 * The class `EngineTestCase` defines utility methods for making assertions. | |
| 389 */ | |
| 390 class EngineTestCase extends JUnitTestCase { | |
| 391 static int _PRINT_RANGE = 6; | |
| 392 | |
| 393 /** | |
| 394 * Assert that the tokens in the actual stream of tokens have the same types a
nd lexemes as the | |
| 395 * tokens in the expected stream of tokens. Note that this does not assert any
thing about the | |
| 396 * offsets of the tokens (although the lengths will be equal). | |
| 397 * | |
| 398 * @param expectedStream the head of the stream of tokens that were expected | |
| 399 * @param actualStream the head of the stream of tokens that were actually fou
nd | |
| 400 * @throws AssertionFailedError if the two streams of tokens are not the same | |
| 401 */ | |
| 402 static void assertAllMatch(Token expectedStream, Token actualStream) { | |
| 403 Token left = expectedStream; | |
| 404 Token right = actualStream; | |
| 405 while (left.type != TokenType.EOF && right.type != TokenType.EOF) { | |
| 406 assertMatches(left, right); | |
| 407 left = left.next; | |
| 408 right = right.next; | |
| 409 } | |
| 410 } | |
| 411 | |
| 412 /** | |
| 413 * Assert that the given array is non-`null` and contains the expected element
s. The | |
| 414 * elements can appear in any order. | |
| 415 * | |
| 416 * @param array the array being tested | |
| 417 * @param expectedElements the expected elements | |
| 418 * @throws AssertionFailedError if the array is `null` or does not contain the
expected | |
| 419 * elements | |
| 420 */ | |
| 421 static void assertContains(List<Object> array, List<Object> expectedElements)
{ | |
| 422 int expectedSize = expectedElements.length; | |
| 423 if (array == null) { | |
| 424 JUnitTestCase.fail("Expected array of length ${expectedSize}; found null")
; | |
| 425 } | |
| 426 if (array.length != expectedSize) { | |
| 427 JUnitTestCase.fail("Expected array of length ${expectedSize}; contained ${
array.length} elements"); | |
| 428 } | |
| 429 List<bool> found = new List<bool>.filled(expectedSize, false); | |
| 430 for (int i = 0; i < expectedSize; i++) { | |
| 431 assertContains2(array, found, expectedElements[i]); | |
| 432 } | |
| 433 } | |
| 434 | |
| 435 /** | |
| 436 * Assert that the array of actual values contain exactly the same values as t
hose in the array of | |
| 437 * expected value, with the exception that the order of the elements is not re
quired to be the | |
| 438 * same. | |
| 439 * | |
| 440 * @param expectedValues the values that are expected to be found | |
| 441 * @param actualValues the actual values that are being compared against the e
xpected values | |
| 442 */ | |
| 443 static void assertEqualsIgnoreOrder(List<Object> expectedValues, List<Object>
actualValues) { | |
| 444 JUnitTestCase.assertNotNull(actualValues); | |
| 445 int expectedLength = expectedValues.length; | |
| 446 JUnitTestCase.assertEquals(expectedLength, actualValues.length); | |
| 447 List<bool> found = new List<bool>.filled(expectedLength, false); | |
| 448 for (int i = 0; i < expectedLength; i++) { | |
| 449 found[i] = false; | |
| 450 } | |
| 451 for (Object actualValue in actualValues) { | |
| 452 bool wasExpected = false; | |
| 453 for (int i = 0; i < expectedLength; i++) { | |
| 454 if (!found[i] && expectedValues[i] == actualValue) { | |
| 455 found[i] = true; | |
| 456 wasExpected = true; | |
| 457 break; | |
| 458 } | |
| 459 } | |
| 460 if (!wasExpected) { | |
| 461 JUnitTestCase.fail("The actual value ${actualValue} was not expected"); | |
| 462 } | |
| 463 } | |
| 464 } | |
| 465 | |
| 466 /** | |
| 467 * Assert that a given String is equal to an expected value. | |
| 468 * | |
| 469 * @param expected the expected String value | |
| 470 * @param actual the actual String value | |
| 471 */ | |
| 472 static void assertEqualString(String expected, String actual) { | |
| 473 if (actual == null || expected == null) { | |
| 474 if (identical(actual, expected)) { | |
| 475 return; | |
| 476 } | |
| 477 if (actual == null) { | |
| 478 JUnitTestCase.assertTrueMsg("Content not as expected: is 'null' expected
: ${expected}", false); | |
| 479 } else { | |
| 480 JUnitTestCase.assertTrueMsg("Content not as expected: expected 'null' is
: ${actual}", false); | |
| 481 } | |
| 482 } | |
| 483 int diffPos = getDiffPos(expected, actual); | |
| 484 if (diffPos != -1) { | |
| 485 int diffAhead = Math.max(0, diffPos - _PRINT_RANGE); | |
| 486 int diffAfter = Math.min(actual.length, diffPos + _PRINT_RANGE); | |
| 487 String diffStr = "${actual.substring(diffAhead, diffPos)}^${actual.substri
ng(diffPos, diffAfter)}"; | |
| 488 String message = "Content not as expected: is\n${actual}\nDiffers at pos $
{diffPos}: ${diffStr}\nexpected:\n${expected}"; | |
| 489 JUnitTestCase.assertEqualsMsg(message, expected, actual); | |
| 490 } | |
| 491 } | |
| 492 | |
| 493 /** | |
| 494 * Assert that the given list is non-`null` and has exactly expected elements. | |
| 495 * | |
| 496 * @param list the list being tested | |
| 497 * @param expectedElements the expected elements | |
| 498 * @throws AssertionFailedError if the list is `null` or does not have the exp
ected elements | |
| 499 */ | |
| 500 static void assertExactElements(List list, List<Object> expectedElements) { | |
| 501 int expectedSize = expectedElements.length; | |
| 502 if (list == null) { | |
| 503 JUnitTestCase.fail("Expected list of size ${expectedSize}; found null"); | |
| 504 } | |
| 505 if (list.length != expectedSize) { | |
| 506 JUnitTestCase.fail("Expected list of size ${expectedSize}; contained ${lis
t.length} elements"); | |
| 507 } | |
| 508 for (int i = 0; i < expectedSize; i++) { | |
| 509 Object element = list[i]; | |
| 510 Object expectedElement = expectedElements[i]; | |
| 511 if (!element == expectedElement) { | |
| 512 JUnitTestCase.fail("Expected ${expectedElement} at [${i}]; found ${eleme
nt}"); | |
| 513 } | |
| 514 } | |
| 515 } | |
| 516 | |
| 517 /** | |
| 518 * Assert that the given array is non-`null` and has exactly expected elements
. | |
| 519 * | |
| 520 * @param array the array being tested | |
| 521 * @param expectedElements the expected elements | |
| 522 * @throws AssertionFailedError if the array is `null` or does not have the ex
pected | |
| 523 * elements | |
| 524 */ | |
| 525 static void assertExactElements2(List<Object> array, List<Object> expectedElem
ents) { | |
| 526 int expectedSize = expectedElements.length; | |
| 527 if (array == null) { | |
| 528 JUnitTestCase.fail("Expected array of size ${expectedSize}; found null"); | |
| 529 } | |
| 530 if (array.length != expectedSize) { | |
| 531 JUnitTestCase.fail("Expected array of size ${expectedSize}; contained ${ar
ray.length} elements"); | |
| 532 } | |
| 533 for (int i = 0; i < expectedSize; i++) { | |
| 534 Object element = array[i]; | |
| 535 Object expectedElement = expectedElements[i]; | |
| 536 if (!element == expectedElement) { | |
| 537 JUnitTestCase.fail("Expected ${expectedElement} at [${i}]; found ${eleme
nt}"); | |
| 538 } | |
| 539 } | |
| 540 } | |
| 541 | |
| 542 /** | |
| 543 * Assert that the given list is non-`null` and has exactly expected elements. | |
| 544 * | |
| 545 * @param set the list being tested | |
| 546 * @param expectedElements the expected elements | |
| 547 * @throws AssertionFailedError if the list is `null` or does not have the exp
ected elements | |
| 548 */ | |
| 549 static void assertExactElements3(Set set, List<Object> expectedElements) { | |
| 550 int expectedSize = expectedElements.length; | |
| 551 if (set == null) { | |
| 552 JUnitTestCase.fail("Expected list of size ${expectedSize}; found null"); | |
| 553 } | |
| 554 if (set.length != expectedSize) { | |
| 555 JUnitTestCase.fail("Expected list of size ${expectedSize}; contained ${set
.length} elements"); | |
| 556 } | |
| 557 for (int i = 0; i < expectedSize; i++) { | |
| 558 Object expectedElement = expectedElements[i]; | |
| 559 if (!set.contains(expectedElement)) { | |
| 560 JUnitTestCase.fail("Expected ${expectedElement} in set${set}"); | |
| 561 } | |
| 562 } | |
| 563 } | |
| 564 | |
| 565 /** | |
| 566 * Assert that the given object is an instance of the expected class. | |
| 567 * | |
| 568 * @param expectedClass the class that the object is expected to be an instanc
e of | |
| 569 * @param object the object being tested | |
| 570 * @return the object that was being tested | |
| 571 * @throws Exception if the object is not an instance of the expected class | |
| 572 */ | |
| 573 static Object assertInstanceOf(Type expectedClass, Object object) { | |
| 574 if (!isInstanceOf(object, expectedClass)) { | |
| 575 JUnitTestCase.fail("Expected instance of ${expectedClass.toString()}, foun
d ${(object == null ? "null" : object.runtimeType.toString())}"); | |
| 576 } | |
| 577 return object as Object; | |
| 578 } | |
| 579 | |
| 580 /** | |
| 581 * Assert that the given array is non-`null` and has the expected number of el
ements. | |
| 582 * | |
| 583 * @param expectedLength the expected number of elements | |
| 584 * @param array the array being tested | |
| 585 * @throws AssertionFailedError if the array is `null` or does not have the ex
pected number | |
| 586 * of elements | |
| 587 */ | |
| 588 static void assertLength(int expectedLength, List<Object> array) { | |
| 589 if (array == null) { | |
| 590 JUnitTestCase.fail("Expected array of length ${expectedLength}; found null
"); | |
| 591 } else if (array.length != expectedLength) { | |
| 592 JUnitTestCase.fail("Expected array of length ${expectedLength}; contained
${array.length} elements"); | |
| 593 } | |
| 594 } | |
| 595 | |
| 596 /** | |
| 597 * Assert that the actual token has the same type and lexeme as the expected t
oken. Note that this | |
| 598 * does not assert anything about the offsets of the tokens (although the leng
ths will be equal). | |
| 599 * | |
| 600 * @param expectedToken the token that was expected | |
| 601 * @param actualToken the token that was found | |
| 602 * @throws AssertionFailedError if the two tokens are not the same | |
| 603 */ | |
| 604 static void assertMatches(Token expectedToken, Token actualToken) { | |
| 605 JUnitTestCase.assertEquals(expectedToken.type, actualToken.type); | |
| 606 if (expectedToken is KeywordToken) { | |
| 607 assertInstanceOf(KeywordToken, actualToken); | |
| 608 JUnitTestCase.assertEquals(((expectedToken as KeywordToken)).keyword, ((ac
tualToken as KeywordToken)).keyword); | |
| 609 } else if (expectedToken is StringToken) { | |
| 610 assertInstanceOf(StringToken, actualToken); | |
| 611 JUnitTestCase.assertEquals(((expectedToken as StringToken)).lexeme, ((actu
alToken as StringToken)).lexeme); | |
| 612 } | |
| 613 } | |
| 614 | |
| 615 /** | |
| 616 * Assert that the given collection is non-`null` and has the expected number
of elements. | |
| 617 * | |
| 618 * @param expectedSize the expected number of elements | |
| 619 * @param c the collection being tested | |
| 620 * @throws AssertionFailedError if the list is `null` or does not have the exp
ected number | |
| 621 * of elements | |
| 622 */ | |
| 623 static void assertCollectionSize(int expectedSize, Iterable c) { | |
| 624 if (c == null) { | |
| 625 JUnitTestCase.fail("Expected collection of size ${expectedSize}; found nul
l"); | |
| 626 } else if (c.length != expectedSize) { | |
| 627 JUnitTestCase.fail("Expected collection of size ${expectedSize}; contained
${c.length} elements"); | |
| 628 } | |
| 629 } | |
| 630 | |
| 631 /** | |
| 632 * Assert that the given list is non-`null` and has the expected number of ele
ments. | |
| 633 * | |
| 634 * @param expectedSize the expected number of elements | |
| 635 * @param list the list being tested | |
| 636 * @throws AssertionFailedError if the list is `null` or does not have the exp
ected number | |
| 637 * of elements | |
| 638 */ | |
| 639 static void assertSize(int expectedSize, List list) { | |
| 640 if (list == null) { | |
| 641 JUnitTestCase.fail("Expected list of size ${expectedSize}; found null"); | |
| 642 } else if (list.length != expectedSize) { | |
| 643 JUnitTestCase.fail("Expected list of size ${expectedSize}; contained ${lis
t.length} elements"); | |
| 644 } | |
| 645 } | |
| 646 | |
| 647 /** | |
| 648 * Assert that the given map is non-`null` and has the expected number of elem
ents. | |
| 649 * | |
| 650 * @param expectedSize the expected number of elements | |
| 651 * @param map the map being tested | |
| 652 * @throws AssertionFailedError if the map is `null` or does not have the expe
cted number of | |
| 653 * elements | |
| 654 */ | |
| 655 static void assertSize2(int expectedSize, Map map) { | |
| 656 if (map == null) { | |
| 657 JUnitTestCase.fail("Expected map of size ${expectedSize}; found null"); | |
| 658 } else if (map.length != expectedSize) { | |
| 659 JUnitTestCase.fail("Expected map of size ${expectedSize}; contained ${map.
length} elements"); | |
| 660 } | |
| 661 } | |
| 662 | |
| 663 /** | |
| 664 * Assert that the given set is non-`null` and has the expected number of elem
ents. | |
| 665 * | |
| 666 * @param expectedSize the expected number of elements | |
| 667 * @param set the set being tested | |
| 668 * @throws AssertionFailedError if the set is `null` or does not have the expe
cted number of | |
| 669 * elements | |
| 670 */ | |
| 671 static void assertSize3(int expectedSize, Set set) { | |
| 672 if (set == null) { | |
| 673 JUnitTestCase.fail("Expected set of size ${expectedSize}; found null"); | |
| 674 } else if (set.length != expectedSize) { | |
| 675 JUnitTestCase.fail("Expected set of size ${expectedSize}; contained ${set.
length} elements"); | |
| 676 } | |
| 677 } | |
| 678 | |
| 679 /** | |
| 680 * Convert the given array of lines into a single source string. | |
| 681 * | |
| 682 * @param lines the lines to be merged into a single source string | |
| 683 * @return the source string composed of the given lines | |
| 684 */ | |
| 685 static String createSource(List<String> lines) { | |
| 686 PrintStringWriter writer = new PrintStringWriter(); | |
| 687 for (String line in lines) { | |
| 688 writer.println(line); | |
| 689 } | |
| 690 return writer.toString(); | |
| 691 } | |
| 692 | |
| 693 /** | |
| 694 * @return the [ASTNode] with requested type at offset of the "prefix". | |
| 695 */ | |
| 696 static ASTNode findNode(ASTNode root, String code, String prefix, Type clazz)
{ | |
| 697 int offset = code.indexOf(prefix); | |
| 698 if (offset == -1) { | |
| 699 throw new IllegalArgumentException("Not found '${prefix}'."); | |
| 700 } | |
| 701 ASTNode node = new NodeLocator.con1(offset).searchWithin(root); | |
| 702 return node.getAncestor(clazz); | |
| 703 } | |
| 704 static void assertContains2(List<Object> array, List<bool> found, Object eleme
nt) { | |
| 705 if (element == null) { | |
| 706 for (int i = 0; i < array.length; i++) { | |
| 707 if (!found[i]) { | |
| 708 if (array[i] == null) { | |
| 709 found[i] = true; | |
| 710 return; | |
| 711 } | |
| 712 } | |
| 713 } | |
| 714 JUnitTestCase.fail("Does not contain null"); | |
| 715 } else { | |
| 716 for (int i = 0; i < array.length; i++) { | |
| 717 if (!found[i]) { | |
| 718 if (element == array[i]) { | |
| 719 found[i] = true; | |
| 720 return; | |
| 721 } | |
| 722 } | |
| 723 } | |
| 724 JUnitTestCase.fail("Does not contain ${element}"); | |
| 725 } | |
| 726 } | |
| 727 | |
| 728 /** | |
| 729 * Calculate the offset where the given strings differ. | |
| 730 * | |
| 731 * @param str1 the first String to compare | |
| 732 * @param str2 the second String to compare | |
| 733 * @return the offset at which the strings differ (or <code>-1</code> if they
do not) | |
| 734 */ | |
| 735 static int getDiffPos(String str1, String str2) { | |
| 736 int len1 = Math.min(str1.length, str2.length); | |
| 737 int diffPos = -1; | |
| 738 for (int i = 0; i < len1; i++) { | |
| 739 if (str1.codeUnitAt(i) != str2.codeUnitAt(i)) { | |
| 740 diffPos = i; | |
| 741 break; | |
| 742 } | |
| 743 } | |
| 744 if (diffPos == -1 && str1.length != str2.length) { | |
| 745 diffPos = len1; | |
| 746 } | |
| 747 return diffPos; | |
| 748 } | |
| 749 AnalysisContextImpl createAnalysisContext() { | |
| 750 AnalysisContextImpl context = new AnalysisContextImpl(); | |
| 751 context.sourceFactory = new SourceFactory.con2([]); | |
| 752 return context; | |
| 753 } | |
| 754 | |
| 755 /** | |
| 756 * Return the getter in the given type with the given name. Inherited getters
are ignored. | |
| 757 * | |
| 758 * @param type the type in which the getter is declared | |
| 759 * @param getterName the name of the getter to be returned | |
| 760 * @return the property accessor element representing the getter with the give
n name | |
| 761 */ | |
| 762 PropertyAccessorElement getGetter(InterfaceType type, String getterName) { | |
| 763 for (PropertyAccessorElement accessor in type.element.accessors) { | |
| 764 if (accessor.isGetter && accessor.name == getterName) { | |
| 765 return accessor; | |
| 766 } | |
| 767 } | |
| 768 JUnitTestCase.fail("Could not find getter named ${getterName} in ${type.disp
layName}"); | |
| 769 return null; | |
| 770 } | |
| 771 | |
| 772 /** | |
| 773 * Return the method in the given type with the given name. Inherited methods
are ignored. | |
| 774 * | |
| 775 * @param type the type in which the method is declared | |
| 776 * @param methodName the name of the method to be returned | |
| 777 * @return the method element representing the method with the given name | |
| 778 */ | |
| 779 MethodElement getMethod(InterfaceType type, String methodName) { | |
| 780 for (MethodElement method in type.element.methods) { | |
| 781 if (method.name == methodName) { | |
| 782 return method; | |
| 783 } | |
| 784 } | |
| 785 JUnitTestCase.fail("Could not find method named ${methodName} in ${type.disp
layName}"); | |
| 786 return null; | |
| 787 } | |
| 788 static dartSuite() { | |
| 789 _ut.group('EngineTestCase', () { | |
| 790 }); | |
| 791 } | |
| 792 } | |
| 793 main() { | |
| 794 } | |
| 795 | |
| 796 class TestSource implements Source { | |
| 797 int get hashCode => 0; | |
| 798 bool operator ==(Object object) { | |
| 799 return object is TestSource; | |
| 800 } | |
| 801 AnalysisContext get context { | |
| 802 throw new UnsupportedOperationException(); | |
| 803 } | |
| 804 void getContents(Source_ContentReceiver receiver) { | |
| 805 throw new UnsupportedOperationException(); | |
| 806 } | |
| 807 String get fullName { | |
| 808 throw new UnsupportedOperationException(); | |
| 809 } | |
| 810 String get shortName { | |
| 811 throw new UnsupportedOperationException(); | |
| 812 } | |
| 813 String get encoding { | |
| 814 throw new UnsupportedOperationException(); | |
| 815 } | |
| 816 int get modificationStamp { | |
| 817 throw new UnsupportedOperationException(); | |
| 818 } | |
| 819 bool exists() => true; | |
| 820 bool get isInSystemLibrary { | |
| 821 throw new UnsupportedOperationException(); | |
| 822 } | |
| 823 Source resolve(String uri) { | |
| 824 throw new UnsupportedOperationException(); | |
| 825 } | |
| 826 Source resolveRelative(Uri uri) { | |
| 827 throw new UnsupportedOperationException(); | |
| 828 } | |
| 829 UriKind get uriKind { | |
| 830 throw new UnsupportedOperationException(); | |
| 831 } | |
| 832 } | |
| 833 | |
| 834 /** | |
| 835 * Wrapper around [Function] which should be called with "target" and "arguments
". | |
| 836 */ | |
| 837 class MethodTrampoline { | |
| 838 int parameterCount; | |
| 839 Function trampoline; | |
| 840 MethodTrampoline(this.parameterCount, this.trampoline); | |
| 841 Object invoke(target, List arguments) { | |
| 842 if (arguments.length != parameterCount) { | |
| 843 throw new IllegalArgumentException("${arguments.length} != $parameterCount
"); | |
| 844 } | |
| 845 switch (parameterCount) { | |
| 846 case 0: | |
| 847 return trampoline(target); | |
| 848 case 1: | |
| 849 return trampoline(target, arguments[0]); | |
| 850 case 2: | |
| 851 return trampoline(target, arguments[0], arguments[1]); | |
| 852 case 3: | |
| 853 return trampoline(target, arguments[0], arguments[1], arguments[2]); | |
| 854 case 4: | |
| 855 return trampoline(target, arguments[0], arguments[1], arguments[2], argu
ments[3]); | |
| 856 default: | |
| 857 throw new IllegalArgumentException("Not implemented for > 4 arguments"); | |
| 858 } | |
| 859 } | |
| 860 } | |
| OLD | NEW |