Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(343)

Side by Side Diff: pkg/analysis_server/test/edit/refactoring_test.dart

Issue 526183002: Integrate EXTRACT_LOCAL_VARIABLE into the server. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/analysis_server/lib/src/edit/edit_domain.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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.edit.refactoring; 5 library test.edit.refactoring;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 8
9 import 'package:analysis_server/src/edit/edit_domain.dart'; 9 import 'package:analysis_server/src/edit/edit_domain.dart';
10 import 'package:analysis_server/src/protocol.dart'; 10 import 'package:analysis_server/src/protocol.dart';
11 import 'package:analysis_server/src/services/index/index.dart'; 11 import 'package:analysis_server/src/services/index/index.dart';
12 import 'package:analysis_server/src/services/index/local_memory_index.dart'; 12 import 'package:analysis_server/src/services/index/local_memory_index.dart';
13 import 'package:analysis_testing/reflective_tests.dart'; 13 import 'package:analysis_testing/reflective_tests.dart';
14 import 'package:unittest/unittest.dart' hide ERROR; 14 import 'package:unittest/unittest.dart' hide ERROR;
15 15
16 import '../analysis_abstract.dart'; 16 import '../analysis_abstract.dart';
17 17
18 18
19 main() { 19 main() {
20 groupSep = ' | '; 20 groupSep = ' | ';
21 runReflectiveTests(ExtractLocalVariableTest);
21 runReflectiveTests(GetAvailableRefactoringsTest); 22 runReflectiveTests(GetAvailableRefactoringsTest);
22 runReflectiveTests(GetRefactoring_Rename_Test); 23 runReflectiveTests(RenameTest);
23 } 24 }
24 25
25 26
27 @ReflectiveTestCase()
28 class ExtractLocalVariableTest extends _AbstractGetRefactoring_Test {
29 Future<Response> sendExtractRequest(int offset, int length, String name,
30 bool extractAll) {
31 RefactoringKind kind = RefactoringKind.EXTRACT_LOCAL_VARIABLE;
32 Object options = new ExtractLocalVariableOptions(name, extractAll);
33 return sendRequest(kind, offset, length, options, false);
34 }
35
36 Future<Response> sendStringRequest(String search, String name,
37 bool extractAll) {
38 int offset = findOffset(search);
39 int length = search.length;
40 return sendExtractRequest(offset, length, name, extractAll);
41 }
42
43 Future<Response> sendStringSuffixRequest(String search, String suffix,
44 String name, bool extractAll) {
45 int offset = findOffset(search + suffix);
46 int length = search.length;
47 return sendExtractRequest(offset, length, name, extractAll);
48 }
49
50 test_extractAll() {
51 addTestFile('''
52 main() {
53 print(1 + 2);
54 print(1 + 2);
55 }
56 ''');
57 return assertSuccessfulRefactoring(() {
58 return sendStringRequest('1 + 2', 'res', true);
59 }, '''
60 main() {
61 var res = 1 + 2;
62 print(res);
63 print(res);
64 }
65 ''');
66 }
67
68 test_extractOne() {
69 addTestFile('''
70 main() {
71 print(1 + 2);
72 print(1 + 2); // marker
73 }
74 ''');
75 return assertSuccessfulRefactoring(() {
76 return sendStringSuffixRequest('1 + 2', '); // marker', 'res', false);
77 }, '''
78 main() {
79 print(1 + 2);
80 var res = 1 + 2;
81 print(res); // marker
82 }
83 ''');
84 }
85
86 test_nameWarning() {
87 addTestFile('''
88 main() {
89 print(1 + 2);
90 }
91 ''');
92 return getRefactoringResult(() {
93 return sendStringRequest('1 + 2', 'Name', true);
94 }).then((result) {
95 assertResultProblemsWarning(
96 result,
97 'Variable name should start with a lowercase letter.');
98 // ...but there is still a change
99 assertTestRefactoringResult(result, '''
100 main() {
101 var Name = 1 + 2;
102 print(Name);
103 }
104 ''');
105 });
106 }
107
108 test_names() {
109 addTestFile('''
110 class TreeItem {}
111 TreeItem getSelectedItem() => null;
112 main() {
113 var a = getSelectedItem();
114 }
115 ''');
116 return getRefactoringResult(() {
117 return sendStringSuffixRequest('getSelectedItem()', ';', null, true);
118 }).then((result) {
119 ExtractLocalVariableFeedback feedback = result.feedback;
120 expect(
121 feedback.names,
122 unorderedEquals(['treeItem', 'item', 'selectedItem']));
123 expect(result.change, isNull);
124 });
125 }
126
127 test_offsetsLengths() {
128 addTestFile('''
129 main() {
130 print(1 + 2);
131 print(1 + 2);
132 }
133 ''');
134 return getRefactoringResult(() {
135 return sendStringRequest('1 + 2', 'res', true);
136 }).then((result) {
137 ExtractLocalVariableFeedback feedback = result.feedback;
138 expect(feedback.offsets, [findOffset('1 + 2'), findOffset('1 + 2')]);
139 expect(feedback.lengths, [5, 6]);
140 });
141 }
142 }
143
144
26 @ReflectiveTestCase() 145 @ReflectiveTestCase()
27 class GetAvailableRefactoringsTest extends AbstractAnalysisTest { 146 class GetAvailableRefactoringsTest extends AbstractAnalysisTest {
28 /** 147 /**
29 * Tests that there is a RENAME refactoring available at the [search] offset. 148 * Tests that there is a RENAME refactoring available at the [search] offset.
30 */ 149 */
31 Future assertHasRenameRefactoring(String code, String search) { 150 Future assertHasRenameRefactoring(String code, String search) {
32 addTestFile(code); 151 addTestFile(code);
33 return waitForTasksFinished().then((_) { 152 return waitForTasksFinished().then((_) {
34 List<RefactoringKind> kinds = getRefactoringsAtString(search); 153 List<RefactoringKind> kinds = getRefactoringsAtString(search);
35 expect(kinds, contains(RefactoringKind.RENAME)); 154 expect(kinds, contains(RefactoringKind.RENAME));
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 return waitForTasksFinished().then((_) { 317 return waitForTasksFinished().then((_) {
199 List<RefactoringKind> kinds = 318 List<RefactoringKind> kinds =
200 getRefactoringsAtString('// not an element'); 319 getRefactoringsAtString('// not an element');
201 expect(kinds, isNot(contains(RefactoringKind.RENAME))); 320 expect(kinds, isNot(contains(RefactoringKind.RENAME)));
202 }); 321 });
203 } 322 }
204 } 323 }
205 324
206 325
207 @ReflectiveTestCase() 326 @ReflectiveTestCase()
208 class GetRefactoring_Rename_Test extends _AbstractGetRefactoring_Test { 327 class RenameTest extends _AbstractGetRefactoring_Test {
328 Future<Response> sendRenameRequest(String search, String newName,
329 [bool validateOnly = false]) {
330 Request request = new EditGetRefactoringParams(
331 RefactoringKind.RENAME,
332 testFile,
333 findOffset(search),
334 0,
335 validateOnly,
336 options: new RenameOptions(newName)).toRequest('0');
337 return serverChannel.sendRequest(request);
338 }
339
209 test_class() { 340 test_class() {
210 addTestFile(''' 341 addTestFile('''
211 class Test {} 342 class Test {}
212 main() { 343 main() {
213 Test v; 344 Test v;
214 } 345 }
215 '''); 346 ''');
216 String search = 'Test {}'; 347 return assertSuccessfulRefactoring(() {
217 String newName = 'NewName'; 348 return sendRenameRequest('Test {}', 'NewName');
218 return assertSuccessfulRefactoring(search, newName, ''' 349 }, '''
219 class NewName {} 350 class NewName {}
220 main() { 351 main() {
221 NewName v; 352 NewName v;
222 } 353 }
223 '''); 354 ''');
224 } 355 }
225 356
226 test_classMember_field() { 357 test_classMember_field() {
227 addTestFile(''' 358 addTestFile('''
228 class A { 359 class A {
229 var test = 0; 360 var test = 0;
230 main() { 361 main() {
231 print(test); 362 print(test);
232 } 363 }
233 } 364 }
234 '''); 365 ''');
235 String search = 'test = 0'; 366 return assertSuccessfulRefactoring(() {
236 String newName = 'newName'; 367 return sendRenameRequest('test = 0', 'newName');
237 return assertSuccessfulRefactoring(search, newName, ''' 368 }, '''
238 class A { 369 class A {
239 var newName = 0; 370 var newName = 0;
240 main() { 371 main() {
241 print(newName); 372 print(newName);
242 } 373 }
243 } 374 }
244 '''); 375 ''');
245 } 376 }
246 377
247 test_classMember_getter() { 378 test_classMember_getter() {
248 addTestFile(''' 379 addTestFile('''
249 class A { 380 class A {
250 get test => 0; 381 get test => 0;
251 main() { 382 main() {
252 print(test); 383 print(test);
253 } 384 }
254 } 385 }
255 '''); 386 ''');
256 String search = 'test =>'; 387 return assertSuccessfulRefactoring(() {
257 String newName = 'newName'; 388 return sendRenameRequest('test =>', 'newName');
258 return assertSuccessfulRefactoring(search, newName, ''' 389 }, '''
259 class A { 390 class A {
260 get newName => 0; 391 get newName => 0;
261 main() { 392 main() {
262 print(newName); 393 print(newName);
263 } 394 }
264 } 395 }
265 '''); 396 ''');
266 } 397 }
267 398
268 test_classMember_setter() { 399 test_classMember_setter() {
269 addTestFile(''' 400 addTestFile('''
270 class A { 401 class A {
271 set test(x) {} 402 set test(x) {}
272 main() { 403 main() {
273 test = 0; 404 test = 0;
274 } 405 }
275 } 406 }
276 '''); 407 ''');
277 String search = 'test = 0'; 408 return assertSuccessfulRefactoring(() {
278 String newName = 'newName'; 409 return sendRenameRequest('test = 0', 'newName');
279 return assertSuccessfulRefactoring(search, newName, ''' 410 }, '''
280 class A { 411 class A {
281 set newName(x) {} 412 set newName(x) {}
282 main() { 413 main() {
283 newName = 0; 414 newName = 0;
284 } 415 }
285 } 416 }
286 '''); 417 ''');
287 } 418 }
288 419
289 test_class_options_fatalError() { 420 test_class_options_fatalError() {
290 addTestFile(''' 421 addTestFile('''
291 class Test {} 422 class Test {}
292 main() { 423 main() {
293 Test v; 424 Test v;
294 } 425 }
295 '''); 426 ''');
296 return waitForTasksFinished().then((_) { 427 return getRefactoringResult(() {
297 String search = 'Test {}'; 428 return sendRenameRequest('Test {}', '');
298 return sendRenameRequest(search, '').then((Response response) { 429 }).then((result) {
299 var result = new EditGetRefactoringResult.fromResponse(response); 430 assertResultProblemsFatal(result, 'Class name must not be empty.');
300 assertResultProblemsFatal(result, 'Class name must not be empty.'); 431 // ...there is no any change
301 // ...there is no any change 432 expect(result.change, isNull);
302 expect(result.change, isNull);
303 });
304 }); 433 });
305 } 434 }
306 435
307 test_class_validateOnly() { 436 test_class_validateOnly() {
308 addTestFile(''' 437 addTestFile('''
309 class Test {} 438 class Test {}
310 main() { 439 main() {
311 Test v; 440 Test v;
312 } 441 }
313 '''); 442 ''');
314 String search = 'Test {}'; 443 return getRefactoringResult(() {
315 String newName = 'NewName'; 444 return sendRenameRequest('Test {}', 'NewName', true);
316 return getRefactoringResult( 445 }).then((result) {
317 search,
318 newName,
319 validateOnly: true).then((result) {
320 assertResultProblemsOK(result); 446 assertResultProblemsOK(result);
321 expect(result.change, isNull); 447 expect(result.change, isNull);
322 }); 448 });
323 } 449 }
324 450
325 test_class_warning() { 451 test_class_warning() {
326 addTestFile(''' 452 addTestFile('''
327 class Test {} 453 class Test {}
328 main() { 454 main() {
329 Test v; 455 Test v;
330 } 456 }
331 '''); 457 ''');
332 return waitForTasksFinished().then((_) { 458 return getRefactoringResult(() {
333 String search = 'Test {}'; 459 return sendRenameRequest('Test {}', 'newName');
334 return sendRenameRequest(search, 'newName').then((Response response) { 460 }).then((result) {
335 var result = new EditGetRefactoringResult.fromResponse(response); 461 assertResultProblemsWarning(
336 assertResultProblemsWarning( 462 result,
337 result, 463 'Class name should start with an uppercase letter.');
338 'Class name should start with an uppercase letter.'); 464 // ...but there is still a change
339 // ...but there is still a change 465 assertTestRefactoringResult(result, '''
340 assertTestRefactoringResult(result, '''
341 class newName {} 466 class newName {}
342 main() { 467 main() {
343 newName v; 468 newName v;
344 } 469 }
345 '''); 470 ''');
346 }).then((_) { 471 }).then((_) {
347 return sendRenameRequest(search, 'NewName').then((Response response) { 472 // "NewName" is a perfectly valid name
348 var result = new EditGetRefactoringResult.fromResponse(response); 473 return getRefactoringResult(() {
349 // OK 474 return sendRenameRequest('Test {}', 'NewName');
350 assertResultProblemsOK(result); 475 }).then((result) {
351 }); 476 assertResultProblemsOK(result);
477 // ...and there is a new change
478 assertTestRefactoringResult(result, '''
479 class NewName {}
480 main() {
481 NewName v;
482 }
483 ''');
352 }); 484 });
353 }); 485 });
354 } 486 }
355 487
356 test_constructor() { 488 test_constructor() {
357 addTestFile(''' 489 addTestFile('''
358 class A { 490 class A {
359 A.test() {} 491 A.test() {}
360 } 492 }
361 main() { 493 main() {
362 new A.test(); 494 new A.test();
363 } 495 }
364 '''); 496 ''');
365 String search = 'test();'; 497 String search = 'test();';
366 String newName = 'newName'; 498 String newName = 'newName';
367 return assertSuccessfulRefactoring(search, newName, ''' 499 return assertSuccessfulRefactoring(() {
500 return sendRenameRequest('test();', 'newName');
501 }, '''
368 class A { 502 class A {
369 A.newName() {} 503 A.newName() {}
370 } 504 }
371 main() { 505 main() {
372 new A.newName(); 506 new A.newName();
373 } 507 }
374 '''); 508 ''');
375 } 509 }
376 510
377 test_feedback() { 511 test_feedback() {
378 addTestFile(''' 512 addTestFile('''
379 class Test {} 513 class Test {}
380 main() { 514 main() {
381 Test v; 515 Test v;
382 } 516 }
383 '''); 517 ''');
384 String search = 'st v;'; 518 return getRefactoringResult(() {
385 String newName = 'NewName'; 519 return sendRenameRequest('st v;', 'NewName');
386 return getRefactoringResult(search, newName).then((result) { 520 }).then((result) {
387 RenameFeedback feedback = result.feedback; 521 RenameFeedback feedback = result.feedback;
388 expect(feedback, isNotNull); 522 expect(feedback, isNotNull);
389 expect(feedback.offset, findOffset('Test v;')); 523 expect(feedback.offset, findOffset('Test v;'));
390 expect(feedback.length, 'Test'.length); 524 expect(feedback.length, 'Test'.length);
391 }); 525 });
392 } 526 }
393 527
394 test_function() { 528 test_function() {
395 addTestFile(''' 529 addTestFile('''
396 test() {} 530 test() {}
397 main() { 531 main() {
398 test(); 532 test();
399 print(test); 533 print(test);
400 } 534 }
401 '''); 535 ''');
402 String search = 'test() {}'; 536 return assertSuccessfulRefactoring(() {
403 String newName = 'newName'; 537 return sendRenameRequest('test() {}', 'newName');
404 return assertSuccessfulRefactoring(search, newName, ''' 538 }, '''
405 newName() {} 539 newName() {}
406 main() { 540 main() {
407 newName(); 541 newName();
408 print(newName); 542 print(newName);
409 } 543 }
410 '''); 544 ''');
411 } 545 }
412 546
413 test_init_fatalError_noElement() { 547 test_init_fatalError_noElement() {
414 addTestFile('// nothing to rename'); 548 addTestFile('// nothing to rename');
415 String search = '// nothing'; 549 return getRefactoringResult(() {
416 return getRefactoringResult(search, null).then((result) { 550 return sendRenameRequest('// nothing', null);
551 }).then((result) {
417 assertResultProblemsFatal(result, 'Unable to create a refactoring'); 552 assertResultProblemsFatal(result, 'Unable to create a refactoring');
418 // ...there is no any change 553 // ...there is no any change
419 expect(result.change, isNull); 554 expect(result.change, isNull);
420 }); 555 });
421 } 556 }
422 557
423 test_localVariable() { 558 test_localVariable() {
424 addTestFile(''' 559 addTestFile('''
425 main() { 560 main() {
426 int test = 0; 561 int test = 0;
427 test = 1; 562 test = 1;
428 test += 2; 563 test += 2;
429 print(test); 564 print(test);
430 } 565 }
431 '''); 566 ''');
432 String search = 'test = 1'; 567 return assertSuccessfulRefactoring(() {
433 String newName = 'newName'; 568 return sendRenameRequest('test = 1', 'newName');
434 return assertSuccessfulRefactoring(search, newName, ''' 569 }, '''
435 main() { 570 main() {
436 int newName = 0; 571 int newName = 0;
437 newName = 1; 572 newName = 1;
438 newName += 2; 573 newName += 2;
439 print(newName); 574 print(newName);
440 } 575 }
441 '''); 576 ''');
442 } 577 }
443 578
444 test_localVariable_finalCheck_shadowError() { 579 test_localVariable_finalCheck_shadowError() {
445 addTestFile(''' 580 addTestFile('''
446 main() { 581 main() {
447 var newName; 582 var newName;
448 int test = 0; 583 int test = 0;
449 print(test); 584 print(test);
450 } 585 }
451 '''); 586 ''');
452 String search = 'test = 0'; 587 return getRefactoringResult(() {
453 String newName = 'newName'; 588 return sendRenameRequest('test = 0', 'newName');
454 return getRefactoringResult(search, newName).then((result) { 589 }).then((result) {
455 assertResultProblemsError(result, "Duplicate local variable 'newName'."); 590 assertResultProblemsError(result, "Duplicate local variable 'newName'.");
456 }); 591 });
457 } 592 }
458 } 593 }
459 594
460 595
461 @ReflectiveTestCase() 596 @ReflectiveTestCase()
462 class _AbstractGetRefactoring_Test extends AbstractAnalysisTest { 597 class _AbstractGetRefactoring_Test extends AbstractAnalysisTest {
463 /** 598 /**
464 * Asserts that [result] has a single ERROR problem. 599 * Asserts that [result] has a single ERROR problem.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 expect(problems, hasLength(1)); 646 expect(problems, hasLength(1));
512 expect( 647 expect(
513 problem.severity, 648 problem.severity,
514 RefactoringProblemSeverity.WARNING, 649 RefactoringProblemSeverity.WARNING,
515 reason: problem.toString()); 650 reason: problem.toString());
516 if (message != null) { 651 if (message != null) {
517 expect(problem.message, message); 652 expect(problem.message, message);
518 } 653 }
519 } 654 }
520 655
521 Future assertSuccessfulRefactoring(String search, String newName, 656 Future assertSuccessfulRefactoring(Future<Response> requestSender(),
522 String expectedCode) { 657 String expectedCode) {
523 return getRefactoringResult(search, newName).then((result) { 658 return getRefactoringResult(requestSender).then((result) {
524 assertResultProblemsOK(result); 659 assertResultProblemsOK(result);
525 assertTestRefactoringResult(result, expectedCode); 660 assertTestRefactoringResult(result, expectedCode);
526 }); 661 });
527 } 662 }
528 663
529 /** 664 /**
530 * Asserts that the given [EditGetRefactoringResult] has a [testFile] change 665 * Asserts that the given [EditGetRefactoringResult] has a [testFile] change
531 * which results in the [expectedCode]. 666 * which results in the [expectedCode].
532 */ 667 */
533 void assertTestRefactoringResult(EditGetRefactoringResult result, 668 void assertTestRefactoringResult(EditGetRefactoringResult result,
534 String expectedCode) { 669 String expectedCode) {
535 SourceChange change = result.change; 670 SourceChange change = result.change;
536 expect(change, isNotNull); 671 expect(change, isNotNull);
537 for (SourceFileEdit fileEdit in change.edits) { 672 for (SourceFileEdit fileEdit in change.edits) {
538 if (fileEdit.file == testFile) { 673 if (fileEdit.file == testFile) {
539 String actualCode = SourceEdit.applySequence(testCode, fileEdit.edits); 674 String actualCode = SourceEdit.applySequence(testCode, fileEdit.edits);
540 expect(actualCode, expectedCode); 675 expect(actualCode, expectedCode);
541 return; 676 return;
542 } 677 }
543 } 678 }
544 fail('No SourceFileEdit for $testFile in $change'); 679 fail('No SourceFileEdit for $testFile in $change');
545 } 680 }
546 681
547 @override 682 @override
548 Index createIndex() { 683 Index createIndex() {
549 return createLocalMemoryIndex(); 684 return createLocalMemoryIndex();
550 } 685 }
551 686
552 Future<EditGetRefactoringResult> getRefactoringResult(String search, 687 Future<EditGetRefactoringResult> getRefactoringResult(Future<Response>
553 String newName, {bool validateOnly: false}) { 688 requestSender()) {
554 return waitForTasksFinished().then((_) { 689 return waitForTasksFinished().then((_) {
555 return sendRenameRequest( 690 return requestSender().then((Response response) {
556 search,
557 newName,
558 validateOnly: validateOnly).then((Response response) {
559 return new EditGetRefactoringResult.fromResponse(response); 691 return new EditGetRefactoringResult.fromResponse(response);
560 }); 692 });
561 }); 693 });
562 } 694 }
563 695
564 Future sendRenameRequest(String search, String newName, {bool validateOnly: 696 Future<Response> sendRequest(RefactoringKind kind, int offset, int length,
565 false}) { 697 Object options, [bool validateOnly = false]) {
566 Request request = new EditGetRefactoringParams( 698 Request request = new EditGetRefactoringParams(
567 RefactoringKind.RENAME, 699 kind,
568 testFile, 700 testFile,
569 findOffset(search), 701 offset,
570 0, 702 length,
571 validateOnly, 703 validateOnly,
572 options: new RenameOptions(newName)).toRequest('0'); 704 options: options).toRequest('0');
573 return serverChannel.sendRequest(request); 705 return serverChannel.sendRequest(request);
574 } 706 }
575 707
576 @override 708 @override
577 void setUp() { 709 void setUp() {
578 super.setUp(); 710 super.setUp();
579 server.handlers = [new EditDomainHandler(server),]; 711 server.handlers = [new EditDomainHandler(server),];
580 createProject(); 712 createProject();
581 handler = new EditDomainHandler(server); 713 handler = new EditDomainHandler(server);
582 } 714 }
583 } 715 }
OLDNEW
« no previous file with comments | « pkg/analysis_server/lib/src/edit/edit_domain.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698