| Index: pkg/analysis_services/test/correction/fix_test.dart
|
| diff --git a/pkg/analysis_services/test/correction/fix_test.dart b/pkg/analysis_services/test/correction/fix_test.dart
|
| index f7f600503dd5b30287bbdad65e088207b3d7532c..6fdf85b1bc9998978992e2eca16d4a3c44213716 100644
|
| --- a/pkg/analysis_services/test/correction/fix_test.dart
|
| +++ b/pkg/analysis_services/test/correction/fix_test.dart
|
| @@ -32,15 +32,55 @@ class FixProcessorTest extends AbstractSingleUnitTest {
|
| Index index;
|
| SearchEngineImpl searchEngine;
|
|
|
| + Fix fix;
|
| + Change change;
|
| + String resultCode;
|
| +
|
| void assertHasFix(FixKind kind, String expected) {
|
| AnalysisError error = _findErrorToFix();
|
| - Fix fix = _computeFix(kind, error);
|
| + fix = _assertHasFix(kind, error);
|
| + change = fix.change;
|
| // apply to "file"
|
| - List<FileEdit> fileEdits = fix.change.edits;
|
| + List<FileEdit> fileEdits = change.edits;
|
| expect(fileEdits, hasLength(1));
|
| - String actualCode = _applyEdits(testCode, fix.change.edits[0].edits);
|
| + resultCode = _applyEdits(testCode, change.edits[0].edits);
|
| // verify
|
| - expect(expected, actualCode);
|
| + expect(resultCode, expected);
|
| + }
|
| +
|
| + void assertHasPositionGroup(String id, List<Position> expectedPositions) {
|
| + List<PositionGroup> positionGroups = change.positionGroups;
|
| + for (PositionGroup group in positionGroups) {
|
| + if (group.id == id) {
|
| + expect(group.positions, unorderedEquals(expectedPositions));
|
| + return;
|
| + }
|
| + }
|
| + fail('No PositionGroup with id=$id found in $positionGroups');
|
| + }
|
| +
|
| + void assertNoFix(FixKind kind) {
|
| + AnalysisError error = _findErrorToFix();
|
| + List<Fix> fixes = computeFixes(searchEngine, testFile, testUnit, error);
|
| + for (Fix fix in fixes) {
|
| + if (fix.kind == kind) {
|
| + throw fail('Unexpected fix $kind in\n${fixes.join('\n')}');
|
| + }
|
| + }
|
| + }
|
| +
|
| + Position expectedPosition(String search) {
|
| + int offset = resultCode.indexOf(search);
|
| + int length = getLeadingIdentifierLength(search);
|
| + return new Position(testFile, offset, length);
|
| + }
|
| +
|
| + List<Position> expectedPositions(List<String> patterns) {
|
| + List<Position> positions = <Position>[];
|
| + patterns.forEach((String search) {
|
| + positions.add(expectedPosition(search));
|
| + });
|
| + return positions;
|
| }
|
|
|
| void setUp() {
|
| @@ -63,6 +103,387 @@ main() {
|
| ''');
|
| }
|
|
|
| + void test_changeToStaticAccess_method() {
|
| + _indexTestUnit('''
|
| +class A {
|
| + static foo() {}
|
| +}
|
| +main(A a) {
|
| + a.foo();
|
| +}
|
| +''');
|
| + assertHasFix(FixKind.CHANGE_TO_STATIC_ACCESS, '''
|
| +class A {
|
| + static foo() {}
|
| +}
|
| +main(A a) {
|
| + A.foo();
|
| +}
|
| +''');
|
| + }
|
| +
|
| + void test_changeToStaticAccess_method_prefixLibrary() {
|
| + _indexTestUnit('''
|
| +import 'dart:async' as pref;
|
| +main(pref.Future f) {
|
| + f.wait([]);
|
| +}
|
| +''');
|
| + assertHasFix(FixKind.CHANGE_TO_STATIC_ACCESS, '''
|
| +import 'dart:async' as pref;
|
| +main(pref.Future f) {
|
| + pref.Future.wait([]);
|
| +}
|
| +''');
|
| + }
|
| +
|
| + void test_changeToStaticAccess_property() {
|
| + _indexTestUnit('''
|
| +class A {
|
| + static get foo => 42;
|
| +}
|
| +main(A a) {
|
| + a.foo;
|
| +}
|
| +''');
|
| + assertHasFix(FixKind.CHANGE_TO_STATIC_ACCESS, '''
|
| +class A {
|
| + static get foo => 42;
|
| +}
|
| +main(A a) {
|
| + A.foo;
|
| +}
|
| +''');
|
| + }
|
| +
|
| + void test_createClass() {
|
| + _indexTestUnit('''
|
| +main() {
|
| + Test v = null;
|
| +}
|
| +''');
|
| + assertHasFix(FixKind.CREATE_CLASS, '''
|
| +main() {
|
| + Test v = null;
|
| +}
|
| +
|
| +class Test {
|
| +}
|
| +''');
|
| + assertHasPositionGroup('NAME', expectedPositions(['Test v =', 'Test {']));
|
| + }
|
| +
|
| + void test_createConstructorSuperExplicit() {
|
| + _indexTestUnit('''
|
| +class A {
|
| + A(bool p1, int p2, double p3, String p4, {p5});
|
| +}
|
| +class B extends A {
|
| + B() {}
|
| +}
|
| +''');
|
| + assertHasFix(FixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, '''
|
| +class A {
|
| + A(bool p1, int p2, double p3, String p4, {p5});
|
| +}
|
| +class B extends A {
|
| + B() : super(false, 0, 0.0, '') {}
|
| +}
|
| +''');
|
| + }
|
| +
|
| + void test_createConstructorSuperExplicit_hasInitializers() {
|
| + _indexTestUnit('''
|
| +class A {
|
| + A(int p);
|
| +}
|
| +class B extends A {
|
| + int field;
|
| + B() : field = 42 {}
|
| +}
|
| +''');
|
| + assertHasFix(FixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, '''
|
| +class A {
|
| + A(int p);
|
| +}
|
| +class B extends A {
|
| + int field;
|
| + B() : field = 42, super(0) {}
|
| +}
|
| +''');
|
| + }
|
| +
|
| + void test_createConstructorSuperExplicit_named() {
|
| + _indexTestUnit('''
|
| +class A {
|
| + A.named(int p);
|
| +}
|
| +class B extends A {
|
| + B() {}
|
| +}
|
| +''');
|
| + assertHasFix(FixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, '''
|
| +class A {
|
| + A.named(int p);
|
| +}
|
| +class B extends A {
|
| + B() : super.named(0) {}
|
| +}
|
| +''');
|
| + }
|
| +
|
| + void test_createConstructorSuperExplicit_named_private() {
|
| + _indexTestUnit('''
|
| +class A {
|
| + A._named(int p);
|
| +}
|
| +class B extends A {
|
| + B() {}
|
| +}
|
| +''');
|
| + assertNoFix(FixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION);
|
| + }
|
| +
|
| + void test_createConstructor_insteadOfSyntheticDefault() {
|
| + _indexTestUnit('''
|
| +class A {
|
| + int field;
|
| +
|
| + method() {}
|
| +}
|
| +main() {
|
| + new A(1, 2.0);
|
| +}
|
| +''');
|
| + assertHasFix(FixKind.CREATE_CONSTRUCTOR, '''
|
| +class A {
|
| + int field;
|
| +
|
| + A(int i, double d) {
|
| + }
|
| +
|
| + method() {}
|
| +}
|
| +main() {
|
| + new A(1, 2.0);
|
| +}
|
| +''');
|
| + }
|
| +
|
| + void test_createConstructor_named() {
|
| + _indexTestUnit('''
|
| +class A {
|
| + method() {}
|
| +}
|
| +main() {
|
| + new A.named(1, 2.0);
|
| +}
|
| +''');
|
| + assertHasFix(FixKind.CREATE_CONSTRUCTOR, '''
|
| +class A {
|
| + A.named(int i, double d) {
|
| + }
|
| +
|
| + method() {}
|
| +}
|
| +main() {
|
| + new A.named(1, 2.0);
|
| +}
|
| +''');
|
| + }
|
| +
|
| + void test_expectedToken_semicolon() {
|
| + _indexTestUnit('''
|
| +main() {
|
| + print(0)
|
| +}
|
| +''');
|
| + assertHasFix(FixKind.INSERT_SEMICOLON, '''
|
| +main() {
|
| + print(0);
|
| +}
|
| +''');
|
| + }
|
| +
|
| + void test_isNotNull() {
|
| + _indexTestUnit('''
|
| +main(p) {
|
| + p is! Null;
|
| +}
|
| +''');
|
| + assertHasFix(FixKind.USE_NOT_EQ_NULL, '''
|
| +main(p) {
|
| + p != null;
|
| +}
|
| +''');
|
| + }
|
| +
|
| + void test_isNull() {
|
| + _indexTestUnit('''
|
| +main(p) {
|
| + p is Null;
|
| +}
|
| +''');
|
| + assertHasFix(FixKind.USE_EQ_EQ_NULL, '''
|
| +main(p) {
|
| + p == null;
|
| +}
|
| +''');
|
| + }
|
| +
|
| + void test_makeEnclosingClassAbstract_declaresAbstractMethod() {
|
| + _indexTestUnit('''
|
| +class A {
|
| + m();
|
| +}
|
| +''');
|
| + assertHasFix(FixKind.MAKE_CLASS_ABSTRACT, '''
|
| +abstract class A {
|
| + m();
|
| +}
|
| +''');
|
| + }
|
| +
|
| + void test_makeEnclosingClassAbstract_inheritsAbstractMethod() {
|
| + _indexTestUnit('''
|
| +abstract class A {
|
| + m();
|
| +}
|
| +class B extends A {
|
| +}
|
| +''');
|
| + assertHasFix(FixKind.MAKE_CLASS_ABSTRACT, '''
|
| +abstract class A {
|
| + m();
|
| +}
|
| +abstract class B extends A {
|
| +}
|
| +''');
|
| + }
|
| +
|
| + void test_removeParentheses_inGetterDeclaration() {
|
| + _indexTestUnit('''
|
| +class A {
|
| + int get foo() => 0;
|
| +}
|
| +''');
|
| + assertHasFix(FixKind.REMOVE_PARAMETERS_IN_GETTER_DECLARATION, '''
|
| +class A {
|
| + int get foo => 0;
|
| +}
|
| +''');
|
| + }
|
| +
|
| + void test_removeParentheses_inGetterInvocation() {
|
| + _indexTestUnit('''
|
| +class A {
|
| + int get foo => 0;
|
| +}
|
| +main(A a) {
|
| + a.foo();
|
| +}
|
| +''');
|
| + assertHasFix(FixKind.REMOVE_PARENTHESIS_IN_GETTER_INVOCATION, '''
|
| +class A {
|
| + int get foo => 0;
|
| +}
|
| +main(A a) {
|
| + a.foo;
|
| +}
|
| +''');
|
| + }
|
| +
|
| + void test_removeUnnecessaryCast_assignment() {
|
| + _indexTestUnit('''
|
| +main(Object p) {
|
| + if (p is String) {
|
| + String v = ((p as String));
|
| + }
|
| +}
|
| +''');
|
| + assertHasFix(FixKind.REMOVE_UNNECASSARY_CAST, '''
|
| +main(Object p) {
|
| + if (p is String) {
|
| + String v = p;
|
| + }
|
| +}
|
| +''');
|
| + }
|
| +
|
| + void test_removeUnusedImport() {
|
| + _indexTestUnit('''
|
| +import 'dart:math';
|
| +main() {
|
| +}
|
| +''');
|
| + assertHasFix(FixKind.REMOVE_UNUSED_IMPORT, '''
|
| +main() {
|
| +}
|
| +''');
|
| + }
|
| +
|
| + void test_removeUnusedImport_anotherImportOnLine() {
|
| + _indexTestUnit('''
|
| +import 'dart:math'; import 'dart:async';
|
| +
|
| +main() {
|
| + Future f;
|
| +}
|
| +''');
|
| + assertHasFix(FixKind.REMOVE_UNUSED_IMPORT, '''
|
| +import 'dart:async';
|
| +
|
| +main() {
|
| + Future f;
|
| +}
|
| +''');
|
| + }
|
| +
|
| + void test_removeUnusedImport_severalLines() {
|
| + _indexTestUnit('''
|
| +import
|
| + 'dart:math';
|
| +main() {
|
| +}
|
| +''');
|
| + assertHasFix(FixKind.REMOVE_UNUSED_IMPORT, '''
|
| +main() {
|
| +}
|
| +''');
|
| + }
|
| +
|
| + void test_replaceWithConstInstanceCreation() {
|
| + _indexTestUnit('''
|
| +class A {
|
| + const A();
|
| +}
|
| +const a = new A();
|
| +''');
|
| + assertHasFix(FixKind.USE_CONST, '''
|
| +class A {
|
| + const A();
|
| +}
|
| +const a = const A();
|
| +''');
|
| + }
|
| +
|
| + void test_useEffectiveIntegerDivision() {
|
| + _indexTestUnit('''
|
| +main() {
|
| + var a = 5;
|
| + var b = 2;
|
| + print((a / b).toInt());
|
| +}
|
| +''');
|
| + assertHasFix(FixKind.USE_EFFECTIVE_INTEGER_DIVISION, '''
|
| +main() {
|
| + var a = 5;
|
| + var b = 2;
|
| + print(a ~/ b);
|
| +}
|
| +''');
|
| + }
|
| +
|
| String _applyEdits(String code, List<Edit> edits) {
|
| edits.sort((a, b) => b.offset - a.offset);
|
| edits.forEach((Edit edit) {
|
| @@ -73,7 +494,10 @@ main() {
|
| return code;
|
| }
|
|
|
| - Fix _computeFix(FixKind kind, AnalysisError error) {
|
| + /**
|
| + * Computes fixes and verifies that there is a fix of the given kind.
|
| + */
|
| + Fix _assertHasFix(FixKind kind, AnalysisError error) {
|
| List<Fix> fixes = computeFixes(searchEngine, testFile, testUnit, error);
|
| for (Fix fix in fixes) {
|
| if (fix.kind == kind) {
|
| @@ -84,7 +508,7 @@ main() {
|
| }
|
|
|
| AnalysisError _findErrorToFix() {
|
| - List<AnalysisError> errors = context.getErrors(testSource).errors;
|
| + List<AnalysisError> errors = context.computeErrors(testSource);
|
| expect(
|
| errors,
|
| hasLength(1),
|
|
|