| // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| library services.analyzer_server_test; |
| |
| import 'package:dart_services/src/analysis_server.dart'; |
| import 'package:dart_services/src/api_classes.dart'; |
| import 'package:dart_services/src/common.dart'; |
| import 'package:dart_services/src/flutter_web.dart'; |
| import 'package:test/test.dart'; |
| |
| const completionCode = r''' |
| void main() { |
| int i = 0; |
| i. |
| } |
| '''; |
| |
| const completionFilterCode = r''' |
| void main() { |
| pr |
| } |
| '''; |
| |
| const completionLargeNamespaces = r''' |
| class A {} |
| class AB {} |
| class ABC {} |
| void main() { |
| var c = A |
| } |
| class ZZ {} |
| class a {} |
| '''; |
| |
| const quickFixesCode = r''' |
| void main() { |
| int i = 0 |
| } |
| '''; |
| |
| const badFormatCode = r''' |
| void main() |
| { |
| int i = 0; |
| } |
| '''; |
| |
| const formattedCode = r''' |
| void main() { |
| int i = 0; |
| } |
| '''; |
| |
| const formatWithIssues = ''' |
| void main() { foo() } |
| '''; |
| |
| void main() => defineTests(); |
| |
| void defineTests() { |
| AnalysisServerWrapper analysisServer; |
| FlutterWebManager flutterWebManager; |
| |
| group('analysis_server', () { |
| setUp(() async { |
| flutterWebManager = FlutterWebManager(sdkPath); |
| analysisServer = AnalysisServerWrapper(sdkPath, flutterWebManager); |
| await analysisServer.init(); |
| }); |
| |
| tearDown(() => analysisServer.shutdown()); |
| |
| test('simple_completion', () { |
| // Just after i. |
| return analysisServer |
| .complete(completionCode, 32) |
| .then((CompleteResponse results) { |
| expect(results.replacementLength, 0); |
| expect(results.replacementOffset, 32); |
| expect(completionsContains(results, 'abs'), true); |
| expect(completionsContains(results, 'codeUnitAt'), false); |
| }); |
| }); |
| |
| test('repro #126 - completions polluted on second request', () { |
| // https://github.com/dart-lang/dart-services/issues/126 |
| return analysisServer |
| .complete(completionFilterCode, 17) |
| .then((CompleteResponse results) { |
| return analysisServer |
| .complete(completionFilterCode, 17) |
| .then((CompleteResponse results) { |
| expect(results.replacementLength, 2); |
| expect(results.replacementOffset, 16); |
| expect(completionsContains(results, 'print'), true); |
| expect(completionsContains(results, 'pow'), false); |
| }); |
| }); |
| }); |
| |
| test('import_test', () { |
| String testCode = "import '/'; main() { int a = 0; a. }"; |
| |
| return analysisServer |
| .complete(testCode, 9) |
| .then((CompleteResponse results) { |
| expect(results.completions.every((Map<String, String> completion) { |
| return completion['completion'].startsWith('dart:'); |
| }), true); |
| }); |
| }); |
| |
| test('import_and_other_test', () { |
| String testCode = "import '/'; main() { int a = 0; a. }"; |
| |
| return analysisServer |
| .complete(testCode, 34) |
| .then((CompleteResponse results) { |
| expect(completionsContains(results, 'abs'), true); |
| }); |
| }); |
| |
| test('simple_quickFix', () { |
| return analysisServer |
| .getFixes(quickFixesCode, 25) |
| .then((FixesResponse results) { |
| expect(results.fixes.length, 1); |
| expect(results.fixes[0].offset, 24); |
| expect(results.fixes[0].length, 1); //we need an insertion |
| |
| // We should be getting an insert ; fix |
| expect(results.fixes[0].fixes.length, 1); |
| CandidateFix fix = results.fixes[0].fixes[0]; |
| expect(fix.message.contains(';'), true); |
| expect(fix.edits[0].length, 0); |
| expect(fix.edits[0].offset, 25); |
| expect(fix.edits[0].replacement, ';'); |
| }); |
| }); |
| |
| test('simple_format', () async { |
| FormatResponse results = await analysisServer.format(badFormatCode, 0); |
| expect(results.newString, formattedCode); |
| }); |
| |
| test('format good code', () async { |
| FormatResponse results = |
| await analysisServer.format(formattedCode.replaceAll('\n', ' '), 0); |
| expect(results.newString, formattedCode); |
| }); |
| |
| test('format with issues', () async { |
| FormatResponse results = await analysisServer.format(formatWithIssues, 0); |
| expect(results.newString, formatWithIssues); |
| }); |
| |
| test('analyze', () async { |
| AnalysisResults results = await analysisServer.analyze(sampleCode); |
| expect(results.issues, isEmpty); |
| }); |
| |
| test('analyze with errors', () async { |
| AnalysisResults results = await analysisServer.analyze(sampleCodeError); |
| expect(results.issues, hasLength(1)); |
| }); |
| |
| test('analyze strong', () async { |
| AnalysisResults results = await analysisServer.analyze(sampleStrongError); |
| expect(results.issues, hasLength(1)); |
| AnalysisIssue issue = results.issues.first; |
| expect(issue.kind, 'error'); |
| }); |
| |
| test('analyze dart-2', () async { |
| await analysisServer.shutdown(); |
| |
| flutterWebManager = FlutterWebManager(sdkPath); |
| |
| analysisServer = AnalysisServerWrapper(sdkPath, flutterWebManager); |
| await analysisServer.init(); |
| |
| AnalysisResults results = await analysisServer.analyze(sampleDart2OK); |
| expect(results.issues, hasLength(0)); |
| }); |
| |
| test('filter completions', () async { |
| // just after A |
| var idx = 61; |
| expect(completionLargeNamespaces.substring(idx - 1, idx), 'A'); |
| var results = |
| await analysisServer.complete(completionLargeNamespaces, 61); |
| expect(completionsContains(results, 'A'), true); |
| expect(completionsContains(results, 'AB'), true); |
| expect(completionsContains(results, 'ABC'), true); |
| expect(completionsContains(results, 'a'), true); |
| expect(completionsContains(results, 'ZZ'), false); |
| }); |
| }); |
| } |
| |
| bool completionsContains(CompleteResponse response, String completion) => |
| response.completions.any((map) => map['completion'] == completion); |