| 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 test.services.refactoring.inline_method; | 5 library test.services.refactoring.inline_method; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:analysis_server/src/protocol.dart' hide Element; | 9 import 'package:analysis_server/src/protocol.dart' hide Element; |
| 10 import 'package:analysis_server/src/services/refactoring/inline_method.dart'; | 10 import 'package:analysis_server/src/services/refactoring/inline_method.dart'; |
| 11 import 'package:analysis_server/src/services/refactoring/refactoring.dart'; | 11 import 'package:analysis_server/src/services/refactoring/refactoring.dart'; |
| 12 import 'package:analyzer/src/generated/source.dart'; | 12 import 'package:analyzer/src/generated/source.dart'; |
| 13 import 'package:unittest/unittest.dart'; | 13 import 'package:unittest/unittest.dart'; |
| 14 | 14 |
| 15 import '../../reflective_tests.dart'; | 15 import '../../reflective_tests.dart'; |
| 16 import 'abstract_refactoring.dart'; | 16 import 'abstract_refactoring.dart'; |
| 17 import 'package:analysis_server/src/services/correction/status.dart'; |
| 17 | 18 |
| 18 | 19 |
| 19 main() { | 20 main() { |
| 20 groupSep = ' | '; | 21 groupSep = ' | '; |
| 21 runReflectiveTests(InlineMethodTest); | 22 runReflectiveTests(InlineMethodTest); |
| 22 } | 23 } |
| 23 | 24 |
| 24 | 25 |
| 25 @reflectiveTest | 26 @reflectiveTest |
| 26 class InlineMethodTest extends RefactoringTest { | 27 class InlineMethodTest extends RefactoringTest { |
| 27 InlineMethodRefactoringImpl refactoring; | 28 InlineMethodRefactoringImpl refactoring; |
| 28 bool deleteSource; | 29 bool deleteSource; |
| 29 bool inlineAll; | 30 bool inlineAll; |
| 30 | 31 |
| 31 test_access_FunctionElement() { | 32 test_access_FunctionElement() async { |
| 32 indexTestUnit(r''' | 33 indexTestUnit(r''' |
| 33 test(a, b) { | 34 test(a, b) { |
| 34 return a + b; | 35 return a + b; |
| 35 } | 36 } |
| 36 main() { | 37 main() { |
| 37 var res = test(1, 2); | 38 var res = test(1, 2); |
| 38 } | 39 } |
| 39 '''); | 40 '''); |
| 40 _createRefactoring('test(1, 2)'); | 41 _createRefactoring('test(1, 2)'); |
| 41 // validate state | 42 // validate state |
| 42 return refactoring.checkInitialConditions().then((_) { | 43 await refactoring.checkInitialConditions(); |
| 43 expect(refactoring.refactoringName, 'Inline Function'); | 44 expect(refactoring.refactoringName, 'Inline Function'); |
| 44 expect(refactoring.className, isNull); | 45 expect(refactoring.className, isNull); |
| 45 expect(refactoring.methodName, 'test'); | 46 expect(refactoring.methodName, 'test'); |
| 46 expect(refactoring.isDeclaration, isFalse); | 47 expect(refactoring.isDeclaration, isFalse); |
| 47 }); | |
| 48 } | 48 } |
| 49 | 49 |
| 50 test_access_MethodElement() { | 50 test_access_MethodElement() async { |
| 51 indexTestUnit(r''' | 51 indexTestUnit(r''' |
| 52 class A { | 52 class A { |
| 53 test(a, b) { | 53 test(a, b) { |
| 54 return a + b; | 54 return a + b; |
| 55 } | 55 } |
| 56 main() { | 56 main() { |
| 57 var res = test(1, 2); | 57 var res = test(1, 2); |
| 58 } | 58 } |
| 59 } | 59 } |
| 60 '''); | 60 '''); |
| 61 _createRefactoring('test(a, b)'); | 61 _createRefactoring('test(a, b)'); |
| 62 // validate state | 62 // validate state |
| 63 return refactoring.checkInitialConditions().then((_) { | 63 await refactoring.checkInitialConditions(); |
| 64 expect(refactoring.refactoringName, 'Inline Method'); | 64 expect(refactoring.refactoringName, 'Inline Method'); |
| 65 expect(refactoring.className, 'A'); | 65 expect(refactoring.className, 'A'); |
| 66 expect(refactoring.methodName, 'test'); | 66 expect(refactoring.methodName, 'test'); |
| 67 expect(refactoring.isDeclaration, isTrue); | 67 expect(refactoring.isDeclaration, isTrue); |
| 68 }); | |
| 69 } | 68 } |
| 70 | 69 |
| 71 test_bad_cascadeInvocation() { | 70 test_bad_cascadeInvocation() async { |
| 72 indexTestUnit(r''' | 71 indexTestUnit(r''' |
| 73 class A { | 72 class A { |
| 74 foo() {} | 73 foo() {} |
| 75 bar() {} | 74 bar() {} |
| 76 test() {} | 75 test() {} |
| 77 } | 76 } |
| 78 main() { | 77 main() { |
| 79 A a = new A(); | 78 A a = new A(); |
| 80 a..foo()..test()..bar(); | 79 a..foo()..test()..bar(); |
| 81 } | 80 } |
| 82 '''); | 81 '''); |
| 83 _createRefactoring('test() {'); | 82 _createRefactoring('test() {'); |
| 84 // error | 83 // error |
| 85 return refactoring.checkAllConditions().then((status) { | 84 RefactoringStatus status = await refactoring.checkAllConditions(); |
| 86 var location = new SourceRange(findOffset('..test()'), '..test()'.length); | 85 var location = new SourceRange(findOffset('..test()'), '..test()'.length); |
| 87 assertRefactoringStatus( | 86 assertRefactoringStatus( |
| 88 status, | 87 status, |
| 89 RefactoringProblemSeverity.ERROR, | 88 RefactoringProblemSeverity.ERROR, |
| 90 expectedMessage: 'Cannot inline cascade invocation.', | 89 expectedMessage: 'Cannot inline cascade invocation.', |
| 91 expectedContextRange: location); | 90 expectedContextRange: location); |
| 92 }); | |
| 93 } | 91 } |
| 94 | 92 |
| 95 test_bad_constructor() { | 93 test_bad_constructor() { |
| 96 indexTestUnit(r''' | 94 indexTestUnit(r''' |
| 97 class A { | 95 class A { |
| 98 A.named() {} | 96 A.named() {} |
| 99 } | 97 } |
| 100 '''); | 98 '''); |
| 101 _createRefactoring('named() {}'); | 99 _createRefactoring('named() {}'); |
| 102 // error | 100 // error |
| 103 return _assertInvalidSelection(); | 101 return _assertInvalidSelection(); |
| 104 } | 102 } |
| 105 | 103 |
| 106 test_bad_deleteSource_inlineOne() { | 104 test_bad_deleteSource_inlineOne() async { |
| 107 indexTestUnit(r''' | 105 indexTestUnit(r''' |
| 108 test(a, b) { | 106 test(a, b) { |
| 109 return a + b; | 107 return a + b; |
| 110 } | 108 } |
| 111 main() { | 109 main() { |
| 112 var res1 = test(1, 2); | 110 var res1 = test(1, 2); |
| 113 var res2 = test(10, 20); | 111 var res2 = test(10, 20); |
| 114 } | 112 } |
| 115 '''); | 113 '''); |
| 116 _createRefactoring('test(1, 2)'); | 114 _createRefactoring('test(1, 2)'); |
| 117 // error | 115 // initial conditions |
| 118 return refactoring.checkInitialConditions().then((status) { | 116 RefactoringStatus status = await refactoring.checkInitialConditions(); |
| 119 assertRefactoringStatusOK(status); | 117 assertRefactoringStatusOK(status); |
| 120 refactoring.deleteSource = true; | 118 refactoring.deleteSource = true; |
| 121 refactoring.inlineAll = false; | 119 refactoring.inlineAll = false; |
| 122 return refactoring.checkFinalConditions().then((status) { | 120 // final conditions |
| 123 assertRefactoringStatus( | 121 status = await refactoring.checkFinalConditions(); |
| 124 status, | 122 assertRefactoringStatus( |
| 125 RefactoringProblemSeverity.ERROR, | 123 status, |
| 126 expectedMessage: 'All references must be inlined to remove the sourc
e.'); | 124 RefactoringProblemSeverity.ERROR, |
| 127 }); | 125 expectedMessage: 'All references must be inlined to remove the source.')
; |
| 128 }); | |
| 129 } | 126 } |
| 130 | 127 |
| 131 test_bad_notExecutableElement() { | 128 test_bad_notExecutableElement() { |
| 132 indexTestUnit(r''' | 129 indexTestUnit(r''' |
| 133 main() { | 130 main() { |
| 134 } | 131 } |
| 135 '''); | 132 '''); |
| 136 _createRefactoring(') {'); | 133 _createRefactoring(') {'); |
| 137 // error | 134 // error |
| 138 return _assertInvalidSelection(); | 135 return _assertInvalidSelection(); |
| (...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 '''); | 766 '''); |
| 770 _createRefactoring('message =>'); | 767 _createRefactoring('message =>'); |
| 771 // validate change | 768 // validate change |
| 772 return _assertSuccessfulRefactoring(r''' | 769 return _assertSuccessfulRefactoring(r''' |
| 773 main() { | 770 main() { |
| 774 print('Hello, World!'); | 771 print('Hello, World!'); |
| 775 } | 772 } |
| 776 '''); | 773 '''); |
| 777 } | 774 } |
| 778 | 775 |
| 779 test_initialMode_all() { | 776 test_initialMode_all() async { |
| 780 indexTestUnit(r''' | 777 indexTestUnit(r''' |
| 781 test(a, b) { | 778 test(a, b) { |
| 782 return a + b; | 779 return a + b; |
| 783 } | 780 } |
| 784 main() { | 781 main() { |
| 785 var res = test(1, 2); | 782 var res = test(1, 2); |
| 786 } | 783 } |
| 787 '''); | 784 '''); |
| 788 _createRefactoring('test(a, b)'); | 785 _createRefactoring('test(a, b)'); |
| 789 // validate state | 786 // validate state |
| 790 return refactoring.checkInitialConditions().then((_) { | 787 await refactoring.checkInitialConditions(); |
| 791 expect(refactoring.deleteSource, true); | 788 expect(refactoring.deleteSource, true); |
| 792 expect(refactoring.inlineAll, true); | 789 expect(refactoring.inlineAll, true); |
| 793 }); | |
| 794 } | 790 } |
| 795 | 791 |
| 796 test_initialMode_single() { | 792 test_initialMode_single() async { |
| 797 indexTestUnit(r''' | 793 indexTestUnit(r''' |
| 798 test(a, b) { | 794 test(a, b) { |
| 799 return a + b; | 795 return a + b; |
| 800 } | 796 } |
| 801 main() { | 797 main() { |
| 802 var res1 = test(1, 2); | 798 var res1 = test(1, 2); |
| 803 var res2 = test(10, 20); | 799 var res2 = test(10, 20); |
| 804 } | 800 } |
| 805 '''); | 801 '''); |
| 806 _createRefactoring('test(1, 2)'); | 802 _createRefactoring('test(1, 2)'); |
| 807 deleteSource = false; | 803 deleteSource = false; |
| 808 // validate state | 804 // validate state |
| 809 return refactoring.checkInitialConditions().then((_) { | 805 await refactoring.checkInitialConditions(); |
| 810 expect(refactoring.deleteSource, false); | 806 expect(refactoring.deleteSource, false); |
| 811 expect(refactoring.inlineAll, false); | 807 expect(refactoring.inlineAll, false); |
| 812 }); | |
| 813 } | 808 } |
| 814 | 809 |
| 815 test_method_emptyBody() { | 810 test_method_emptyBody() { |
| 816 indexTestUnit(r''' | 811 indexTestUnit(r''' |
| 817 abstract class A { | 812 abstract class A { |
| 818 test(); | 813 test(); |
| 819 } | 814 } |
| 820 main(A a) { | 815 main(A a) { |
| 821 print(a.test()); | 816 print(a.test()); |
| 822 } | 817 } |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1097 '''); | 1092 '''); |
| 1098 _createRefactoring('test('); | 1093 _createRefactoring('test('); |
| 1099 // validate change | 1094 // validate change |
| 1100 return _assertSuccessfulRefactoring(r''' | 1095 return _assertSuccessfulRefactoring(r''' |
| 1101 main() { | 1096 main() { |
| 1102 print(null); | 1097 print(null); |
| 1103 } | 1098 } |
| 1104 '''); | 1099 '''); |
| 1105 } | 1100 } |
| 1106 | 1101 |
| 1107 test_noArgument_required() { | 1102 test_noArgument_required() async { |
| 1108 verifyNoTestUnitErrors = false; | 1103 verifyNoTestUnitErrors = false; |
| 1109 indexTestUnit(r''' | 1104 indexTestUnit(r''' |
| 1110 test(a) { | 1105 test(a) { |
| 1111 print(a); | 1106 print(a); |
| 1112 } | 1107 } |
| 1113 main() { | 1108 main() { |
| 1114 test(); | 1109 test(); |
| 1115 } | 1110 } |
| 1116 '''); | 1111 '''); |
| 1117 _createRefactoring('test();'); | 1112 _createRefactoring('test();'); |
| 1118 // error | 1113 // error |
| 1119 return refactoring.checkAllConditions().then((status) { | 1114 RefactoringStatus status = await refactoring.checkAllConditions(); |
| 1120 var location = new SourceRange(findOffset('test();'), 'test()'.length); | 1115 var location = new SourceRange(findOffset('test();'), 'test()'.length); |
| 1121 assertRefactoringStatus( | 1116 assertRefactoringStatus( |
| 1122 status, | 1117 status, |
| 1123 RefactoringProblemSeverity.ERROR, | 1118 RefactoringProblemSeverity.ERROR, |
| 1124 expectedMessage: 'No argument for the parameter "a".', | 1119 expectedMessage: 'No argument for the parameter "a".', |
| 1125 expectedContextRange: location); | 1120 expectedContextRange: location); |
| 1126 }); | |
| 1127 } | 1121 } |
| 1128 | 1122 |
| 1129 test_reference_expressionBody() { | 1123 test_reference_expressionBody() { |
| 1130 indexTestUnit(r''' | 1124 indexTestUnit(r''' |
| 1131 String message() => 'Hello, World!'; | 1125 String message() => 'Hello, World!'; |
| 1132 main() { | 1126 main() { |
| 1133 print(message); | 1127 print(message); |
| 1134 } | 1128 } |
| 1135 '''); | 1129 '''); |
| 1136 _createRefactoring('message()'); | 1130 _createRefactoring('message()'); |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1386 _createRefactoring('test(bool a, bool b)'); | 1380 _createRefactoring('test(bool a, bool b)'); |
| 1387 // validate change | 1381 // validate change |
| 1388 return _assertSuccessfulRefactoring(r''' | 1382 return _assertSuccessfulRefactoring(r''' |
| 1389 main(bool p, bool p2, bool p3) { | 1383 main(bool p, bool p2, bool p3) { |
| 1390 var res1 = p && (p2 || p3); | 1384 var res1 = p && (p2 || p3); |
| 1391 var res2 = p || p2 || p3; | 1385 var res2 = p || p2 || p3; |
| 1392 } | 1386 } |
| 1393 '''); | 1387 '''); |
| 1394 } | 1388 } |
| 1395 | 1389 |
| 1396 Future _assertConditionsError(String message) { | 1390 Future _assertConditionsError(String message) async { |
| 1397 return refactoring.checkAllConditions().then((status) { | 1391 RefactoringStatus status = await refactoring.checkAllConditions(); |
| 1398 assertRefactoringStatus( | 1392 assertRefactoringStatus( |
| 1399 status, | 1393 status, |
| 1400 RefactoringProblemSeverity.ERROR, | 1394 RefactoringProblemSeverity.ERROR, |
| 1401 expectedMessage: message); | 1395 expectedMessage: message); |
| 1402 }); | |
| 1403 } | 1396 } |
| 1404 | 1397 |
| 1405 Future _assertConditionsFatal(String message) { | 1398 Future _assertConditionsFatal(String message) async { |
| 1406 return refactoring.checkAllConditions().then((status) { | 1399 RefactoringStatus status = await refactoring.checkAllConditions(); |
| 1407 assertRefactoringStatus( | 1400 assertRefactoringStatus( |
| 1408 status, | 1401 status, |
| 1409 RefactoringProblemSeverity.FATAL, | 1402 RefactoringProblemSeverity.FATAL, |
| 1410 expectedMessage: message); | 1403 expectedMessage: message); |
| 1411 }); | |
| 1412 } | 1404 } |
| 1413 | 1405 |
| 1414 Future _assertInvalidSelection() { | 1406 Future _assertInvalidSelection() { |
| 1415 return _assertConditionsFatal( | 1407 return _assertConditionsFatal( |
| 1416 'Method declaration or reference must be selected to activate this refac
toring.'); | 1408 'Method declaration or reference must be selected to activate this refac
toring.'); |
| 1417 } | 1409 } |
| 1418 | 1410 |
| 1419 Future _assertSuccessfulRefactoring(String expectedCode) { | 1411 Future _assertSuccessfulRefactoring(String expectedCode) async { |
| 1420 return refactoring.checkInitialConditions().then((status) { | 1412 RefactoringStatus status = await refactoring.checkInitialConditions(); |
| 1421 assertRefactoringStatusOK(status); | 1413 assertRefactoringStatusOK(status); |
| 1422 if (deleteSource != null) { | 1414 // configure |
| 1423 refactoring.deleteSource = deleteSource; | 1415 if (deleteSource != null) { |
| 1424 } | 1416 refactoring.deleteSource = deleteSource; |
| 1425 if (inlineAll != null) { | 1417 } |
| 1426 refactoring.inlineAll = inlineAll; | 1418 if (inlineAll != null) { |
| 1427 } | 1419 refactoring.inlineAll = inlineAll; |
| 1428 return refactoring.checkFinalConditions().then((status) { | 1420 } |
| 1429 assertRefactoringStatusOK(status); | 1421 // final conditions |
| 1430 return refactoring.createChange().then((SourceChange change) { | 1422 status = await refactoring.checkFinalConditions(); |
| 1431 this.refactoringChange = change; | 1423 assertRefactoringStatusOK(status); |
| 1432 assertTestChangeResult(expectedCode); | 1424 // change |
| 1433 }); | 1425 SourceChange change = await refactoring.createChange(); |
| 1434 }); | 1426 this.refactoringChange = change; |
| 1435 }); | 1427 assertTestChangeResult(expectedCode); |
| 1436 } | 1428 } |
| 1437 | 1429 |
| 1438 void _createRefactoring(String search) { | 1430 void _createRefactoring(String search) { |
| 1439 int offset = findOffset(search); | 1431 int offset = findOffset(search); |
| 1440 refactoring = new InlineMethodRefactoring(searchEngine, testUnit, offset); | 1432 refactoring = new InlineMethodRefactoring(searchEngine, testUnit, offset); |
| 1441 } | 1433 } |
| 1442 } | 1434 } |
| OLD | NEW |