| 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 // This code was auto-generated, is not intended to be edited, and is subject to | 5 // This code was auto-generated, is not intended to be edited, and is subject to |
| 6 // significant change. Please see the README file for more information. | 6 // significant change. Please see the README file for more information. |
| 7 | 7 |
| 8 library test.services.correction.fix; | 8 library test.services.correction.fix; |
| 9 | 9 |
| 10 import 'package:analysis_services/correction/change.dart'; | 10 import 'package:analysis_services/correction/change.dart'; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 runReflectiveTests(FixProcessorTest); | 25 runReflectiveTests(FixProcessorTest); |
| 26 }); | 26 }); |
| 27 } | 27 } |
| 28 | 28 |
| 29 | 29 |
| 30 @ReflectiveTestCase() | 30 @ReflectiveTestCase() |
| 31 class FixProcessorTest extends AbstractSingleUnitTest { | 31 class FixProcessorTest extends AbstractSingleUnitTest { |
| 32 Index index; | 32 Index index; |
| 33 SearchEngineImpl searchEngine; | 33 SearchEngineImpl searchEngine; |
| 34 | 34 |
| 35 Fix fix; |
| 36 Change change; |
| 37 String resultCode; |
| 38 |
| 35 void assertHasFix(FixKind kind, String expected) { | 39 void assertHasFix(FixKind kind, String expected) { |
| 36 AnalysisError error = _findErrorToFix(); | 40 AnalysisError error = _findErrorToFix(); |
| 37 Fix fix = _computeFix(kind, error); | 41 fix = _assertHasFix(kind, error); |
| 42 change = fix.change; |
| 38 // apply to "file" | 43 // apply to "file" |
| 39 List<FileEdit> fileEdits = fix.change.edits; | 44 List<FileEdit> fileEdits = change.edits; |
| 40 expect(fileEdits, hasLength(1)); | 45 expect(fileEdits, hasLength(1)); |
| 41 String actualCode = _applyEdits(testCode, fix.change.edits[0].edits); | 46 resultCode = _applyEdits(testCode, change.edits[0].edits); |
| 42 // verify | 47 // verify |
| 43 expect(expected, actualCode); | 48 expect(resultCode, expected); |
| 49 } |
| 50 |
| 51 void assertHasPositionGroup(String id, List<Position> expectedPositions) { |
| 52 List<PositionGroup> positionGroups = change.positionGroups; |
| 53 for (PositionGroup group in positionGroups) { |
| 54 if (group.id == id) { |
| 55 expect(group.positions, unorderedEquals(expectedPositions)); |
| 56 return; |
| 57 } |
| 58 } |
| 59 fail('No PositionGroup with id=$id found in $positionGroups'); |
| 60 } |
| 61 |
| 62 void assertNoFix(FixKind kind) { |
| 63 AnalysisError error = _findErrorToFix(); |
| 64 List<Fix> fixes = computeFixes(searchEngine, testFile, testUnit, error); |
| 65 for (Fix fix in fixes) { |
| 66 if (fix.kind == kind) { |
| 67 throw fail('Unexpected fix $kind in\n${fixes.join('\n')}'); |
| 68 } |
| 69 } |
| 70 } |
| 71 |
| 72 Position expectedPosition(String search) { |
| 73 int offset = resultCode.indexOf(search); |
| 74 int length = getLeadingIdentifierLength(search); |
| 75 return new Position(testFile, offset, length); |
| 76 } |
| 77 |
| 78 List<Position> expectedPositions(List<String> patterns) { |
| 79 List<Position> positions = <Position>[]; |
| 80 patterns.forEach((String search) { |
| 81 positions.add(expectedPosition(search)); |
| 82 }); |
| 83 return positions; |
| 44 } | 84 } |
| 45 | 85 |
| 46 void setUp() { | 86 void setUp() { |
| 47 super.setUp(); | 87 super.setUp(); |
| 48 index = createLocalMemoryIndex(); | 88 index = createLocalMemoryIndex(); |
| 49 searchEngine = new SearchEngineImpl(index); | 89 searchEngine = new SearchEngineImpl(index); |
| 50 verifyNoTestUnitErrors = false; | 90 verifyNoTestUnitErrors = false; |
| 51 } | 91 } |
| 52 | 92 |
| 53 void test_boolean() { | 93 void test_boolean() { |
| 54 _indexTestUnit(''' | 94 _indexTestUnit(''' |
| 55 main() { | 95 main() { |
| 56 boolean v; | 96 boolean v; |
| 57 } | 97 } |
| 58 '''); | 98 '''); |
| 59 assertHasFix(FixKind.REPLACE_BOOLEAN_WITH_BOOL, ''' | 99 assertHasFix(FixKind.REPLACE_BOOLEAN_WITH_BOOL, ''' |
| 60 main() { | 100 main() { |
| 61 bool v; | 101 bool v; |
| 62 } | 102 } |
| 63 '''); | 103 '''); |
| 64 } | 104 } |
| 65 | 105 |
| 106 void test_changeToStaticAccess_method() { |
| 107 _indexTestUnit(''' |
| 108 class A { |
| 109 static foo() {} |
| 110 } |
| 111 main(A a) { |
| 112 a.foo(); |
| 113 } |
| 114 '''); |
| 115 assertHasFix(FixKind.CHANGE_TO_STATIC_ACCESS, ''' |
| 116 class A { |
| 117 static foo() {} |
| 118 } |
| 119 main(A a) { |
| 120 A.foo(); |
| 121 } |
| 122 '''); |
| 123 } |
| 124 |
| 125 void test_changeToStaticAccess_method_prefixLibrary() { |
| 126 _indexTestUnit(''' |
| 127 import 'dart:async' as pref; |
| 128 main(pref.Future f) { |
| 129 f.wait([]); |
| 130 } |
| 131 '''); |
| 132 assertHasFix(FixKind.CHANGE_TO_STATIC_ACCESS, ''' |
| 133 import 'dart:async' as pref; |
| 134 main(pref.Future f) { |
| 135 pref.Future.wait([]); |
| 136 } |
| 137 '''); |
| 138 } |
| 139 |
| 140 void test_changeToStaticAccess_property() { |
| 141 _indexTestUnit(''' |
| 142 class A { |
| 143 static get foo => 42; |
| 144 } |
| 145 main(A a) { |
| 146 a.foo; |
| 147 } |
| 148 '''); |
| 149 assertHasFix(FixKind.CHANGE_TO_STATIC_ACCESS, ''' |
| 150 class A { |
| 151 static get foo => 42; |
| 152 } |
| 153 main(A a) { |
| 154 A.foo; |
| 155 } |
| 156 '''); |
| 157 } |
| 158 |
| 159 void test_createClass() { |
| 160 _indexTestUnit(''' |
| 161 main() { |
| 162 Test v = null; |
| 163 } |
| 164 '''); |
| 165 assertHasFix(FixKind.CREATE_CLASS, ''' |
| 166 main() { |
| 167 Test v = null; |
| 168 } |
| 169 |
| 170 class Test { |
| 171 } |
| 172 '''); |
| 173 assertHasPositionGroup('NAME', expectedPositions(['Test v =', 'Test {'])); |
| 174 } |
| 175 |
| 176 void test_createConstructorSuperExplicit() { |
| 177 _indexTestUnit(''' |
| 178 class A { |
| 179 A(bool p1, int p2, double p3, String p4, {p5}); |
| 180 } |
| 181 class B extends A { |
| 182 B() {} |
| 183 } |
| 184 '''); |
| 185 assertHasFix(FixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, ''' |
| 186 class A { |
| 187 A(bool p1, int p2, double p3, String p4, {p5}); |
| 188 } |
| 189 class B extends A { |
| 190 B() : super(false, 0, 0.0, '') {} |
| 191 } |
| 192 '''); |
| 193 } |
| 194 |
| 195 void test_createConstructorSuperExplicit_hasInitializers() { |
| 196 _indexTestUnit(''' |
| 197 class A { |
| 198 A(int p); |
| 199 } |
| 200 class B extends A { |
| 201 int field; |
| 202 B() : field = 42 {} |
| 203 } |
| 204 '''); |
| 205 assertHasFix(FixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, ''' |
| 206 class A { |
| 207 A(int p); |
| 208 } |
| 209 class B extends A { |
| 210 int field; |
| 211 B() : field = 42, super(0) {} |
| 212 } |
| 213 '''); |
| 214 } |
| 215 |
| 216 void test_createConstructorSuperExplicit_named() { |
| 217 _indexTestUnit(''' |
| 218 class A { |
| 219 A.named(int p); |
| 220 } |
| 221 class B extends A { |
| 222 B() {} |
| 223 } |
| 224 '''); |
| 225 assertHasFix(FixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, ''' |
| 226 class A { |
| 227 A.named(int p); |
| 228 } |
| 229 class B extends A { |
| 230 B() : super.named(0) {} |
| 231 } |
| 232 '''); |
| 233 } |
| 234 |
| 235 void test_createConstructorSuperExplicit_named_private() { |
| 236 _indexTestUnit(''' |
| 237 class A { |
| 238 A._named(int p); |
| 239 } |
| 240 class B extends A { |
| 241 B() {} |
| 242 } |
| 243 '''); |
| 244 assertNoFix(FixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION); |
| 245 } |
| 246 |
| 247 void test_createConstructor_insteadOfSyntheticDefault() { |
| 248 _indexTestUnit(''' |
| 249 class A { |
| 250 int field; |
| 251 |
| 252 method() {} |
| 253 } |
| 254 main() { |
| 255 new A(1, 2.0); |
| 256 } |
| 257 '''); |
| 258 assertHasFix(FixKind.CREATE_CONSTRUCTOR, ''' |
| 259 class A { |
| 260 int field; |
| 261 |
| 262 A(int i, double d) { |
| 263 } |
| 264 |
| 265 method() {} |
| 266 } |
| 267 main() { |
| 268 new A(1, 2.0); |
| 269 } |
| 270 '''); |
| 271 } |
| 272 |
| 273 void test_createConstructor_named() { |
| 274 _indexTestUnit(''' |
| 275 class A { |
| 276 method() {} |
| 277 } |
| 278 main() { |
| 279 new A.named(1, 2.0); |
| 280 } |
| 281 '''); |
| 282 assertHasFix(FixKind.CREATE_CONSTRUCTOR, ''' |
| 283 class A { |
| 284 A.named(int i, double d) { |
| 285 } |
| 286 |
| 287 method() {} |
| 288 } |
| 289 main() { |
| 290 new A.named(1, 2.0); |
| 291 } |
| 292 '''); |
| 293 } |
| 294 |
| 295 void test_expectedToken_semicolon() { |
| 296 _indexTestUnit(''' |
| 297 main() { |
| 298 print(0) |
| 299 } |
| 300 '''); |
| 301 assertHasFix(FixKind.INSERT_SEMICOLON, ''' |
| 302 main() { |
| 303 print(0); |
| 304 } |
| 305 '''); |
| 306 } |
| 307 |
| 308 void test_isNotNull() { |
| 309 _indexTestUnit(''' |
| 310 main(p) { |
| 311 p is! Null; |
| 312 } |
| 313 '''); |
| 314 assertHasFix(FixKind.USE_NOT_EQ_NULL, ''' |
| 315 main(p) { |
| 316 p != null; |
| 317 } |
| 318 '''); |
| 319 } |
| 320 |
| 321 void test_isNull() { |
| 322 _indexTestUnit(''' |
| 323 main(p) { |
| 324 p is Null; |
| 325 } |
| 326 '''); |
| 327 assertHasFix(FixKind.USE_EQ_EQ_NULL, ''' |
| 328 main(p) { |
| 329 p == null; |
| 330 } |
| 331 '''); |
| 332 } |
| 333 |
| 334 void test_makeEnclosingClassAbstract_declaresAbstractMethod() { |
| 335 _indexTestUnit(''' |
| 336 class A { |
| 337 m(); |
| 338 } |
| 339 '''); |
| 340 assertHasFix(FixKind.MAKE_CLASS_ABSTRACT, ''' |
| 341 abstract class A { |
| 342 m(); |
| 343 } |
| 344 '''); |
| 345 } |
| 346 |
| 347 void test_makeEnclosingClassAbstract_inheritsAbstractMethod() { |
| 348 _indexTestUnit(''' |
| 349 abstract class A { |
| 350 m(); |
| 351 } |
| 352 class B extends A { |
| 353 } |
| 354 '''); |
| 355 assertHasFix(FixKind.MAKE_CLASS_ABSTRACT, ''' |
| 356 abstract class A { |
| 357 m(); |
| 358 } |
| 359 abstract class B extends A { |
| 360 } |
| 361 '''); |
| 362 } |
| 363 |
| 364 void test_removeParentheses_inGetterDeclaration() { |
| 365 _indexTestUnit(''' |
| 366 class A { |
| 367 int get foo() => 0; |
| 368 } |
| 369 '''); |
| 370 assertHasFix(FixKind.REMOVE_PARAMETERS_IN_GETTER_DECLARATION, ''' |
| 371 class A { |
| 372 int get foo => 0; |
| 373 } |
| 374 '''); |
| 375 } |
| 376 |
| 377 void test_removeParentheses_inGetterInvocation() { |
| 378 _indexTestUnit(''' |
| 379 class A { |
| 380 int get foo => 0; |
| 381 } |
| 382 main(A a) { |
| 383 a.foo(); |
| 384 } |
| 385 '''); |
| 386 assertHasFix(FixKind.REMOVE_PARENTHESIS_IN_GETTER_INVOCATION, ''' |
| 387 class A { |
| 388 int get foo => 0; |
| 389 } |
| 390 main(A a) { |
| 391 a.foo; |
| 392 } |
| 393 '''); |
| 394 } |
| 395 |
| 396 void test_removeUnnecessaryCast_assignment() { |
| 397 _indexTestUnit(''' |
| 398 main(Object p) { |
| 399 if (p is String) { |
| 400 String v = ((p as String)); |
| 401 } |
| 402 } |
| 403 '''); |
| 404 assertHasFix(FixKind.REMOVE_UNNECASSARY_CAST, ''' |
| 405 main(Object p) { |
| 406 if (p is String) { |
| 407 String v = p; |
| 408 } |
| 409 } |
| 410 '''); |
| 411 } |
| 412 |
| 413 void test_removeUnusedImport() { |
| 414 _indexTestUnit(''' |
| 415 import 'dart:math'; |
| 416 main() { |
| 417 } |
| 418 '''); |
| 419 assertHasFix(FixKind.REMOVE_UNUSED_IMPORT, ''' |
| 420 main() { |
| 421 } |
| 422 '''); |
| 423 } |
| 424 |
| 425 void test_removeUnusedImport_anotherImportOnLine() { |
| 426 _indexTestUnit(''' |
| 427 import 'dart:math'; import 'dart:async'; |
| 428 |
| 429 main() { |
| 430 Future f; |
| 431 } |
| 432 '''); |
| 433 assertHasFix(FixKind.REMOVE_UNUSED_IMPORT, ''' |
| 434 import 'dart:async'; |
| 435 |
| 436 main() { |
| 437 Future f; |
| 438 } |
| 439 '''); |
| 440 } |
| 441 |
| 442 void test_removeUnusedImport_severalLines() { |
| 443 _indexTestUnit(''' |
| 444 import |
| 445 'dart:math'; |
| 446 main() { |
| 447 } |
| 448 '''); |
| 449 assertHasFix(FixKind.REMOVE_UNUSED_IMPORT, ''' |
| 450 main() { |
| 451 } |
| 452 '''); |
| 453 } |
| 454 |
| 455 void test_replaceWithConstInstanceCreation() { |
| 456 _indexTestUnit(''' |
| 457 class A { |
| 458 const A(); |
| 459 } |
| 460 const a = new A(); |
| 461 '''); |
| 462 assertHasFix(FixKind.USE_CONST, ''' |
| 463 class A { |
| 464 const A(); |
| 465 } |
| 466 const a = const A(); |
| 467 '''); |
| 468 } |
| 469 |
| 470 void test_useEffectiveIntegerDivision() { |
| 471 _indexTestUnit(''' |
| 472 main() { |
| 473 var a = 5; |
| 474 var b = 2; |
| 475 print((a / b).toInt()); |
| 476 } |
| 477 '''); |
| 478 assertHasFix(FixKind.USE_EFFECTIVE_INTEGER_DIVISION, ''' |
| 479 main() { |
| 480 var a = 5; |
| 481 var b = 2; |
| 482 print(a ~/ b); |
| 483 } |
| 484 '''); |
| 485 } |
| 486 |
| 66 String _applyEdits(String code, List<Edit> edits) { | 487 String _applyEdits(String code, List<Edit> edits) { |
| 67 edits.sort((a, b) => b.offset - a.offset); | 488 edits.sort((a, b) => b.offset - a.offset); |
| 68 edits.forEach((Edit edit) { | 489 edits.forEach((Edit edit) { |
| 69 code = code.substring(0, edit.offset) + | 490 code = code.substring(0, edit.offset) + |
| 70 edit.replacement + | 491 edit.replacement + |
| 71 code.substring(edit.end); | 492 code.substring(edit.end); |
| 72 }); | 493 }); |
| 73 return code; | 494 return code; |
| 74 } | 495 } |
| 75 | 496 |
| 76 Fix _computeFix(FixKind kind, AnalysisError error) { | 497 /** |
| 498 * Computes fixes and verifies that there is a fix of the given kind. |
| 499 */ |
| 500 Fix _assertHasFix(FixKind kind, AnalysisError error) { |
| 77 List<Fix> fixes = computeFixes(searchEngine, testFile, testUnit, error); | 501 List<Fix> fixes = computeFixes(searchEngine, testFile, testUnit, error); |
| 78 for (Fix fix in fixes) { | 502 for (Fix fix in fixes) { |
| 79 if (fix.kind == kind) { | 503 if (fix.kind == kind) { |
| 80 return fix; | 504 return fix; |
| 81 } | 505 } |
| 82 } | 506 } |
| 83 throw fail('Expected to find fix $kind in\n${fixes.join('\n')}'); | 507 throw fail('Expected to find fix $kind in\n${fixes.join('\n')}'); |
| 84 } | 508 } |
| 85 | 509 |
| 86 AnalysisError _findErrorToFix() { | 510 AnalysisError _findErrorToFix() { |
| 87 List<AnalysisError> errors = context.getErrors(testSource).errors; | 511 List<AnalysisError> errors = context.computeErrors(testSource); |
| 88 expect( | 512 expect( |
| 89 errors, | 513 errors, |
| 90 hasLength(1), | 514 hasLength(1), |
| 91 reason: 'Exactly 1 error expected, but ${errors.length} found:\n' + | 515 reason: 'Exactly 1 error expected, but ${errors.length} found:\n' + |
| 92 errors.join('\n')); | 516 errors.join('\n')); |
| 93 return errors[0]; | 517 return errors[0]; |
| 94 } | 518 } |
| 95 | 519 |
| 96 void _indexTestUnit(String code) { | 520 void _indexTestUnit(String code) { |
| 97 resolveTestUnit(code); | 521 resolveTestUnit(code); |
| 98 index.indexUnit(context, testUnit); | 522 index.indexUnit(context, testUnit); |
| 99 } | 523 } |
| 100 } | 524 } |
| OLD | NEW |