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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 test('excluded folder', () { | 61 test('excluded folder', () { |
62 String fileA = '/project/aaa/a.dart'; | 62 String fileA = '/project/aaa/a.dart'; |
63 String fileB = '/project/bbb/b.dart'; | 63 String fileB = '/project/bbb/b.dart'; |
64 resourceProvider.newFile(fileA, '// a'); | 64 resourceProvider.newFile(fileA, '// a'); |
65 resourceProvider.newFile(fileB, '// b'); | 65 resourceProvider.newFile(fileB, '// b'); |
66 var response = testSetAnalysisRoots(['/project'], ['/project/bbb']); | 66 var response = testSetAnalysisRoots(['/project'], ['/project/bbb']); |
67 var serverRef = server; | 67 var serverRef = server; |
68 expect(response, isResponseSuccess('0')); | 68 expect(response, isResponseSuccess('0')); |
69 // unit "a" is resolved eventually | 69 // unit "a" is resolved eventually |
70 // unit "b" is not resolved | 70 // unit "b" is not resolved |
71 return waitForServerOperationsPerformed(server).then((_) { | 71 return server.onAnalysisComplete.then((_) { |
72 expect(serverRef.getResolvedCompilationUnits(fileA), hasLength(1)); | 72 expect(serverRef.getResolvedCompilationUnits(fileA), hasLength(1)); |
73 expect(serverRef.getResolvedCompilationUnits(fileB), isEmpty); | 73 expect(serverRef.getResolvedCompilationUnits(fileB), isEmpty); |
74 }); | 74 }); |
75 }); | 75 }); |
76 }); | 76 }); |
77 | 77 |
78 group('included', () { | 78 group('included', () { |
79 test('new folder', () { | 79 test('new folder', () { |
80 String file = '/project/bin/test.dart'; | 80 String file = '/project/bin/test.dart'; |
81 resourceProvider.newFile('/project/pubspec.yaml', 'name: project'); | 81 resourceProvider.newFile('/project/pubspec.yaml', 'name: project'); |
82 resourceProvider.newFile(file, 'main() {}'); | 82 resourceProvider.newFile(file, 'main() {}'); |
83 var response = testSetAnalysisRoots(['/project'], []); | 83 var response = testSetAnalysisRoots(['/project'], []); |
84 var serverRef = server; | 84 var serverRef = server; |
85 expect(response, isResponseSuccess('0')); | 85 expect(response, isResponseSuccess('0')); |
86 // verify that unit is resolved eventually | 86 // verify that unit is resolved eventually |
87 return waitForServerOperationsPerformed(server).then((_) { | 87 return server.onAnalysisComplete.then((_) { |
88 var units = serverRef.getResolvedCompilationUnits(file); | 88 var units = serverRef.getResolvedCompilationUnits(file); |
89 expect(units, hasLength(1)); | 89 expect(units, hasLength(1)); |
90 }); | 90 }); |
91 }); | 91 }); |
92 }); | 92 }); |
93 }); | 93 }); |
94 | 94 |
95 group('setPriorityFiles', () { | 95 group('setPriorityFiles', () { |
96 test('invalid', () { | 96 test('invalid', () { |
97 // TODO(paulberry): under the "eventual consistency" model this request | 97 // TODO(paulberry): under the "eventual consistency" model this request |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 | 156 |
157 | 157 |
158 void test_setSubscriptions() { | 158 void test_setSubscriptions() { |
159 test('before analysis', () { | 159 test('before analysis', () { |
160 AnalysisTestHelper helper = new AnalysisTestHelper(); | 160 AnalysisTestHelper helper = new AnalysisTestHelper(); |
161 // subscribe | 161 // subscribe |
162 helper.addAnalysisSubscriptionHighlights(helper.testFile); | 162 helper.addAnalysisSubscriptionHighlights(helper.testFile); |
163 // create project | 163 // create project |
164 helper.createSingleFileProject('int V = 42;'); | 164 helper.createSingleFileProject('int V = 42;'); |
165 // wait, there are highlight regions | 165 // wait, there are highlight regions |
166 helper.waitForOperationsFinished().then((_) { | 166 helper.onAnalysisComplete.then((_) { |
167 var highlights = helper.getHighlights(helper.testFile); | 167 var highlights = helper.getHighlights(helper.testFile); |
168 expect(highlights, isNotEmpty); | 168 expect(highlights, isNotEmpty); |
169 }); | 169 }); |
170 }); | 170 }); |
171 | 171 |
172 test('after analysis', () { | 172 test('after analysis', () { |
173 AnalysisTestHelper helper = new AnalysisTestHelper(); | 173 AnalysisTestHelper helper = new AnalysisTestHelper(); |
174 // create project | 174 // create project |
175 helper.createSingleFileProject('int V = 42;'); | 175 helper.createSingleFileProject('int V = 42;'); |
176 // wait, no regions initially | 176 // wait, no regions initially |
177 return helper.waitForOperationsFinished().then((_) { | 177 return helper.onAnalysisComplete.then((_) { |
178 var highlights = helper.getHighlights(helper.testFile); | 178 var highlights = helper.getHighlights(helper.testFile); |
179 expect(highlights, isEmpty); | 179 expect(highlights, isEmpty); |
180 // subscribe | 180 // subscribe |
181 helper.addAnalysisSubscriptionHighlights(helper.testFile); | 181 helper.addAnalysisSubscriptionHighlights(helper.testFile); |
182 // wait, has regions | 182 // wait, has regions |
183 return helper.waitForOperationsFinished().then((_) { | 183 return helper.onAnalysisComplete.then((_) { |
184 var highlights = helper.getHighlights(helper.testFile); | 184 var highlights = helper.getHighlights(helper.testFile); |
185 expect(highlights, isNotEmpty); | 185 expect(highlights, isNotEmpty); |
186 }); | 186 }); |
187 }); | 187 }); |
188 }); | 188 }); |
189 | 189 |
190 test('after analysis, no such file', () { | 190 test('after analysis, no such file', () { |
191 AnalysisTestHelper helper = new AnalysisTestHelper(); | 191 AnalysisTestHelper helper = new AnalysisTestHelper(); |
192 helper.createSingleFileProject('int V = 42;'); | 192 helper.createSingleFileProject('int V = 42;'); |
193 return helper.waitForOperationsFinished().then((_) { | 193 return helper.onAnalysisComplete.then((_) { |
194 String noFile = '/no-such-file.dart'; | 194 String noFile = '/no-such-file.dart'; |
195 helper.addAnalysisSubscriptionHighlights(noFile); | 195 helper.addAnalysisSubscriptionHighlights(noFile); |
196 return helper.waitForOperationsFinished().then((_) { | 196 return helper.onAnalysisComplete.then((_) { |
197 var highlights = helper.getHighlights(noFile); | 197 var highlights = helper.getHighlights(noFile); |
198 expect(highlights, isEmpty); | 198 expect(highlights, isEmpty); |
199 }); | 199 }); |
200 }); | 200 }); |
201 }); | 201 }); |
202 | 202 |
203 test('after analysis, SDK file', () { | 203 test('after analysis, SDK file', () { |
204 AnalysisTestHelper helper = new AnalysisTestHelper(); | 204 AnalysisTestHelper helper = new AnalysisTestHelper(); |
205 helper.createSingleFileProject(''' | 205 helper.createSingleFileProject(''' |
206 main() { | 206 main() { |
207 print(42); | 207 print(42); |
208 } | 208 } |
209 '''); | 209 '''); |
210 return helper.waitForOperationsFinished().then((_) { | 210 return helper.onAnalysisComplete.then((_) { |
211 String file = '/lib/core/core.dart'; | 211 String file = '/lib/core/core.dart'; |
212 helper.addAnalysisSubscriptionNavigation(file); | 212 helper.addAnalysisSubscriptionNavigation(file); |
213 return helper.waitForOperationsFinished().then((_) { | 213 return helper.onAnalysisComplete.then((_) { |
214 var navigationRegions = helper.getNavigation(file); | 214 var navigationRegions = helper.getNavigation(file); |
215 expect(navigationRegions, isNotEmpty); | 215 expect(navigationRegions, isNotEmpty); |
216 }); | 216 }); |
217 }); | 217 }); |
218 }); | 218 }); |
219 } | 219 } |
220 | 220 |
221 | 221 |
222 testUpdateContent() { | 222 testUpdateContent() { |
223 test('bad type', () { | 223 test('bad type', () { |
224 AnalysisTestHelper helper = new AnalysisTestHelper(); | 224 AnalysisTestHelper helper = new AnalysisTestHelper(); |
225 helper.createSingleFileProject('// empty'); | 225 helper.createSingleFileProject('// empty'); |
226 return helper.waitForOperationsFinished().then((_) { | 226 return helper.onAnalysisComplete.then((_) { |
227 Request request = new Request('0', ANALYSIS_UPDATE_CONTENT, { | 227 Request request = new Request('0', ANALYSIS_UPDATE_CONTENT, { |
228 'files': { | 228 'files': { |
229 helper.testFile: { | 229 helper.testFile: { |
230 TYPE: 'foo', | 230 TYPE: 'foo', |
231 } | 231 } |
232 } | 232 } |
233 }); | 233 }); |
234 Response response = helper.handler.handleRequest(request); | 234 Response response = helper.handler.handleRequest(request); |
235 expect(response, isResponseFailure('0')); | 235 expect(response, isResponseFailure('0')); |
236 }); | 236 }); |
237 }); | 237 }); |
238 | 238 |
239 test('full content', () { | 239 test('full content', () { |
240 AnalysisTestHelper helper = new AnalysisTestHelper(); | 240 AnalysisTestHelper helper = new AnalysisTestHelper(); |
241 helper.createSingleFileProject('// empty'); | 241 helper.createSingleFileProject('// empty'); |
242 return helper.waitForOperationsFinished().then((_) { | 242 return helper.onAnalysisComplete.then((_) { |
243 // no errors initially | 243 // no errors initially |
244 List<AnalysisError> errors = helper.getTestErrors(); | 244 List<AnalysisError> errors = helper.getTestErrors(); |
245 expect(errors, isEmpty); | 245 expect(errors, isEmpty); |
246 // update code | 246 // update code |
247 helper.sendContentChange(new AddContentOverlay('library lib')); | 247 helper.sendContentChange(new AddContentOverlay('library lib')); |
248 // wait, there is an error | 248 // wait, there is an error |
249 return helper.waitForOperationsFinished().then((_) { | 249 return helper.onAnalysisComplete.then((_) { |
250 List<AnalysisError> errors = helper.getTestErrors(); | 250 List<AnalysisError> errors = helper.getTestErrors(); |
251 expect(errors, hasLength(1)); | 251 expect(errors, hasLength(1)); |
252 }); | 252 }); |
253 }); | 253 }); |
254 }); | 254 }); |
255 | 255 |
256 test('incremental', () { | 256 test('incremental', () { |
257 AnalysisTestHelper helper = new AnalysisTestHelper(); | 257 AnalysisTestHelper helper = new AnalysisTestHelper(); |
258 String initialContent = 'library A;'; | 258 String initialContent = 'library A;'; |
259 helper.createSingleFileProject(initialContent); | 259 helper.createSingleFileProject(initialContent); |
260 return helper.waitForOperationsFinished().then((_) { | 260 return helper.onAnalysisComplete.then((_) { |
261 // no errors initially | 261 // no errors initially |
262 List<AnalysisError> errors = helper.getTestErrors(); | 262 List<AnalysisError> errors = helper.getTestErrors(); |
263 expect(errors, isEmpty); | 263 expect(errors, isEmpty); |
264 // Add the file to the cache | 264 // Add the file to the cache |
265 helper.sendContentChange(new AddContentOverlay(initialContent)); | 265 helper.sendContentChange(new AddContentOverlay(initialContent)); |
266 // update code | 266 // update code |
267 helper.sendContentChange( | 267 helper.sendContentChange( |
268 new ChangeContentOverlay( | 268 new ChangeContentOverlay( |
269 [new SourceEdit('library '.length, 'A;'.length, 'lib')])); | 269 [new SourceEdit('library '.length, 'A;'.length, 'lib')])); |
270 // wait, there is an error | 270 // wait, there is an error |
271 return helper.waitForOperationsFinished().then((_) { | 271 return helper.onAnalysisComplete.then((_) { |
272 List<AnalysisError> errors = helper.getTestErrors(); | 272 List<AnalysisError> errors = helper.getTestErrors(); |
273 expect(errors, hasLength(1)); | 273 expect(errors, hasLength(1)); |
274 }); | 274 }); |
275 }); | 275 }); |
276 }); | 276 }); |
277 | 277 |
278 test('change on disk, normal', () { | 278 test('change on disk, normal', () { |
279 AnalysisTestHelper helper = new AnalysisTestHelper(); | 279 AnalysisTestHelper helper = new AnalysisTestHelper(); |
280 helper.createSingleFileProject('library A;'); | 280 helper.createSingleFileProject('library A;'); |
281 return helper.waitForOperationsFinished().then((_) { | 281 return helper.onAnalysisComplete.then((_) { |
282 // There should be no errors | 282 // There should be no errors |
283 expect(helper.getTestErrors(), hasLength(0)); | 283 expect(helper.getTestErrors(), hasLength(0)); |
284 // Change file on disk, adding a syntax error. | 284 // Change file on disk, adding a syntax error. |
285 helper.resourceProvider.modifyFile(helper.testFile, 'library lib'); | 285 helper.resourceProvider.modifyFile(helper.testFile, 'library lib'); |
286 // There should be errors now. | 286 // There should be errors now. |
287 return pumpEventQueue().then((_) { | 287 return pumpEventQueue().then((_) { |
288 return helper.waitForOperationsFinished().then((_) { | 288 return helper.onAnalysisComplete.then((_) { |
289 expect(helper.getTestErrors(), hasLength(1)); | 289 expect(helper.getTestErrors(), hasLength(1)); |
290 }); | 290 }); |
291 }); | 291 }); |
292 }); | 292 }); |
293 }); | 293 }); |
294 | 294 |
295 test('change on disk, during override', () { | 295 test('change on disk, during override', () { |
296 AnalysisTestHelper helper = new AnalysisTestHelper(); | 296 AnalysisTestHelper helper = new AnalysisTestHelper(); |
297 helper.createSingleFileProject('library A;'); | 297 helper.createSingleFileProject('library A;'); |
298 return helper.waitForOperationsFinished().then((_) { | 298 return helper.onAnalysisComplete.then((_) { |
299 // update code | 299 // update code |
300 helper.sendContentChange(new AddContentOverlay('library B;')); | 300 helper.sendContentChange(new AddContentOverlay('library B;')); |
301 // There should be no errors | 301 // There should be no errors |
302 return helper.waitForOperationsFinished().then((_) { | 302 return helper.onAnalysisComplete.then((_) { |
303 expect(helper.getTestErrors(), hasLength(0)); | 303 expect(helper.getTestErrors(), hasLength(0)); |
304 // Change file on disk, adding a syntax error. | 304 // Change file on disk, adding a syntax error. |
305 helper.resourceProvider.modifyFile(helper.testFile, 'library lib'); | 305 helper.resourceProvider.modifyFile(helper.testFile, 'library lib'); |
306 // There should still be no errors (file should not have been reread). | 306 // There should still be no errors (file should not have been reread). |
307 return helper.waitForOperationsFinished().then((_) { | 307 return helper.onAnalysisComplete.then((_) { |
308 expect(helper.getTestErrors(), hasLength(0)); | 308 expect(helper.getTestErrors(), hasLength(0)); |
309 // Send a content change with a null content param--file should be | 309 // Send a content change with a null content param--file should be |
310 // reread from disk. | 310 // reread from disk. |
311 helper.sendContentChange(new RemoveContentOverlay()); | 311 helper.sendContentChange(new RemoveContentOverlay()); |
312 // There should be errors now. | 312 // There should be errors now. |
313 return helper.waitForOperationsFinished().then((_) { | 313 return helper.onAnalysisComplete.then((_) { |
314 expect(helper.getTestErrors(), hasLength(1)); | 314 expect(helper.getTestErrors(), hasLength(1)); |
315 }); | 315 }); |
316 }); | 316 }); |
317 }); | 317 }); |
318 }); | 318 }); |
319 }); | 319 }); |
320 | 320 |
321 group('out of range', () { | 321 group('out of range', () { |
322 Future outOfRangeTest(SourceEdit edit) { | 322 Future outOfRangeTest(SourceEdit edit) { |
323 AnalysisTestHelper helper = new AnalysisTestHelper(); | 323 AnalysisTestHelper helper = new AnalysisTestHelper(); |
324 helper.createSingleFileProject('library A;'); | 324 helper.createSingleFileProject('library A;'); |
325 return helper.waitForOperationsFinished().then((_) { | 325 return helper.onAnalysisComplete.then((_) { |
326 helper.sendContentChange(new AddContentOverlay('library B;')); | 326 helper.sendContentChange(new AddContentOverlay('library B;')); |
327 return helper.waitForOperationsFinished().then((_) { | 327 return helper.onAnalysisComplete.then((_) { |
328 ChangeContentOverlay contentChange = new ChangeContentOverlay([edit]); | 328 ChangeContentOverlay contentChange = new ChangeContentOverlay([edit]); |
329 Request request = new AnalysisUpdateContentParams({ | 329 Request request = new AnalysisUpdateContentParams({ |
330 helper.testFile: contentChange | 330 helper.testFile: contentChange |
331 }).toRequest('0'); | 331 }).toRequest('0'); |
332 Response response = helper.handler.handleRequest(request); | 332 Response response = helper.handler.handleRequest(request); |
333 expect( | 333 expect( |
334 response, | 334 response, |
335 isResponseFailure('0', RequestErrorCode.INVALID_OVERLAY_CHANGE)); | 335 isResponseFailure('0', RequestErrorCode.INVALID_OVERLAY_CHANGE)); |
336 }); | 336 }); |
337 }); | 337 }); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 filesHighlights[params.file] = params.regions; | 466 filesHighlights[params.file] = params.regions; |
467 } | 467 } |
468 if (notification.event == ANALYSIS_NAVIGATION) { | 468 if (notification.event == ANALYSIS_NAVIGATION) { |
469 var params = | 469 var params = |
470 new AnalysisNavigationParams.fromNotification(notification); | 470 new AnalysisNavigationParams.fromNotification(notification); |
471 filesNavigation[params.file] = params.regions; | 471 filesNavigation[params.file] = params.regions; |
472 } | 472 } |
473 }); | 473 }); |
474 } | 474 } |
475 | 475 |
| 476 /** |
| 477 * Returns a [Future] that completes when the server's analysis is complete. |
| 478 */ |
| 479 Future get onAnalysisComplete { |
| 480 return server.onAnalysisComplete; |
| 481 } |
| 482 |
476 void addAnalysisSubscription(AnalysisService service, String file) { | 483 void addAnalysisSubscription(AnalysisService service, String file) { |
477 // add file to subscription | 484 // add file to subscription |
478 var files = analysisSubscriptions[service]; | 485 var files = analysisSubscriptions[service]; |
479 if (files == null) { | 486 if (files == null) { |
480 files = <String>[]; | 487 files = <String>[]; |
481 analysisSubscriptions[service] = files; | 488 analysisSubscriptions[service] = files; |
482 } | 489 } |
483 files.add(file); | 490 files.add(file); |
484 // set subscriptions | 491 // set subscriptions |
485 Request request = | 492 Request request = |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 return path; | 618 return path; |
612 } | 619 } |
613 | 620 |
614 /** | 621 /** |
615 * Stops the associated server. | 622 * Stops the associated server. |
616 */ | 623 */ |
617 void stopServer() { | 624 void stopServer() { |
618 server.done(); | 625 server.done(); |
619 } | 626 } |
620 | 627 |
621 /** | |
622 * Returns a [Future] that completes when this this helper finished all its | |
623 * scheduled tasks. | |
624 */ | |
625 Future waitForOperationsFinished() { | |
626 return waitForServerOperationsPerformed(server); | |
627 } | |
628 | |
629 static String _getCodeString(code) { | 628 static String _getCodeString(code) { |
630 if (code is List<String>) { | 629 if (code is List<String>) { |
631 code = code.join('\n'); | 630 code = code.join('\n'); |
632 } | 631 } |
633 return code as String; | 632 return code as String; |
634 } | 633 } |
635 } | 634 } |
OLD | NEW |