blob: c51d1867e2133b1c49fbf5b256fc1d19ee324b6b [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.services.completion.dart.keyword;
import 'package:analysis_server/src/protocol.dart';
import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
import 'package:analysis_server/src/services/completion/keyword_computer.dart';
import 'package:analyzer/src/generated/scanner.dart';
import 'package:unittest/unittest.dart';
import '../../reflective_tests.dart';
import 'completion_test_util.dart';
main() {
groupSep = ' | ';
runReflectiveTests(KeywordComputerTest);
}
@reflectiveTest
class KeywordComputerTest extends AbstractCompletionTest {
void assertSuggestKeywords(Iterable<Keyword> expectedKeywords, [int relevance
= DART_RELEVANCE_KEYWORD]) {
Set<Keyword> actualKeywords = new Set<Keyword>();
request.suggestions.forEach((CompletionSuggestion s) {
if (s.kind == CompletionSuggestionKind.KEYWORD) {
Keyword k = Keyword.keywords[s.completion];
if (k == null) {
fail('Invalid keyword suggested: ${s.completion}');
} else {
if (!actualKeywords.add(k)) {
fail('Duplicate keyword suggested: ${s.completion}');
}
}
expect(s.relevance, equals(relevance), reason: k.toString());
expect(s.selectionOffset, equals(s.completion.length));
expect(s.selectionLength, equals(0));
expect(s.isDeprecated, equals(false));
expect(s.isPotential, equals(false));
}
});
if (expectedKeywords.any((k) => k is String)) {
StringBuffer msg = new StringBuffer();
msg.writeln('Expected set should be:');
expectedKeywords.forEach((n) {
Keyword k = Keyword.keywords[n];
msg.writeln(' Keyword.${k.name},');
});
fail(msg.toString());
}
if (!_equalSets(expectedKeywords, actualKeywords)) {
StringBuffer msg = new StringBuffer();
msg.writeln('Expected:');
_appendKeywords(msg, expectedKeywords);
msg.writeln('but found:');
_appendKeywords(msg, actualKeywords);
fail(msg.toString());
}
}
@override
void setUpComputer() {
computer = new KeywordComputer();
}
test_after_class() {
addTestSource('class A {} ^');
expect(computeFast(), isTrue);
assertSuggestKeywords(
[
Keyword.ABSTRACT,
Keyword.CLASS,
Keyword.CONST,
Keyword.FINAL,
Keyword.TYPEDEF,
Keyword.VAR],
DART_RELEVANCE_HIGH);
}
test_after_class2() {
addTestSource('class A {} c^');
expect(computeFast(), isTrue);
assertSuggestKeywords(
[
Keyword.ABSTRACT,
Keyword.CLASS,
Keyword.CONST,
Keyword.FINAL,
Keyword.TYPEDEF,
Keyword.VAR],
DART_RELEVANCE_HIGH);
}
test_after_import() {
addTestSource('import foo; ^');
expect(computeFast(), isTrue);
assertSuggestKeywords(
[
Keyword.ABSTRACT,
Keyword.CLASS,
Keyword.CONST,
Keyword.EXPORT,
Keyword.FINAL,
Keyword.IMPORT,
Keyword.PART,
Keyword.TYPEDEF,
Keyword.VAR],
DART_RELEVANCE_HIGH);
}
test_after_import2() {
addTestSource('import foo; c^');
expect(computeFast(), isTrue);
assertSuggestKeywords(
[
Keyword.ABSTRACT,
Keyword.CLASS,
Keyword.CONST,
Keyword.EXPORT,
Keyword.FINAL,
Keyword.IMPORT,
Keyword.PART,
Keyword.TYPEDEF,
Keyword.VAR],
DART_RELEVANCE_HIGH);
}
test_before_import() {
addTestSource('^ import foo;');
expect(computeFast(), isTrue);
assertSuggestKeywords(
[Keyword.EXPORT, Keyword.IMPORT, Keyword.LIBRARY, Keyword.PART],
DART_RELEVANCE_HIGH);
}
test_class() {
addTestSource('class A ^');
expect(computeFast(), isTrue);
assertSuggestKeywords(
[Keyword.EXTENDS, Keyword.IMPLEMENTS],
DART_RELEVANCE_HIGH);
}
test_class2() {
addTestSource('class A e^');
expect(computeFast(), isTrue);
assertSuggestKeywords(
[Keyword.EXTENDS, Keyword.IMPLEMENTS],
DART_RELEVANCE_HIGH);
}
test_class3() {
addTestSource('class A e^ { }');
expect(computeFast(), isTrue);
assertSuggestKeywords(
[Keyword.EXTENDS, Keyword.IMPLEMENTS],
DART_RELEVANCE_HIGH);
}
test_class_extends() {
addTestSource('class A extends foo ^');
expect(computeFast(), isTrue);
assertSuggestKeywords(
[Keyword.IMPLEMENTS, Keyword.WITH],
DART_RELEVANCE_HIGH);
}
test_class_extends2() {
addTestSource('class A extends foo i^');
expect(computeFast(), isTrue);
assertSuggestKeywords(
[Keyword.IMPLEMENTS, Keyword.WITH],
DART_RELEVANCE_HIGH);
}
test_class_extends3() {
addTestSource('class A extends foo i^ { }');
expect(computeFast(), isTrue);
assertSuggestKeywords(
[Keyword.IMPLEMENTS, Keyword.WITH],
DART_RELEVANCE_HIGH);
}
test_class_extends_name() {
addTestSource('class A extends ^');
expect(computeFast(), isTrue);
assertSuggestKeywords([]);
}
test_class_implements() {
addTestSource('class A ^ implements foo');
expect(computeFast(), isTrue);
assertSuggestKeywords([Keyword.EXTENDS], DART_RELEVANCE_HIGH);
}
test_class_implements2() {
addTestSource('class A e^ implements foo');
expect(computeFast(), isTrue);
// TODO (danrubel) refinement: don't suggest implements
assertSuggestKeywords(
[Keyword.EXTENDS, Keyword.IMPLEMENTS],
DART_RELEVANCE_HIGH);
}
test_class_implements3() {
addTestSource('class A e^ implements foo { }');
expect(computeFast(), isTrue);
// TODO (danrubel) refinement: don't suggest implements
assertSuggestKeywords(
[Keyword.EXTENDS, Keyword.IMPLEMENTS],
DART_RELEVANCE_HIGH);
}
test_class_implements_name() {
addTestSource('class A implements ^');
expect(computeFast(), isTrue);
assertSuggestKeywords([]);
}
test_class_name() {
addTestSource('class ^');
expect(computeFast(), isTrue);
assertSuggestKeywords([]);
}
test_class_with() {
addTestSource('class A extends foo with bar ^');
expect(computeFast(), isTrue);
assertSuggestKeywords([Keyword.IMPLEMENTS], DART_RELEVANCE_HIGH);
}
test_class_with2() {
addTestSource('class A extends foo with bar i^');
expect(computeFast(), isTrue);
assertSuggestKeywords([Keyword.IMPLEMENTS], DART_RELEVANCE_HIGH);
}
test_class_with3() {
addTestSource('class A extends foo with bar i^ { }');
expect(computeFast(), isTrue);
assertSuggestKeywords([Keyword.IMPLEMENTS], DART_RELEVANCE_HIGH);
}
test_class_with_name() {
addTestSource('class A extends foo with ^');
expect(computeFast(), isTrue);
assertSuggestKeywords([]);
}
test_empty() {
addTestSource('^');
expect(computeFast(), isTrue);
assertSuggestKeywords(
[
Keyword.ABSTRACT,
Keyword.CLASS,
Keyword.CONST,
Keyword.EXPORT,
Keyword.FINAL,
Keyword.IMPORT,
Keyword.LIBRARY,
Keyword.PART,
Keyword.TYPEDEF,
Keyword.VAR],
DART_RELEVANCE_HIGH);
}
test_function_body() {
addTestSource('main() {^}');
expect(computeFast(), isTrue);
assertSuggestKeywords(
[
Keyword.ASSERT,
Keyword.CASE,
Keyword.CONTINUE,
Keyword.DO,
Keyword.FACTORY,
Keyword.FINAL,
Keyword.FOR,
Keyword.IF,
Keyword.NEW,
Keyword.RETHROW,
Keyword.RETURN,
Keyword.SUPER,
Keyword.SWITCH,
Keyword.THIS,
Keyword.THROW,
Keyword.TRY,
Keyword.VAR,
Keyword.VOID,
Keyword.WHILE]);
}
test_function_body2() {
addTestSource('main() {{}^}');
expect(computeFast(), isTrue);
assertSuggestKeywords(
[
Keyword.ASSERT,
Keyword.CASE,
Keyword.CONTINUE,
Keyword.DO,
Keyword.FACTORY,
Keyword.FINAL,
Keyword.FOR,
Keyword.IF,
Keyword.NEW,
Keyword.RETHROW,
Keyword.RETURN,
Keyword.SUPER,
Keyword.SWITCH,
Keyword.THIS,
Keyword.THROW,
Keyword.TRY,
Keyword.VAR,
Keyword.VOID,
Keyword.WHILE]);
}
test_in_class() {
addTestSource('class A {^}');
expect(computeFast(), isTrue);
assertSuggestKeywords(
[
Keyword.CONST,
Keyword.DYNAMIC,
Keyword.FACTORY,
Keyword.FINAL,
Keyword.GET,
Keyword.OPERATOR,
Keyword.SET,
Keyword.STATIC,
Keyword.VAR,
Keyword.VOID]);
}
test_library() {
addTestSource('library foo;^');
expect(computeFast(), isTrue);
assertSuggestKeywords(
[
Keyword.ABSTRACT,
Keyword.CLASS,
Keyword.CONST,
Keyword.EXPORT,
Keyword.FINAL,
Keyword.IMPORT,
Keyword.PART,
Keyword.TYPEDEF,
Keyword.VAR],
DART_RELEVANCE_HIGH);
}
test_library_name() {
addTestSource('library ^');
expect(computeFast(), isTrue);
assertSuggestKeywords([]);
}
test_method_body() {
addTestSource('class A { foo() {^}}');
expect(computeFast(), isTrue);
assertSuggestKeywords(
[
Keyword.ASSERT,
Keyword.CASE,
Keyword.CONTINUE,
Keyword.DO,
Keyword.FACTORY,
Keyword.FINAL,
Keyword.FOR,
Keyword.IF,
Keyword.NEW,
Keyword.RETHROW,
Keyword.RETURN,
Keyword.SUPER,
Keyword.SWITCH,
Keyword.THIS,
Keyword.THROW,
Keyword.TRY,
Keyword.VAR,
Keyword.VOID,
Keyword.WHILE]);
}
test_named_constructor_invocation() {
addTestSource('void main() {new Future.^}');
expect(computeFast(), isTrue);
assertSuggestKeywords([]);
}
test_part_of() {
addTestSource('part of foo;^');
expect(computeFast(), isTrue);
assertSuggestKeywords(
[
Keyword.ABSTRACT,
Keyword.CLASS,
Keyword.CONST,
Keyword.EXPORT,
Keyword.FINAL,
Keyword.IMPORT,
Keyword.PART,
Keyword.TYPEDEF,
Keyword.VAR],
DART_RELEVANCE_HIGH);
}
test_partial_class() {
addTestSource('cl^');
expect(computeFast(), isTrue);
assertSuggestKeywords(
[
Keyword.ABSTRACT,
Keyword.CLASS,
Keyword.CONST,
Keyword.EXPORT,
Keyword.FINAL,
Keyword.IMPORT,
Keyword.LIBRARY,
Keyword.PART,
Keyword.TYPEDEF,
Keyword.VAR],
DART_RELEVANCE_HIGH);
}
test_partial_class2() {
addTestSource('library a; cl^');
expect(computeFast(), isTrue);
assertSuggestKeywords(
[
Keyword.ABSTRACT,
Keyword.CLASS,
Keyword.CONST,
Keyword.EXPORT,
Keyword.FINAL,
Keyword.IMPORT,
Keyword.PART,
Keyword.TYPEDEF,
Keyword.VAR],
DART_RELEVANCE_HIGH);
}
void _appendKeywords(StringBuffer msg, Iterable<Keyword> keywords) {
List<Keyword> sorted = keywords.toList();
sorted.sort((k1, k2) => k1.name.compareTo(k2.name));
sorted.forEach((k) => msg.writeln(' Keyword.${k.name},'));
}
bool _equalSets(Iterable<Keyword> iter1, Iterable<Keyword> iter2) {
if (iter1.length != iter2.length) return false;
if (iter1.any((k) => !iter2.contains(k))) return false;
if (iter2.any((k) => !iter1.contains(k))) return false;
return true;
}
}