blob: 7413542f59caef7578a5046607b5d56a6f8ab966 [file] [log] [blame]
// 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.
library test.domain.completion;
import 'dart:async';
import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/domain_completion.dart';
import 'package:analysis_server/src/protocol.dart';
import 'package:analysis_server/src/services/index/index.dart' show Index;
import 'package:analysis_server/src/services/index/local_memory_index.dart';
import 'reflective_tests.dart';
import 'package:unittest/unittest.dart';
import 'analysis_abstract.dart';
import 'mocks.dart';
main() {
groupSep = ' | ';
runReflectiveTests(CompletionTest);
}
@ReflectiveTestCase()
class CompletionTest extends AbstractAnalysisTest {
String completionId;
int completionOffset;
int replacementOffset;
int replacementLength;
List<CompletionSuggestion> suggestions = [];
bool suggestionsDone = false;
String addTestFile(String content) {
completionOffset = content.indexOf('^');
expect(completionOffset, isNot(equals(-1)), reason: 'missing ^');
int nextOffset = content.indexOf('^', completionOffset + 1);
expect(nextOffset, equals(-1), reason: 'too many ^');
return super.addTestFile(
content.substring(0, completionOffset) +
content.substring(completionOffset + 1));
}
void assertHasResult(CompletionSuggestionKind kind, String completion,
[CompletionRelevance relevance = CompletionRelevance.DEFAULT, bool isDeprecated
= false, bool isPotential = false]) {
var cs;
suggestions.forEach((s) {
if (s.completion == completion) {
if (cs == null) {
cs = s;
} else {
fail('expected exactly one $completion but found > 1');
}
}
});
if (cs == null) {
var completions = suggestions.map((s) => s.completion).toList();
fail('expected "$completion" but found\n $completions');
}
expect(cs.kind, equals(kind));
expect(cs.relevance, equals(relevance));
expect(cs.selectionOffset, equals(completion.length));
expect(cs.selectionLength, equals(0));
expect(cs.isDeprecated, equals(isDeprecated));
expect(cs.isPotential, equals(isPotential));
}
void assertNoResult(String completion) {
if (suggestions.any((cs) => cs.completion == completion)) {
fail('did not expect completion: $completion');
}
}
void assertValidId(String id) {
expect(id, isNotNull);
expect(id.isNotEmpty, isTrue);
}
@override
Index createIndex() {
return createLocalMemoryIndex();
}
Future getSuggestions() {
return waitForTasksFinished().then((_) {
Request request =
new CompletionGetSuggestionsParams(testFile, completionOffset).toRequest('0');
Response response = handleSuccessfulRequest(request);
var result = new CompletionGetSuggestionsResult.fromResponse(response);
completionId = response.id;
assertValidId(completionId);
return pumpEventQueue().then((_) {
expect(suggestionsDone, isTrue);
});
});
}
void processNotification(Notification notification) {
if (notification.event == COMPLETION_RESULTS) {
var params = new CompletionResultsParams.fromNotification(notification);
String id = params.id;
assertValidId(id);
if (id == completionId) {
expect(suggestionsDone, isFalse);
replacementOffset = params.replacementOffset;
replacementLength = params.replacementLength;
suggestionsDone = params.isLast;
expect(suggestionsDone, isNotNull);
suggestions = params.results;
}
}
}
@override
void setUp() {
super.setUp();
createProject();
handler = new CompletionDomainHandler(server);
}
test_html() {
testFile = '/project/web/test.html';
addTestFile('''
<html>^</html>
''');
return getSuggestions().then((_) {
expect(replacementOffset, equals(completionOffset));
expect(replacementLength, equals(0));
expect(suggestions, hasLength(0));
});
}
test_imports() {
addTestFile('''
import 'dart:html';
main() {^}
''');
return getSuggestions().then((_) {
expect(replacementOffset, equals(completionOffset));
expect(replacementLength, equals(0));
assertHasResult(CompletionSuggestionKind.CLASS, 'Object');
assertHasResult(CompletionSuggestionKind.CLASS, 'HtmlElement');
assertNoResult('test');
});
}
test_imports_prefixed() {
addTestFile('''
import 'dart:html' as foo;
main() {^}
''');
return getSuggestions().then((_) {
expect(replacementOffset, equals(completionOffset));
expect(replacementLength, equals(0));
assertHasResult(CompletionSuggestionKind.CLASS, 'Object');
assertHasResult(CompletionSuggestionKind.LIBRARY_PREFIX, 'foo');
assertNoResult('HtmlElement');
assertNoResult('test');
});
}
test_keyword() {
addTestFile('library A; cl^');
return getSuggestions().then((_) {
expect(replacementOffset, equals(completionOffset - 2));
expect(replacementLength, equals(2));
assertHasResult(
CompletionSuggestionKind.KEYWORD,
'import',
CompletionRelevance.HIGH);
assertHasResult(
CompletionSuggestionKind.KEYWORD,
'class',
CompletionRelevance.HIGH);
});
}
test_locals() {
addTestFile('class A {var a; x() {var b;^}}');
return getSuggestions().then((_) {
expect(replacementOffset, equals(completionOffset));
expect(replacementLength, equals(0));
assertHasResult(CompletionSuggestionKind.CLASS, 'A');
assertHasResult(CompletionSuggestionKind.GETTER, 'a');
assertHasResult(CompletionSuggestionKind.LOCAL_VARIABLE, 'b');
assertHasResult(CompletionSuggestionKind.METHOD, 'x');
});
}
test_invocation() {
addTestFile('class A {b() {}} main() {A a; a.^}');
return getSuggestions().then((_) {
expect(replacementOffset, equals(completionOffset));
expect(replacementLength, equals(0));
assertHasResult(CompletionSuggestionKind.METHOD, 'b');
});
}
test_topLevel() {
addTestFile('''
typedef foo();
var test = '';
main() {tes^t}
''');
return getSuggestions().then((_) {
expect(replacementOffset, equals(completionOffset - 3));
expect(replacementLength, equals(4));
assertHasResult(CompletionSuggestionKind.CLASS, 'Object');
assertHasResult(CompletionSuggestionKind.TOP_LEVEL_VARIABLE, 'test');
assertNoResult('HtmlElement');
});
}
}