Chromium Code Reviews| Index: pkg/analysis_server/test/domain_analysis_test.dart |
| diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart |
| index 0470195a1cc186e2e41c752920189fef9383937d..6dc1154676886fc0accafbe0fd978855b78cf14f 100644 |
| --- a/pkg/analysis_server/test/domain_analysis_test.dart |
| +++ b/pkg/analysis_server/test/domain_analysis_test.dart |
| @@ -4,6 +4,8 @@ |
| library test.domain.analysis; |
| +import 'dart:async'; |
| + |
| import 'package:analysis_server/src/analysis_server.dart'; |
| import 'package:analysis_server/src/domain_analysis.dart'; |
| import 'package:analysis_server/src/protocol.dart'; |
| @@ -12,19 +14,107 @@ import 'package:unittest/unittest.dart'; |
| import 'mocks.dart'; |
| + |
| +/** |
| + * A helper to test 'analysis.*' requests. |
| + */ |
| +class AnalysisTestHelper { |
| + MockServerChannel serverChannel; |
| + MemoryResourceProvider resourceProvider; |
| + AnalysisServer server; |
| + AnalysisDomainHandler handler; |
| + |
| + Map<String, List<AnalysisError>> filesErrors = {}; |
| + |
| + String testFile = '/project/bin/test.dart'; |
| + String testCode; |
| + |
| + AnalysisTestHelper() { |
| + serverChannel = new MockServerChannel(); |
| + resourceProvider = new MemoryResourceProvider(); |
| + server = new AnalysisServer(serverChannel, resourceProvider); |
| + handler = new AnalysisDomainHandler(server); |
| + // listen for notifications |
| + Stream<Notification> notificationStream = serverChannel.notificationController.stream; |
| + notificationStream.listen((Notification notification) { |
| + if (notification.event == AnalysisDomainHandler.ERRORS_NOTIFICATION) { |
| + String file = notification.getParameter(AnalysisServer.FILE_PARAM); |
| + List<Map<String, Object>> errorMaps = notification.getParameter(AnalysisServer.ERRORS_PARAM); |
| + filesErrors[file] = errorMaps.map(jsonToAnalysisError).toList(); |
| + } |
| + }); |
| + } |
| + |
| + /** |
| + * Returns a [Future] that completes when this this helper finished all its |
| + * scheduled tasks. |
| + */ |
| + Future waitForTasksFinished() { |
| + return waitForServerTasksFinished(server); |
| + } |
| + |
| + /** |
| + * Returns [AnalysisError]s recorded for the given [file]. |
| + * May be empty, but not `null`. |
| + */ |
| + List<AnalysisError> getErrors(String file) { |
| + List<AnalysisError> errors = filesErrors[file]; |
| + if (errors != null) { |
| + return errors; |
| + } |
| + return <AnalysisError>[]; |
| + } |
| + |
| + /** |
| + * Returns [AnalysisError]s recorded for the [testFile]. |
| + * May be empty, but not `null`. |
| + */ |
| + List<AnalysisError> getTestErrors() { |
| + return getErrors(testFile); |
| + } |
| + |
| + /** |
| + * Creates a project with a single Dart file `/project/bin/test.dart` with |
| + * the given [code]. |
| + */ |
| + createSingleFileProject(code) { |
| + if (code is List<String>) { |
| + code = code.join('\n'); |
| + } |
| + this.testCode = code; |
| + resourceProvider.newFolder('/project'); |
| + resourceProvider.newFile('/project/pubspec.yaml', 'name: project'); |
| + resourceProvider.newFile(testFile, testCode); |
| + Request request = new Request('0', AnalysisDomainHandler.SET_ANALYSIS_ROOTS_METHOD); |
| + request.setParameter(AnalysisDomainHandler.INCLUDED_PARAM, ['/project']); |
| + request.setParameter(AnalysisDomainHandler.EXCLUDED_PARAM, []); |
| + Response response = handler.handleRequest(request); |
| + expect(response, isResponseSuccess('0')); |
| + } |
| +} |
| + |
| + |
| + |
| main() { |
| groupSep = ' | '; |
| + AnalysisTestHelper helper; |
| + MockServerChannel serverChannel; |
| AnalysisServer server; |
| AnalysisDomainHandler handler; |
| MemoryResourceProvider resourceProvider = new MemoryResourceProvider(); |
| setUp(() { |
| - var serverChannel = new MockServerChannel(); |
| + helper = new AnalysisTestHelper(); |
| + serverChannel = new MockServerChannel(); |
| server = new AnalysisServer(serverChannel, resourceProvider); |
| handler = new AnalysisDomainHandler(server); |
| }); |
| + group('notification.errors', () { |
| + testNotificationErrors(); |
|
Brian Wilkerson
2014/05/28 14:25:21
Why are these tests in a separate method? And if t
scheglov
2014/05/28 15:46:37
I want to start structuring tests.
It seems that d
|
| + }); |
| + |
| group('AnalysisDomainHandler', () { |
| test('getFixes', () { |
| var request = new Request('0', AnalysisDomainHandler.GET_FIXES_METHOD); |
| @@ -72,7 +162,7 @@ main() { |
| var serverRef = server; |
| expect(response, isResponseSuccess('0')); |
| // verify that unit is resolved eventually |
| - return pumpEventQueue(1000).then((_) { |
| + return waitForServerTasksFinished(server).then((_) { |
| var unit = serverRef.test_getResolvedCompilationUnit('/project/bin/test.dart'); |
| expect(unit, isNotNull); |
| }); |
| @@ -143,3 +233,68 @@ main() { |
| }); |
| }); |
| } |
| + |
| + |
| +testNotificationErrors() { |
| + AnalysisTestHelper helper; |
| + |
| + setUp(() { |
| + helper = new AnalysisTestHelper(); |
| + }); |
| + |
| + test('ParserErrorCode', () { |
| + helper.createSingleFileProject('library lib'); |
| + return helper.waitForTasksFinished().then((_) { |
| + List<AnalysisError> errors = helper.getTestErrors(); |
| + expect(errors, hasLength(1)); |
| + AnalysisError error = errors[0]; |
| + expect(error.file, '/project/bin/test.dart'); |
| + expect(error.errorCode, 'ParserErrorCode.EXPECTED_TOKEN'); |
| + expect(error.offset, isPositive); |
| + expect(error.length, isNonNegative); |
| + expect(error.message, isNotNull); |
| + }); |
| + }); |
| + |
| + test('StaticWarningCode', () { |
| + helper.createSingleFileProject([ |
| + 'main() {', |
| + ' print(unknown);', |
| + '}']); |
| + return helper.waitForTasksFinished().then((_) { |
| + List<AnalysisError> errors = helper.getTestErrors(); |
| + expect(errors, hasLength(1)); |
| + AnalysisError error = errors[0]; |
| + expect(error.errorCode, 'StaticWarningCode.UNDEFINED_IDENTIFIER'); |
| + }); |
| + }); |
| +} |
| + |
| + |
| +class AnalysisError { |
| + final String file; |
| + final String errorCode; |
| + final int offset; |
| + final int length; |
| + final String message; |
| + final String correction; |
| + AnalysisError(this.file, this.errorCode, this.offset, this.length, |
| + this.message, this.correction); |
| + |
| + @override |
| + String toString() { |
| + return 'NotificationError(file=$file; errorCode=$errorCode; ' |
| + 'offset=$offset; length=$length; message=$message)'; |
| + } |
| +} |
| + |
| + |
| +AnalysisError jsonToAnalysisError(Map<String, Object> json) { |
| + return new AnalysisError( |
| + json['file'], |
| + json['errorCode'], |
| + json['offset'], |
| + json['length'], |
| + json['message'], |
| + json['correction']); |
| +} |