blob: 469ba02dab0b3541e8716ca568d5f92003956626 [file] [log] [blame]
// Copyright (c) 2019, 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 'dart:async';
import 'dart:convert';
import 'package:analysis_server/protocol/protocol.dart';
import 'package:analysis_server/protocol/protocol_constants.dart';
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/domain_completion.dart';
import 'package:analysis_server/src/protocol_server.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../../../analysis_abstract.dart';
import '../../../constants.dart';
@reflectiveTest
class AvailableSuggestionsBase extends AbstractAnalysisTest {
final Map<int, AvailableSuggestionSet> idToSetMap = {};
final Map<String, AvailableSuggestionSet> uriToSetMap = {};
final Map<String, CompletionResultsParams> idToSuggestions = {};
final Map<String, ExistingImports> fileToExistingImports = {};
void assertJsonText(Object object, String expected) {
expected = expected.trimRight();
var actual = JsonEncoder.withIndent(' ').convert(object);
if (actual != expected) {
print('-----');
print(actual);
print('-----');
}
expect(actual, expected);
}
String jsonOfPath(String path) {
path = convertPath(path);
return json.encode(path);
}
@override
void processNotification(Notification notification) {
super.processNotification(notification);
if (notification.event == COMPLETION_NOTIFICATION_AVAILABLE_SUGGESTIONS) {
var params = CompletionAvailableSuggestionsParams.fromNotification(
notification,
);
for (var set in params.changedLibraries) {
idToSetMap[set.id] = set;
uriToSetMap[set.uri] = set;
}
for (var id in params.removedLibraries) {
var set = idToSetMap.remove(id);
uriToSetMap.remove(set?.uri);
}
} else if (notification.event == COMPLETION_RESULTS) {
var params = CompletionResultsParams.fromNotification(notification);
idToSuggestions[params.id] = params;
} else if (notification.event == COMPLETION_NOTIFICATION_EXISTING_IMPORTS) {
var params = CompletionExistingImportsParams.fromNotification(
notification,
);
fileToExistingImports[params.file] = params.imports;
} else if (notification.event == SERVER_NOTIFICATION_ERROR) {
fail('${notification.toJson()}');
}
}
/// Remove the set with the given [uri].
/// The set must be already received.
void removeSet(String uri) {
var set = uriToSetMap.remove(uri);
expect(set, isNotNull);
idToSetMap.remove(set.id);
}
@override
void setUp() {
super.setUp();
projectPath = convertPath('/home');
testFile = convertPath('/home/test/lib/test.dart');
newFile('/home/test/pubspec.yaml', content: '');
newFile('/home/test/.packages', content: '''
test:${toUri('/home/test/lib')}
''');
createProject();
handler = server.handlers.whereType<CompletionDomainHandler>().single;
_setCompletionSubscriptions([CompletionService.AVAILABLE_SUGGESTION_SETS]);
}
Future<CompletionResultsParams> waitForGetSuggestions(String id) async {
while (true) {
var result = idToSuggestions[id];
if (result != null) {
return result;
}
await Future.delayed(const Duration(milliseconds: 1));
}
}
Future<AvailableSuggestionSet> waitForSetWithUri(String uri) async {
while (true) {
var result = uriToSetMap[uri];
if (result != null) {
return result;
}
await Future.delayed(const Duration(milliseconds: 1));
}
}
Future<void> waitForSetWithUriRemoved(String uri) async {
while (true) {
var result = uriToSetMap[uri];
if (result == null) {
return;
}
await Future.delayed(const Duration(milliseconds: 1));
}
}
void _setCompletionSubscriptions(List<CompletionService> subscriptions) {
handleSuccessfulRequest(
CompletionSetSubscriptionsParams(subscriptions).toRequest('0'),
);
}
}