|  | // Copyright (c) 2019, 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. | 
|  |  | 
|  | import 'dart:io'; | 
|  |  | 
|  | import 'package:expect/expect.dart'; | 
|  | import 'package:test_runner/src/static_error.dart'; | 
|  |  | 
|  | import 'utils.dart'; | 
|  |  | 
|  | void main() { | 
|  | testProperties(); | 
|  | testIsWarning(); | 
|  | testCompareTo(); | 
|  | testValidate(); | 
|  | } | 
|  |  | 
|  | void testProperties() { | 
|  | var analyzer = StaticError(ErrorSource.analyzer, "E.CODE", | 
|  | path: 'test.dart', line: 1, column: 2, length: 3, sourceLines: {1, 3, 5}); | 
|  | Expect.equals(analyzer.source, ErrorSource.analyzer); | 
|  | Expect.equals(analyzer.message, "E.CODE"); | 
|  | Expect.equals(analyzer.path, 'test.dart'); | 
|  | Expect.equals(analyzer.line, 1); | 
|  | Expect.equals(analyzer.column, 2); | 
|  | Expect.equals(analyzer.length, 3); | 
|  | Expect.isTrue(analyzer.isSpecified); | 
|  | Expect.setEquals({1, 3, 5}, analyzer.sourceLines); | 
|  |  | 
|  | var cfe = StaticError(ErrorSource.cfe, "Error.", | 
|  | path: '${Directory.current.path}/test.dart', line: 4, column: 5); | 
|  | Expect.equals(cfe.source, ErrorSource.cfe); | 
|  | Expect.equals(cfe.message, "Error."); | 
|  | Expect.equals(cfe.path, 'test.dart'); // Current path gets removed. | 
|  | Expect.equals(cfe.line, 4); | 
|  | Expect.equals(cfe.column, 5); | 
|  | Expect.equals(cfe.length, 0); | 
|  | Expect.isTrue(cfe.isSpecified); | 
|  | Expect.isTrue(cfe.sourceLines.isEmpty); | 
|  |  | 
|  | var unspecified = StaticError(ErrorSource.web, "unspecified", | 
|  | path: 'test.dart', line: 1, column: 2); | 
|  | Expect.isFalse(unspecified.isSpecified); | 
|  | } | 
|  |  | 
|  | void testIsWarning() { | 
|  | // Analyzer only. | 
|  | Expect.isTrue( | 
|  | makeError(analyzerError: "STATIC_WARNING.INVALID_OPTION").isWarning); | 
|  | Expect.isFalse( | 
|  | makeError(analyzerError: "SYNTACTIC_ERROR.MISSING_FUNCTION_BODY") | 
|  | .isWarning); | 
|  | Expect.isFalse(makeError( | 
|  | analyzerError: "COMPILE_TIME_ERROR.NOT_ENOUGH_POSITIONAL_ARGUMENTS") | 
|  | .isWarning); | 
|  |  | 
|  | // CFE only. | 
|  | Expect.isFalse(makeError(cfeError: "Any error message.").isWarning); | 
|  |  | 
|  | // Web only. | 
|  | Expect.isFalse(makeError(webError: "Any error message.").isWarning); | 
|  | } | 
|  |  | 
|  | void testCompareTo() { | 
|  | var errors = [ | 
|  | // Order by line. | 
|  | makeError(line: 1, column: 2, length: 2, cfeError: "E."), | 
|  | makeError(line: 2, column: 1, length: 1, cfeError: "E."), | 
|  |  | 
|  | // Then column. | 
|  | makeError(line: 3, column: 1, length: 2, cfeError: "E."), | 
|  | makeError(line: 3, column: 2, length: 1, cfeError: "E."), | 
|  |  | 
|  | // Then length. | 
|  | makeError(line: 4, column: 1, length: 1, cfeError: "Z."), | 
|  | makeError(line: 4, column: 1, length: 2, cfeError: "A."), | 
|  |  | 
|  | // Then source. | 
|  | makeError(line: 5, column: 1, length: 1, analyzerError: "Z.CODE"), | 
|  | makeError(line: 5, column: 1, length: 1, cfeError: "A."), | 
|  |  | 
|  | // Then message. | 
|  | makeError(line: 6, column: 1, length: 1, cfeError: "A."), | 
|  | makeError(line: 6, column: 1, length: 1, cfeError: "Z."), | 
|  | ]; | 
|  |  | 
|  | // Every pair of errors in the array should be ordered correctly. | 
|  | for (var i = 0; i < errors.length; i++) { | 
|  | for (var j = 0; j < errors.length; j++) { | 
|  | var expected = (i - j).sign; | 
|  | Expect.equals(expected, errors[i].compareTo(errors[j]), | 
|  | "Expected $expected comparison for:\n${errors[i]}\n${errors[j]}"); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void testValidate() { | 
|  | // No errors. | 
|  | expectValidate([], [], null); | 
|  |  | 
|  | // Same errors. | 
|  | expectValidate([ | 
|  | makeError(line: 1, column: 2, length: 3, analyzerError: "ERR.A"), | 
|  | makeError(line: 2, column: 2, length: 3, analyzerError: "ERR.B"), | 
|  | makeError(line: 3, column: 2, length: 3, analyzerError: "ERR.C"), | 
|  | ], [ | 
|  | // Order doesn't matter. | 
|  | makeError(line: 3, column: 2, length: 3, analyzerError: "ERR.C"), | 
|  | makeError(line: 1, column: 2, length: 3, analyzerError: "ERR.A"), | 
|  | makeError(line: 2, column: 2, length: 3, analyzerError: "ERR.B"), | 
|  | ], null); | 
|  |  | 
|  | // Catches differences in any field. | 
|  | expectValidate([ | 
|  | makeError(line: 1, column: 2, length: 3, analyzerError: "ERR.A"), | 
|  | makeError(line: 2, column: 2, length: 3, analyzerError: "ERR.B"), | 
|  | makeError(line: 3, column: 2, length: 3, analyzerError: "ERR.C"), | 
|  | ], [ | 
|  | makeError(line: 1, column: 9, length: 3, analyzerError: "ERR.A"), | 
|  | makeError(line: 2, column: 2, length: 9, analyzerError: "ERR.B"), | 
|  | makeError(line: 3, column: 2, length: 3, analyzerError: "ERR.Z"), | 
|  | ], """ | 
|  | - Wrong error location test.dart line 1, column 2, length 3: ERR.A | 
|  | Expected column 2 but was column 9. | 
|  |  | 
|  | - Wrong error location test.dart line 2, column 2, length 3: ERR.B | 
|  | Expected length 3 but was length 9. | 
|  |  | 
|  | - Wrong message at test.dart line 3, column 2, length 3: ERR.Z | 
|  | Expected: ERR.C"""); | 
|  |  | 
|  | expectValidate([ | 
|  | makeError(line: 4, column: 2, length: 3, cfeError: "Four."), | 
|  | ], [ | 
|  | makeError(line: 4, column: 2, length: 3, cfeError: "Zzz."), | 
|  | ], """ | 
|  | - Wrong message at test.dart line 4, column 2, length 3: Zzz. | 
|  | Expected: Four."""); | 
|  |  | 
|  | expectValidate([ | 
|  | makeError(line: 5, column: 2, length: 3, webError: "Web 5."), | 
|  | ], [ | 
|  | makeError(line: 5, column: 2, length: 3, webError: "Web Z."), | 
|  | ], """ | 
|  | - Wrong message at test.dart line 5, column 2, length 3: Web Z. | 
|  | Expected: Web 5."""); | 
|  |  | 
|  | // Unexpected errors. | 
|  | expectValidate([ | 
|  | makeError(line: 2, column: 2, length: 3, cfeError: "One."), | 
|  | makeError(line: 4, column: 2, length: 3, cfeError: "Two."), | 
|  | makeError(line: 6, column: 2, length: 3, cfeError: "Tres."), | 
|  | ], [ | 
|  | makeError(line: 1, column: 2, length: 3, cfeError: "1."), | 
|  | makeError(line: 2, column: 2, length: 3, cfeError: "One."), | 
|  | makeError(line: 3, column: 2, length: 3, cfeError: "3."), | 
|  | makeError(line: 4, column: 2, length: 3, cfeError: "Two."), | 
|  | makeError(line: 5, column: 2, length: 3, cfeError: "5."), | 
|  | makeError(line: 6, column: 2, length: 3, cfeError: "Tres."), | 
|  | makeError(line: 7, column: 2, length: 3, cfeError: "7."), | 
|  | ], """ | 
|  | - Unexpected error at test.dart line 1, column 2, length 3: 1. | 
|  |  | 
|  | - Unexpected error at test.dart line 3, column 2, length 3: 3. | 
|  |  | 
|  | - Unexpected error at test.dart line 5, column 2, length 3: 5. | 
|  |  | 
|  | - Unexpected error at test.dart line 7, column 2, length 3: 7."""); | 
|  |  | 
|  | // Missing errors. | 
|  | expectValidate([ | 
|  | makeError(line: 1, column: 2, length: 3, analyzerError: "ERR.A"), | 
|  | makeError(line: 2, column: 2, length: 3, analyzerError: "ERR.B"), | 
|  | makeError(line: 3, column: 2, length: 3, analyzerError: "ERR.C"), | 
|  | makeError(line: 4, column: 2, length: 3, analyzerError: "ERR.D"), | 
|  | makeError(line: 5, column: 2, length: 3, analyzerError: "ERR.E"), | 
|  | ], [ | 
|  | makeError(line: 2, column: 2, length: 3, analyzerError: "ERR.B"), | 
|  | makeError(line: 4, column: 2, length: 3, analyzerError: "ERR.D"), | 
|  | ], """ | 
|  | - Missing expected error at test.dart line 1, column 2, length 3: ERR.A | 
|  |  | 
|  | - Missing expected error at test.dart line 3, column 2, length 3: ERR.C | 
|  |  | 
|  | - Missing expected error at test.dart line 5, column 2, length 3: ERR.E"""); | 
|  |  | 
|  | // Unspecified errors. | 
|  | expectValidate([ | 
|  | // Missing. | 
|  | makeError(line: 2, column: 2, length: 3, cfeError: "unspecified"), | 
|  |  | 
|  | // Right. | 
|  | makeError(line: 6, column: 2, length: 3, cfeError: "unspecified"), | 
|  | ], [ | 
|  | makeError(line: 6, column: 2, length: 3, cfeError: "Actual 1."), | 
|  |  | 
|  | // Unexpected. | 
|  | makeError(line: 9, column: 9, length: 3, cfeError: "Actual 2."), | 
|  | ], """ | 
|  | - Missing expected unspecified error at test.dart line 2, column 2, length 3. | 
|  |  | 
|  | - Unexpected error at test.dart line 9, column 9, length 3: Actual 2."""); | 
|  |  | 
|  | // Unspecified errors can match multiple errors on the same line. | 
|  | expectValidate([ | 
|  | makeError(line: 1, column: 2, length: 3, analyzerError: "unspecified"), | 
|  | ], [ | 
|  | makeError(line: 1, column: 1, length: 3, analyzerError: "ERROR.CODE1"), | 
|  | makeError(line: 1, column: 2, length: 3, analyzerError: "ERROR.CODE2"), | 
|  | makeError(line: 1, column: 3, length: 3, analyzerError: "ERROR.CODE3"), | 
|  | ], null); | 
|  |  | 
|  | expectValidate([ | 
|  | makeError(line: 1, column: 2, length: 3, cfeError: "unspecified"), | 
|  | ], [ | 
|  | makeError(line: 1, column: 1, length: 3, cfeError: "Actual 1."), | 
|  | makeError(line: 1, column: 2, length: 3, cfeError: "Actual 2."), | 
|  | makeError(line: 1, column: 3, length: 3, cfeError: "Actual 3."), | 
|  | ], null); | 
|  |  | 
|  | expectValidate([ | 
|  | makeError(line: 1, column: 2, length: 3, webError: "unspecified"), | 
|  | ], [ | 
|  | makeError(line: 1, column: 1, length: 3, webError: "Web 1."), | 
|  | makeError(line: 1, column: 2, length: 3, webError: "Web 2."), | 
|  | makeError(line: 1, column: 3, length: 3, webError: "Web 3."), | 
|  | ], null); | 
|  |  | 
|  | // Same message. | 
|  | expectValidate([ | 
|  | makeError(line: 1, column: 2, length: 1, cfeError: "message"), | 
|  | makeError(line: 2, column: 3, length: 2, cfeError: "message"), | 
|  | ], [ | 
|  | makeError(line: 1, column: 2, length: 1, cfeError: "message"), | 
|  | makeError(line: 2, column: 3, length: 2, cfeError: "message"), | 
|  | makeError(line: 3, column: 3, length: 3, cfeError: "message"), | 
|  | ], '- Unexpected error at test.dart line 3, column 3, length 3: message'); | 
|  |  | 
|  | // Same location. | 
|  | expectValidate([ | 
|  | makeError(line: 1, column: 2, length: 1, cfeError: "message 1"), | 
|  | makeError(line: 1, column: 2, length: 1, cfeError: "message 2"), | 
|  | ], [ | 
|  | makeError(line: 1, column: 2, length: 1, cfeError: "wrong 1"), | 
|  | makeError(line: 1, column: 2, length: 1, cfeError: "wrong 2"), | 
|  | makeError(line: 1, column: 2, length: 1, cfeError: "wrong 3"), | 
|  | ], ''' | 
|  | - Wrong message at test.dart line 1, column 2, length 1: wrong 1 | 
|  | Expected: message 1 | 
|  |  | 
|  | - Wrong message at test.dart line 1, column 2, length 1: wrong 2 | 
|  | Expected: message 2 | 
|  |  | 
|  | - Unexpected error at test.dart line 1, column 2, length 1: wrong 3'''); | 
|  |  | 
|  | // Prefer match over wrong message. | 
|  | expectValidate([ | 
|  | makeError(line: 10, column: 1, length: 1, cfeError: "match"), | 
|  | makeError(line: 10, column: 1, length: 1, cfeError: "a wrong message"), | 
|  | ], [ | 
|  | makeError(line: 1, column: 1, length: 1, cfeError: /* not a */ "match"), | 
|  | makeError(line: 10, column: 1, length: 1, cfeError: "match"), | 
|  | ], ''' | 
|  | - Missing expected error at test.dart line 10, column 1, length 1: a wrong message | 
|  |  | 
|  | - Unexpected error at test.dart line 1, column 1, length 1: match'''); | 
|  |  | 
|  | // Combined. | 
|  | expectValidate([ | 
|  | makeError(line: 10, column: 1, length: 1, cfeError: "match"), | 
|  | makeError(line: 20, column: 2, length: 2, cfeError: "missing"), | 
|  | makeError(line: 20, column: 2, length: 2, cfeError: "message"), | 
|  | makeError(line: 30, column: 3, length: 3, cfeError: "wrong location"), | 
|  | makeError(line: 40, column: 4, length: 4, cfeError: "match"), | 
|  | ], [ | 
|  | makeError(line: 1, column: 2, length: 1, cfeError: "unexpected"), | 
|  | makeError(line: 10, column: 3, length: 3, cfeError: "wrong location"), | 
|  | makeError(line: 20, column: 2, length: 2, cfeError: "wrong message"), | 
|  | makeError(line: 10, column: 1, length: 1, cfeError: "match"), | 
|  | makeError(line: 40, column: 4, length: 4, cfeError: "match"), | 
|  | ], ''' | 
|  | - Wrong error location test.dart line 30, column 3, length 3: wrong location | 
|  | Expected line 30 but was line 10. | 
|  |  | 
|  | - Wrong message at test.dart line 20, column 2, length 2: wrong message | 
|  | Expected: message | 
|  |  | 
|  | - Missing expected error at test.dart line 20, column 2, length 2: missing | 
|  |  | 
|  | - Unexpected error at test.dart line 1, column 2, length 1: unexpected'''); | 
|  |  | 
|  | // If expectation has context, actual must match it. | 
|  | expectValidate([ | 
|  | makeError(line: 1, column: 2, length: 3, cfeError: "Error.", context: [ | 
|  | makeError(line: 4, column: 5, length: 6, contextError: "Context A."), | 
|  | makeError(line: 7, column: 8, length: 9, contextError: "Context B."), | 
|  | ]), | 
|  | ], [ | 
|  | makeError(line: 1, column: 2, length: 3, cfeError: "Error.", context: [ | 
|  | makeError(line: 4, column: 5, length: 6, contextError: "Context A."), | 
|  | makeError(line: 7, column: 8, length: 9, contextError: "Context B."), | 
|  | ]), | 
|  | ], null); | 
|  |  | 
|  | // Actual context is different. | 
|  | expectValidate([ | 
|  | makeError(line: 1, column: 2, length: 3, cfeError: "Error.", context: [ | 
|  | makeError(line: 4, column: 5, length: 6, contextError: "Context A."), | 
|  | ]), | 
|  | ], [ | 
|  | makeError(line: 1, column: 2, length: 3, cfeError: "Error.", context: [ | 
|  | makeError(line: 4, column: 5, length: 6, contextError: "Context Z."), | 
|  | ]), | 
|  | ], """ | 
|  | - Wrong context message at test.dart line 4, column 5, length 6: Context Z. | 
|  | Expected: Context A."""); | 
|  |  | 
|  | // Missing some actual context. | 
|  | expectValidate([ | 
|  | makeError(line: 1, column: 2, length: 3, cfeError: "Error.", context: [ | 
|  | makeError(line: 4, column: 5, length: 6, contextError: "Context A."), | 
|  | makeError(line: 7, column: 8, length: 9, contextError: "Context B."), | 
|  | ]), | 
|  | ], [ | 
|  | makeError(line: 1, column: 2, length: 3, cfeError: "Error.", context: [ | 
|  | makeError(line: 7, column: 8, length: 9, contextError: "Context B."), | 
|  | ]), | 
|  | ], """ | 
|  | - Missing expected context message at test.dart line 4, column 5, length 6: Context A."""); | 
|  |  | 
|  | // Missing all actual context. | 
|  | expectValidate([ | 
|  | makeError(line: 1, column: 2, length: 3, cfeError: "Error.", context: [ | 
|  | makeError(line: 4, column: 5, length: 6, contextError: "Context A."), | 
|  | makeError(line: 7, column: 8, length: 9, contextError: "Context B."), | 
|  | ]), | 
|  | ], [ | 
|  | makeError(line: 1, column: 2, length: 3, cfeError: "Error."), | 
|  | ], """ | 
|  | - Missing expected context message at test.dart line 4, column 5, length 6: Context A. | 
|  |  | 
|  | - Missing expected context message at test.dart line 7, column 8, length 9: Context B."""); | 
|  |  | 
|  | // Unexpected extra actual context. | 
|  | expectValidate([ | 
|  | makeError(line: 1, column: 2, length: 3, cfeError: "Error.", context: [ | 
|  | makeError(line: 4, column: 5, length: 6, contextError: "Context A."), | 
|  | ]), | 
|  | ], [ | 
|  | makeError(line: 1, column: 2, length: 3, cfeError: "Error.", context: [ | 
|  | makeError(line: 4, column: 5, length: 6, contextError: "Context A."), | 
|  | makeError(line: 7, column: 8, length: 9, contextError: "Context B."), | 
|  | ]), | 
|  | ], """ | 
|  | - Unexpected context message at test.dart line 7, column 8, length 9: Context B."""); | 
|  |  | 
|  | // Actual context owned by wrong error. | 
|  | // TODO(rnystrom): This error is pretty confusing. Ideally we would detect | 
|  | // this case specifically and give better guidance. | 
|  | expectValidate([ | 
|  | makeError(line: 1, column: 2, length: 3, cfeError: "Error A.", context: [ | 
|  | makeError(line: 4, column: 5, length: 6, contextError: "Context A."), | 
|  | makeError(line: 33, column: 5, length: 6, contextError: "Context."), | 
|  | ]), | 
|  | makeError(line: 10, column: 2, length: 3, cfeError: "Error B.", context: [ | 
|  | makeError(line: 11, column: 5, length: 6, contextError: "Context B."), | 
|  | ]), | 
|  | ], [ | 
|  | makeError(line: 1, column: 2, length: 3, cfeError: "Error A.", context: [ | 
|  | makeError(line: 4, column: 5, length: 6, contextError: "Context A."), | 
|  | ]), | 
|  | makeError(line: 10, column: 2, length: 3, cfeError: "Error B.", context: [ | 
|  | makeError(line: 11, column: 5, length: 6, contextError: "Context B."), | 
|  | makeError(line: 33, column: 5, length: 6, contextError: "Context."), | 
|  | ]), | 
|  | ], """ | 
|  | - Missing expected context message at test.dart line 33, column 5, length 6: Context. | 
|  |  | 
|  | - Unexpected context message at test.dart line 33, column 5, length 6: Context."""); | 
|  |  | 
|  | // If expectation has no context at all, then ignore actual context. | 
|  | expectValidate([ | 
|  | makeError(line: 1, column: 2, length: 3, cfeError: "Error."), | 
|  | ], [ | 
|  | makeError(line: 1, column: 2, length: 3, cfeError: "Error.", context: [ | 
|  | makeError(line: 4, column: 5, length: 6, contextError: "Context A."), | 
|  | makeError(line: 7, column: 8, length: 9, contextError: "Context B."), | 
|  | ]), | 
|  | ], null); | 
|  | } | 
|  |  | 
|  | void expectValidate(List<StaticError> expected, List<StaticError> actual, | 
|  | String? expectedValidation) { | 
|  | var actualValidation = StaticError.validateExpectations(expected, actual); | 
|  | if (expectedValidation == null) { | 
|  | Expect.isNull(actualValidation); | 
|  | } else { | 
|  | Expect.isNotNull(actualValidation); | 
|  | Expect.stringEquals(expectedValidation, actualValidation!); | 
|  | } | 
|  | } |