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.correction.assist; | 5 library test.services.correction.assist; |
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/assist.dart'; | 8 import 'package:analysis_server/src/services/correction/assist.dart'; |
9 import 'package:analyzer/src/generated/source.dart'; | 9 import 'package:analyzer/src/generated/source.dart'; |
10 import 'package:unittest/unittest.dart'; | 10 import 'package:unittest/unittest.dart'; |
11 | 11 |
12 import '../../abstract_single_unit.dart'; | 12 import '../../abstract_single_unit.dart'; |
13 import '../../reflective_tests.dart'; | 13 import '../../reflective_tests.dart'; |
14 | 14 |
15 | |
16 main() { | 15 main() { |
17 groupSep = ' | '; | 16 groupSep = ' | '; |
18 runReflectiveTests(AssistProcessorTest); | 17 runReflectiveTests(AssistProcessorTest); |
19 } | 18 } |
20 | 19 |
21 | |
22 @reflectiveTest | 20 @reflectiveTest |
23 class AssistProcessorTest extends AbstractSingleUnitTest { | 21 class AssistProcessorTest extends AbstractSingleUnitTest { |
24 int offset; | 22 int offset; |
25 int length; | 23 int length; |
26 | 24 |
27 Assist assist; | 25 Assist assist; |
28 SourceChange change; | 26 SourceChange change; |
29 String resultCode; | 27 String resultCode; |
30 LinkedEditGroup linkedPositionGroup; | 28 LinkedEditGroup linkedPositionGroup; |
31 | 29 |
32 /** | 30 /** |
33 * Asserts that there is an [Assist] of the given [kind] at [offset] which | 31 * Asserts that there is an [Assist] of the given [kind] at [offset] which |
34 * produces the [expected] code when applied to [testCode]. | 32 * produces the [expected] code when applied to [testCode]. |
35 */ | 33 */ |
36 void assertHasAssist(AssistKind kind, String expected) { | 34 void assertHasAssist(AssistKind kind, String expected) { |
37 assist = _assertHasAssist(kind); | 35 assist = _assertHasAssist(kind); |
38 change = assist.change; | 36 change = assist.change; |
39 // apply to "file" | 37 // apply to "file" |
40 List<SourceFileEdit> fileEdits = change.edits; | 38 List<SourceFileEdit> fileEdits = change.edits; |
41 expect(fileEdits, hasLength(1)); | 39 expect(fileEdits, hasLength(1)); |
42 resultCode = SourceEdit.applySequence(testCode, change.edits[0].edits); | 40 resultCode = SourceEdit.applySequence(testCode, change.edits[0].edits); |
43 // verify | 41 // verify |
44 expect(resultCode, expected); | 42 expect(resultCode, expected); |
45 } | 43 } |
46 | 44 |
47 /** | 45 /** |
48 * Calls [assertHasAssist] at the offset of [offsetSearch] in [testCode]. | 46 * Calls [assertHasAssist] at the offset of [offsetSearch] in [testCode]. |
49 */ | 47 */ |
50 void assertHasAssistAt(String offsetSearch, AssistKind kind, | 48 void assertHasAssistAt( |
51 String expected) { | 49 String offsetSearch, AssistKind kind, String expected) { |
52 offset = findOffset(offsetSearch); | 50 offset = findOffset(offsetSearch); |
53 assertHasAssist(kind, expected); | 51 assertHasAssist(kind, expected); |
54 } | 52 } |
55 | 53 |
56 /** | 54 /** |
57 * Asserts that there is no [Assist] of the given [kind] at [offset]. | 55 * Asserts that there is no [Assist] of the given [kind] at [offset]. |
58 */ | 56 */ |
59 void assertNoAssist(AssistKind kind) { | 57 void assertNoAssist(AssistKind kind) { |
60 List<Assist> assists = computeAssists(testUnit, offset, length); | 58 List<Assist> assists = computeAssists(testUnit, offset, length); |
61 for (Assist assist in assists) { | 59 for (Assist assist in assists) { |
(...skipping 17 matching lines...) Expand all Loading... |
79 } | 77 } |
80 | 78 |
81 List<Position> expectedPositions(List<String> patterns) { | 79 List<Position> expectedPositions(List<String> patterns) { |
82 List<Position> positions = <Position>[]; | 80 List<Position> positions = <Position>[]; |
83 patterns.forEach((String search) { | 81 patterns.forEach((String search) { |
84 positions.add(expectedPosition(search)); | 82 positions.add(expectedPosition(search)); |
85 }); | 83 }); |
86 return positions; | 84 return positions; |
87 } | 85 } |
88 | 86 |
89 List<LinkedEditSuggestion> expectedSuggestions(LinkedEditSuggestionKind kind, | 87 List<LinkedEditSuggestion> expectedSuggestions( |
90 List<String> values) { | 88 LinkedEditSuggestionKind kind, List<String> values) { |
91 return values.map((value) { | 89 return values.map((value) { |
92 return new LinkedEditSuggestion(value, kind); | 90 return new LinkedEditSuggestion(value, kind); |
93 }).toList(); | 91 }).toList(); |
94 } | 92 } |
95 | 93 |
96 void setUp() { | 94 void setUp() { |
97 super.setUp(); | 95 super.setUp(); |
98 offset = 0; | 96 offset = 0; |
99 length = 0; | 97 length = 0; |
100 } | 98 } |
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 } | 586 } |
589 List<int> readBytes() => <int>[]; | 587 List<int> readBytes() => <int>[]; |
590 '''); | 588 '''); |
591 assertHasAssistAt('readBytes();', AssistKind.ASSIGN_TO_LOCAL_VARIABLE, ''' | 589 assertHasAssistAt('readBytes();', AssistKind.ASSIGN_TO_LOCAL_VARIABLE, ''' |
592 main() { | 590 main() { |
593 List<int> bytes; | 591 List<int> bytes; |
594 var readBytes = readBytes(); | 592 var readBytes = readBytes(); |
595 } | 593 } |
596 List<int> readBytes() => <int>[]; | 594 List<int> readBytes() => <int>[]; |
597 '''); | 595 '''); |
598 _assertLinkedGroup( | 596 _assertLinkedGroup(change.linkedEditGroups[0], [ |
599 change.linkedEditGroups[0], | 597 'readBytes = ' |
600 ['readBytes = '], | 598 ], expectedSuggestions( |
601 expectedSuggestions( | 599 LinkedEditSuggestionKind.VARIABLE, ['list', 'bytes2', 'readBytes'])); |
602 LinkedEditSuggestionKind.VARIABLE, | |
603 ['list', 'bytes2', 'readBytes'])); | |
604 } | 600 } |
605 | 601 |
606 void test_assignToLocalVariable_alreadyAssignment() { | 602 void test_assignToLocalVariable_alreadyAssignment() { |
607 resolveTestUnit(''' | 603 resolveTestUnit(''' |
608 main() { | 604 main() { |
609 var vvv; | 605 var vvv; |
610 vvv = 42; | 606 vvv = 42; |
611 } | 607 } |
612 '''); | 608 '''); |
613 assertNoAssistAt('vvv =', AssistKind.ASSIGN_TO_LOCAL_VARIABLE); | 609 assertNoAssistAt('vvv =', AssistKind.ASSIGN_TO_LOCAL_VARIABLE); |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 } | 778 } |
783 | 779 |
784 void test_convertToExpressionBody_OK_method_onBlock() { | 780 void test_convertToExpressionBody_OK_method_onBlock() { |
785 resolveTestUnit(''' | 781 resolveTestUnit(''' |
786 class A { | 782 class A { |
787 m() { // marker | 783 m() { // marker |
788 return 42; | 784 return 42; |
789 } | 785 } |
790 } | 786 } |
791 '''); | 787 '''); |
792 assertHasAssistAt( | 788 assertHasAssistAt('{ // marker', AssistKind.CONVERT_INTO_EXPRESSION_BODY, |
793 '{ // marker', | |
794 AssistKind.CONVERT_INTO_EXPRESSION_BODY, | |
795 ''' | 789 ''' |
796 class A { | 790 class A { |
797 m() => 42; | 791 m() => 42; |
798 } | 792 } |
799 '''); | 793 '''); |
800 } | 794 } |
801 | 795 |
802 void test_convertToExpressionBody_OK_topFunction_onReturnStatement() { | 796 void test_convertToExpressionBody_OK_topFunction_onReturnStatement() { |
803 resolveTestUnit(''' | 797 resolveTestUnit(''' |
804 fff() { | 798 fff() { |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1135 1 + 2 - 3 + 4; | 1129 1 + 2 - 3 + 4; |
1136 } | 1130 } |
1137 '''); | 1131 '''); |
1138 assertHasAssistAt('+ 2', AssistKind.EXCHANGE_OPERANDS, ''' | 1132 assertHasAssistAt('+ 2', AssistKind.EXCHANGE_OPERANDS, ''' |
1139 main() { | 1133 main() { |
1140 2 + 1 - 3 + 4; | 1134 2 + 1 - 3 + 4; |
1141 } | 1135 } |
1142 '''); | 1136 '''); |
1143 } | 1137 } |
1144 | 1138 |
1145 void | 1139 void test_exchangeBinaryExpressionArguments_OK_extended_sameOperator_afterFirs
t() { |
1146 test_exchangeBinaryExpressionArguments_OK_extended_sameOperator_afterFirst
() { | |
1147 resolveTestUnit(''' | 1140 resolveTestUnit(''' |
1148 main() { | 1141 main() { |
1149 1 + 2 + 3; | 1142 1 + 2 + 3; |
1150 } | 1143 } |
1151 '''); | 1144 '''); |
1152 assertHasAssistAt('+ 2', AssistKind.EXCHANGE_OPERANDS, ''' | 1145 assertHasAssistAt('+ 2', AssistKind.EXCHANGE_OPERANDS, ''' |
1153 main() { | 1146 main() { |
1154 2 + 3 + 1; | 1147 2 + 3 + 1; |
1155 } | 1148 } |
1156 '''); | 1149 '''); |
1157 } | 1150 } |
1158 | 1151 |
1159 void | 1152 void test_exchangeBinaryExpressionArguments_OK_extended_sameOperator_afterSeco
nd() { |
1160 test_exchangeBinaryExpressionArguments_OK_extended_sameOperator_afterSecon
d() { | |
1161 resolveTestUnit(''' | 1153 resolveTestUnit(''' |
1162 main() { | 1154 main() { |
1163 1 + 2 + 3; | 1155 1 + 2 + 3; |
1164 } | 1156 } |
1165 '''); | 1157 '''); |
1166 assertHasAssistAt('+ 3', AssistKind.EXCHANGE_OPERANDS, ''' | 1158 assertHasAssistAt('+ 3', AssistKind.EXCHANGE_OPERANDS, ''' |
1167 main() { | 1159 main() { |
1168 3 + 1 + 2; | 1160 3 + 1 + 2; |
1169 } | 1161 } |
1170 '''); | 1162 '''); |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1365 String expected = ''' | 1357 String expected = ''' |
1366 class MyTypeName {} | 1358 class MyTypeName {} |
1367 main(p) { | 1359 main(p) { |
1368 if (p is MyTypeName) { | 1360 if (p is MyTypeName) { |
1369 MyTypeName myTypeName = p; | 1361 MyTypeName myTypeName = p; |
1370 } | 1362 } |
1371 p = null; | 1363 p = null; |
1372 } | 1364 } |
1373 '''; | 1365 '''; |
1374 assertHasAssistAt( | 1366 assertHasAssistAt( |
1375 'is MyType', | 1367 'is MyType', AssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected); |
1376 AssistKind.INTRODUCE_LOCAL_CAST_TYPE, | 1368 _assertLinkedGroup(change.linkedEditGroups[0], [ |
1377 expected); | 1369 'myTypeName = ' |
1378 _assertLinkedGroup( | 1370 ], expectedSuggestions( |
1379 change.linkedEditGroups[0], | 1371 LinkedEditSuggestionKind.VARIABLE, ['myTypeName', 'typeName', 'name'])); |
1380 ['myTypeName = '], | |
1381 expectedSuggestions( | |
1382 LinkedEditSuggestionKind.VARIABLE, | |
1383 ['myTypeName', 'typeName', 'name'])); | |
1384 // another good location | 1372 // another good location |
1385 assertHasAssistAt('if (p', AssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected); | 1373 assertHasAssistAt('if (p', AssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected); |
1386 } | 1374 } |
1387 | 1375 |
1388 void test_introduceLocalTestedType_OK_while() { | 1376 void test_introduceLocalTestedType_OK_while() { |
1389 resolveTestUnit(''' | 1377 resolveTestUnit(''' |
1390 main(p) { | 1378 main(p) { |
1391 while (p is String) { | 1379 while (p is String) { |
1392 } | 1380 } |
1393 p = null; | 1381 p = null; |
1394 } | 1382 } |
1395 '''); | 1383 '''); |
1396 String expected = ''' | 1384 String expected = ''' |
1397 main(p) { | 1385 main(p) { |
1398 while (p is String) { | 1386 while (p is String) { |
1399 String s = p; | 1387 String s = p; |
1400 } | 1388 } |
1401 p = null; | 1389 p = null; |
1402 } | 1390 } |
1403 '''; | 1391 '''; |
1404 assertHasAssistAt( | 1392 assertHasAssistAt( |
1405 'is String', | 1393 'is String', AssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected); |
1406 AssistKind.INTRODUCE_LOCAL_CAST_TYPE, | |
1407 expected); | |
1408 assertHasAssistAt( | 1394 assertHasAssistAt( |
1409 'while (p', | 1395 'while (p', AssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected); |
1410 AssistKind.INTRODUCE_LOCAL_CAST_TYPE, | |
1411 expected); | |
1412 } | 1396 } |
1413 | 1397 |
1414 void test_invalidSelection() { | 1398 void test_invalidSelection() { |
1415 resolveTestUnit(''); | 1399 resolveTestUnit(''); |
1416 List<Assist> assists = computeAssists(testUnit, -1, 0); | 1400 List<Assist> assists = computeAssists(testUnit, -1, 0); |
1417 expect(assists, isEmpty); | 1401 expect(assists, isEmpty); |
1418 } | 1402 } |
1419 | 1403 |
1420 void test_invertIfStatement_blocks() { | 1404 void test_invertIfStatement_blocks() { |
1421 resolveTestUnit(''' | 1405 resolveTestUnit(''' |
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2021 void test_joinVariableDeclaration_onDeclaration_wrong_lastStatement() { | 2005 void test_joinVariableDeclaration_onDeclaration_wrong_lastStatement() { |
2022 resolveTestUnit(''' | 2006 resolveTestUnit(''' |
2023 main() { | 2007 main() { |
2024 if (true) | 2008 if (true) |
2025 var v; | 2009 var v; |
2026 } | 2010 } |
2027 '''); | 2011 '''); |
2028 assertNoAssistAt('v;', AssistKind.JOIN_VARIABLE_DECLARATION); | 2012 assertNoAssistAt('v;', AssistKind.JOIN_VARIABLE_DECLARATION); |
2029 } | 2013 } |
2030 | 2014 |
2031 void | 2015 void test_joinVariableDeclaration_onDeclaration_wrong_nextNotAssignmentExpress
ion() { |
2032 test_joinVariableDeclaration_onDeclaration_wrong_nextNotAssignmentExpressi
on() { | |
2033 resolveTestUnit(''' | 2016 resolveTestUnit(''' |
2034 main() { | 2017 main() { |
2035 var v; | 2018 var v; |
2036 42; | 2019 42; |
2037 } | 2020 } |
2038 '''); | 2021 '''); |
2039 assertNoAssistAt('v;', AssistKind.JOIN_VARIABLE_DECLARATION); | 2022 assertNoAssistAt('v;', AssistKind.JOIN_VARIABLE_DECLARATION); |
2040 } | 2023 } |
2041 | 2024 |
2042 void | 2025 void test_joinVariableDeclaration_onDeclaration_wrong_nextNotExpressionStateme
nt() { |
2043 test_joinVariableDeclaration_onDeclaration_wrong_nextNotExpressionStatemen
t() { | |
2044 resolveTestUnit(''' | 2026 resolveTestUnit(''' |
2045 main() { | 2027 main() { |
2046 var v; | 2028 var v; |
2047 if (true) return; | 2029 if (true) return; |
2048 } | 2030 } |
2049 '''); | 2031 '''); |
2050 assertNoAssistAt('v;', AssistKind.JOIN_VARIABLE_DECLARATION); | 2032 assertNoAssistAt('v;', AssistKind.JOIN_VARIABLE_DECLARATION); |
2051 } | 2033 } |
2052 | 2034 |
2053 void | 2035 void test_joinVariableDeclaration_onDeclaration_wrong_nextNotPureAssignment()
{ |
2054 test_joinVariableDeclaration_onDeclaration_wrong_nextNotPureAssignment() { | |
2055 resolveTestUnit(''' | 2036 resolveTestUnit(''' |
2056 main() { | 2037 main() { |
2057 var v; | 2038 var v; |
2058 v += 1; | 2039 v += 1; |
2059 } | 2040 } |
2060 '''); | 2041 '''); |
2061 assertNoAssistAt('v;', AssistKind.JOIN_VARIABLE_DECLARATION); | 2042 assertNoAssistAt('v;', AssistKind.JOIN_VARIABLE_DECLARATION); |
2062 } | 2043 } |
2063 | 2044 |
2064 void test_joinVariableDeclaration_onDeclaration_wrong_notOneVariable() { | 2045 void test_joinVariableDeclaration_onDeclaration_wrong_notOneVariable() { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2136 } | 2117 } |
2137 '''); | 2118 '''); |
2138 } | 2119 } |
2139 | 2120 |
2140 void test_replaceConditionalWithIfElse_OK_return() { | 2121 void test_replaceConditionalWithIfElse_OK_return() { |
2141 resolveTestUnit(''' | 2122 resolveTestUnit(''' |
2142 main() { | 2123 main() { |
2143 return true ? 111 : 222; | 2124 return true ? 111 : 222; |
2144 } | 2125 } |
2145 '''); | 2126 '''); |
2146 assertHasAssistAt( | 2127 assertHasAssistAt('return ', AssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE, |
2147 'return ', | |
2148 AssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE, | |
2149 ''' | 2128 ''' |
2150 main() { | 2129 main() { |
2151 if (true) { | 2130 if (true) { |
2152 return 111; | 2131 return 111; |
2153 } else { | 2132 } else { |
2154 return 222; | 2133 return 222; |
2155 } | 2134 } |
2156 } | 2135 } |
2157 '''); | 2136 '''); |
2158 } | 2137 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2195 resolveTestUnit(''' | 2174 resolveTestUnit(''' |
2196 main() { | 2175 main() { |
2197 int vvv; | 2176 int vvv; |
2198 if (true) { | 2177 if (true) { |
2199 vvv = 111; | 2178 vvv = 111; |
2200 } else { | 2179 } else { |
2201 vvv = 222; | 2180 vvv = 222; |
2202 } | 2181 } |
2203 } | 2182 } |
2204 '''); | 2183 '''); |
2205 assertHasAssistAt( | 2184 assertHasAssistAt('if (true)', AssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL, |
2206 'if (true)', | |
2207 AssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL, | |
2208 ''' | 2185 ''' |
2209 main() { | 2186 main() { |
2210 int vvv; | 2187 int vvv; |
2211 vvv = true ? 111 : 222; | 2188 vvv = true ? 111 : 222; |
2212 } | 2189 } |
2213 '''); | 2190 '''); |
2214 } | 2191 } |
2215 | 2192 |
2216 void test_replaceIfElseWithConditional_OK_return() { | 2193 void test_replaceIfElseWithConditional_OK_return() { |
2217 resolveTestUnit(''' | 2194 resolveTestUnit(''' |
2218 main() { | 2195 main() { |
2219 if (true) { | 2196 if (true) { |
2220 return 111; | 2197 return 111; |
2221 } else { | 2198 } else { |
2222 return 222; | 2199 return 222; |
2223 } | 2200 } |
2224 } | 2201 } |
2225 '''); | 2202 '''); |
2226 assertHasAssistAt( | 2203 assertHasAssistAt('if (true)', AssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL, |
2227 'if (true)', | |
2228 AssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL, | |
2229 ''' | 2204 ''' |
2230 main() { | 2205 main() { |
2231 return true ? 111 : 222; | 2206 return true ? 111 : 222; |
2232 } | 2207 } |
2233 '''); | 2208 '''); |
2234 } | 2209 } |
2235 | 2210 |
2236 void test_replaceIfElseWithConditional_wrong_expressionVsReturn() { | 2211 void test_replaceIfElseWithConditional_wrong_expressionVsReturn() { |
2237 resolveTestUnit(''' | 2212 resolveTestUnit(''' |
2238 main() { | 2213 main() { |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2657 positions.add(new Position(testFile, offset)); | 2632 positions.add(new Position(testFile, offset)); |
2658 } | 2633 } |
2659 return positions; | 2634 return positions; |
2660 } | 2635 } |
2661 | 2636 |
2662 void _setStartEndSelection() { | 2637 void _setStartEndSelection() { |
2663 offset = findOffset('// start\n') + '// start\n'.length; | 2638 offset = findOffset('// start\n') + '// start\n'.length; |
2664 length = findOffset('// end') - offset; | 2639 length = findOffset('// end') - offset; |
2665 } | 2640 } |
2666 } | 2641 } |
OLD | NEW |