| 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.rename_class_member; | 5 library test.services.refactoring.rename_class_member; |
| 6 | 6 |
| 7 import 'package:analysis_server/src/protocol.dart'; | 7 import 'package:analysis_server/src/protocol.dart'; |
| 8 import 'package:analysis_server/src/services/correction/status.dart'; |
| 8 import 'package:unittest/unittest.dart'; | 9 import 'package:unittest/unittest.dart'; |
| 9 | 10 |
| 10 import '../../reflective_tests.dart'; | 11 import '../../reflective_tests.dart'; |
| 11 import 'abstract_rename.dart'; | 12 import 'abstract_rename.dart'; |
| 12 | 13 |
| 13 | 14 |
| 14 main() { | 15 main() { |
| 15 groupSep = ' | '; | 16 groupSep = ' | '; |
| 16 runReflectiveTests(RenameClassMemberTest); | 17 runReflectiveTests(RenameClassMemberTest); |
| 17 } | 18 } |
| 18 | 19 |
| 19 | 20 |
| 20 @reflectiveTest | 21 @reflectiveTest |
| 21 class RenameClassMemberTest extends RenameRefactoringTest { | 22 class RenameClassMemberTest extends RenameRefactoringTest { |
| 22 test_checkFinalConditions_hasMember_MethodElement() { | 23 test_checkFinalConditions_hasMember_MethodElement() async { |
| 23 indexTestUnit(''' | 24 indexTestUnit(''' |
| 24 class A { | 25 class A { |
| 25 test() {} | 26 test() {} |
| 26 newName() {} // existing | 27 newName() {} // existing |
| 27 } | 28 } |
| 28 '''); | 29 '''); |
| 29 createRenameRefactoringAtString('test() {}'); | 30 createRenameRefactoringAtString('test() {}'); |
| 30 // check status | 31 // check status |
| 31 refactoring.newName = 'newName'; | 32 refactoring.newName = 'newName'; |
| 32 return refactoring.checkFinalConditions().then((status) { | 33 RefactoringStatus status = await refactoring.checkFinalConditions(); |
| 33 assertRefactoringStatus( | 34 assertRefactoringStatus( |
| 34 status, | 35 status, |
| 35 RefactoringProblemSeverity.ERROR, | 36 RefactoringProblemSeverity.ERROR, |
| 36 expectedMessage: "Class 'A' already declares method with name 'newName
'.", | 37 expectedMessage: "Class 'A' already declares method with name 'newName'.
", |
| 37 expectedContextSearch: 'newName() {} // existing'); | 38 expectedContextSearch: 'newName() {} // existing'); |
| 38 }); | |
| 39 } | 39 } |
| 40 | 40 |
| 41 test_checkFinalConditions_OK_noShadow() { | 41 test_checkFinalConditions_OK_noShadow() async { |
| 42 indexTestUnit(''' | 42 indexTestUnit(''' |
| 43 class A { | 43 class A { |
| 44 int newName; | 44 int newName; |
| 45 } | 45 } |
| 46 class B { | 46 class B { |
| 47 test() {} | 47 test() {} |
| 48 } | 48 } |
| 49 class C extends A { | 49 class C extends A { |
| 50 main() { | 50 main() { |
| 51 print(newName); | 51 print(newName); |
| 52 } | 52 } |
| 53 } | 53 } |
| 54 '''); | 54 '''); |
| 55 createRenameRefactoringAtString('test() {}'); | 55 createRenameRefactoringAtString('test() {}'); |
| 56 // check status | 56 // check status |
| 57 refactoring.newName = 'newName'; | 57 refactoring.newName = 'newName'; |
| 58 return refactoring.checkFinalConditions().then((status) { | 58 RefactoringStatus status = await refactoring.checkFinalConditions(); |
| 59 assertRefactoringStatusOK(status); | 59 assertRefactoringStatusOK(status); |
| 60 }); | |
| 61 } | 60 } |
| 62 | 61 |
| 63 test_checkFinalConditions_shadowed_byLocal_inSameClass() { | 62 test_checkFinalConditions_shadowed_byLocal_inSameClass() async { |
| 64 indexTestUnit(''' | 63 indexTestUnit(''' |
| 65 class A { | 64 class A { |
| 66 test() {} | 65 test() {} |
| 67 main() { | 66 main() { |
| 68 var newName; | 67 var newName; |
| 69 test(); // marker | 68 test(); // marker |
| 70 } | 69 } |
| 71 } | 70 } |
| 72 '''); | 71 '''); |
| 73 createRenameRefactoringAtString('test() {}'); | 72 createRenameRefactoringAtString('test() {}'); |
| 74 // check status | 73 // check status |
| 75 refactoring.newName = 'newName'; | 74 refactoring.newName = 'newName'; |
| 76 return refactoring.checkFinalConditions().then((status) { | 75 RefactoringStatus status = await refactoring.checkFinalConditions(); |
| 77 assertRefactoringStatus( | 76 assertRefactoringStatus( |
| 78 status, | 77 status, |
| 79 RefactoringProblemSeverity.ERROR, | 78 RefactoringProblemSeverity.ERROR, |
| 80 expectedMessage: | 79 expectedMessage: |
| 81 "Usage of renamed method will be shadowed by local variable 'newNa
me'.", | 80 "Usage of renamed method will be shadowed by local variable 'newName
'.", |
| 82 expectedContextSearch: 'test(); // marker'); | 81 expectedContextSearch: 'test(); // marker'); |
| 83 }); | |
| 84 } | 82 } |
| 85 | 83 |
| 86 test_checkFinalConditions_shadowed_byLocal_inSubClass() { | 84 test_checkFinalConditions_shadowed_byLocal_inSubClass() async { |
| 87 indexTestUnit(''' | 85 indexTestUnit(''' |
| 88 class A { | 86 class A { |
| 89 test() {} | 87 test() {} |
| 90 } | 88 } |
| 91 class B extends A { | 89 class B extends A { |
| 92 main() { | 90 main() { |
| 93 var newName; | 91 var newName; |
| 94 test(); // marker | 92 test(); // marker |
| 95 } | 93 } |
| 96 } | 94 } |
| 97 '''); | 95 '''); |
| 98 createRenameRefactoringAtString('test() {}'); | 96 createRenameRefactoringAtString('test() {}'); |
| 99 // check status | 97 // check status |
| 100 refactoring.newName = 'newName'; | 98 refactoring.newName = 'newName'; |
| 101 return refactoring.checkFinalConditions().then((status) { | 99 RefactoringStatus status = await refactoring.checkFinalConditions(); |
| 102 assertRefactoringStatus( | 100 assertRefactoringStatus( |
| 103 status, | 101 status, |
| 104 RefactoringProblemSeverity.ERROR, | 102 RefactoringProblemSeverity.ERROR, |
| 105 expectedMessage: | 103 expectedMessage: |
| 106 "Usage of renamed method will be shadowed by local variable 'newNa
me'.", | 104 "Usage of renamed method will be shadowed by local variable 'newName
'.", |
| 107 expectedContextSearch: 'test(); // marker'); | 105 expectedContextSearch: 'test(); // marker'); |
| 108 }); | |
| 109 } | 106 } |
| 110 | 107 |
| 111 test_checkFinalConditions_shadowed_byLocal_OK_qualifiedReference() { | 108 test_checkFinalConditions_shadowed_byLocal_OK_qualifiedReference() async { |
| 112 indexTestUnit(''' | 109 indexTestUnit(''' |
| 113 class A { | 110 class A { |
| 114 test() {} | 111 test() {} |
| 115 main() { | 112 main() { |
| 116 var newName; | 113 var newName; |
| 117 this.test(); // marker | 114 this.test(); // marker |
| 118 } | 115 } |
| 119 } | 116 } |
| 120 '''); | 117 '''); |
| 121 createRenameRefactoringAtString('test() {}'); | 118 createRenameRefactoringAtString('test() {}'); |
| 122 // check status | 119 // check status |
| 123 refactoring.newName = 'newName'; | 120 refactoring.newName = 'newName'; |
| 124 return refactoring.checkFinalConditions().then((status) { | 121 RefactoringStatus status = await refactoring.checkFinalConditions(); |
| 125 assertRefactoringStatusOK(status); | 122 assertRefactoringStatusOK(status); |
| 126 }); | |
| 127 } | 123 } |
| 128 | 124 |
| 129 test_checkFinalConditions_shadowed_byLocal_OK_renamedNotUsed() { | 125 test_checkFinalConditions_shadowed_byLocal_OK_renamedNotUsed() async { |
| 130 indexTestUnit(''' | 126 indexTestUnit(''' |
| 131 class A { | 127 class A { |
| 132 test() {} | 128 test() {} |
| 133 main() { | 129 main() { |
| 134 var newName; | 130 var newName; |
| 135 } | 131 } |
| 136 } | 132 } |
| 137 '''); | 133 '''); |
| 138 createRenameRefactoringAtString('test() {}'); | 134 createRenameRefactoringAtString('test() {}'); |
| 139 // check status | 135 // check status |
| 140 refactoring.newName = 'newName'; | 136 refactoring.newName = 'newName'; |
| 141 return refactoring.checkFinalConditions().then((status) { | 137 RefactoringStatus status = await refactoring.checkFinalConditions(); |
| 142 assertRefactoringStatusOK(status); | 138 assertRefactoringStatusOK(status); |
| 143 }); | |
| 144 } | 139 } |
| 145 | 140 |
| 146 test_checkFinalConditions_shadowed_byParameter_inSameClass() { | 141 test_checkFinalConditions_shadowed_byParameter_inSameClass() async { |
| 147 indexTestUnit(''' | 142 indexTestUnit(''' |
| 148 class A { | 143 class A { |
| 149 test() {} | 144 test() {} |
| 150 main(newName) { | 145 main(newName) { |
| 151 test(); // marker | 146 test(); // marker |
| 152 } | 147 } |
| 153 } | 148 } |
| 154 '''); | 149 '''); |
| 155 createRenameRefactoringAtString('test() {}'); | 150 createRenameRefactoringAtString('test() {}'); |
| 156 // check status | 151 // check status |
| 157 refactoring.newName = 'newName'; | 152 refactoring.newName = 'newName'; |
| 158 return refactoring.checkFinalConditions().then((status) { | 153 RefactoringStatus status = await refactoring.checkFinalConditions(); |
| 159 assertRefactoringStatus( | 154 assertRefactoringStatus( |
| 160 status, | 155 status, |
| 161 RefactoringProblemSeverity.ERROR, | 156 RefactoringProblemSeverity.ERROR, |
| 162 expectedMessage: | 157 expectedMessage: |
| 163 "Usage of renamed method will be shadowed by parameter 'newName'."
, | 158 "Usage of renamed method will be shadowed by parameter 'newName'.", |
| 164 expectedContextSearch: 'test(); // marker'); | 159 expectedContextSearch: 'test(); // marker'); |
| 165 }); | |
| 166 } | 160 } |
| 167 | 161 |
| 168 test_checkFinalConditions_shadowed_inSubClass() { | 162 test_checkFinalConditions_shadowed_inSubClass() async { |
| 169 indexTestUnit(''' | 163 indexTestUnit(''' |
| 170 class A { | 164 class A { |
| 171 newName() {} // marker | 165 newName() {} // marker |
| 172 } | 166 } |
| 173 class B extends A { | 167 class B extends A { |
| 174 test() {} | 168 test() {} |
| 175 main() { | 169 main() { |
| 176 newName(); | 170 newName(); |
| 177 } | 171 } |
| 178 } | 172 } |
| 179 '''); | 173 '''); |
| 180 createRenameRefactoringAtString('test() {}'); | 174 createRenameRefactoringAtString('test() {}'); |
| 181 // check status | 175 // check status |
| 182 refactoring.newName = 'newName'; | 176 refactoring.newName = 'newName'; |
| 183 return refactoring.checkFinalConditions().then((status) { | 177 RefactoringStatus status = await refactoring.checkFinalConditions(); |
| 184 assertRefactoringStatus( | 178 assertRefactoringStatus( |
| 185 status, | 179 status, |
| 186 RefactoringProblemSeverity.ERROR, | 180 RefactoringProblemSeverity.ERROR, |
| 187 expectedMessage: "Renamed method will shadow method 'A.newName'.", | 181 expectedMessage: "Renamed method will shadow method 'A.newName'.", |
| 188 expectedContextSearch: 'newName() {} // marker'); | 182 expectedContextSearch: 'newName() {} // marker'); |
| 189 }); | |
| 190 } | 183 } |
| 191 | 184 |
| 192 test_checkFinalConditions_shadowsSuper_inSubClass_FieldElement() { | 185 test_checkFinalConditions_shadowsSuper_inSubClass_FieldElement() async { |
| 193 indexTestUnit(''' | 186 indexTestUnit(''' |
| 194 class A { | 187 class A { |
| 195 int newName; // marker | 188 int newName; // marker |
| 196 } | 189 } |
| 197 class B extends A { | 190 class B extends A { |
| 198 test() {} | 191 test() {} |
| 199 } | 192 } |
| 200 class C extends B { | 193 class C extends B { |
| 201 main() { | 194 main() { |
| 202 print(newName); | 195 print(newName); |
| 203 } | 196 } |
| 204 } | 197 } |
| 205 '''); | 198 '''); |
| 206 createRenameRefactoringAtString('test() {}'); | 199 createRenameRefactoringAtString('test() {}'); |
| 207 // check status | 200 // check status |
| 208 refactoring.newName = 'newName'; | 201 refactoring.newName = 'newName'; |
| 209 return refactoring.checkFinalConditions().then((status) { | 202 RefactoringStatus status = await refactoring.checkFinalConditions(); |
| 210 assertRefactoringStatus( | 203 assertRefactoringStatus( |
| 211 status, | 204 status, |
| 212 RefactoringProblemSeverity.ERROR, | 205 RefactoringProblemSeverity.ERROR, |
| 213 expectedMessage: "Renamed method will shadow field 'A.newName'.", | 206 expectedMessage: "Renamed method will shadow field 'A.newName'.", |
| 214 expectedContextSearch: 'newName; // marker'); | 207 expectedContextSearch: 'newName; // marker'); |
| 215 }); | |
| 216 } | 208 } |
| 217 | 209 |
| 218 test_checkFinalConditions_shadowsSuper_MethodElement() { | 210 test_checkFinalConditions_shadowsSuper_MethodElement() async { |
| 219 indexTestUnit(''' | 211 indexTestUnit(''' |
| 220 class A { | 212 class A { |
| 221 test() {} | 213 test() {} |
| 222 } | 214 } |
| 223 class B extends A { | 215 class B extends A { |
| 224 newName() {} // marker | 216 newName() {} // marker |
| 225 main() { | 217 main() { |
| 226 test(); | 218 test(); |
| 227 } | 219 } |
| 228 } | 220 } |
| 229 '''); | 221 '''); |
| 230 createRenameRefactoringAtString('test() {}'); | 222 createRenameRefactoringAtString('test() {}'); |
| 231 // check status | 223 // check status |
| 232 refactoring.newName = 'newName'; | 224 refactoring.newName = 'newName'; |
| 233 return refactoring.checkFinalConditions().then((status) { | 225 RefactoringStatus status = await refactoring.checkFinalConditions(); |
| 234 assertRefactoringStatus( | 226 assertRefactoringStatus( |
| 235 status, | 227 status, |
| 236 RefactoringProblemSeverity.ERROR, | 228 RefactoringProblemSeverity.ERROR, |
| 237 expectedMessage: "Renamed method will be shadowed by method 'B.newName
'.", | 229 expectedMessage: "Renamed method will be shadowed by method 'B.newName'.
", |
| 238 expectedContextSearch: 'newName() {} // marker'); | 230 expectedContextSearch: 'newName() {} // marker'); |
| 239 }); | |
| 240 } | 231 } |
| 241 | 232 |
| 242 test_checkInitialConditions_operator() { | 233 test_checkInitialConditions_operator() async { |
| 243 indexTestUnit(''' | 234 indexTestUnit(''' |
| 244 class A { | 235 class A { |
| 245 operator -(other) => this; | 236 operator -(other) => this; |
| 246 } | 237 } |
| 247 '''); | 238 '''); |
| 248 createRenameRefactoringAtString('-(other)'); | 239 createRenameRefactoringAtString('-(other)'); |
| 249 // check status | 240 // check status |
| 250 refactoring.newName = 'newName'; | 241 refactoring.newName = 'newName'; |
| 251 return refactoring.checkInitialConditions().then((status) { | 242 RefactoringStatus status = await refactoring.checkInitialConditions(); |
| 252 assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL); | 243 assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL); |
| 253 }); | |
| 254 } | 244 } |
| 255 | 245 |
| 256 test_checkNewName_FieldElement() { | 246 test_checkNewName_FieldElement() { |
| 257 indexTestUnit(''' | 247 indexTestUnit(''' |
| 258 class A { | 248 class A { |
| 259 int test; | 249 int test; |
| 260 } | 250 } |
| 261 '''); | 251 '''); |
| 262 createRenameRefactoringAtString('test;'); | 252 createRenameRefactoringAtString('test;'); |
| 263 // null | 253 // null |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 E e = new E(); | 522 E e = new E(); |
| 533 a.newName(); | 523 a.newName(); |
| 534 b.newName(); | 524 b.newName(); |
| 535 c.newName(); | 525 c.newName(); |
| 536 d.newName(); | 526 d.newName(); |
| 537 e.test(); | 527 e.test(); |
| 538 } | 528 } |
| 539 '''); | 529 '''); |
| 540 } | 530 } |
| 541 | 531 |
| 542 test_createChange_MethodElement_potential() { | 532 test_createChange_MethodElement_potential() async { |
| 543 indexTestUnit(''' | 533 indexTestUnit(''' |
| 544 class A { | 534 class A { |
| 545 test() {} | 535 test() {} |
| 546 } | 536 } |
| 547 main(var a) { | 537 main(var a) { |
| 548 a.test(); // 1 | 538 a.test(); // 1 |
| 549 new A().test(); | 539 new A().test(); |
| 550 a.test(); // 2 | 540 a.test(); // 2 |
| 551 } | 541 } |
| 552 '''); | 542 '''); |
| 553 // configure refactoring | 543 // configure refactoring |
| 554 createRenameRefactoringAtString('test() {}'); | 544 createRenameRefactoringAtString('test() {}'); |
| 555 expect(refactoring.refactoringName, 'Rename Method'); | 545 expect(refactoring.refactoringName, 'Rename Method'); |
| 556 expect(refactoring.oldName, 'test'); | 546 expect(refactoring.oldName, 'test'); |
| 557 refactoring.newName = 'newName'; | 547 refactoring.newName = 'newName'; |
| 558 // validate change | 548 // validate change |
| 559 return assertSuccessfulRefactoring(''' | 549 await assertSuccessfulRefactoring(''' |
| 560 class A { | 550 class A { |
| 561 newName() {} | 551 newName() {} |
| 562 } | 552 } |
| 563 main(var a) { | 553 main(var a) { |
| 564 a.newName(); // 1 | 554 a.newName(); // 1 |
| 565 new A().newName(); | 555 new A().newName(); |
| 566 a.newName(); // 2 | 556 a.newName(); // 2 |
| 567 } | 557 } |
| 568 ''').then((_) { | 558 '''); |
| 569 assertPotentialEdits(['test(); // 1', 'test(); // 2']); | 559 assertPotentialEdits(['test(); // 1', 'test(); // 2']); |
| 570 }); | |
| 571 } | 560 } |
| 572 | 561 |
| 573 test_createChange_MethodElement_potential_private_otherLibrary() { | 562 test_createChange_MethodElement_potential_private_otherLibrary() async { |
| 574 indexUnit('/lib.dart', ''' | 563 indexUnit('/lib.dart', ''' |
| 575 library lib; | 564 library lib; |
| 576 main(p) { | 565 main(p) { |
| 577 p._test(); | 566 p._test(); |
| 578 } | 567 } |
| 579 '''); | 568 '''); |
| 580 indexTestUnit(''' | 569 indexTestUnit(''' |
| 581 class A { | 570 class A { |
| 582 _test() {} | 571 _test() {} |
| 583 } | 572 } |
| 584 main(var a) { | 573 main(var a) { |
| 585 a._test(); | 574 a._test(); |
| 586 new A()._test(); | 575 new A()._test(); |
| 587 } | 576 } |
| 588 '''); | 577 '''); |
| 589 // configure refactoring | 578 // configure refactoring |
| 590 createRenameRefactoringAtString('_test() {}'); | 579 createRenameRefactoringAtString('_test() {}'); |
| 591 expect(refactoring.refactoringName, 'Rename Method'); | 580 expect(refactoring.refactoringName, 'Rename Method'); |
| 592 expect(refactoring.oldName, '_test'); | 581 expect(refactoring.oldName, '_test'); |
| 593 refactoring.newName = 'newName'; | 582 refactoring.newName = 'newName'; |
| 594 // validate change | 583 // validate change |
| 595 return assertSuccessfulRefactoring(''' | 584 await assertSuccessfulRefactoring(''' |
| 596 class A { | 585 class A { |
| 597 newName() {} | 586 newName() {} |
| 598 } | 587 } |
| 599 main(var a) { | 588 main(var a) { |
| 600 a.newName(); | 589 a.newName(); |
| 601 new A().newName(); | 590 new A().newName(); |
| 602 } | 591 } |
| 603 ''').then((_) { | 592 '''); |
| 604 assertNoFileChange('/lib.dart'); | 593 assertNoFileChange('/lib.dart'); |
| 605 }); | |
| 606 } | 594 } |
| 607 | 595 |
| 608 test_createChange_PropertyAccessorElement_getter() { | 596 test_createChange_PropertyAccessorElement_getter() { |
| 609 indexTestUnit(''' | 597 indexTestUnit(''' |
| 610 class A { | 598 class A { |
| 611 get test {} // marker | 599 get test {} // marker |
| 612 set test(x) {} | 600 set test(x) {} |
| 613 main() { | 601 main() { |
| 614 print(test); | 602 print(test); |
| 615 test = 1; | 603 test = 1; |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 // validate change | 720 // validate change |
| 733 return assertSuccessfulRefactoring(''' | 721 return assertSuccessfulRefactoring(''' |
| 734 class A<NewName> { | 722 class A<NewName> { |
| 735 NewName field; | 723 NewName field; |
| 736 List<NewName> items; | 724 List<NewName> items; |
| 737 NewName method(NewName p) => null; | 725 NewName method(NewName p) => null; |
| 738 } | 726 } |
| 739 '''); | 727 '''); |
| 740 } | 728 } |
| 741 } | 729 } |
| OLD | NEW |