| 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.domain.analysis; | 5 library test.domain.analysis; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:analysis_server/src/analysis_server.dart'; | 9 import 'package:analysis_server/src/analysis_server.dart'; |
| 10 import 'package:analysis_server/src/constants.dart'; | 10 import 'package:analysis_server/src/constants.dart'; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 MemoryResourceProvider resourceProvider = new MemoryResourceProvider(); | 26 MemoryResourceProvider resourceProvider = new MemoryResourceProvider(); |
| 27 | 27 |
| 28 setUp(() { | 28 setUp(() { |
| 29 serverChannel = new MockServerChannel(); | 29 serverChannel = new MockServerChannel(); |
| 30 server = new AnalysisServer(serverChannel, resourceProvider); | 30 server = new AnalysisServer(serverChannel, resourceProvider); |
| 31 handler = new AnalysisDomainHandler(server); | 31 handler = new AnalysisDomainHandler(server); |
| 32 }); | 32 }); |
| 33 | 33 |
| 34 group('notification.errors', testNotificationErrors); | 34 group('notification.errors', testNotificationErrors); |
| 35 group('notification.highlights', testNotificationHighlights); | 35 group('notification.highlights', testNotificationHighlights); |
| 36 group('notification.navigation', testNotificationNavigation); |
| 36 group('updateContent', testUpdateContent); | 37 group('updateContent', testUpdateContent); |
| 37 group('setSubscriptions', test_setSubscriptions); | 38 group('setSubscriptions', test_setSubscriptions); |
| 38 | 39 |
| 39 group('AnalysisDomainHandler', () { | 40 group('AnalysisDomainHandler', () { |
| 40 test('getFixes', () { | 41 test('getFixes', () { |
| 41 var request = new Request('0', METHOD_GET_FIXES); | 42 var request = new Request('0', METHOD_GET_FIXES); |
| 42 request.setParameter(ERRORS, []); | 43 request.setParameter(ERRORS, []); |
| 43 var response = handler.handleRequest(request); | 44 var response = handler.handleRequest(request); |
| 44 // TODO(scheglov) implement | 45 // TODO(scheglov) implement |
| 45 expect(response, isNull); | 46 expect(response, isNull); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 class AnalysisTestHelper { | 168 class AnalysisTestHelper { |
| 168 MockServerChannel serverChannel; | 169 MockServerChannel serverChannel; |
| 169 MemoryResourceProvider resourceProvider; | 170 MemoryResourceProvider resourceProvider; |
| 170 AnalysisServer server; | 171 AnalysisServer server; |
| 171 AnalysisDomainHandler handler; | 172 AnalysisDomainHandler handler; |
| 172 | 173 |
| 173 Map<String, List<String>> analysisSubscriptions = {}; | 174 Map<String, List<String>> analysisSubscriptions = {}; |
| 174 | 175 |
| 175 Map<String, List<AnalysisError>> filesErrors = {}; | 176 Map<String, List<AnalysisError>> filesErrors = {}; |
| 176 Map<String, List<Map<String, Object>>> filesHighlights = {}; | 177 Map<String, List<Map<String, Object>>> filesHighlights = {}; |
| 178 Map<String, List<Map<String, Object>>> filesNavigation = {}; |
| 177 | 179 |
| 178 String testFile = '/project/bin/test.dart'; | 180 String testFile = '/project/bin/test.dart'; |
| 179 String testCode; | 181 String testCode; |
| 180 | 182 |
| 181 AnalysisTestHelper() { | 183 AnalysisTestHelper() { |
| 182 serverChannel = new MockServerChannel(); | 184 serverChannel = new MockServerChannel(); |
| 183 resourceProvider = new MemoryResourceProvider(); | 185 resourceProvider = new MemoryResourceProvider(); |
| 184 server = new AnalysisServer(serverChannel, resourceProvider); | 186 server = new AnalysisServer(serverChannel, resourceProvider); |
| 185 handler = new AnalysisDomainHandler(server); | 187 handler = new AnalysisDomainHandler(server); |
| 186 // listen for notifications | 188 // listen for notifications |
| 187 Stream<Notification> notificationStream = serverChannel.notificationControll
er.stream; | 189 Stream<Notification> notificationStream = serverChannel.notificationControll
er.stream; |
| 188 notificationStream.listen((Notification notification) { | 190 notificationStream.listen((Notification notification) { |
| 189 if (notification.event == NOTIFICATION_ERRORS) { | 191 if (notification.event == NOTIFICATION_ERRORS) { |
| 190 String file = notification.getParameter(FILE); | 192 String file = notification.getParameter(FILE); |
| 191 List<Map<String, Object>> errorMaps = notification.getParameter(ERRORS); | 193 List<Map<String, Object>> errorMaps = notification.getParameter(ERRORS); |
| 192 filesErrors[file] = errorMaps.map(jsonToAnalysisError).toList(); | 194 filesErrors[file] = errorMaps.map(jsonToAnalysisError).toList(); |
| 193 } | 195 } |
| 194 if (notification.event == NOTIFICATION_HIGHLIGHTS) { | 196 if (notification.event == NOTIFICATION_HIGHLIGHTS) { |
| 195 String file = notification.getParameter(FILE); | 197 String file = notification.getParameter(FILE); |
| 196 filesHighlights[file] = notification.getParameter(REGIONS); | 198 filesHighlights[file] = notification.getParameter(REGIONS); |
| 197 } | 199 } |
| 200 if (notification.event == NOTIFICATION_NAVIGATION) { |
| 201 String file = notification.getParameter(FILE); |
| 202 filesNavigation[file] = notification.getParameter(REGIONS); |
| 203 } |
| 198 }); | 204 }); |
| 199 } | 205 } |
| 200 | 206 |
| 201 void addAnalysisSubscriptionHighlight(String file) { | 207 void addAnalysisSubscriptionHighlights(String file) { |
| 202 var service = AnalysisService.HIGHLIGHTS; | 208 addAnalysisSubscription(AnalysisService.HIGHLIGHTS, file); |
| 209 } |
| 210 |
| 211 void addAnalysisSubscriptionNavigation(String file) { |
| 212 addAnalysisSubscription(AnalysisService.NAVIGATION, file); |
| 213 } |
| 214 |
| 215 void addAnalysisSubscription(AnalysisService service, String file) { |
| 203 // add file to subscription | 216 // add file to subscription |
| 204 var files = analysisSubscriptions[service.name]; | 217 var files = analysisSubscriptions[service.name]; |
| 205 if (files == null) { | 218 if (files == null) { |
| 206 files = <String>[]; | 219 files = <String>[]; |
| 207 analysisSubscriptions[service.name] = files; | 220 analysisSubscriptions[service.name] = files; |
| 208 } | 221 } |
| 209 files.add(file); | 222 files.add(file); |
| 210 // set subscriptions | 223 // set subscriptions |
| 211 Request request = new Request('0', METHOD_SET_ANALYSIS_SUBSCRIPTIONS); | 224 Request request = new Request('0', METHOD_SET_ANALYSIS_SUBSCRIPTIONS); |
| 212 request.setParameter(SUBSCRIPTIONS, analysisSubscriptions); | 225 request.setParameter(SUBSCRIPTIONS, analysisSubscriptions); |
| 213 handleSuccessfulRequest(request); | 226 handleSuccessfulRequest(request); |
| 214 } | 227 } |
| 215 | 228 |
| 216 /** | 229 /** |
| 217 * Returns a [Future] that completes when this this helper finished all its | 230 * Returns a [Future] that completes when this this helper finished all its |
| 218 * scheduled tasks. | 231 * scheduled tasks. |
| 219 */ | 232 */ |
| 220 Future waitForOperationsFinished() { | 233 Future waitForOperationsFinished() { |
| 221 return waitForServerOperationsPerformed(server); | 234 return waitForServerOperationsPerformed(server); |
| 222 } | 235 } |
| 223 | 236 |
| 224 /** | 237 /** |
| 238 * Returns the offset of [search] in [testCode]. |
| 239 * Fails if not found. |
| 240 */ |
| 241 int findOffset(String search) { |
| 242 int offset = testCode.indexOf(search); |
| 243 expect(offset, isNot(-1)); |
| 244 return offset; |
| 245 } |
| 246 |
| 247 /** |
| 225 * Returns [AnalysisError]s recorded for the given [file]. | 248 * Returns [AnalysisError]s recorded for the given [file]. |
| 226 * May be empty, but not `null`. | 249 * May be empty, but not `null`. |
| 227 */ | 250 */ |
| 228 List<AnalysisError> getErrors(String file) { | 251 List<AnalysisError> getErrors(String file) { |
| 229 List<AnalysisError> errors = filesErrors[file]; | 252 List<AnalysisError> errors = filesErrors[file]; |
| 230 if (errors != null) { | 253 if (errors != null) { |
| 231 return errors; | 254 return errors; |
| 232 } | 255 } |
| 233 return <AnalysisError>[]; | 256 return <AnalysisError>[]; |
| 234 } | 257 } |
| 235 | 258 |
| 236 /** | 259 /** |
| 237 * Returns highlights recorded for the given [file]. | 260 * Returns highlights recorded for the given [file]. |
| 238 * May be empty, but not `null`. | 261 * May be empty, but not `null`. |
| 239 */ | 262 */ |
| 240 List<Map<String, Object>> getHighlights(String file) { | 263 List<Map<String, Object>> getHighlights(String file) { |
| 241 List<Map<String, Object>> highlights = filesHighlights[file]; | 264 List<Map<String, Object>> highlights = filesHighlights[file]; |
| 242 if (highlights != null) { | 265 if (highlights != null) { |
| 243 return highlights; | 266 return highlights; |
| 244 } | 267 } |
| 245 return []; | 268 return []; |
| 246 } | 269 } |
| 247 | 270 |
| 248 /** | 271 /** |
| 272 * Returns navigation regions recorded for the given [file]. |
| 273 * May be empty, but not `null`. |
| 274 */ |
| 275 List<Map<String, Object>> getNavigation(String file) { |
| 276 List<Map<String, Object>> navigation = filesNavigation[file]; |
| 277 if (navigation != null) { |
| 278 return navigation; |
| 279 } |
| 280 return []; |
| 281 } |
| 282 |
| 283 /** |
| 249 * Returns [AnalysisError]s recorded for the [testFile]. | 284 * Returns [AnalysisError]s recorded for the [testFile]. |
| 250 * May be empty, but not `null`. | 285 * May be empty, but not `null`. |
| 251 */ | 286 */ |
| 252 List<AnalysisError> getTestErrors() { | 287 List<AnalysisError> getTestErrors() { |
| 253 return getErrors(testFile); | 288 return getErrors(testFile); |
| 254 } | 289 } |
| 255 | 290 |
| 256 /** | 291 /** |
| 257 * Returns highlights recorded for the given [testFile]. | 292 * Returns highlights recorded for the given [testFile]. |
| 258 * May be empty, but not `null`. | 293 * May be empty, but not `null`. |
| 259 */ | 294 */ |
| 260 List<Map<String, Object>> getTestHighlights() { | 295 List<Map<String, Object>> getTestHighlights() { |
| 261 return getHighlights(testFile); | 296 return getHighlights(testFile); |
| 262 } | 297 } |
| 263 | 298 |
| 264 /** | 299 /** |
| 300 * Returns navigation information recorded for the given [testFile]. |
| 301 * May be empty, but not `null`. |
| 302 */ |
| 303 List<Map<String, Object>> getTestNavigation() { |
| 304 return getNavigation(testFile); |
| 305 } |
| 306 |
| 307 /** |
| 265 * Creates an empty project `/project`. | 308 * Creates an empty project `/project`. |
| 266 */ | 309 */ |
| 267 void createEmptyProject() { | 310 void createEmptyProject() { |
| 268 resourceProvider.newFolder('/project'); | 311 resourceProvider.newFolder('/project'); |
| 269 Request request = new Request('0', METHOD_SET_ANALYSIS_ROOTS); | 312 Request request = new Request('0', METHOD_SET_ANALYSIS_ROOTS); |
| 270 request.setParameter(INCLUDED, ['/project']); | 313 request.setParameter(INCLUDED, ['/project']); |
| 271 request.setParameter(EXCLUDED, []); | 314 request.setParameter(EXCLUDED, []); |
| 272 handleSuccessfulRequest(request); | 315 handleSuccessfulRequest(request); |
| 273 } | 316 } |
| 274 | 317 |
| 275 /** | 318 /** |
| 276 * Creates a project with a single Dart file `/project/bin/test.dart` with | 319 * Creates a project with a single Dart file `/project/bin/test.dart` with |
| 277 * the given [code]. | 320 * the given [code]. |
| 278 */ | 321 */ |
| 279 void createSingleFileProject(code) { | 322 void createSingleFileProject(code) { |
| 280 this.testCode = _getCodeString(code); | 323 this.testCode = _getCodeString(code); |
| 281 resourceProvider.newFolder('/project'); | 324 resourceProvider.newFolder('/project'); |
| 282 resourceProvider.newFile(testFile, testCode); | 325 resourceProvider.newFile(testFile, testCode); |
| 283 Request request = new Request('0', METHOD_SET_ANALYSIS_ROOTS); | 326 Request request = new Request('0', METHOD_SET_ANALYSIS_ROOTS); |
| 284 request.setParameter(INCLUDED, ['/project']); | 327 request.setParameter(INCLUDED, ['/project']); |
| 285 request.setParameter(EXCLUDED, []); | 328 request.setParameter(EXCLUDED, []); |
| 286 handleSuccessfulRequest(request); | 329 handleSuccessfulRequest(request); |
| 287 } | 330 } |
| 288 | 331 |
| 289 void setFileContent(String path, String content) { | 332 String setFileContent(String path, String content) { |
| 290 resourceProvider.newFile(path, content); | 333 resourceProvider.newFile(path, content); |
| 334 return path; |
| 291 } | 335 } |
| 292 | 336 |
| 293 /** | 337 /** |
| 294 * Validates that the given [request] is handled successfully. | 338 * Validates that the given [request] is handled successfully. |
| 295 */ | 339 */ |
| 296 void handleSuccessfulRequest(Request request) { | 340 void handleSuccessfulRequest(Request request) { |
| 297 Response response = handler.handleRequest(request); | 341 Response response = handler.handleRequest(request); |
| 298 expect(response, isResponseSuccess('0')); | 342 expect(response, isResponseSuccess('0')); |
| 299 } | 343 } |
| 300 | 344 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 expect(error.errorCode, 'StaticWarningCode.UNDEFINED_IDENTIFIER'); | 391 expect(error.errorCode, 'StaticWarningCode.UNDEFINED_IDENTIFIER'); |
| 348 }); | 392 }); |
| 349 }); | 393 }); |
| 350 } | 394 } |
| 351 | 395 |
| 352 | 396 |
| 353 class NotificationHighlightHelper extends AnalysisTestHelper { | 397 class NotificationHighlightHelper extends AnalysisTestHelper { |
| 354 List<Map<String, Object>> regions; | 398 List<Map<String, Object>> regions; |
| 355 | 399 |
| 356 Future prepareRegions(then()) { | 400 Future prepareRegions(then()) { |
| 357 addAnalysisSubscriptionHighlight(testFile); | 401 addAnalysisSubscriptionHighlights(testFile); |
| 358 return waitForOperationsFinished().then((_) { | 402 return waitForOperationsFinished().then((_) { |
| 359 regions = getTestHighlights(); | 403 regions = getTestHighlights(); |
| 360 then(); | 404 then(); |
| 361 }); | 405 }); |
| 362 } | 406 } |
| 363 | 407 |
| 364 void assertHasRawRegion(HighlightType type, int offset, int length) { | 408 void assertHasRawRegion(HighlightType type, int offset, int length) { |
| 365 for (Map<String, Object> region in regions) { | 409 for (Map<String, Object> region in regions) { |
| 366 if (region['offset'] == offset && region['length'] == length | 410 if (region['offset'] == offset && region['length'] == length |
| 367 && region['type'] == type.name) { | 411 && region['type'] == type.name) { |
| (...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1077 return testRegions(code, (NotificationHighlightHelper helper) { | 1121 return testRegions(code, (NotificationHighlightHelper helper) { |
| 1078 helper.assertHasRegion(HighlightType.TYPE_PARAMETER, 'T> {'); | 1122 helper.assertHasRegion(HighlightType.TYPE_PARAMETER, 'T> {'); |
| 1079 helper.assertHasRegion(HighlightType.TYPE_PARAMETER, 'T fff;'); | 1123 helper.assertHasRegion(HighlightType.TYPE_PARAMETER, 'T fff;'); |
| 1080 helper.assertHasRegion(HighlightType.TYPE_PARAMETER, 'T mmm('); | 1124 helper.assertHasRegion(HighlightType.TYPE_PARAMETER, 'T mmm('); |
| 1081 helper.assertHasRegion(HighlightType.TYPE_PARAMETER, 'T p)'); | 1125 helper.assertHasRegion(HighlightType.TYPE_PARAMETER, 'T p)'); |
| 1082 }); | 1126 }); |
| 1083 }); | 1127 }); |
| 1084 } | 1128 } |
| 1085 | 1129 |
| 1086 | 1130 |
| 1131 |
| 1132 |
| 1133 class NotificationNavigationHelper extends AnalysisTestHelper { |
| 1134 List<Map<String, Object>> regions; |
| 1135 |
| 1136 Future prepareRegions(then()) { |
| 1137 addAnalysisSubscriptionNavigation(testFile); |
| 1138 return waitForOperationsFinished().then((_) { |
| 1139 regions = getTestNavigation(); |
| 1140 then(); |
| 1141 }); |
| 1142 } |
| 1143 |
| 1144 void assertHasRegion(String regionSearch, String targetSearch) { |
| 1145 var regionOffset = findOffset(regionSearch); |
| 1146 int regionLength = findIdentifierLength(regionSearch); |
| 1147 var targetOffset = findOffset(targetSearch); |
| 1148 var targetLength = findIdentifierLength(targetSearch); |
| 1149 asserHasRegionInts(regionOffset, regionLength, targetOffset, targetLength); |
| 1150 } |
| 1151 |
| 1152 void asserHasOperatorRegion(String search, int regionLength, int targetLength)
{ |
| 1153 var regionOffset = findOffset(search); |
| 1154 var region = asserHasRegionInts(regionOffset, regionLength, -1, 0); |
| 1155 if (targetLength != -1) { |
| 1156 expect(region['targets'][0]['length'], targetLength); |
| 1157 } |
| 1158 } |
| 1159 |
| 1160 asserHasRegionInts(int regionOffset, int regionLength, |
| 1161 int targetOffset, int targetLength) { |
| 1162 Map<String, Object> region = findRegion(regionOffset, regionLength); |
| 1163 if (region != null) { |
| 1164 List<Map<String, Object>> targets = region['targets']; |
| 1165 if (targetOffset == -1) { |
| 1166 return region; |
| 1167 } |
| 1168 var target = findTarget(targets, testFile, targetOffset, targetLength); |
| 1169 if (target != null) { |
| 1170 return target; |
| 1171 } |
| 1172 } |
| 1173 fail('Expected to find (offset=$regionOffset; length=$regionLength) => ' |
| 1174 '(offset=$targetOffset; length=$targetLength) in\n' |
| 1175 '${regions.join('\n')}'); |
| 1176 } |
| 1177 |
| 1178 Map<String, Object> findRegionString(String search, [bool notNull]) { |
| 1179 int offset = findOffset(search); |
| 1180 int length = search.length; |
| 1181 return findRegion(offset, length, notNull); |
| 1182 } |
| 1183 |
| 1184 Map<String, Object> findRegionAt(String search, [bool notNull]) { |
| 1185 int offset = findOffset(search); |
| 1186 for (Map<String, Object> region in regions) { |
| 1187 if (region['offset'] == offset) { |
| 1188 if (notNull == false) { |
| 1189 fail('Not expected to find at offset=$offset in\n' |
| 1190 '${regions.join('\n')}'); |
| 1191 } |
| 1192 return region; |
| 1193 } |
| 1194 } |
| 1195 if (notNull == true) { |
| 1196 fail('Expected to find at offset=$offset in\n' |
| 1197 '${regions.join('\n')}'); |
| 1198 } |
| 1199 return null; |
| 1200 } |
| 1201 |
| 1202 Map<String, Object> findRegionIdentifier(String search, [bool notNull]) { |
| 1203 int offset = findOffset(search); |
| 1204 int length = findIdentifierLength(search); |
| 1205 return findRegion(offset, length, notNull); |
| 1206 } |
| 1207 |
| 1208 Map<String, Object> findRegion(int offset, int length, [bool notNull]) { |
| 1209 for (Map<String, Object> region in regions) { |
| 1210 if (region['offset'] == offset && region['length'] == length) { |
| 1211 if (notNull == false) { |
| 1212 fail('Not expected to find (offset=$offset; length=$length) in\n' |
| 1213 '${regions.join('\n')}'); |
| 1214 } |
| 1215 return region; |
| 1216 } |
| 1217 } |
| 1218 if (notNull == true) { |
| 1219 fail('Expected to find (offset=$offset; length=$length) in\n' |
| 1220 '${regions.join('\n')}'); |
| 1221 } |
| 1222 return null; |
| 1223 } |
| 1224 |
| 1225 Map<String, Object> findTarget(List<Map<String, Object>> targets, |
| 1226 String file, int offset, int length) { |
| 1227 for (Map<String, Object> target in targets) { |
| 1228 if (target['file'] == file && |
| 1229 target['offset'] == offset && |
| 1230 target['length'] == length) { |
| 1231 return target; |
| 1232 } |
| 1233 } |
| 1234 return null; |
| 1235 } |
| 1236 |
| 1237 void assertNoRegion(String regionSearch) { |
| 1238 var regionOffset = findOffset(regionSearch); |
| 1239 var regionLength = findIdentifierLength(regionSearch); |
| 1240 for (Map<String, Object> region in regions) { |
| 1241 if (region['offset'] == regionOffset && region['length'] == regionLength)
{ |
| 1242 fail('Unexpected (offset=$regionOffset; length=$regionLength) in\n' |
| 1243 '${regions.join('\n')}'); |
| 1244 } |
| 1245 } |
| 1246 } |
| 1247 } |
| 1248 |
| 1249 |
| 1250 int findIdentifierLength(String search) { |
| 1251 int length = 0; |
| 1252 while (length < search.length) { |
| 1253 int c = search.codeUnitAt(length); |
| 1254 if (!(c >= 'a'.codeUnitAt(0) && c <= 'z'.codeUnitAt(0) || |
| 1255 c >= 'A'.codeUnitAt(0) && c <= 'Z'.codeUnitAt(0) || |
| 1256 c >= '0'.codeUnitAt(0) && c <= '9'.codeUnitAt(0))) { |
| 1257 break; |
| 1258 } |
| 1259 length++; |
| 1260 } |
| 1261 return length; |
| 1262 } |
| 1263 |
| 1264 |
| 1265 testNotificationNavigation() { |
| 1266 Future testNavigation(String code, then(NotificationNavigationHelper helper))
{ |
| 1267 var helper = new NotificationNavigationHelper(); |
| 1268 helper.createSingleFileProject(code); |
| 1269 return helper.prepareRegions(() { |
| 1270 then(helper); |
| 1271 }); |
| 1272 } |
| 1273 |
| 1274 group('constructor', () { |
| 1275 test('named', () { |
| 1276 var code = ''' |
| 1277 class A { |
| 1278 A.named(int p) {} |
| 1279 } |
| 1280 '''; |
| 1281 return testNavigation(code, (NotificationNavigationHelper helper) { |
| 1282 // has region for complete "A.named" |
| 1283 helper.asserHasRegionInts( |
| 1284 helper.findOffset('A.named'), 'A.named'.length, |
| 1285 helper.findOffset('named(int'), 'named'.length); |
| 1286 // no separate regions for "A" and "named" |
| 1287 helper.assertNoRegion('A.named('); |
| 1288 helper.assertNoRegion('named('); |
| 1289 // validate that we don't forget to resolve parameters |
| 1290 helper.asserHasRegionInts( |
| 1291 helper.findOffset('int p'), 'int'.length, |
| 1292 -1, 0); |
| 1293 }); |
| 1294 }); |
| 1295 |
| 1296 test('unnamed', () { |
| 1297 var code = ''' |
| 1298 class A { |
| 1299 A(int p) {} |
| 1300 } |
| 1301 '''; |
| 1302 return testNavigation(code, (NotificationNavigationHelper helper) { |
| 1303 // has constructor region for "A()" |
| 1304 helper.asserHasRegionInts( |
| 1305 helper.findOffset('A(int p)'), 'A'.length, |
| 1306 helper.findOffset('A(int p)'), 0); |
| 1307 // validate that we don't forget to resolve parameters |
| 1308 helper.asserHasRegionInts( |
| 1309 helper.findOffset('int p'), 'int'.length, |
| 1310 -1, 0); |
| 1311 }); |
| 1312 }); |
| 1313 }); |
| 1314 |
| 1315 group('identifier', () { |
| 1316 test('resolved', () { |
| 1317 var code = ''' |
| 1318 class AAA {} |
| 1319 main() { |
| 1320 AAA aaa = null; |
| 1321 print(aaa); |
| 1322 } |
| 1323 '''; |
| 1324 return testNavigation(code, (NotificationNavigationHelper helper) { |
| 1325 helper.assertHasRegion('AAA aaa', 'AAA {}'); |
| 1326 helper.assertHasRegion('aaa);', 'aaa = null'); |
| 1327 helper.assertHasRegion('main() {', 'main() {'); |
| 1328 }); |
| 1329 }); |
| 1330 |
| 1331 test('unresolved', () { |
| 1332 var code = ''' |
| 1333 main() { |
| 1334 print(noo); |
| 1335 } |
| 1336 '''; |
| 1337 return testNavigation(code, (NotificationNavigationHelper helper) { |
| 1338 helper.assertNoRegion('noo);'); |
| 1339 }); |
| 1340 }); |
| 1341 }); |
| 1342 |
| 1343 test('fieldFormalParameter', () { |
| 1344 var code = ''' |
| 1345 class A { |
| 1346 int fff = 123; |
| 1347 A(this.fff); |
| 1348 } |
| 1349 '''; |
| 1350 return testNavigation(code, (NotificationNavigationHelper helper) { |
| 1351 helper.assertHasRegion('fff);', 'fff = 123'); |
| 1352 }); |
| 1353 }); |
| 1354 |
| 1355 group('instanceCreation', () { |
| 1356 test('named', () { |
| 1357 var code = ''' |
| 1358 class A { |
| 1359 A.named() {} |
| 1360 } |
| 1361 main() { |
| 1362 new A.named(); |
| 1363 } |
| 1364 '''; |
| 1365 return testNavigation(code, (NotificationNavigationHelper helper) { |
| 1366 helper.asserHasRegionInts( |
| 1367 helper.findOffset('new A.named'), 'new A.named'.length, |
| 1368 helper.findOffset('named()'), 'named'.length); |
| 1369 }); |
| 1370 }); |
| 1371 |
| 1372 test('unnamed', () { |
| 1373 var code = ''' |
| 1374 class A { |
| 1375 A() {} |
| 1376 } |
| 1377 main() { |
| 1378 new A(); |
| 1379 } |
| 1380 '''; |
| 1381 return testNavigation(code, (NotificationNavigationHelper helper) { |
| 1382 helper.asserHasRegionInts( |
| 1383 helper.findOffset('new A'), 'new A'.length, |
| 1384 helper.findOffset('A()'), ''.length); |
| 1385 }); |
| 1386 }); |
| 1387 }); |
| 1388 |
| 1389 group('operator', () { |
| 1390 test('int', () { |
| 1391 var code = ''' |
| 1392 main() { |
| 1393 var v = 0; |
| 1394 v - 1; |
| 1395 v + 2; |
| 1396 -v; // unary |
| 1397 --v; |
| 1398 ++v; |
| 1399 v--; // mm |
| 1400 v++; // pp |
| 1401 v -= 3; |
| 1402 v += 4; |
| 1403 v *= 5; |
| 1404 v /= 6; |
| 1405 } |
| 1406 '''; |
| 1407 return testNavigation(code, (NotificationNavigationHelper helper) { |
| 1408 helper.asserHasOperatorRegion('- 1;', 1, 1); |
| 1409 helper.asserHasOperatorRegion('+ 2;', 1, 1); |
| 1410 helper.asserHasOperatorRegion('-v; // unary', 1, -1); |
| 1411 helper.asserHasOperatorRegion('--v;', 2, 1); |
| 1412 helper.asserHasOperatorRegion('++v;', 2, 1); |
| 1413 helper.asserHasOperatorRegion('--; // mm', 2, 1); |
| 1414 helper.asserHasOperatorRegion('++; // pp', 2, 1); |
| 1415 helper.asserHasOperatorRegion('-= 3;', 2, 1); |
| 1416 helper.asserHasOperatorRegion('+= 4;', 2, 1); |
| 1417 helper.asserHasOperatorRegion('*= 5;', 2, 1); |
| 1418 helper.asserHasOperatorRegion('/= 6;', 2, 1); |
| 1419 }); |
| 1420 }); |
| 1421 |
| 1422 test('list', () { |
| 1423 var code = ''' |
| 1424 main() { |
| 1425 List<int> v = [1, 2, 3]; |
| 1426 v[0]; // [] |
| 1427 v[1] = 1; // []= |
| 1428 v[2] += 2; |
| 1429 } |
| 1430 '''; |
| 1431 return testNavigation(code, (NotificationNavigationHelper helper) { |
| 1432 helper.asserHasOperatorRegion(']; // []', 1, 2); |
| 1433 helper.asserHasOperatorRegion('] = 1', 1, 3); |
| 1434 helper.asserHasOperatorRegion('] += 2', 1, 3); |
| 1435 helper.asserHasOperatorRegion('+= 2', 2, 1); |
| 1436 }); |
| 1437 }); |
| 1438 }); |
| 1439 |
| 1440 test('partOf', () { |
| 1441 var helper = new NotificationNavigationHelper(); |
| 1442 var code = ''' |
| 1443 part of lib; |
| 1444 '''; |
| 1445 helper.createSingleFileProject(code); |
| 1446 var libPath = helper.setFileContent('/project/bin/lib.dart', ''' |
| 1447 library lib; |
| 1448 part 'test.dart'; |
| 1449 '''); |
| 1450 return helper.prepareRegions(() { |
| 1451 var region = helper.findRegionString('part of lib', true); |
| 1452 var target = region['targets'][0]; |
| 1453 expect(target['file'], libPath); |
| 1454 }); |
| 1455 }); |
| 1456 |
| 1457 group('string', () { |
| 1458 test('export', () { |
| 1459 var code = ''' |
| 1460 export "dart:math"; |
| 1461 '''; |
| 1462 return testNavigation(code, (NotificationNavigationHelper helper) { |
| 1463 helper.findRegionString('export "dart:math"', true); |
| 1464 }); |
| 1465 }); |
| 1466 |
| 1467 test('export unresolved URI', () { |
| 1468 var code = ''' |
| 1469 export 'no.dart'; |
| 1470 '''; |
| 1471 return testNavigation(code, (NotificationNavigationHelper helper) { |
| 1472 helper.findRegionAt('export ', false); |
| 1473 }); |
| 1474 }); |
| 1475 |
| 1476 test('import', () { |
| 1477 var code = ''' |
| 1478 import "dart:math" as m; |
| 1479 '''; |
| 1480 return testNavigation(code, (NotificationNavigationHelper helper) { |
| 1481 helper.findRegionString('import "dart:math"', true); |
| 1482 }); |
| 1483 }); |
| 1484 |
| 1485 test('import no URI', () { |
| 1486 var code = ''' |
| 1487 import ; |
| 1488 '''; |
| 1489 return testNavigation(code, (NotificationNavigationHelper helper) { |
| 1490 helper.findRegionAt('import ', false); |
| 1491 }); |
| 1492 }); |
| 1493 |
| 1494 test('import unresolved URI', () { |
| 1495 var code = ''' |
| 1496 import 'no.dart'; |
| 1497 '''; |
| 1498 return testNavigation(code, (NotificationNavigationHelper helper) { |
| 1499 helper.findRegionAt('import ', false); |
| 1500 }); |
| 1501 }); |
| 1502 |
| 1503 test('part', () { |
| 1504 var helper = new NotificationNavigationHelper(); |
| 1505 var code = ''' |
| 1506 library lib; |
| 1507 part "my_part.dart"; |
| 1508 '''; |
| 1509 helper.createSingleFileProject(code); |
| 1510 var unitPath = helper.setFileContent('/project/bin/my_part.dart', ''' |
| 1511 part of lib; |
| 1512 '''); |
| 1513 return helper.prepareRegions(() { |
| 1514 var region = helper.findRegionString('part "my_part.dart"', true); |
| 1515 var target = region['targets'][0]; |
| 1516 expect(target['file'], unitPath); |
| 1517 }); |
| 1518 }); |
| 1519 |
| 1520 test('part unresolved URI', () { |
| 1521 // TODO(scheglov) why do we throw MemoryResourceException here? |
| 1522 // This Source/File does not exist. |
| 1523 // var helper = new NotificationNavigationHelper(); |
| 1524 // var code = ''' |
| 1525 //library lib; |
| 1526 //part "my_part.dart"; |
| 1527 //'''; |
| 1528 // helper.createSingleFileProject(code); |
| 1529 // return helper.prepareRegions(() { |
| 1530 // helper.findRegionAt('part ', false); |
| 1531 // }); |
| 1532 }); |
| 1533 }); |
| 1534 } |
| 1535 |
| 1536 |
| 1087 testUpdateContent() { | 1537 testUpdateContent() { |
| 1088 test('full content', () { | 1538 test('full content', () { |
| 1089 AnalysisTestHelper helper = new AnalysisTestHelper(); | 1539 AnalysisTestHelper helper = new AnalysisTestHelper(); |
| 1090 helper.createSingleFileProject('// empty'); | 1540 helper.createSingleFileProject('// empty'); |
| 1091 return helper.waitForOperationsFinished().then((_) { | 1541 return helper.waitForOperationsFinished().then((_) { |
| 1092 // no errors initially | 1542 // no errors initially |
| 1093 List<AnalysisError> errors = helper.getTestErrors(); | 1543 List<AnalysisError> errors = helper.getTestErrors(); |
| 1094 expect(errors, isEmpty); | 1544 expect(errors, isEmpty); |
| 1095 // update code | 1545 // update code |
| 1096 { | 1546 { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1139 }); | 1589 }); |
| 1140 }); | 1590 }); |
| 1141 }); | 1591 }); |
| 1142 } | 1592 } |
| 1143 | 1593 |
| 1144 | 1594 |
| 1145 void test_setSubscriptions() { | 1595 void test_setSubscriptions() { |
| 1146 test('before analysis', () { | 1596 test('before analysis', () { |
| 1147 AnalysisTestHelper helper = new AnalysisTestHelper(); | 1597 AnalysisTestHelper helper = new AnalysisTestHelper(); |
| 1148 // subscribe | 1598 // subscribe |
| 1149 helper.addAnalysisSubscriptionHighlight(helper.testFile); | 1599 helper.addAnalysisSubscriptionHighlights(helper.testFile); |
| 1150 // create project | 1600 // create project |
| 1151 helper.createSingleFileProject('int V = 42;'); | 1601 helper.createSingleFileProject('int V = 42;'); |
| 1152 // wait, there are highlight regions | 1602 // wait, there are highlight regions |
| 1153 helper.waitForOperationsFinished().then((_) { | 1603 helper.waitForOperationsFinished().then((_) { |
| 1154 var highlights = helper.getHighlights(helper.testFile); | 1604 var highlights = helper.getHighlights(helper.testFile); |
| 1155 expect(highlights, isNot(isEmpty)); | 1605 expect(highlights, isNot(isEmpty)); |
| 1156 }); | 1606 }); |
| 1157 }); | 1607 }); |
| 1158 | 1608 |
| 1159 test('after analysis', () { | 1609 test('after analysis', () { |
| 1160 AnalysisTestHelper helper = new AnalysisTestHelper(); | 1610 AnalysisTestHelper helper = new AnalysisTestHelper(); |
| 1161 // create project | 1611 // create project |
| 1162 helper.createSingleFileProject('int V = 42;'); | 1612 helper.createSingleFileProject('int V = 42;'); |
| 1163 // wait, no regions initially | 1613 // wait, no regions initially |
| 1164 return helper.waitForOperationsFinished().then((_) { | 1614 return helper.waitForOperationsFinished().then((_) { |
| 1165 var highlights = helper.getHighlights(helper.testFile); | 1615 var highlights = helper.getHighlights(helper.testFile); |
| 1166 expect(highlights, isEmpty); | 1616 expect(highlights, isEmpty); |
| 1167 // subscribe | 1617 // subscribe |
| 1168 helper.addAnalysisSubscriptionHighlight(helper.testFile); | 1618 helper.addAnalysisSubscriptionHighlights(helper.testFile); |
| 1169 // wait, has regions | 1619 // wait, has regions |
| 1170 return helper.waitForOperationsFinished().then((_) { | 1620 return helper.waitForOperationsFinished().then((_) { |
| 1171 var highlights = helper.getHighlights(helper.testFile); | 1621 var highlights = helper.getHighlights(helper.testFile); |
| 1172 expect(highlights, isNot(isEmpty)); | 1622 expect(highlights, isNot(isEmpty)); |
| 1173 }); | 1623 }); |
| 1174 }); | 1624 }); |
| 1175 }); | 1625 }); |
| 1176 } | 1626 } |
| OLD | NEW |