| 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 import 'package:analysis_server/plugin/protocol/protocol.dart'; | 5 import 'package:analysis_server/plugin/protocol/protocol.dart'; |
| 6 import 'package:test/test.dart'; | 6 import 'package:test/test.dart'; |
| 7 import 'package:test_reflective_loader/test_reflective_loader.dart'; | 7 import 'package:test_reflective_loader/test_reflective_loader.dart'; |
| 8 | 8 |
| 9 import '../integration_tests.dart'; | 9 import '../integration_tests.dart'; |
| 10 | 10 |
| 11 main() { | 11 main() { |
| 12 defineReflectiveSuite(() { | 12 defineReflectiveSuite(() { |
| 13 defineReflectiveTests(AnalysisNavigationTest); | 13 defineReflectiveTests(AnalysisNavigationTest); |
| 14 defineReflectiveTests(AnalysisNavigationTest_Driver); | 14 defineReflectiveTests(AnalysisNavigationTest_Driver); |
| 15 }); | 15 }); |
| 16 } | 16 } |
| 17 | 17 |
| 18 class AbstractAnalysisNavigationTest | 18 class AbstractAnalysisNavigationTest |
| 19 extends AbstractAnalysisServerIntegrationTest { | 19 extends AbstractAnalysisServerIntegrationTest { |
| 20 test_navigation() { | 20 test_navigation() async { |
| 21 String pathname1 = sourcePath('test1.dart'); | 21 String pathname1 = sourcePath('test1.dart'); |
| 22 String text1 = r''' | 22 String text1 = r''' |
| 23 library foo; | 23 library foo; |
| 24 | 24 |
| 25 import 'dart:async'; | 25 import 'dart:async'; |
| 26 part 'test2.dart'; | 26 part 'test2.dart'; |
| 27 | 27 |
| 28 class Class<TypeParameter> { | 28 class Class<TypeParameter> { |
| 29 Class.constructor(); /* constructor declaration */ | 29 Class.constructor(); /* constructor declaration */ |
| 30 | 30 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 60 }); | 60 }); |
| 61 List<NavigationRegion> regions; | 61 List<NavigationRegion> regions; |
| 62 List<NavigationTarget> targets; | 62 List<NavigationTarget> targets; |
| 63 List<String> targetFiles; | 63 List<String> targetFiles; |
| 64 onAnalysisNavigation.listen((AnalysisNavigationParams params) { | 64 onAnalysisNavigation.listen((AnalysisNavigationParams params) { |
| 65 expect(params.file, equals(pathname1)); | 65 expect(params.file, equals(pathname1)); |
| 66 regions = params.regions; | 66 regions = params.regions; |
| 67 targets = params.targets; | 67 targets = params.targets; |
| 68 targetFiles = params.files; | 68 targetFiles = params.files; |
| 69 }); | 69 }); |
| 70 return analysisFinished.then((_) { | 70 |
| 71 // There should be a single error, due to the fact that 'dart:async' is | 71 await analysisFinished; |
| 72 // not used. | 72 |
| 73 expect(currentAnalysisErrors[pathname1], hasLength(1)); | 73 // There should be a single error, due to the fact that 'dart:async' is not |
| 74 expect(currentAnalysisErrors[pathname2], isEmpty); | 74 // used. |
| 75 NavigationTarget findTargetElement(int index) { | 75 expect(currentAnalysisErrors[pathname1], hasLength(1)); |
| 76 for (NavigationRegion region in regions) { | 76 expect(currentAnalysisErrors[pathname2], isEmpty); |
| 77 if (region.offset <= index && index < region.offset + region.length) { | 77 NavigationTarget findTargetElement(int index) { |
| 78 expect(region.targets, hasLength(1)); | 78 for (NavigationRegion region in regions) { |
| 79 int targetIndex = region.targets[0]; | 79 if (region.offset <= index && index < region.offset + region.length) { |
| 80 return targets[targetIndex]; | 80 expect(region.targets, hasLength(1)); |
| 81 } | 81 int targetIndex = region.targets[0]; |
| 82 return targets[targetIndex]; |
| 82 } | 83 } |
| 83 fail('No element found for index $index'); | |
| 84 return null; | |
| 85 } | 84 } |
| 85 fail('No element found for index $index'); |
| 86 return null; |
| 87 } |
| 86 | 88 |
| 87 void checkLocal( | 89 void checkLocal( |
| 88 String source, String expectedTarget, ElementKind expectedKind) { | 90 String source, String expectedTarget, ElementKind expectedKind) { |
| 89 int sourceIndex = text1.indexOf(source); | 91 int sourceIndex = text1.indexOf(source); |
| 90 int targetIndex = text1.indexOf(expectedTarget); | 92 int targetIndex = text1.indexOf(expectedTarget); |
| 91 NavigationTarget element = findTargetElement(sourceIndex); | 93 NavigationTarget element = findTargetElement(sourceIndex); |
| 92 expect(targetFiles[element.fileIndex], equals(pathname1)); | 94 expect(targetFiles[element.fileIndex], equals(pathname1)); |
| 93 expect(element.offset, equals(targetIndex)); | 95 expect(element.offset, equals(targetIndex)); |
| 94 expect(element.kind, equals(expectedKind)); | 96 expect(element.kind, equals(expectedKind)); |
| 95 } | 97 } |
| 96 | 98 |
| 97 void checkRemote(String source, String expectedTargetRegexp, | 99 void checkRemote( |
| 98 ElementKind expectedKind) { | 100 String source, String expectedTargetRegexp, ElementKind expectedKind) { |
| 99 int sourceIndex = text1.indexOf(source); | 101 int sourceIndex = text1.indexOf(source); |
| 100 NavigationTarget element = findTargetElement(sourceIndex); | 102 NavigationTarget element = findTargetElement(sourceIndex); |
| 101 expect(targetFiles[element.fileIndex], matches(expectedTargetRegexp)); | 103 expect(targetFiles[element.fileIndex], matches(expectedTargetRegexp)); |
| 102 expect(element.kind, equals(expectedKind)); | 104 expect(element.kind, equals(expectedKind)); |
| 103 } | 105 } |
| 104 | 106 |
| 105 // TODO(paulberry): will the element type 'CLASS_TYPE_ALIAS' ever appear | 107 // TODO(paulberry): will the element type 'CLASS_TYPE_ALIAS' ever appear as |
| 106 // as a navigation target? | 108 // a navigation target? |
| 107 checkLocal('Class<int>', 'Class<TypeParameter>', ElementKind.CLASS); | 109 checkLocal('Class<int>', 'Class<TypeParameter>', ElementKind.CLASS); |
| 108 checkRemote( | 110 checkRemote("'test2.dart';", r'test2.dart$', ElementKind.COMPILATION_UNIT); |
| 109 "'test2.dart';", r'test2.dart$', ElementKind.COMPILATION_UNIT); | 111 checkLocal( |
| 110 checkLocal( | 112 'Class<int>.constructor', |
| 111 'Class<int>.constructor', | 113 'constructor(); /* constructor declaration */', |
| 112 'constructor(); /* constructor declaration */', | 114 ElementKind.CONSTRUCTOR); |
| 113 ElementKind.CONSTRUCTOR); | 115 checkLocal( |
| 114 checkLocal( | 116 'constructor(); // usage', |
| 115 'constructor(); // usage', | 117 'constructor(); /* constructor declaration */', |
| 116 'constructor(); /* constructor declaration */', | 118 ElementKind.CONSTRUCTOR); |
| 117 ElementKind.CONSTRUCTOR); | 119 checkLocal('field;', 'field;', ElementKind.FIELD); |
| 118 checkLocal('field;', 'field;', ElementKind.FIELD); | 120 checkLocal('function(() => localVariable.field)', |
| 119 checkLocal('function(() => localVariable.field)', | 121 'function(FunctionTypeAlias parameter)', ElementKind.FUNCTION); |
| 120 'function(FunctionTypeAlias parameter)', ElementKind.FUNCTION); | 122 checkLocal('FunctionTypeAlias parameter', 'FunctionTypeAlias();', |
| 121 checkLocal('FunctionTypeAlias parameter', 'FunctionTypeAlias();', | 123 ElementKind.FUNCTION_TYPE_ALIAS); |
| 122 ElementKind.FUNCTION_TYPE_ALIAS); | 124 checkLocal('field)', 'field;', ElementKind.GETTER); |
| 123 checkLocal('field)', 'field;', ElementKind.GETTER); | 125 checkRemote("'dart:async'", r'async\.dart$', ElementKind.LIBRARY); |
| 124 checkRemote("'dart:async'", r'async\.dart$', ElementKind.LIBRARY); | 126 checkLocal( |
| 125 checkLocal( | 127 'localVariable.field', 'localVariable =', ElementKind.LOCAL_VARIABLE); |
| 126 'localVariable.field', 'localVariable =', ElementKind.LOCAL_VARIABLE); | 128 checkLocal('method();', 'method() {', ElementKind.METHOD); |
| 127 checkLocal('method();', 'method() {', ElementKind.METHOD); | 129 checkLocal('parameter());', 'parameter) {', ElementKind.PARAMETER); |
| 128 checkLocal('parameter());', 'parameter) {', ElementKind.PARAMETER); | 130 checkLocal('field = 1', 'field;', ElementKind.SETTER); |
| 129 checkLocal('field = 1', 'field;', ElementKind.SETTER); | 131 checkLocal('topLevelVariable;', 'topLevelVariable;', |
| 130 checkLocal('topLevelVariable;', 'topLevelVariable;', | 132 ElementKind.TOP_LEVEL_VARIABLE); |
| 131 ElementKind.TOP_LEVEL_VARIABLE); | 133 checkLocal( |
| 132 checkLocal( | 134 'TypeParameter field;', 'TypeParameter>', ElementKind.TYPE_PARAMETER); |
| 133 'TypeParameter field;', 'TypeParameter>', ElementKind.TYPE_PARAMETER); | |
| 134 }); | |
| 135 } | 135 } |
| 136 } | 136 } |
| 137 | 137 |
| 138 @reflectiveTest | 138 @reflectiveTest |
| 139 class AnalysisNavigationTest extends AbstractAnalysisNavigationTest {} | 139 class AnalysisNavigationTest extends AbstractAnalysisNavigationTest {} |
| 140 | 140 |
| 141 @reflectiveTest | 141 @reflectiveTest |
| 142 class AnalysisNavigationTest_Driver extends AbstractAnalysisNavigationTest { | 142 class AnalysisNavigationTest_Driver extends AbstractAnalysisNavigationTest { |
| 143 @override | 143 @override |
| 144 bool get enableNewAnalysisDriver => true; | 144 bool get enableNewAnalysisDriver => true; |
| 145 } | 145 } |
| OLD | NEW |