// Copyright (c) 2014, 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. import 'package:analysis_server/protocol/protocol.dart'; import 'package:analysis_server/protocol/protocol_generated.dart'; import 'package:analysis_server/src/analysis_server.dart'; import 'package:analysis_server/src/domain_execution.dart'; import 'package:analysis_server/src/protocol_server.dart'; import 'package:analyzer/file_system/memory_file_system.dart'; import 'package:analyzer/instrumentation/instrumentation.dart'; import 'package:analyzer/src/generated/sdk.dart'; import 'package:test/test.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import 'analysis_abstract.dart'; import 'mocks.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(ExecutionDomainTest); }); group('ExecutionDomainHandler', () { MemoryResourceProvider provider = new MemoryResourceProvider(); AnalysisServer server; ExecutionDomainHandler handler; setUp(() { server = new AnalysisServer( new MockServerChannel(), provider, new AnalysisServerOptions(), new DartSdkManager('', false), InstrumentationService.NULL_SERVICE); handler = new ExecutionDomainHandler(server); }); group('createContext/deleteContext', () { test('create/delete multiple contexts', () { Request request = new ExecutionCreateContextParams('/a/b.dart').toRequest('0'); Response response = handler.handleRequest(request); expect(response, isResponseSuccess('0')); ExecutionCreateContextResult result = new ExecutionCreateContextResult.fromResponse(response); String id0 = result.id; request = new ExecutionCreateContextParams('/c/d.dart').toRequest('1'); response = handler.handleRequest(request); expect(response, isResponseSuccess('1')); result = new ExecutionCreateContextResult.fromResponse(response); String id1 = result.id; expect(id0 == id1, isFalse); request = new ExecutionDeleteContextParams(id0).toRequest('2'); response = handler.handleRequest(request); expect(response, isResponseSuccess('2')); request = new ExecutionDeleteContextParams(id1).toRequest('3'); response = handler.handleRequest(request); expect(response, isResponseSuccess('3')); }); test('delete non-existent context', () { Request request = new ExecutionDeleteContextParams('13').toRequest('0'); Response response = handler.handleRequest(request); // TODO(brianwilkerson) It isn't currently specified to be an error if a // client attempts to delete a context that doesn't exist. Should it be? // expect(response, isResponseFailure('0')); expect(response, isResponseSuccess('0')); }); }); // TODO(brianwilkerson) Re-enable these tests if we re-enable the // execution.mapUri request. // group('mapUri', () { // String contextId; // // void createExecutionContextIdForFile(String path) { // Request request = new ExecutionCreateContextParams(path).toRequest('0'); // Response response = handler.handleRequest(request); // expect(response, isResponseSuccess('0')); // ExecutionCreateContextResult result = // new ExecutionCreateContextResult.fromResponse(response); // contextId = result.id; // } // // setUp(() { // Folder folder = provider.newFile('/a/b.dart', '').parent; // server.folderMap.putIfAbsent(folder, () { // SourceFactory factory = // new SourceFactory([new ResourceUriResolver(provider)]); // AnalysisContext context = // AnalysisEngine.instance.createAnalysisContext(); // context.sourceFactory = factory; // return context; // }); // createExecutionContextIdForFile('/a/b.dart'); // }); // // tearDown(() { // Request request = // new ExecutionDeleteContextParams(contextId).toRequest('1'); // Response response = handler.handleRequest(request); // expect(response, isResponseSuccess('1')); // }); // // group('file to URI', () { // test('does not exist', () { // Request request = // new ExecutionMapUriParams(contextId, file: '/a/c.dart') // .toRequest('2'); // Response response = handler.handleRequest(request); // expect(response, isResponseFailure('2')); // }); // // test('directory', () { // provider.newFolder('/a/d'); // Request request = // new ExecutionMapUriParams(contextId, file: '/a/d').toRequest('2'); // Response response = handler.handleRequest(request); // expect(response, isResponseFailure('2')); // }); // }); // // group('URI to file', () { // test('invalid', () { // Request request = // new ExecutionMapUriParams(contextId, uri: 'foo:///a/b.dart') // .toRequest('2'); // Response response = handler.handleRequest(request); // expect(response, isResponseFailure('2')); // }); // }); // // test('invalid context id', () { // Request request = // new ExecutionMapUriParams('xxx', uri: '').toRequest('4'); // Response response = handler.handleRequest(request); // expect(response, isResponseFailure('4')); // }); // // test('both file and uri', () { // Request request = // new ExecutionMapUriParams('xxx', file: '', uri: '').toRequest('5'); // Response response = handler.handleRequest(request); // expect(response, isResponseFailure('5')); // }); // // test('neither file nor uri', () { // Request request = new ExecutionMapUriParams('xxx').toRequest('6'); // Response response = handler.handleRequest(request); // expect(response, isResponseFailure('6')); // }); // }); }); } @reflectiveTest class ExecutionDomainTest extends AbstractAnalysisTest { String contextId; @override void setUp() { super.setUp(); createProject(); handler = new ExecutionDomainHandler(server); _createExecutionContext(testFile); } @override void tearDown() { _disposeExecutionContext(); super.tearDown(); } test_getSuggestions() async { var code = r''' class A { int foo; } void contextFunction() { var a = new A(); // context line } '''; String path = newFile('/test.dart').path; newFile(path, content: code); Request request = new ExecutionGetSuggestionsParams( 'a.', 2, path, code.indexOf('// context line'), []).toRequest('0'); Response response = await waitResponse(request); var result = new ExecutionGetSuggestionsResult.fromResponse(response); // expect(result.suggestions, isNotEmpty); // // expect( // result.suggestions, // contains( // predicate((s) => s.completion == 'foo'))); // TODO(brianwilkerson) Restore the expectations above (and delete the line // below) after the functionality has been re-enabled. expect(result.suggestions, isEmpty); } void test_mapUri_file() { String path = newFile('/a/b.dart').path; // map the file ExecutionMapUriResult result = _mapUri(file: path); expect(result.file, isNull); expect(result.uri, new Uri.file(path).toString()); } void test_mapUri_file_dartUriKind() { String path = server.findSdk().mapDartUri('dart:async').fullName; // hack - pretend that the SDK file exists in the project FS newFile(path, content: '// hack'); // map file ExecutionMapUriResult result = _mapUri(file: path); expect(result.file, isNull); expect(result.uri, 'dart:async'); } void test_mapUri_uri() { String path = newFile('/a/b.dart').path; // map the uri ExecutionMapUriResult result = _mapUri(uri: new Uri.file(path).toString()); expect(result.file, convertPath('/a/b.dart')); expect(result.uri, isNull); } void _createExecutionContext(String path) { Request request = new ExecutionCreateContextParams(path).toRequest('0'); Response response = handler.handleRequest(request); expect(response, isResponseSuccess('0')); ExecutionCreateContextResult result = new ExecutionCreateContextResult.fromResponse(response); contextId = result.id; } void _disposeExecutionContext() { Request request = new ExecutionDeleteContextParams(contextId).toRequest('1'); Response response = handler.handleRequest(request); expect(response, isResponseSuccess('1')); } ExecutionMapUriResult _mapUri({String file, String uri}) { Request request = new ExecutionMapUriParams(contextId, file: file, uri: uri) .toRequest('2'); Response response = handler.handleRequest(request); expect(response, isResponseSuccess('2')); return new ExecutionMapUriResult.fromResponse(response); } }