| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 library test.plugin.analysis_contributor; |
| 6 |
| 7 import 'dart:async'; |
| 8 |
| 9 import 'package:analysis_server/analysis/analysis_domain.dart'; |
| 10 import 'package:analysis_server/analysis/navigation/navigation_core.dart'; |
| 11 import 'package:analysis_server/plugin/navigation.dart'; |
| 12 import 'package:analysis_server/src/constants.dart'; |
| 13 import 'package:analysis_server/src/protocol.dart'; |
| 14 import 'package:analyzer/src/generated/engine.dart'; |
| 15 import 'package:analyzer/src/generated/source.dart'; |
| 16 import 'package:analyzer/task/dart.dart'; |
| 17 import 'package:plugin/plugin.dart'; |
| 18 import 'package:test_reflective_loader/test_reflective_loader.dart'; |
| 19 import 'package:unittest/unittest.dart'; |
| 20 |
| 21 import '../analysis_abstract.dart'; |
| 22 import '../utils.dart'; |
| 23 |
| 24 main() { |
| 25 initializeTestEnvironment(); |
| 26 if (AnalysisEngine.instance.useTaskModel) { |
| 27 defineReflectiveTests(SetAnalysisDomainTest); |
| 28 } |
| 29 } |
| 30 |
| 31 /** |
| 32 * This test uses [SET_ANALYSIS_DOMAIN_EXTENSION_POINT_ID] and |
| 33 * [NAVIGATION_CONTRIBUTOR_EXTENSION_POINT_ID] extension points to validate |
| 34 * that plugins can listen for analysis and force sending navigation |
| 35 * notifications. |
| 36 */ |
| 37 @reflectiveTest |
| 38 class SetAnalysisDomainTest extends AbstractAnalysisTest { |
| 39 final Set<String> parsedUnitFiles = new Set<String>(); |
| 40 bool contributorMayAddRegion = false; |
| 41 |
| 42 List<NavigationRegion> regions; |
| 43 List<NavigationTarget> targets; |
| 44 List<String> targetFiles; |
| 45 |
| 46 @override |
| 47 void addServerPlugins(List<Plugin> plugins) { |
| 48 var plugin = new TestSetAnalysisDomainPlugin(this); |
| 49 plugins.add(plugin); |
| 50 } |
| 51 |
| 52 @override |
| 53 void processNotification(Notification notification) { |
| 54 if (notification.event == ANALYSIS_NAVIGATION) { |
| 55 var params = new AnalysisNavigationParams.fromNotification(notification); |
| 56 // TODO(scheglov) we check for "params.regions.isNotEmpty" because |
| 57 // normal, Dart only, navigation notifications are scheduled as |
| 58 // operations, but plugins use "notificationSite.scheduleNavigation" |
| 59 // which is not scheduled yet. So, it comes *before* the Dart one, and |
| 60 // gets lost. |
| 61 if (params.file == testFile && params.regions.isNotEmpty) { |
| 62 regions = params.regions; |
| 63 targets = params.targets; |
| 64 targetFiles = params.files; |
| 65 } |
| 66 } |
| 67 } |
| 68 |
| 69 Future test_contributorIsInvoked() async { |
| 70 createProject(); |
| 71 addAnalysisSubscription(AnalysisService.NAVIGATION, testFile); |
| 72 addTestFile('// usually no navigation'); |
| 73 await server.onAnalysisComplete; |
| 74 // we have PARSED_UNIT |
| 75 expect(parsedUnitFiles, contains(testFile)); |
| 76 // we have an additional navigation region/target |
| 77 expect(regions, hasLength(1)); |
| 78 { |
| 79 NavigationRegion region = regions.single; |
| 80 expect(region.offset, 1); |
| 81 expect(region.length, 5); |
| 82 expect(region.targets.single, 0); |
| 83 } |
| 84 { |
| 85 NavigationTarget target = targets.single; |
| 86 expect(target.fileIndex, 0); |
| 87 expect(target.offset, 1); |
| 88 expect(target.length, 2); |
| 89 expect(target.startLine, 3); |
| 90 expect(target.startColumn, 4); |
| 91 } |
| 92 expect(targetFiles.single, '/testLocation.dart'); |
| 93 } |
| 94 } |
| 95 |
| 96 class TestNavigationContributor implements NavigationContributor { |
| 97 final SetAnalysisDomainTest test; |
| 98 |
| 99 TestNavigationContributor(this.test); |
| 100 |
| 101 @override |
| 102 void computeNavigation(NavigationHolder holder, AnalysisContext context, |
| 103 Source source, int offset, int length) { |
| 104 if (test.contributorMayAddRegion) { |
| 105 holder.addRegion(1, 5, ElementKind.CLASS, |
| 106 new Location('/testLocation.dart', 1, 2, 3, 4)); |
| 107 } |
| 108 } |
| 109 } |
| 110 |
| 111 class TestSetAnalysisDomainPlugin implements Plugin { |
| 112 final SetAnalysisDomainTest test; |
| 113 |
| 114 TestSetAnalysisDomainPlugin(this.test); |
| 115 |
| 116 @override |
| 117 String get uniqueIdentifier => 'test'; |
| 118 |
| 119 @override |
| 120 void registerExtensionPoints(RegisterExtensionPoint register) {} |
| 121 |
| 122 @override |
| 123 void registerExtensions(RegisterExtension register) { |
| 124 register(SET_ANALYSIS_DOMAIN_EXTENSION_POINT_ID, _setAnalysisDomain); |
| 125 register(NAVIGATION_CONTRIBUTOR_EXTENSION_POINT_ID, |
| 126 new TestNavigationContributor(test)); |
| 127 } |
| 128 |
| 129 void _setAnalysisDomain(AnalysisDomain domain) { |
| 130 domain.onResultComputed(PARSED_UNIT).listen((result) { |
| 131 expect(result.context, isNotNull); |
| 132 expect(result.target, isNotNull); |
| 133 expect(result.value, isNotNull); |
| 134 Source source = result.target.source; |
| 135 test.parsedUnitFiles.add(source.fullName); |
| 136 // let the navigation contributor to work |
| 137 test.contributorMayAddRegion = true; |
| 138 try { |
| 139 domain.scheduleNotification( |
| 140 result.context, source, AnalysisService.NAVIGATION); |
| 141 } finally { |
| 142 test.contributorMayAddRegion = false; |
| 143 } |
| 144 }); |
| 145 } |
| 146 } |
| OLD | NEW |