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 |