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

Side by Side Diff: pkg/analysis_server/test/services/refactoring/extract_local_test.dart

Issue 489973002: Initial 'Extract Local' implementation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: tweaks Created 6 years, 4 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
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library test.services.refactoring.extract_local;
6
7 import 'dart:async';
8
9 import 'package:analysis_server/src/services/correction/change.dart';
10 import 'package:analysis_server/src/services/correction/status.dart';
11 import 'package:analysis_server/src/services/refactoring/extract_local.dart';
12 import 'package:analysis_testing/reflective_tests.dart';
13 import 'package:unittest/unittest.dart';
14
15 import 'abstract_refactoring.dart';
16
17
18 main() {
19 groupSep = ' | ';
20 runReflectiveTests(ExtractLocalTest);
21 }
22
23
24 @ReflectiveTestCase()
25 class ExtractLocalTest extends RefactoringTest {
26 ExtractLocalRefactoringImpl refactoring;
27
28 test_checkFinalConditions_sameVariable_after() {
29 indexTestUnit('''
30 main() {
31 int a = 1 + 2;
32 var res;
33 }
34 ''');
35 _createRefactoringForString('1 + 2');
36 // conflicting name
37 return refactoring.checkAllConditions().then((status) {
38 assertRefactoringStatus(
39 status,
40 RefactoringStatusSeverity.WARNING,
41 expectedMessage:
42 "A variable with name 'res' is already defined in the visible scop e.");
43 });
44 }
45
46 test_checkFinalConditions_sameVariable_before() {
47 indexTestUnit('''
48 main() {
49 var res;
50 int a = 1 + 2;
51 }
52 ''');
53 _createRefactoringForString('1 + 2');
54 // conflicting name
55 return refactoring.checkAllConditions().then((status) {
56 assertRefactoringStatus(
57 status,
58 RefactoringStatusSeverity.WARNING,
59 expectedMessage:
60 "A variable with name 'res' is already defined in the visible scop e.");
61 });
62 }
63
64 test_checkInitialConditions_assignmentLeftHandSize() {
65 indexTestUnit('''
66 main() {
67 var v = 0;
68 v = 1;
69 }
70 ''');
71 _createRefactoringWithSuffix('v', ' = 1;');
72 // check conditions
73 return refactoring.checkInitialConditions().then((status) {
74 assertRefactoringStatus(
75 status,
76 RefactoringStatusSeverity.FATAL,
77 expectedMessage: 'Cannot extract the left-hand side of an assignment.' );
78 });
79 }
80
81 test_checkInitialConditions_methodName_reference() {
82 indexTestUnit('''
83 main() {
84 main();
85 }
86 ''');
87 _createRefactoringWithSuffix('main', '();');
88 // check conditions
89 return refactoring.checkInitialConditions().then((status) {
90 assertRefactoringStatus(
91 status,
92 RefactoringStatusSeverity.FATAL,
93 expectedMessage: 'Cannot extract a single method name.');
94 });
95 }
96
97 test_checkInitialConditions_nameOfProperty_prefixedIdentifier() {
98 indexTestUnit('''
99 main(p) {
100 p.value; // marker
101 }
102 ''');
103 _createRefactoringWithSuffix('value', '; // marker');
104 // check conditions
105 return refactoring.checkInitialConditions().then((status) {
106 assertRefactoringStatus(
107 status,
108 RefactoringStatusSeverity.FATAL,
109 expectedMessage: 'Cannot extract name part of a property access.');
110 });
111 }
112
113 test_checkInitialConditions_nameOfProperty_propertyAccess() {
114 indexTestUnit('''
115 main() {
116 foo().length; // marker
117 }
118 String foo() => '';
119 ''');
120 _createRefactoringWithSuffix('length', '; // marker');
121 // check conditions
122 return refactoring.checkInitialConditions().then((status) {
123 assertRefactoringStatus(
124 status,
125 RefactoringStatusSeverity.FATAL,
126 expectedMessage: 'Cannot extract name part of a property access.');
127 });
128 }
129
130 test_checkInitialConditions_namePartOfDeclaration_variable() {
131 indexTestUnit('''
132 main() {
133 int vvv = 0;
134 }
135 ''');
136 _createRefactoringWithSuffix('vvv', ' = 0;');
137 // check conditions
138 return refactoring.checkInitialConditions().then((status) {
139 assertRefactoringStatus(
140 status,
141 RefactoringStatusSeverity.FATAL,
142 expectedMessage: 'Cannot extract the name part of a declaration.');
143 });
144 }
145
146 test_checkInitialConditions_notPartOfFunction() {
147 indexTestUnit('''
148 int a = 1 + 2;
149 ''');
150 _createRefactoringForString('1 + 2');
151 // check conditions
152 return refactoring.checkInitialConditions().then((status) {
153 assertRefactoringStatus(
154 status,
155 RefactoringStatusSeverity.FATAL,
156 expectedMessage:
157 'Expression inside of function must be selected to activate this r efactoring.');
158 });
159 }
160
161 test_checkInitialConditions_stringSelection_leadingQuote() {
162 indexTestUnit('''
163 main() {
164 var vvv = 'abc';
165 }
166 ''');
167 _createRefactoringForString("'a");
168 // check conditions
169 return refactoring.checkInitialConditions().then((status) {
170 assertRefactoringStatus(
171 status,
172 RefactoringStatusSeverity.FATAL,
173 expectedMessage:
174 'Cannot extract only leading or trailing quote of string literal.' );
175 });
176 }
177
178 test_checkInitialConditions_stringSelection_trailingQuote() {
179 indexTestUnit('''
180 main() {
181 var vvv = 'abc';
182 }
183 ''');
184 _createRefactoringForString("c'");
185 // check conditions
186 return refactoring.checkInitialConditions().then((status) {
187 assertRefactoringStatus(
188 status,
189 RefactoringStatusSeverity.FATAL,
190 expectedMessage:
191 'Cannot extract only leading or trailing quote of string literal.' );
192 });
193 }
194
195 test_checkLocalName() {
196 indexTestUnit('''
197 main() {
198 int a = 1 + 2;
199 }
200 ''');
201 _createRefactoringForString('1 + 2');
202 expect(refactoring.refactoringName, 'Extract Local Variable');
203 // null
204 refactoring.name = null;
205 assertRefactoringStatus(
206 refactoring.checkName(),
207 RefactoringStatusSeverity.ERROR,
208 expectedMessage: "Variable name must not be null.");
209 // empty
210 refactoring.name = '';
211 assertRefactoringStatus(
212 refactoring.checkName(),
213 RefactoringStatusSeverity.ERROR,
214 expectedMessage: "Variable name must not be empty.");
215 // OK
216 refactoring.name = 'res';
217 assertRefactoringStatusOK(refactoring.checkName());
218 }
219
220 test_completeStatementExpression() {
221 indexTestUnit('''
222 main(p) {
223 p.toString();
224 }
225 ''');
226 _createRefactoringForString('p.toString()');
227 // apply refactoring
228 return _assertSuccessfulRefactoring('''
229 main(p) {
230 var res = p.toString();
231 }
232 ''');
233 }
234
235 test_const_argument_inConstInstanceCreation() {
236 indexTestUnit('''
237 class A {
238 const A(int a, int b);
239 }
240 main() {
241 const A(1, 2);
242 }
243 ''');
244 _createRefactoringForString('1');
245 // apply refactoring
246 return _assertSuccessfulRefactoring('''
247 class A {
248 const A(int a, int b);
249 }
250 main() {
251 const res = 1;
252 const A(res, 2);
253 }
254 ''');
255 }
256
257 test_const_inList() {
258 indexTestUnit('''
259 main() {
260 const [1, 2];
261 }
262 ''');
263 _createRefactoringForString('1');
264 // apply refactoring
265 return _assertSuccessfulRefactoring('''
266 main() {
267 const res = 1;
268 const [res, 2];
269 }
270 ''');
271 }
272
273 test_const_inList_inBinaryExpression() {
274 indexTestUnit('''
275 main() {
276 const [1 + 2, 3];
277 }
278 ''');
279 _createRefactoringForString('1');
280 // apply refactoring
281 return _assertSuccessfulRefactoring('''
282 main() {
283 const res = 1;
284 const [res + 2, 3];
285 }
286 ''');
287 }
288
289 test_const_inList_inConditionalExpression() {
290 indexTestUnit('''
291 main(bool b) {
292 const [b ? 1 : 2, 3];
293 }
294 ''');
295 _createRefactoringForString('1');
296 // apply refactoring
297 return _assertSuccessfulRefactoring('''
298 main(bool b) {
299 const res = 1;
300 const [b ? res : 2, 3];
301 }
302 ''');
303 }
304
305 test_const_inList_inParenthesis() {
306 indexTestUnit('''
307 main() {
308 const [(1), 2];
309 }
310 ''');
311 _createRefactoringForString('1');
312 // apply refactoring
313 return _assertSuccessfulRefactoring('''
314 main() {
315 const res = 1;
316 const [(res), 2];
317 }
318 ''');
319 }
320
321 test_const_inList_inPrefixExpression() {
322 indexTestUnit('''
323 main() {
324 const [!true, 2];
325 }
326 ''');
327 _createRefactoringForString('true');
328 // apply refactoring
329 return _assertSuccessfulRefactoring('''
330 main() {
331 const res = true;
332 const [!res, 2];
333 }
334 ''');
335 }
336
337 test_const_inMap_key() {
338 indexTestUnit('''
339 main() {
340 const {1: 2};
341 }
342 ''');
343 _createRefactoringForString('1');
344 // apply refactoring
345 return _assertSuccessfulRefactoring('''
346 main() {
347 const res = 1;
348 const {res: 2};
349 }
350 ''');
351 }
352
353 test_const_inMap_value() {
354 indexTestUnit('''
355 main() {
356 const {1: 2};
357 }
358 ''');
359 _createRefactoringForString('2');
360 // apply refactoring
361 return _assertSuccessfulRefactoring('''
362 main() {
363 const res = 2;
364 const {1: res};
365 }
366 ''');
367 }
368
369 test_fragmentExpression() {
370 indexTestUnit('''
371 main() {
372 int a = 1 + 2 + 3 + 4;
373 }
374 ''');
375 _createRefactoringForString('2 + 3');
376 // apply refactoring
377 return _assertSuccessfulRefactoring('''
378 main() {
379 var res = 2 + 3;
380 int a = 1 + res + 4;
381 }
382 ''');
383 }
384
385 test_fragmentExpression_leadingNotWhitespace() {
386 indexTestUnit('''
387 main() {
388 int a = 1 + 2 + 3 + 4;
389 }
390 ''');
391 _createRefactoringForString('+ 2');
392 // check conditions
393 return _assertInitialConditions_fatal_selection();
394 }
395
396 test_fragmentExpression_leadingPartialSelection() {
397 indexTestUnit('''
398 main() {
399 int a = 111 + 2 + 3 + 4;
400 }
401 ''');
402 _createRefactoringForString('11 + 2');
403 // check conditions
404 return _assertInitialConditions_fatal_selection();
405 }
406
407 test_fragmentExpression_leadingWhitespace() {
408 indexTestUnit('''
409 main() {
410 int a = 1 + 2 + 3 + 4;
411 }
412 ''');
413 _createRefactoringForString(' 2 + 3');
414 // apply refactoring
415 return _assertSuccessfulRefactoring('''
416 main() {
417 var res = 2 + 3;
418 int a = 1 +res + 4;
419 }
420 ''');
421 }
422
423 test_fragmentExpression_notAssociativeOperator() {
424 indexTestUnit('''
425 main() {
426 int a = 1 - 2 - 3 - 4;
427 }
428 ''');
429 _createRefactoringForString('2 - 3');
430 // check conditions
431 return _assertInitialConditions_fatal_selection();
432 }
433
434 test_fragmentExpression_trailingNotWhitespace() {
435 indexTestUnit('''
436 main() {
437 int a = 1 + 2 + 3 + 4;
438 }
439 ''');
440 _createRefactoringForString('2 + 3 +');
441 // check conditions
442 return _assertInitialConditions_fatal_selection();
443 }
444
445 test_fragmentExpression_trailingPartialSelection() {
446 indexTestUnit('''
447 main() {
448 int a = 1 + 2 + 3 + 444;
449 }
450 ''');
451 _createRefactoringForString('2 + 3 + 44');
452 // check conditions
453 return _assertInitialConditions_fatal_selection();
454 }
455
456 test_fragmentExpression_trailingWhitespace() {
457 indexTestUnit('''
458 main() {
459 int a = 1 + 2 + 3 + 4;
460 }
461 ''');
462 _createRefactoringForString('2 + 3 ');
463 // apply refactoring
464 return _assertSuccessfulRefactoring('''
465 main() {
466 var res = 2 + 3 ;
467 int a = 1 + res+ 4;
468 }
469 ''');
470 }
471
472 test_occurences_disableOccurences() {
473 indexTestUnit('''
474 int foo() => 42;
475 main() {
476 int a = 1 + foo();
477 int b = 2 + foo(); // marker
478 }
479 ''');
480 _createRefactoringWithSuffix('foo()', '; // marker');
481 refactoring.extractAll = false;
482 // apply refactoring
483 return _assertSuccessfulRefactoring('''
484 int foo() => 42;
485 main() {
486 int a = 1 + foo();
487 var res = foo();
488 int b = 2 + res; // marker
489 }
490 ''');
491 }
492
493 test_occurences_ignore_assignmentLeftHandSize() {
494 indexTestUnit('''
495 main() {
496 int v = 1;
497 v = 2;
498 print(() {v = 2;});
499 print(1 + (() {v = 2; return 3;})());
500 print(v); // marker
501 }
502 ''');
503 _createRefactoringWithSuffix('v', '); // marker');
504 // apply refactoring
505 return _assertSuccessfulRefactoring('''
506 main() {
507 int v = 1;
508 v = 2;
509 print(() {v = 2;});
510 print(1 + (() {v = 2; return 3;})());
511 var res = v;
512 print(res); // marker
513 }
514 ''');
515 }
516
517 test_occurences_ignore_nameOfVariableDeclariton() {
518 indexTestUnit('''
519 main() {
520 int v = 1;
521 print(v); // marker
522 }
523 ''');
524 _createRefactoringWithSuffix('v', '); // marker');
525 // apply refactoring
526 return _assertSuccessfulRefactoring('''
527 main() {
528 int v = 1;
529 var res = v;
530 print(res); // marker
531 }
532 ''');
533 }
534
535 test_occurences_singleExpression() {
536 indexTestUnit('''
537 int foo() => 42;
538 main() {
539 int a = 1 + foo();
540 int b = 2 + foo(); // marker
541 }
542 ''');
543 _createRefactoringWithSuffix('foo()', '; // marker');
544 // apply refactoring
545 return _assertSuccessfulRefactoring('''
546 int foo() => 42;
547 main() {
548 var res = foo();
549 int a = 1 + res;
550 int b = 2 + res; // marker
551 }
552 ''');
553 }
554
555 test_occurences_useDominator() {
556 indexTestUnit('''
557 main() {
558 if (true) {
559 print(42);
560 } else {
561 print(42);
562 }
563 }
564 ''');
565 _createRefactoringForString('42');
566 // apply refactoring
567 return _assertSuccessfulRefactoring('''
568 main() {
569 var res = 42;
570 if (true) {
571 print(res);
572 } else {
573 print(res);
574 }
575 }
576 ''');
577 }
578
579 test_occurences_whenComment() {
580 indexTestUnit('''
581 int foo() => 42;
582 main() {
583 /*int a = 1 + foo();*/
584 int b = 2 + foo(); // marker
585 }
586 ''');
587 _createRefactoringWithSuffix('foo()', '; // marker');
588 // apply refactoring
589 return _assertSuccessfulRefactoring('''
590 int foo() => 42;
591 main() {
592 /*int a = 1 + foo();*/
593 var res = foo();
594 int b = 2 + res; // marker
595 }
596 ''');
597 }
598
599 test_occurences_withSpace() {
600 indexTestUnit('''
601 int foo(String s) => 42;
602 main() {
603 int a = 1 + foo('has space');
604 int b = 2 + foo('has space'); // marker
605 }
606 ''');
607 _createRefactoringWithSuffix("foo('has space')", '; // marker');
608 // apply refactoring
609 return _assertSuccessfulRefactoring('''
610 int foo(String s) => 42;
611 main() {
612 var res = foo('has space');
613 int a = 1 + res;
614 int b = 2 + res; // marker
615 }
616 ''');
617 }
618
619 test_offsets_lengths() {
620 // TODO(scheglov) implement and test
621 }
622
623 test_singleExpression() {
624 indexTestUnit('''
625 main() {
626 int a = 1 + 2;
627 }
628 ''');
629 _createRefactoringForString('1 + 2');
630 // apply refactoring
631 return _assertSuccessfulRefactoring('''
632 main() {
633 var res = 1 + 2;
634 int a = res;
635 }
636 ''');
637 }
638
639 test_singleExpression_getter() {
640 indexTestUnit('''
641 class A {
642 int get foo => 42;
643 }
644 main() {
645 A a = new A();
646 int b = 1 + a.foo; // marker
647 }
648 ''');
649 _createRefactoringWithSuffix('a.foo', '; // marker');
650 // apply refactoring
651 return _assertSuccessfulRefactoring('''
652 class A {
653 int get foo => 42;
654 }
655 main() {
656 A a = new A();
657 var res = a.foo;
658 int b = 1 + res; // marker
659 }
660 ''');
661 }
662
663 test_singleExpression_inMethod() {
664 indexTestUnit('''
665 class A {
666 main() {
667 print(1 + 2);
668 }
669 }
670 ''');
671 _createRefactoringForString('1 + 2');
672 // apply refactoring
673 return _assertSuccessfulRefactoring('''
674 class A {
675 main() {
676 var res = 1 + 2;
677 print(res);
678 }
679 }
680 ''');
681 }
682
683 test_singleExpression_leadingNotWhitespace() {
684 indexTestUnit('''
685 main() {
686 int a = 12 + 345;
687 }
688 ''');
689 _createRefactoringForString('+ 345');
690 // check conditions
691 return _assertInitialConditions_fatal_selection();
692 }
693
694 test_singleExpression_leadingWhitespace() {
695 indexTestUnit('''
696 main() {
697 int a = 12 /*abc*/ + 345;
698 }
699 ''');
700 _createRefactoringForString('12 /*abc*/');
701 // apply refactoring
702 return _assertSuccessfulRefactoring('''
703 main() {
704 var res = 12 /*abc*/;
705 int a = res + 345;
706 }
707 ''');
708 }
709
710 /**
711 * Here we use knowledge how exactly `1 + 2 + 3 + 41 is parsed. We know that
712 * `1 + 2` will be a separate and complete binary expression, so it can be
713 * handled as a single expression.
714 */
715 test_singleExpression_partOfBinaryExpression() {
716 indexTestUnit('''
717 main() {
718 int a = 1 + 2 + 3 + 4;
719 }
720 ''');
721 _createRefactoringForString('1 + 2');
722 // apply refactoring
723 return _assertSuccessfulRefactoring('''
724 main() {
725 var res = 1 + 2;
726 int a = res + 3 + 4;
727 }
728 ''');
729 }
730
731 test_singleExpression_trailingComment() {
732 indexTestUnit('''
733 main() {
734 int a = 1 + 2;
735 }
736 ''');
737 _createRefactoringForString(' 1 + 2');
738 // apply refactoring
739 return _assertSuccessfulRefactoring('''
740 main() {
741 var res = 1 + 2;
742 int a = res;
743 }
744 ''');
745 }
746
747 test_singleExpression_trailingNotWhitespace() {
748 indexTestUnit('''
749 main() {
750 int a = 12 + 345;
751 }
752 ''');
753 _createRefactoringForString('12 +');
754 // check conditions
755 return _assertInitialConditions_fatal_selection();
756 }
757
758 test_singleExpression_trailingWhitespace() {
759 indexTestUnit('''
760 main() {
761 int a = 1 + 2 ;
762 }
763 ''');
764 _createRefactoringForString('1 + 2 ');
765 // apply refactoring
766 return _assertSuccessfulRefactoring('''
767 main() {
768 var res = 1 + 2 ;
769 int a = res;
770 }
771 ''');
772 }
773
774 test_stringLiteral_part() {
775 indexTestUnit('''
776 main() {
777 print('abcdefgh');
778 }
779 ''');
780 _createRefactoringForString('cde');
781 // apply refactoring
782 return _assertSuccessfulRefactoring(r'''
783 main() {
784 var res = 'cde';
785 print('ab${res}fgh');
786 }
787 ''');
788 }
789
790 test_stringLiteral_whole() {
791 indexTestUnit('''
792 main() {
793 print('abc');
794 }
795 ''');
796 _createRefactoringForString("'abc'");
797 // apply refactoring
798 return _assertSuccessfulRefactoring('''
799 main() {
800 var res = 'abc';
801 print(res);
802 }
803 ''');
804 }
805
806 Future _assertInitialConditions_fatal_selection() {
807 return refactoring.checkInitialConditions().then((status) {
808 assertRefactoringStatus(
809 status,
810 RefactoringStatusSeverity.FATAL,
811 expectedMessage: 'Expression must be selected to activate this refacto ring.');
812 });
813 }
814
815 /**
816 * Checks that all conditions are OK and the result of applying the [Change]
817 * to [testUnit] is [expectedCode].
818 */
819 Future _assertSuccessfulRefactoring(String expectedCode) {
820 return assertRefactoringConditionsOK().then((_) {
821 return refactoring.createChange().then((Change refactoringChange) {
822 this.refactoringChange = refactoringChange;
823 assertTestChangeResult(expectedCode);
824 });
825 });
826 }
827
828 void _createRefactoring(int offset, int length) {
829 refactoring = new ExtractLocalRefactoringImpl(testUnit, offset, length);
830 refactoring.name = 'res';
831 }
832
833 /**
834 * Creates a new refactoring in [refactoring] for the selection range of the
835 * given [search] pattern.
836 */
837 void _createRefactoringForString(String search) {
838 int offset = findOffset(search);
839 int length = search.length;
840 _createRefactoring(offset, length);
841 }
842
843 void _createRefactoringWithSuffix(String selectionSearch, String suffix) {
844 int offset = findOffset(selectionSearch + suffix);
845 int length = selectionSearch.length;
846 _createRefactoring(offset, length);
847 }
848 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698