| 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.analysis.notification.navigation; | 5 library test.analysis.notification.navigation; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:analysis_server/src/constants.dart'; | 9 import 'package:analysis_server/src/constants.dart'; |
| 10 import 'package:analysis_server/src/protocol.dart'; | 10 import 'package:analysis_server/src/protocol.dart'; |
| 11 import 'package:test_reflective_loader/test_reflective_loader.dart'; | 11 import 'package:test_reflective_loader/test_reflective_loader.dart'; |
| 12 import 'package:unittest/unittest.dart'; | 12 import 'package:unittest/unittest.dart'; |
| 13 | 13 |
| 14 import '../analysis_abstract.dart'; | 14 import '../analysis_abstract.dart'; |
| 15 | 15 |
| 16 main() { | 16 main() { |
| 17 groupSep = ' | '; | 17 groupSep = ' | '; |
| 18 defineReflectiveTests(AnalysisNotificationNavigationTest); | 18 defineReflectiveTests(AnalysisNotificationNavigationTest); |
| 19 } | 19 } |
| 20 | 20 |
| 21 class AbstractNavigationTest extends AbstractAnalysisTest { |
| 22 List<NavigationRegion> regions; |
| 23 List<NavigationTarget> targets; |
| 24 List<String> targetFiles; |
| 25 |
| 26 NavigationRegion testRegion; |
| 27 List<int> testTargetIndexes; |
| 28 NavigationTarget testTarget; |
| 29 |
| 30 /** |
| 31 * Validates that there is a target in [testTargetIndexes] with [file], |
| 32 * at [offset] and with the given [length]. |
| 33 */ |
| 34 void assertHasFileTarget(String file, int offset, int length) { |
| 35 List<NavigationTarget> testTargets = |
| 36 testTargetIndexes.map((int index) => targets[index]).toList(); |
| 37 for (NavigationTarget target in testTargets) { |
| 38 if (targetFiles[target.fileIndex] == file && |
| 39 target.offset == offset && |
| 40 target.length == length) { |
| 41 testTarget = target; |
| 42 return; |
| 43 } |
| 44 } |
| 45 fail( |
| 46 'Expected to find target (file=$file; offset=$offset; length=$length) in
\n' |
| 47 '${testRegion} in\n' '${testTargets.join('\n')}'); |
| 48 } |
| 49 |
| 50 void assertHasOperatorRegion(String regionSearch, int regionLength, |
| 51 String targetSearch, int targetLength) { |
| 52 assertHasRegion(regionSearch, regionLength); |
| 53 assertHasTarget(targetSearch, targetLength); |
| 54 } |
| 55 |
| 56 /** |
| 57 * Validates that there is a region at the offset of [search] in [testFile]. |
| 58 * If [length] is not specified explicitly, then length of an identifier |
| 59 * from [search] is used. |
| 60 */ |
| 61 void assertHasRegion(String search, [int length = -1]) { |
| 62 int offset = findOffset(search); |
| 63 if (length == -1) { |
| 64 length = findIdentifierLength(search); |
| 65 } |
| 66 findRegion(offset, length, true); |
| 67 } |
| 68 |
| 69 /** |
| 70 * Validates that there is a region at the offset of [search] in [testFile] |
| 71 * with the given [length] or the length of [search]. |
| 72 */ |
| 73 void assertHasRegionString(String search, [int length = -1]) { |
| 74 int offset = findOffset(search); |
| 75 if (length == -1) { |
| 76 length = search.length; |
| 77 } |
| 78 findRegion(offset, length, true); |
| 79 } |
| 80 |
| 81 /** |
| 82 * Validates that there is an identifier region at [regionSearch] with target |
| 83 * at [targetSearch]. |
| 84 */ |
| 85 void assertHasRegionTarget(String regionSearch, String targetSearch) { |
| 86 assertHasRegion(regionSearch); |
| 87 assertHasTarget(targetSearch); |
| 88 } |
| 89 |
| 90 /** |
| 91 * Validates that there is a target in [testTargets] with [testFile], at the |
| 92 * offset of [search] in [testFile], and with the given [length] or the length |
| 93 * of an leading identifier in [search]. |
| 94 */ |
| 95 void assertHasTarget(String search, [int length = -1]) { |
| 96 int offset = findOffset(search); |
| 97 if (length == -1) { |
| 98 length = findIdentifierLength(search); |
| 99 } |
| 100 assertHasFileTarget(testFile, offset, length); |
| 101 } |
| 102 |
| 103 /** |
| 104 * Validates that there is no a region at [search] and with the given |
| 105 * [length]. |
| 106 */ |
| 107 void assertNoRegion(String search, int length) { |
| 108 int offset = findOffset(search); |
| 109 findRegion(offset, length, false); |
| 110 } |
| 111 |
| 112 /** |
| 113 * Validates that there is no a region at [search] with any length. |
| 114 */ |
| 115 void assertNoRegionAt(String search) { |
| 116 int offset = findOffset(search); |
| 117 findRegion(offset, -1, false); |
| 118 } |
| 119 |
| 120 /** |
| 121 * Validates that there is no a region for [search] string. |
| 122 */ |
| 123 void assertNoRegionString(String search) { |
| 124 int offset = findOffset(search); |
| 125 int length = search.length; |
| 126 findRegion(offset, length, false); |
| 127 } |
| 128 |
| 129 void assertRegionsSorted() { |
| 130 int lastEnd = -1; |
| 131 for (NavigationRegion region in regions) { |
| 132 int offset = region.offset; |
| 133 if (offset < lastEnd) { |
| 134 fail('$lastEnd was expected to be > $offset in\n' + regions.join('\n')); |
| 135 } |
| 136 lastEnd = offset + region.length; |
| 137 } |
| 138 } |
| 139 |
| 140 /** |
| 141 * Finds the navigation region with the given [offset] and [length]. |
| 142 * If [length] is `-1`, then it is ignored. |
| 143 * |
| 144 * If [exists] is `true`, then fails if such region does not exist. |
| 145 * Otherwise remembers this it into [testRegion]. |
| 146 * Also fills [testTargets] with its targets. |
| 147 * |
| 148 * If [exists] is `false`, then fails if such region exists. |
| 149 */ |
| 150 void findRegion(int offset, int length, bool exists) { |
| 151 for (NavigationRegion region in regions) { |
| 152 if (region.offset == offset && |
| 153 (length == -1 || region.length == length)) { |
| 154 if (exists == false) { |
| 155 fail('Not expected to find (offset=$offset; length=$length) in\n' |
| 156 '${regions.join('\n')}'); |
| 157 } |
| 158 testRegion = region; |
| 159 testTargetIndexes = region.targets; |
| 160 return; |
| 161 } |
| 162 } |
| 163 if (exists == true) { |
| 164 fail('Expected to find (offset=$offset; length=$length) in\n' |
| 165 '${regions.join('\n')}'); |
| 166 } |
| 167 } |
| 168 } |
| 169 |
| 21 @reflectiveTest | 170 @reflectiveTest |
| 22 class AnalysisNotificationNavigationTest extends AbstractNavigationTest { | 171 class AnalysisNotificationNavigationTest extends AbstractNavigationTest { |
| 23 Future prepareNavigation() { | 172 Future prepareNavigation() { |
| 24 addAnalysisSubscription(AnalysisService.NAVIGATION, testFile); | 173 addAnalysisSubscription(AnalysisService.NAVIGATION, testFile); |
| 25 return waitForTasksFinished().then((_) { | 174 return waitForTasksFinished().then((_) { |
| 26 assertRegionsSorted(); | 175 assertRegionsSorted(); |
| 27 }); | 176 }); |
| 28 } | 177 } |
| 29 | 178 |
| 30 void processNotification(Notification notification) { | 179 void processNotification(Notification notification) { |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 int aaa = 42; | 437 int aaa = 42; |
| 289 print(aaa); | 438 print(aaa); |
| 290 } | 439 } |
| 291 import 'dart:math'; | 440 import 'dart:math'; |
| 292 '''); | 441 '''); |
| 293 return prepareNavigation().then((_) { | 442 return prepareNavigation().then((_) { |
| 294 assertHasRegionTarget('aaa);', 'aaa = 42'); | 443 assertHasRegionTarget('aaa);', 'aaa = 42'); |
| 295 }); | 444 }); |
| 296 } | 445 } |
| 297 | 446 |
| 447 test_inComment() async { |
| 448 addTestFile(''' |
| 449 class FirstClass {} |
| 450 class SecondClass { |
| 451 /** |
| 452 * Return a [FirstClass] object equivalent to this object in every other way. |
| 453 */ |
| 454 convert() { |
| 455 return new FirstClass(); |
| 456 } |
| 457 } |
| 458 '''); |
| 459 await prepareNavigation(); |
| 460 assertHasRegionTarget('FirstClass]', 'FirstClass {'); |
| 461 assertHasRegionTarget('FirstClass(', 'FirstClass {'); |
| 462 } |
| 463 |
| 298 test_instanceCreation_implicit() { | 464 test_instanceCreation_implicit() { |
| 299 addTestFile(''' | 465 addTestFile(''' |
| 300 class A { | 466 class A { |
| 301 } | 467 } |
| 302 main() { | 468 main() { |
| 303 new A(); | 469 new A(); |
| 304 } | 470 } |
| 305 '''); | 471 '''); |
| 306 return prepareNavigation().then((_) { | 472 return prepareNavigation().then((_) { |
| 307 assertHasRegionString('A()', 'A'.length); | 473 assertHasRegionString('A()', 'A'.length); |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 631 test_type_void() { | 797 test_type_void() { |
| 632 addTestFile(''' | 798 addTestFile(''' |
| 633 void main() { | 799 void main() { |
| 634 } | 800 } |
| 635 '''); | 801 '''); |
| 636 return prepareNavigation().then((_) { | 802 return prepareNavigation().then((_) { |
| 637 assertNoRegionAt('void'); | 803 assertNoRegionAt('void'); |
| 638 }); | 804 }); |
| 639 } | 805 } |
| 640 } | 806 } |
| 641 | |
| 642 class AbstractNavigationTest extends AbstractAnalysisTest { | |
| 643 List<NavigationRegion> regions; | |
| 644 List<NavigationTarget> targets; | |
| 645 List<String> targetFiles; | |
| 646 | |
| 647 NavigationRegion testRegion; | |
| 648 List<int> testTargetIndexes; | |
| 649 NavigationTarget testTarget; | |
| 650 | |
| 651 /** | |
| 652 * Validates that there is a target in [testTargetIndexes] with [file], | |
| 653 * at [offset] and with the given [length]. | |
| 654 */ | |
| 655 void assertHasFileTarget(String file, int offset, int length) { | |
| 656 List<NavigationTarget> testTargets = | |
| 657 testTargetIndexes.map((int index) => targets[index]).toList(); | |
| 658 for (NavigationTarget target in testTargets) { | |
| 659 if (targetFiles[target.fileIndex] == file && | |
| 660 target.offset == offset && | |
| 661 target.length == length) { | |
| 662 testTarget = target; | |
| 663 return; | |
| 664 } | |
| 665 } | |
| 666 fail( | |
| 667 'Expected to find target (file=$file; offset=$offset; length=$length) in
\n' | |
| 668 '${testRegion} in\n' '${testTargets.join('\n')}'); | |
| 669 } | |
| 670 | |
| 671 void assertHasOperatorRegion(String regionSearch, int regionLength, | |
| 672 String targetSearch, int targetLength) { | |
| 673 assertHasRegion(regionSearch, regionLength); | |
| 674 assertHasTarget(targetSearch, targetLength); | |
| 675 } | |
| 676 | |
| 677 /** | |
| 678 * Validates that there is a region at the offset of [search] in [testFile]. | |
| 679 * If [length] is not specified explicitly, then length of an identifier | |
| 680 * from [search] is used. | |
| 681 */ | |
| 682 void assertHasRegion(String search, [int length = -1]) { | |
| 683 int offset = findOffset(search); | |
| 684 if (length == -1) { | |
| 685 length = findIdentifierLength(search); | |
| 686 } | |
| 687 findRegion(offset, length, true); | |
| 688 } | |
| 689 | |
| 690 /** | |
| 691 * Validates that there is a region at the offset of [search] in [testFile] | |
| 692 * with the given [length] or the length of [search]. | |
| 693 */ | |
| 694 void assertHasRegionString(String search, [int length = -1]) { | |
| 695 int offset = findOffset(search); | |
| 696 if (length == -1) { | |
| 697 length = search.length; | |
| 698 } | |
| 699 findRegion(offset, length, true); | |
| 700 } | |
| 701 | |
| 702 /** | |
| 703 * Validates that there is an identifier region at [regionSearch] with target | |
| 704 * at [targetSearch]. | |
| 705 */ | |
| 706 void assertHasRegionTarget(String regionSearch, String targetSearch) { | |
| 707 assertHasRegion(regionSearch); | |
| 708 assertHasTarget(targetSearch); | |
| 709 } | |
| 710 | |
| 711 /** | |
| 712 * Validates that there is a target in [testTargets] with [testFile], at the | |
| 713 * offset of [search] in [testFile], and with the given [length] or the length | |
| 714 * of an leading identifier in [search]. | |
| 715 */ | |
| 716 void assertHasTarget(String search, [int length = -1]) { | |
| 717 int offset = findOffset(search); | |
| 718 if (length == -1) { | |
| 719 length = findIdentifierLength(search); | |
| 720 } | |
| 721 assertHasFileTarget(testFile, offset, length); | |
| 722 } | |
| 723 | |
| 724 /** | |
| 725 * Validates that there is no a region at [search] and with the given | |
| 726 * [length]. | |
| 727 */ | |
| 728 void assertNoRegion(String search, int length) { | |
| 729 int offset = findOffset(search); | |
| 730 findRegion(offset, length, false); | |
| 731 } | |
| 732 | |
| 733 /** | |
| 734 * Validates that there is no a region at [search] with any length. | |
| 735 */ | |
| 736 void assertNoRegionAt(String search) { | |
| 737 int offset = findOffset(search); | |
| 738 findRegion(offset, -1, false); | |
| 739 } | |
| 740 | |
| 741 /** | |
| 742 * Validates that there is no a region for [search] string. | |
| 743 */ | |
| 744 void assertNoRegionString(String search) { | |
| 745 int offset = findOffset(search); | |
| 746 int length = search.length; | |
| 747 findRegion(offset, length, false); | |
| 748 } | |
| 749 | |
| 750 void assertRegionsSorted() { | |
| 751 int lastEnd = -1; | |
| 752 for (NavigationRegion region in regions) { | |
| 753 int offset = region.offset; | |
| 754 if (offset < lastEnd) { | |
| 755 fail('$lastEnd was expected to be > $offset in\n' + regions.join('\n')); | |
| 756 } | |
| 757 lastEnd = offset + region.length; | |
| 758 } | |
| 759 } | |
| 760 | |
| 761 /** | |
| 762 * Finds the navigation region with the given [offset] and [length]. | |
| 763 * If [length] is `-1`, then it is ignored. | |
| 764 * | |
| 765 * If [exists] is `true`, then fails if such region does not exist. | |
| 766 * Otherwise remembers this it into [testRegion]. | |
| 767 * Also fills [testTargets] with its targets. | |
| 768 * | |
| 769 * If [exists] is `false`, then fails if such region exists. | |
| 770 */ | |
| 771 void findRegion(int offset, int length, bool exists) { | |
| 772 for (NavigationRegion region in regions) { | |
| 773 if (region.offset == offset && | |
| 774 (length == -1 || region.length == length)) { | |
| 775 if (exists == false) { | |
| 776 fail('Not expected to find (offset=$offset; length=$length) in\n' | |
| 777 '${regions.join('\n')}'); | |
| 778 } | |
| 779 testRegion = region; | |
| 780 testTargetIndexes = region.targets; | |
| 781 return; | |
| 782 } | |
| 783 } | |
| 784 if (exists == true) { | |
| 785 fail('Expected to find (offset=$offset; length=$length) in\n' | |
| 786 '${regions.join('\n')}'); | |
| 787 } | |
| 788 } | |
| 789 } | |
| OLD | NEW |