02adcc9614
After a try block that does not have a "catch" block, suggest the "catch" keyword and nothing else. After a "catch" block, suggest the "finally" keyword. Fix https://github.com/dart-lang/sdk/issues/27560 R=brianwilkerson@google.com Review-Url: https://codereview.chromium.org/2662973007 .
708 lines
23 KiB
Dart
708 lines
23 KiB
Dart
// 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/plugin/protocol/protocol.dart';
|
|
import 'package:analysis_server/src/domain_completion.dart';
|
|
import 'package:analysis_server/src/provisional/completion/completion_core.dart';
|
|
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
|
|
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
|
|
import 'package:analysis_server/src/services/completion/dart/contribution_sorter.dart';
|
|
import 'package:test/test.dart';
|
|
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
|
|
|
import 'analysis_abstract.dart';
|
|
import 'domain_completion_util.dart';
|
|
import 'mocks.dart' show pumpEventQueue;
|
|
|
|
main() {
|
|
defineReflectiveSuite(() {
|
|
defineReflectiveTests(CompletionDomainHandlerTest);
|
|
defineReflectiveTests(_NoSearchEngine);
|
|
});
|
|
}
|
|
|
|
@reflectiveTest
|
|
class CompletionDomainHandlerTest extends AbstractCompletionDomainTest {
|
|
test_ArgumentList_constructor_named_param_label() async {
|
|
addTestFile('main() { new A(^);}'
|
|
'class A { A({one, two}) {} }');
|
|
await getSuggestions();
|
|
assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'one: ',
|
|
relevance: DART_RELEVANCE_NAMED_PARAMETER);
|
|
assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'two: ',
|
|
relevance: DART_RELEVANCE_NAMED_PARAMETER);
|
|
expect(suggestions, hasLength(2));
|
|
}
|
|
|
|
test_ArgumentList_factory_named_param_label() async {
|
|
addTestFile('main() { new A(^);}'
|
|
'class A { factory A({one, two}) => null; }');
|
|
await getSuggestions();
|
|
assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'one: ',
|
|
relevance: DART_RELEVANCE_NAMED_PARAMETER);
|
|
assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'two: ',
|
|
relevance: DART_RELEVANCE_NAMED_PARAMETER);
|
|
expect(suggestions, hasLength(2));
|
|
}
|
|
|
|
test_ArgumentList_imported_function_named_param() async {
|
|
addTestFile('main() { int.parse("16", ^);}');
|
|
await getSuggestions();
|
|
assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'radix: ',
|
|
relevance: DART_RELEVANCE_NAMED_PARAMETER);
|
|
assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'onError: ',
|
|
relevance: DART_RELEVANCE_NAMED_PARAMETER);
|
|
expect(suggestions, hasLength(2));
|
|
}
|
|
|
|
test_ArgumentList_imported_function_named_param1() async {
|
|
addTestFile('main() { foo(o^);} foo({one, two}) {}');
|
|
await getSuggestions();
|
|
assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'one: ',
|
|
relevance: DART_RELEVANCE_NAMED_PARAMETER);
|
|
assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'two: ',
|
|
relevance: DART_RELEVANCE_NAMED_PARAMETER);
|
|
expect(suggestions, hasLength(2));
|
|
}
|
|
|
|
test_ArgumentList_imported_function_named_param2() async {
|
|
addTestFile('mainx() {A a = new A(); a.foo(one: 7, ^);}'
|
|
'class A { foo({one, two}) {} }');
|
|
await getSuggestions();
|
|
assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'two: ',
|
|
relevance: DART_RELEVANCE_NAMED_PARAMETER);
|
|
expect(suggestions, hasLength(1));
|
|
}
|
|
|
|
test_ArgumentList_imported_function_named_param_label1() async {
|
|
addTestFile('main() { int.parse("16", r^: 16);}');
|
|
await getSuggestions();
|
|
assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'radix',
|
|
relevance: DART_RELEVANCE_NAMED_PARAMETER);
|
|
assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'onError',
|
|
relevance: DART_RELEVANCE_NAMED_PARAMETER);
|
|
expect(suggestions, hasLength(2));
|
|
}
|
|
|
|
test_ArgumentList_imported_function_named_param_label3() async {
|
|
addTestFile('main() { int.parse("16", ^: 16);}');
|
|
await getSuggestions();
|
|
assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'radix: ',
|
|
relevance: DART_RELEVANCE_NAMED_PARAMETER);
|
|
assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'onError: ',
|
|
relevance: DART_RELEVANCE_NAMED_PARAMETER);
|
|
expect(suggestions, hasLength(2));
|
|
}
|
|
|
|
test_catch() async {
|
|
addTestFile('main() {try {} ^}');
|
|
await getSuggestions();
|
|
assertHasResult(CompletionSuggestionKind.KEYWORD, 'on',
|
|
relevance: DART_RELEVANCE_KEYWORD);
|
|
assertHasResult(CompletionSuggestionKind.KEYWORD, 'catch',
|
|
relevance: DART_RELEVANCE_KEYWORD);
|
|
assertHasResult(CompletionSuggestionKind.KEYWORD, 'finally',
|
|
relevance: DART_RELEVANCE_KEYWORD);
|
|
expect(suggestions, hasLength(3));
|
|
}
|
|
|
|
test_catch2() async {
|
|
addTestFile('main() {try {} on Foo {} ^}');
|
|
await getSuggestions();
|
|
assertHasResult(CompletionSuggestionKind.KEYWORD, 'on',
|
|
relevance: DART_RELEVANCE_KEYWORD);
|
|
assertHasResult(CompletionSuggestionKind.KEYWORD, 'catch',
|
|
relevance: DART_RELEVANCE_KEYWORD);
|
|
assertHasResult(CompletionSuggestionKind.KEYWORD, 'finally',
|
|
relevance: DART_RELEVANCE_KEYWORD);
|
|
assertHasResult(CompletionSuggestionKind.KEYWORD, 'for',
|
|
relevance: DART_RELEVANCE_KEYWORD);
|
|
suggestions.firstWhere(
|
|
(CompletionSuggestion suggestion) =>
|
|
suggestion.kind != CompletionSuggestionKind.KEYWORD, orElse: () {
|
|
fail('Expected suggestions other than keyword suggestions');
|
|
});
|
|
}
|
|
|
|
test_catch3() async {
|
|
addTestFile('main() {try {} catch (e) {} finally {} ^}');
|
|
await getSuggestions();
|
|
assertNoResult('on');
|
|
assertNoResult('catch');
|
|
assertNoResult('finally');
|
|
assertHasResult(CompletionSuggestionKind.KEYWORD, 'for',
|
|
relevance: DART_RELEVANCE_KEYWORD);
|
|
suggestions.firstWhere(
|
|
(CompletionSuggestion suggestion) =>
|
|
suggestion.kind != CompletionSuggestionKind.KEYWORD, orElse: () {
|
|
fail('Expected suggestions other than keyword suggestions');
|
|
});
|
|
}
|
|
|
|
test_catch4() async {
|
|
addTestFile('main() {try {} finally {} ^}');
|
|
await getSuggestions();
|
|
assertNoResult('on');
|
|
assertNoResult('catch');
|
|
assertNoResult('finally');
|
|
assertHasResult(CompletionSuggestionKind.KEYWORD, 'for',
|
|
relevance: DART_RELEVANCE_KEYWORD);
|
|
suggestions.firstWhere(
|
|
(CompletionSuggestion suggestion) =>
|
|
suggestion.kind != CompletionSuggestionKind.KEYWORD, orElse: () {
|
|
fail('Expected suggestions other than keyword suggestions');
|
|
});
|
|
}
|
|
|
|
test_catch5() async {
|
|
addTestFile('main() {try {} ^ finally {}}');
|
|
await getSuggestions();
|
|
assertHasResult(CompletionSuggestionKind.KEYWORD, 'on',
|
|
relevance: DART_RELEVANCE_KEYWORD);
|
|
assertHasResult(CompletionSuggestionKind.KEYWORD, 'catch',
|
|
relevance: DART_RELEVANCE_KEYWORD);
|
|
expect(suggestions, hasLength(2));
|
|
}
|
|
|
|
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_import_uri_with_trailing() {
|
|
addFile('/project/bin/testA.dart', 'library libA;');
|
|
addTestFile('''
|
|
import '/project/bin/t^.dart';
|
|
main() {}''');
|
|
return getSuggestions().then((_) {
|
|
expect(replacementOffset, equals(completionOffset - 14));
|
|
expect(replacementLength, equals(5 + 14));
|
|
assertHasResult(
|
|
CompletionSuggestionKind.IMPORT, '/project/bin/testA.dart');
|
|
assertNoResult('test');
|
|
});
|
|
}
|
|
|
|
test_imports() {
|
|
addTestFile('''
|
|
import 'dart:html';
|
|
main() {^}
|
|
''');
|
|
return getSuggestions().then((_) {
|
|
expect(replacementOffset, equals(completionOffset));
|
|
expect(replacementLength, equals(0));
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement');
|
|
assertNoResult('test');
|
|
});
|
|
}
|
|
|
|
test_imports_aborted_new_request() async {
|
|
addTestFile('''
|
|
class foo { }
|
|
c^''');
|
|
|
|
// Make a request for suggestions
|
|
Request request1 =
|
|
new CompletionGetSuggestionsParams(testFile, completionOffset)
|
|
.toRequest('7');
|
|
Response response1 = await waitResponse(request1);
|
|
var result1 = new CompletionGetSuggestionsResult.fromResponse(response1);
|
|
var completionId1 = result1.id;
|
|
assertValidId(completionId1);
|
|
|
|
// Perform some analysis but assert that no suggestions have yet been made
|
|
completionId = completionId1;
|
|
await pumpEventQueue(25);
|
|
expect(suggestionsDone, isFalse);
|
|
expect(suggestions, hasLength(0));
|
|
|
|
// Make another request before the first request completes
|
|
Request request2 =
|
|
new CompletionGetSuggestionsParams(testFile, completionOffset)
|
|
.toRequest('8');
|
|
Response response2 = await waitResponse(request2);
|
|
var result2 = new CompletionGetSuggestionsResult.fromResponse(response2);
|
|
var completionId2 = result2.id;
|
|
assertValidId(completionId2);
|
|
|
|
// Wait for both sets of suggestions
|
|
completionId = completionId2;
|
|
await pumpEventQueue();
|
|
expect(allSuggestions[completionId1], hasLength(0));
|
|
expect(allSuggestions[completionId2], same(suggestions));
|
|
assertHasResult(CompletionSuggestionKind.KEYWORD, 'class',
|
|
relevance: DART_RELEVANCE_HIGH);
|
|
}
|
|
|
|
test_imports_aborted_source_changed() async {
|
|
addTestFile('''
|
|
class foo { }
|
|
c^''');
|
|
|
|
// Make a request for suggestions
|
|
Request request =
|
|
new CompletionGetSuggestionsParams(testFile, completionOffset)
|
|
.toRequest('0');
|
|
Response response = await waitResponse(request);
|
|
completionId = response.id;
|
|
assertValidId(completionId);
|
|
|
|
// Perform some analysis but assert that no suggestions have yet been made
|
|
await pumpEventQueue(25);
|
|
expect(suggestionsDone, isFalse);
|
|
expect(suggestions, hasLength(0));
|
|
|
|
// Simulate user deleting text after request but before suggestions returned
|
|
server.updateContent('uc1', {testFile: new AddContentOverlay(testCode)});
|
|
server.updateContent('uc2', {
|
|
testFile: new ChangeContentOverlay(
|
|
[new SourceEdit(completionOffset - 1, 1, '')])
|
|
});
|
|
|
|
// Expect the completion domain to discard request because source changed
|
|
await pumpEventQueue().then((_) {
|
|
expect(suggestionsDone, isTrue);
|
|
});
|
|
expect(suggestions, hasLength(0));
|
|
}
|
|
|
|
test_imports_incremental() async {
|
|
addTestFile('''library foo;
|
|
e^
|
|
import "dart:async";
|
|
import "package:foo/foo.dart";
|
|
class foo { }''');
|
|
await waitForTasksFinished();
|
|
server.updateContent('uc1', {testFile: new AddContentOverlay(testCode)});
|
|
server.updateContent('uc2', {
|
|
testFile:
|
|
new ChangeContentOverlay([new SourceEdit(completionOffset, 0, 'xp')])
|
|
});
|
|
completionOffset += 2;
|
|
await getSuggestions();
|
|
expect(replacementOffset, completionOffset - 3);
|
|
expect(replacementLength, 3);
|
|
assertHasResult(CompletionSuggestionKind.KEYWORD, 'export \'\';',
|
|
selectionOffset: 8, relevance: DART_RELEVANCE_HIGH);
|
|
assertHasResult(CompletionSuggestionKind.KEYWORD, 'import \'\';',
|
|
selectionOffset: 8, relevance: DART_RELEVANCE_HIGH);
|
|
assertNoResult('extends');
|
|
assertNoResult('library');
|
|
}
|
|
|
|
test_imports_partial() async {
|
|
addTestFile('''^
|
|
import "package:foo/foo.dart";
|
|
import "package:bar/bar.dart";
|
|
class Baz { }''');
|
|
|
|
// Wait for analysis then edit the content
|
|
await waitForTasksFinished();
|
|
String revisedContent = testCode.substring(0, completionOffset) +
|
|
'i' +
|
|
testCode.substring(completionOffset);
|
|
++completionOffset;
|
|
server.handleRequest(new AnalysisUpdateContentParams(
|
|
{testFile: new AddContentOverlay(revisedContent)}).toRequest('add1'));
|
|
|
|
// Request code completion immediately after edit
|
|
Response response = await waitResponse(
|
|
new CompletionGetSuggestionsParams(testFile, completionOffset)
|
|
.toRequest('0'));
|
|
completionId = response.id;
|
|
assertValidId(completionId);
|
|
await waitForTasksFinished();
|
|
expect(replacementOffset, completionOffset - 1);
|
|
expect(replacementLength, 1);
|
|
assertHasResult(CompletionSuggestionKind.KEYWORD, 'library',
|
|
relevance: DART_RELEVANCE_HIGH);
|
|
assertHasResult(CompletionSuggestionKind.KEYWORD, 'import \'\';',
|
|
selectionOffset: 8, relevance: DART_RELEVANCE_HIGH);
|
|
assertHasResult(CompletionSuggestionKind.KEYWORD, 'export \'\';',
|
|
selectionOffset: 8, relevance: DART_RELEVANCE_HIGH);
|
|
assertHasResult(CompletionSuggestionKind.KEYWORD, 'part \'\';',
|
|
selectionOffset: 6, relevance: DART_RELEVANCE_HIGH);
|
|
assertNoResult('extends');
|
|
}
|
|
|
|
test_imports_prefixed() {
|
|
addTestFile('''
|
|
import 'dart:html' as foo;
|
|
main() {^}
|
|
''');
|
|
return getSuggestions().then((_) {
|
|
expect(replacementOffset, equals(completionOffset));
|
|
expect(replacementLength, equals(0));
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
|
|
assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'foo');
|
|
assertNoResult('HtmlElement');
|
|
assertNoResult('test');
|
|
});
|
|
}
|
|
|
|
test_imports_prefixed2() {
|
|
addTestFile('''
|
|
import 'dart:html' as foo;
|
|
main() {foo.^}
|
|
''');
|
|
return getSuggestions().then((_) {
|
|
expect(replacementOffset, equals(completionOffset));
|
|
expect(replacementLength, equals(0));
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement');
|
|
assertNoResult('test');
|
|
});
|
|
}
|
|
|
|
test_inComment_block_beforeNode() async {
|
|
addTestFile('''
|
|
main(aaa, bbb) {
|
|
/* text ^ */
|
|
print(42);
|
|
}
|
|
''');
|
|
await getSuggestions();
|
|
expect(suggestions, isEmpty);
|
|
}
|
|
|
|
test_inComment_endOfLine_beforeNode() async {
|
|
addTestFile('''
|
|
main(aaa, bbb) {
|
|
// text ^
|
|
print(42);
|
|
}
|
|
''');
|
|
await getSuggestions();
|
|
expect(suggestions, isEmpty);
|
|
}
|
|
|
|
test_inComment_endOfLine_beforeToken() async {
|
|
addTestFile('''
|
|
main(aaa, bbb) {
|
|
// text ^
|
|
}
|
|
''');
|
|
await getSuggestions();
|
|
expect(suggestions, isEmpty);
|
|
}
|
|
|
|
test_inDartDoc1() async {
|
|
addTestFile('''
|
|
/// ^
|
|
main(aaa, bbb) {}
|
|
''');
|
|
await getSuggestions();
|
|
expect(suggestions, isEmpty);
|
|
}
|
|
|
|
test_inDartDoc2() async {
|
|
addTestFile('''
|
|
/// Some text^
|
|
main(aaa, bbb) {}
|
|
''');
|
|
await getSuggestions();
|
|
expect(suggestions, isEmpty);
|
|
}
|
|
|
|
test_inDartDoc_reference1() async {
|
|
addFile(
|
|
'/testA.dart',
|
|
'''
|
|
part of libA;
|
|
foo(bar) => 0;''');
|
|
addTestFile('''
|
|
library libA;
|
|
part "/testA.dart";
|
|
import "dart:math";
|
|
/// The [^]
|
|
main(aaa, bbb) {}
|
|
''');
|
|
await getSuggestions();
|
|
assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'main',
|
|
relevance: DART_RELEVANCE_LOCAL_FUNCTION);
|
|
assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'foo',
|
|
relevance: DART_RELEVANCE_LOCAL_FUNCTION);
|
|
assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'min');
|
|
}
|
|
|
|
test_inDartDoc_reference2() async {
|
|
addTestFile('''
|
|
/// The [m^]
|
|
main(aaa, bbb) {}
|
|
''');
|
|
await getSuggestions();
|
|
assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'main',
|
|
relevance: DART_RELEVANCE_LOCAL_FUNCTION);
|
|
}
|
|
|
|
test_inherited() {
|
|
addFile('/libA.dart', 'class A {m() {}}');
|
|
addTestFile('''
|
|
import '/libA.dart';
|
|
class B extends A {
|
|
x() {^}
|
|
}
|
|
''');
|
|
return getSuggestions().then((_) {
|
|
expect(replacementOffset, equals(completionOffset));
|
|
expect(replacementLength, equals(0));
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'm');
|
|
});
|
|
}
|
|
|
|
test_invocation() {
|
|
addTestFile('class A {b() {}} main() {A a; a.^}');
|
|
return getSuggestions().then((_) {
|
|
expect(replacementOffset, equals(completionOffset));
|
|
expect(replacementLength, equals(0));
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
|
|
});
|
|
}
|
|
|
|
test_invocation_sdk_relevancy_off() {
|
|
var originalSorter = DartCompletionManager.contributionSorter;
|
|
var mockSorter = new MockRelevancySorter();
|
|
DartCompletionManager.contributionSorter = mockSorter;
|
|
addTestFile('main() {Map m; m.^}');
|
|
return getSuggestions().then((_) {
|
|
// Assert that the CommonUsageComputer has been replaced
|
|
expect(suggestions.any((s) => s.relevance == DART_RELEVANCE_COMMON_USAGE),
|
|
isFalse);
|
|
DartCompletionManager.contributionSorter = originalSorter;
|
|
mockSorter.enabled = false;
|
|
});
|
|
}
|
|
|
|
test_invocation_sdk_relevancy_on() {
|
|
addTestFile('main() {Map m; m.^}');
|
|
return getSuggestions().then((_) {
|
|
// Assert that the CommonUsageComputer is working
|
|
expect(suggestions.any((s) => s.relevance == DART_RELEVANCE_COMMON_USAGE),
|
|
isTrue);
|
|
});
|
|
}
|
|
|
|
test_invocation_withTrailingStmt() {
|
|
addTestFile('class A {b() {}} main() {A a; a.^ int x = 7;}');
|
|
return getSuggestions().then((_) {
|
|
expect(replacementOffset, equals(completionOffset));
|
|
expect(replacementLength, equals(0));
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
|
|
});
|
|
}
|
|
|
|
test_keyword() {
|
|
addTestFile('library A; cl^');
|
|
return getSuggestions().then((_) {
|
|
expect(replacementOffset, equals(completionOffset - 2));
|
|
expect(replacementLength, equals(2));
|
|
assertHasResult(CompletionSuggestionKind.KEYWORD, 'export \'\';',
|
|
selectionOffset: 8, relevance: DART_RELEVANCE_HIGH);
|
|
assertHasResult(CompletionSuggestionKind.KEYWORD, 'class',
|
|
relevance: DART_RELEVANCE_HIGH);
|
|
});
|
|
}
|
|
|
|
test_local_named_constructor() {
|
|
addTestFile('class A {A.c(); x() {new A.^}}');
|
|
return getSuggestions().then((_) {
|
|
expect(replacementOffset, equals(completionOffset));
|
|
expect(replacementLength, equals(0));
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'c');
|
|
assertNoResult('A');
|
|
});
|
|
}
|
|
|
|
test_local_override() {
|
|
addFile('/libA.dart', 'class A {m() {}}');
|
|
addTestFile('''
|
|
import '/libA.dart';
|
|
class B extends A {
|
|
m() {}
|
|
x() {^}
|
|
}
|
|
''');
|
|
return getSuggestions().then((_) {
|
|
expect(replacementOffset, equals(completionOffset));
|
|
expect(replacementLength, equals(0));
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'm',
|
|
relevance: DART_RELEVANCE_LOCAL_METHOD);
|
|
});
|
|
}
|
|
|
|
test_locals() {
|
|
addTestFile('class A {var a; x() {var b;^}} class DateTime { }');
|
|
return getSuggestions().then((_) {
|
|
expect(replacementOffset, equals(completionOffset));
|
|
expect(replacementLength, equals(0));
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'A');
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'a',
|
|
relevance: DART_RELEVANCE_LOCAL_FIELD);
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'b',
|
|
relevance: DART_RELEVANCE_LOCAL_VARIABLE);
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'x',
|
|
relevance: DART_RELEVANCE_LOCAL_METHOD);
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'DateTime');
|
|
});
|
|
}
|
|
|
|
test_offset_past_eof() async {
|
|
addTestFile('main() { }', offset: 300);
|
|
Request request =
|
|
new CompletionGetSuggestionsParams(testFile, completionOffset)
|
|
.toRequest('0');
|
|
Response response = await waitResponse(request);
|
|
expect(response.id, '0');
|
|
expect(response.error.code, RequestErrorCode.INVALID_PARAMETER);
|
|
}
|
|
|
|
test_overrides() {
|
|
addFile('/libA.dart', 'class A {m() {}}');
|
|
addTestFile('''
|
|
import '/libA.dart';
|
|
class B extends A {m() {^}}
|
|
''');
|
|
return getSuggestions().then((_) {
|
|
expect(replacementOffset, equals(completionOffset));
|
|
expect(replacementLength, equals(0));
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'm',
|
|
relevance: DART_RELEVANCE_LOCAL_METHOD);
|
|
});
|
|
}
|
|
|
|
test_partFile() {
|
|
addFile(
|
|
'/project/bin/testA.dart',
|
|
'''
|
|
library libA;
|
|
part "$testFile";
|
|
import 'dart:html';
|
|
class A { }
|
|
''');
|
|
addTestFile('''
|
|
part of libA;
|
|
main() {^}''');
|
|
return getSuggestions().then((_) {
|
|
expect(replacementOffset, equals(completionOffset));
|
|
expect(replacementLength, equals(0));
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement');
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'A');
|
|
assertNoResult('test');
|
|
});
|
|
}
|
|
|
|
test_partFile2() {
|
|
addFile(
|
|
'/testA.dart',
|
|
'''
|
|
part of libA;
|
|
class A { }''');
|
|
addTestFile('''
|
|
library libA;
|
|
part "/testA.dart";
|
|
import 'dart:html';
|
|
main() {^}
|
|
''');
|
|
return getSuggestions().then((_) {
|
|
expect(replacementOffset, equals(completionOffset));
|
|
expect(replacementLength, equals(0));
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement');
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'A');
|
|
assertNoResult('test');
|
|
});
|
|
}
|
|
|
|
test_simple() {
|
|
addTestFile('''
|
|
void main() {
|
|
^
|
|
}
|
|
''');
|
|
return getSuggestions().then((_) {
|
|
expect(replacementOffset, equals(completionOffset));
|
|
expect(replacementLength, equals(0));
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
|
|
assertNoResult('HtmlElement');
|
|
assertNoResult('test');
|
|
});
|
|
}
|
|
|
|
test_static() {
|
|
addTestFile('class A {static b() {} c() {}} main() {A.^}');
|
|
return getSuggestions().then((_) {
|
|
expect(replacementOffset, equals(completionOffset));
|
|
expect(replacementLength, equals(0));
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
|
|
assertNoResult('c');
|
|
});
|
|
}
|
|
|
|
test_topLevel() {
|
|
addTestFile('''
|
|
typedef foo();
|
|
var test = '';
|
|
main() {tes^t}
|
|
''');
|
|
return getSuggestions().then((_) {
|
|
expect(replacementOffset, equals(completionOffset - 3));
|
|
expect(replacementLength, equals(4));
|
|
// Suggestions based upon imported elements are partially filtered
|
|
//assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
|
|
assertHasResult(CompletionSuggestionKind.INVOCATION, 'test',
|
|
relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
|
|
assertNoResult('HtmlElement');
|
|
});
|
|
}
|
|
}
|
|
|
|
class MockRelevancySorter implements DartContributionSorter {
|
|
bool enabled = true;
|
|
|
|
@override
|
|
Future sort(
|
|
CompletionRequest request, Iterable<CompletionSuggestion> suggestions) {
|
|
if (!enabled) {
|
|
throw 'unexpected sort';
|
|
}
|
|
return new Future.value();
|
|
}
|
|
}
|
|
|
|
@reflectiveTest
|
|
class _NoSearchEngine extends AbstractAnalysisTest {
|
|
@override
|
|
void setUp() {
|
|
super.setUp();
|
|
createProject();
|
|
handler = new CompletionDomainHandler(server);
|
|
}
|
|
|
|
test_noSearchEngine() async {
|
|
addTestFile('''
|
|
main() {
|
|
^
|
|
}
|
|
''');
|
|
await waitForTasksFinished();
|
|
Request request =
|
|
new CompletionGetSuggestionsParams(testFile, 0).toRequest('0');
|
|
Response response = handler.handleRequest(request);
|
|
expect(response.error, isNotNull);
|
|
expect(response.error.code, RequestErrorCode.NO_INDEX_GENERATED);
|
|
}
|
|
}
|