| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2017, 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 import 'package:analysis_server/src/protocol_server.dart'; |
| 6 import 'package:analysis_server/src/services/completion/postfix/postfix_completi
on.dart'; |
| 7 import 'package:analyzer/src/dart/analysis/driver.dart'; |
| 8 import 'package:test/test.dart'; |
| 9 import 'package:test_reflective_loader/test_reflective_loader.dart'; |
| 10 |
| 11 import '../../../abstract_single_unit.dart'; |
| 12 |
| 13 main() { |
| 14 defineReflectiveSuite(() { |
| 15 defineReflectiveTests(_AssertTest); |
| 16 defineReflectiveTests(_ForTest); |
| 17 defineReflectiveTests(_NegateTest); |
| 18 defineReflectiveTests(_IfTest); |
| 19 defineReflectiveTests(_NotNullTest); |
| 20 defineReflectiveTests(_ParenTest); |
| 21 defineReflectiveTests(_ReturnTest); |
| 22 defineReflectiveTests(_SwitchTest); |
| 23 defineReflectiveTests(_TryTest); |
| 24 defineReflectiveTests(_WhileTest); |
| 25 }); |
| 26 } |
| 27 |
| 28 class PostfixCompletionTest extends AbstractSingleUnitTest { |
| 29 SourceChange change; |
| 30 |
| 31 void _assertHasChange(String message, String expectedCode, [Function cmp]) { |
| 32 if (change.message == message) { |
| 33 if (!change.edits.isEmpty) { |
| 34 String resultCode = |
| 35 SourceEdit.applySequence(testCode, change.edits[0].edits); |
| 36 expect(resultCode, expectedCode.replaceAll('/*caret*/', '')); |
| 37 if (cmp != null) { |
| 38 int offset = cmp(resultCode); |
| 39 expect(change.selection.offset, offset); |
| 40 } |
| 41 } else { |
| 42 if (cmp != null) { |
| 43 int offset = cmp(testCode); |
| 44 expect(change.selection.offset, offset); |
| 45 } |
| 46 } |
| 47 return; |
| 48 } |
| 49 fail("Expected to find |$message| but got: " + change.message); |
| 50 } |
| 51 |
| 52 _computeCompletion(int offset, String key) async { |
| 53 driver.changeFile(testFile); |
| 54 AnalysisResult result = await driver.getResult(testFile); |
| 55 PostfixCompletionContext context = new PostfixCompletionContext( |
| 56 testFile, |
| 57 result.lineInfo, |
| 58 offset, |
| 59 key, |
| 60 result.driver, |
| 61 testUnit, |
| 62 testUnitElement, |
| 63 result.errors); |
| 64 PostfixCompletionProcessor processor = |
| 65 new PostfixCompletionProcessor(context); |
| 66 bool isApplicable = await processor.isApplicable(); |
| 67 if (!isApplicable) { |
| 68 fail("Postfix completion not applicable at given location"); |
| 69 } |
| 70 PostfixCompletion completion = await processor.compute(); |
| 71 change = completion.change; |
| 72 } |
| 73 |
| 74 _prepareCompletion(String key, String sourceCode) async { |
| 75 testCode = sourceCode.replaceAll('////', ''); |
| 76 int offset = findOffset(key); |
| 77 testCode = testCode.replaceFirst(key, '', offset); |
| 78 await _prepareCompletionAt(offset, key, testCode); |
| 79 } |
| 80 |
| 81 _prepareCompletionAt(int offset, String key, String sourceCode) async { |
| 82 verifyNoTestUnitErrors = false; |
| 83 await resolveTestUnit(sourceCode); |
| 84 await _computeCompletion(offset, key); |
| 85 } |
| 86 } |
| 87 |
| 88 @reflectiveTest |
| 89 class _AssertTest extends PostfixCompletionTest { |
| 90 test_assert() async { |
| 91 await _prepareCompletion( |
| 92 '.assert', |
| 93 ''' |
| 94 f(bool expr) { |
| 95 expr.assert |
| 96 } |
| 97 '''); |
| 98 _assertHasChange( |
| 99 'Expand .assert', |
| 100 ''' |
| 101 f(bool expr) { |
| 102 assert(expr); |
| 103 } |
| 104 '''); |
| 105 } |
| 106 |
| 107 test_assertFunc() async { |
| 108 await _prepareCompletion( |
| 109 '.assert', |
| 110 ''' |
| 111 f() { |
| 112 () => true.assert |
| 113 } |
| 114 '''); |
| 115 _assertHasChange( |
| 116 'Expand .assert', |
| 117 ''' |
| 118 f() { |
| 119 assert(() => true); |
| 120 } |
| 121 '''); |
| 122 } |
| 123 |
| 124 @failingTest |
| 125 test_assertFunc_invalid() async { |
| 126 await _prepareCompletion( |
| 127 '.assert', |
| 128 ''' |
| 129 f() { |
| 130 () => null.assert |
| 131 } |
| 132 '''); |
| 133 } |
| 134 |
| 135 test_assertFuncCmp() async { |
| 136 await _prepareCompletion( |
| 137 '.assert', |
| 138 ''' |
| 139 f(int x, int y) { |
| 140 () => x + 3 > y + 4.assert |
| 141 } |
| 142 '''); |
| 143 _assertHasChange( |
| 144 'Expand .assert', |
| 145 ''' |
| 146 f(int x, int y) { |
| 147 assert(() => x + 3 > y + 4); |
| 148 } |
| 149 '''); |
| 150 } |
| 151 } |
| 152 |
| 153 @reflectiveTest |
| 154 class _ForTest extends PostfixCompletionTest { |
| 155 @failingTest |
| 156 test_for_invalid() async { |
| 157 await _prepareCompletion( |
| 158 '.for', |
| 159 ''' |
| 160 f() { |
| 161 {}.for |
| 162 } |
| 163 '''); |
| 164 } |
| 165 |
| 166 test_forEmptyDynamic() async { |
| 167 await _prepareCompletion( |
| 168 '.for', |
| 169 ''' |
| 170 f() { |
| 171 [].for |
| 172 } |
| 173 '''); |
| 174 _assertHasChange( |
| 175 'Expand .for', |
| 176 ''' |
| 177 f() { |
| 178 for (var value in []) { |
| 179 /*caret*/ |
| 180 } |
| 181 } |
| 182 '''); |
| 183 } |
| 184 |
| 185 test_forEmptyString() async { |
| 186 await _prepareCompletion( |
| 187 '.for', |
| 188 ''' |
| 189 f() { |
| 190 <String>[].for |
| 191 } |
| 192 '''); |
| 193 _assertHasChange( |
| 194 'Expand .for', |
| 195 ''' |
| 196 f() { |
| 197 for (var value in <String>[]) { |
| 198 /*caret*/ |
| 199 } |
| 200 } |
| 201 '''); |
| 202 } |
| 203 |
| 204 test_fori() async { |
| 205 await _prepareCompletion( |
| 206 '.fori', |
| 207 ''' |
| 208 f() { |
| 209 100.fori |
| 210 } |
| 211 '''); |
| 212 _assertHasChange( |
| 213 'Expand .fori', |
| 214 ''' |
| 215 f() { |
| 216 for (int i = 0; i < 100; i++) { |
| 217 /*caret*/ |
| 218 } |
| 219 } |
| 220 '''); |
| 221 } |
| 222 |
| 223 @failingTest |
| 224 test_fori_invalid() async { |
| 225 await _prepareCompletion( |
| 226 '.fori', |
| 227 ''' |
| 228 f() { |
| 229 [].fori |
| 230 } |
| 231 '''); |
| 232 } |
| 233 |
| 234 test_forIntList() async { |
| 235 await _prepareCompletion( |
| 236 '.for', |
| 237 ''' |
| 238 f() { |
| 239 [1,2,3].for |
| 240 } |
| 241 '''); |
| 242 _assertHasChange( |
| 243 'Expand .for', |
| 244 ''' |
| 245 f() { |
| 246 for (var value in [1,2,3]) { |
| 247 /*caret*/ |
| 248 } |
| 249 } |
| 250 '''); |
| 251 } |
| 252 |
| 253 test_foriVar() async { |
| 254 await _prepareCompletion( |
| 255 '.fori', |
| 256 ''' |
| 257 f() { |
| 258 var n = 100; |
| 259 n.fori |
| 260 } |
| 261 '''); |
| 262 _assertHasChange( |
| 263 'Expand .fori', |
| 264 ''' |
| 265 f() { |
| 266 var n = 100; |
| 267 for (int i = 0; i < n; i++) { |
| 268 /*caret*/ |
| 269 } |
| 270 } |
| 271 '''); |
| 272 } |
| 273 |
| 274 test_iterList() async { |
| 275 await _prepareCompletion( |
| 276 '.iter', |
| 277 ''' |
| 278 f() { |
| 279 [1,2,3].iter |
| 280 } |
| 281 '''); |
| 282 _assertHasChange( |
| 283 'Expand .iter', |
| 284 ''' |
| 285 f() { |
| 286 for (var value in [1,2,3]) { |
| 287 /*caret*/ |
| 288 } |
| 289 } |
| 290 '''); |
| 291 } |
| 292 |
| 293 test_iterName() async { |
| 294 await _prepareCompletion( |
| 295 '.iter', |
| 296 ''' |
| 297 f() { |
| 298 var value = [1,2,3]; |
| 299 value.iter |
| 300 } |
| 301 '''); |
| 302 _assertHasChange( |
| 303 'Expand .iter', |
| 304 ''' |
| 305 f() { |
| 306 var value = [1,2,3]; |
| 307 for (var value1 in value) { |
| 308 /*caret*/ |
| 309 } |
| 310 } |
| 311 '''); |
| 312 } |
| 313 } |
| 314 |
| 315 @reflectiveTest |
| 316 class _IfTest extends PostfixCompletionTest { |
| 317 test_Else() async { |
| 318 await _prepareCompletion( |
| 319 '.else', |
| 320 ''' |
| 321 f(bool val) { |
| 322 val.else |
| 323 } |
| 324 '''); |
| 325 _assertHasChange( |
| 326 'Expand .else', |
| 327 ''' |
| 328 f(bool val) { |
| 329 if (!val) { |
| 330 /*caret*/ |
| 331 } |
| 332 } |
| 333 '''); |
| 334 } |
| 335 |
| 336 test_if() async { |
| 337 await _prepareCompletion( |
| 338 '.if', |
| 339 ''' |
| 340 f() { |
| 341 3 < 4.if |
| 342 } |
| 343 '''); |
| 344 _assertHasChange( |
| 345 'Expand .if', |
| 346 ''' |
| 347 f() { |
| 348 if (3 < 4) { |
| 349 /*caret*/ |
| 350 } |
| 351 } |
| 352 '''); |
| 353 } |
| 354 |
| 355 @failingTest |
| 356 test_if_invalid() async { |
| 357 await _prepareCompletion( |
| 358 '.if', |
| 359 ''' |
| 360 f(List expr) { |
| 361 expr.if |
| 362 } |
| 363 '''); |
| 364 } |
| 365 |
| 366 test_ifDynamic() async { |
| 367 await _prepareCompletion( |
| 368 '.if', |
| 369 ''' |
| 370 f(expr) { |
| 371 expr.if |
| 372 } |
| 373 '''); |
| 374 _assertHasChange( |
| 375 'Expand .if', |
| 376 ''' |
| 377 f(expr) { |
| 378 if (expr) { |
| 379 /*caret*/ |
| 380 } |
| 381 } |
| 382 '''); |
| 383 } |
| 384 } |
| 385 |
| 386 @reflectiveTest |
| 387 class _NegateTest extends PostfixCompletionTest { |
| 388 test_negate() async { |
| 389 await _prepareCompletion( |
| 390 '.not', |
| 391 ''' |
| 392 f(expr) { |
| 393 if (expr.not) |
| 394 } |
| 395 '''); |
| 396 _assertHasChange( |
| 397 'Expand .not', |
| 398 ''' |
| 399 f(expr) { |
| 400 if (!expr) |
| 401 } |
| 402 '''); |
| 403 } |
| 404 |
| 405 @failingTest |
| 406 test_negate_invalid() async { |
| 407 await _prepareCompletion( |
| 408 '.not', |
| 409 ''' |
| 410 f(int expr) { |
| 411 if (expr.not) |
| 412 } |
| 413 '''); |
| 414 } |
| 415 |
| 416 test_negateCascade() async { |
| 417 await _prepareCompletion( |
| 418 '.not', |
| 419 ''' |
| 420 f(expr) { |
| 421 if (expr..a..b..c.not) |
| 422 } |
| 423 '''); |
| 424 _assertHasChange( |
| 425 'Expand .not', |
| 426 ''' |
| 427 f(expr) { |
| 428 if (!expr..a..b..c) |
| 429 } |
| 430 '''); |
| 431 } |
| 432 |
| 433 test_negateExpr() async { |
| 434 await _prepareCompletion( |
| 435 '.not', |
| 436 ''' |
| 437 f(int i, int j) { |
| 438 if (i + 3 < j - 4.not) |
| 439 } |
| 440 '''); |
| 441 _assertHasChange( |
| 442 'Expand .not', |
| 443 ''' |
| 444 f(int i, int j) { |
| 445 if (i + 3 >= j - 4) |
| 446 } |
| 447 '''); |
| 448 } |
| 449 |
| 450 test_negateProperty() async { |
| 451 await _prepareCompletion( |
| 452 '.not', |
| 453 ''' |
| 454 f(expr) { |
| 455 if (expr.a.b.c.not) |
| 456 } |
| 457 '''); |
| 458 _assertHasChange( |
| 459 'Expand .not', |
| 460 ''' |
| 461 f(expr) { |
| 462 if (!expr.a.b.c) |
| 463 } |
| 464 '''); |
| 465 } |
| 466 |
| 467 test_notFalse() async { |
| 468 await _prepareCompletion( |
| 469 '!', |
| 470 ''' |
| 471 f() { |
| 472 if (false!) |
| 473 } |
| 474 '''); |
| 475 _assertHasChange( |
| 476 'Expand !', |
| 477 ''' |
| 478 f() { |
| 479 if (true) |
| 480 } |
| 481 '''); |
| 482 } |
| 483 |
| 484 test_notFunc() async { |
| 485 await _prepareCompletion( |
| 486 '.not', |
| 487 ''' |
| 488 bool f() { |
| 489 if (f().not) |
| 490 } |
| 491 '''); |
| 492 _assertHasChange( |
| 493 'Expand .not', |
| 494 ''' |
| 495 bool f() { |
| 496 if (!f()) |
| 497 } |
| 498 '''); |
| 499 } |
| 500 |
| 501 test_notTrue() async { |
| 502 await _prepareCompletion( |
| 503 '.not', |
| 504 ''' |
| 505 f() { |
| 506 if (true.not) |
| 507 } |
| 508 '''); |
| 509 _assertHasChange( |
| 510 'Expand .not', |
| 511 ''' |
| 512 f() { |
| 513 if (false) |
| 514 } |
| 515 '''); |
| 516 } |
| 517 } |
| 518 |
| 519 @reflectiveTest |
| 520 class _NotNullTest extends PostfixCompletionTest { |
| 521 test_nn() async { |
| 522 await _prepareCompletion( |
| 523 '.nn', |
| 524 ''' |
| 525 f(expr) { |
| 526 var list = [1,2,3]; |
| 527 list.nn |
| 528 } |
| 529 '''); |
| 530 _assertHasChange( |
| 531 'Expand .nn', |
| 532 ''' |
| 533 f(expr) { |
| 534 var list = [1,2,3]; |
| 535 if (list != null) { |
| 536 /*caret*/ |
| 537 } |
| 538 } |
| 539 '''); |
| 540 } |
| 541 |
| 542 @failingTest |
| 543 test_nn_invalid() async { |
| 544 await _prepareCompletion( |
| 545 '.nn', |
| 546 ''' |
| 547 f(expr) { |
| 548 var list = [1,2,3]; |
| 549 }.nn |
| 550 '''); |
| 551 } |
| 552 |
| 553 test_nnDynamic() async { |
| 554 await _prepareCompletion( |
| 555 '.nn', |
| 556 ''' |
| 557 f(expr) { |
| 558 expr.nn |
| 559 } |
| 560 '''); |
| 561 _assertHasChange( |
| 562 'Expand .nn', |
| 563 ''' |
| 564 f(expr) { |
| 565 if (expr != null) { |
| 566 /*caret*/ |
| 567 } |
| 568 } |
| 569 '''); |
| 570 } |
| 571 |
| 572 test_notnull() async { |
| 573 await _prepareCompletion( |
| 574 '.notnull', |
| 575 ''' |
| 576 f(expr) { |
| 577 var list = [1,2,3]; |
| 578 list.notnull |
| 579 } |
| 580 '''); |
| 581 _assertHasChange( |
| 582 'Expand .notnull', |
| 583 ''' |
| 584 f(expr) { |
| 585 var list = [1,2,3]; |
| 586 if (list != null) { |
| 587 /*caret*/ |
| 588 } |
| 589 } |
| 590 '''); |
| 591 } |
| 592 |
| 593 test_null() async { |
| 594 await _prepareCompletion( |
| 595 '.null', |
| 596 ''' |
| 597 f(expr) { |
| 598 var list = [1,2,3]; |
| 599 list.null |
| 600 } |
| 601 '''); |
| 602 _assertHasChange( |
| 603 'Expand .null', |
| 604 ''' |
| 605 f(expr) { |
| 606 var list = [1,2,3]; |
| 607 if (list == null) { |
| 608 /*caret*/ |
| 609 } |
| 610 } |
| 611 '''); |
| 612 } |
| 613 |
| 614 test_nullnn() async { |
| 615 await _prepareCompletion( |
| 616 '.nn', |
| 617 ''' |
| 618 f() { |
| 619 null.nn |
| 620 } |
| 621 '''); |
| 622 _assertHasChange( |
| 623 'Expand .nn', |
| 624 ''' |
| 625 f() { |
| 626 if (false) { |
| 627 /*caret*/ |
| 628 } |
| 629 } |
| 630 '''); |
| 631 } |
| 632 |
| 633 test_nullnull() async { |
| 634 await _prepareCompletion( |
| 635 '.null', |
| 636 ''' |
| 637 f() { |
| 638 null.null |
| 639 } |
| 640 '''); |
| 641 _assertHasChange( |
| 642 'Expand .null', |
| 643 ''' |
| 644 f() { |
| 645 if (true) { |
| 646 /*caret*/ |
| 647 } |
| 648 } |
| 649 '''); |
| 650 } |
| 651 } |
| 652 |
| 653 @reflectiveTest |
| 654 class _ParenTest extends PostfixCompletionTest { |
| 655 test_paren() async { |
| 656 await _prepareCompletion( |
| 657 '.par', |
| 658 ''' |
| 659 f(expr) { |
| 660 expr.par |
| 661 } |
| 662 '''); |
| 663 _assertHasChange( |
| 664 'Expand .par', |
| 665 ''' |
| 666 f(expr) { |
| 667 (expr) |
| 668 } |
| 669 '''); |
| 670 } |
| 671 } |
| 672 |
| 673 @reflectiveTest |
| 674 class _ReturnTest extends PostfixCompletionTest { |
| 675 test_return() async { |
| 676 await _prepareCompletion( |
| 677 '.return', |
| 678 ''' |
| 679 f(expr) { |
| 680 expr.return |
| 681 } |
| 682 '''); |
| 683 _assertHasChange( |
| 684 'Expand .return', |
| 685 ''' |
| 686 f(expr) { |
| 687 return expr; |
| 688 } |
| 689 '''); |
| 690 } |
| 691 } |
| 692 |
| 693 @reflectiveTest |
| 694 class _SwitchTest extends PostfixCompletionTest { |
| 695 test_return() async { |
| 696 await _prepareCompletion( |
| 697 '.switch', |
| 698 ''' |
| 699 f(expr) { |
| 700 expr.switch |
| 701 } |
| 702 '''); |
| 703 _assertHasChange( |
| 704 'Expand .switch', |
| 705 ''' |
| 706 f(expr) { |
| 707 switch (expr) { |
| 708 /*caret*/ |
| 709 } |
| 710 } |
| 711 '''); |
| 712 } |
| 713 } |
| 714 |
| 715 @reflectiveTest |
| 716 class _TryTest extends PostfixCompletionTest { |
| 717 test_try() async { |
| 718 await _prepareCompletion( |
| 719 '.try', |
| 720 ''' |
| 721 f() { |
| 722 var x = 1.try |
| 723 } |
| 724 '''); |
| 725 _assertHasChange( |
| 726 'Expand .try', |
| 727 ''' |
| 728 f() { |
| 729 try { |
| 730 var x = 1/*caret*/ |
| 731 } catch (e, s) { |
| 732 print(s); |
| 733 } |
| 734 } |
| 735 '''); |
| 736 } |
| 737 |
| 738 @failingTest |
| 739 test_try_invalid() async { |
| 740 // The semicolon is fine; this fails because of the do-statement. |
| 741 await _prepareCompletion( |
| 742 '.try', |
| 743 ''' |
| 744 f() { |
| 745 do {} while (true);.try |
| 746 } |
| 747 '''); |
| 748 } |
| 749 |
| 750 test_tryMultiline() async { |
| 751 await _prepareCompletion( |
| 752 '.try', |
| 753 ''' |
| 754 f(arg) { |
| 755 arg |
| 756 ..first |
| 757 ..second |
| 758 ..third |
| 759 ..fourth.try |
| 760 } |
| 761 '''); |
| 762 _assertHasChange( |
| 763 'Expand .try', |
| 764 ''' |
| 765 f(arg) { |
| 766 try { |
| 767 arg |
| 768 ..first |
| 769 ..second |
| 770 ..third |
| 771 ..fourth/*caret*/ |
| 772 } catch (e, s) { |
| 773 print(s); |
| 774 } |
| 775 } |
| 776 '''); |
| 777 } |
| 778 |
| 779 test_tryon() async { |
| 780 await _prepareCompletion( |
| 781 '.tryon', |
| 782 ''' |
| 783 f() { |
| 784 var x = 1.tryon |
| 785 } |
| 786 '''); |
| 787 _assertHasChange( |
| 788 'Expand .tryon', |
| 789 ''' |
| 790 f() { |
| 791 try { |
| 792 var x = 1/*caret*/ |
| 793 } on Exception catch (e, s) { |
| 794 print(s); |
| 795 } |
| 796 } |
| 797 '''); |
| 798 } |
| 799 |
| 800 test_tryonThrowStatement() async { |
| 801 await _prepareCompletion( |
| 802 '.tryon', |
| 803 ''' |
| 804 f() { |
| 805 throw 'error';.tryon |
| 806 } |
| 807 '''); |
| 808 _assertHasChange( |
| 809 'Expand .tryon', |
| 810 ''' |
| 811 f() { |
| 812 try { |
| 813 throw 'error';/*caret*/ |
| 814 } on String catch (e, s) { |
| 815 print(s); |
| 816 } |
| 817 } |
| 818 '''); |
| 819 } |
| 820 |
| 821 test_tryonThrowString() async { |
| 822 await _prepareCompletion( |
| 823 '.tryon', |
| 824 ''' |
| 825 f() { |
| 826 throw 'error'.tryon |
| 827 } |
| 828 '''); |
| 829 _assertHasChange( |
| 830 'Expand .tryon', |
| 831 ''' |
| 832 f() { |
| 833 try { |
| 834 throw 'error'/*caret*/ |
| 835 } on String catch (e, s) { |
| 836 print(s); |
| 837 } |
| 838 } |
| 839 '''); |
| 840 } |
| 841 } |
| 842 |
| 843 @reflectiveTest |
| 844 class _WhileTest extends PostfixCompletionTest { |
| 845 test_while() async { |
| 846 await _prepareCompletion( |
| 847 '.while', |
| 848 ''' |
| 849 f(expr) { |
| 850 expr.while |
| 851 } |
| 852 '''); |
| 853 _assertHasChange( |
| 854 'Expand .while', |
| 855 ''' |
| 856 f(expr) { |
| 857 while (expr) { |
| 858 /*caret*/ |
| 859 } |
| 860 } |
| 861 '''); |
| 862 } |
| 863 } |
| OLD | NEW |