// 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 'dart:async';

import 'package:analysis_server/protocol/protocol.dart';
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/plugin/plugin_manager.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:analyzer_plugin/protocol/protocol.dart' as plugin;
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin;
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'domain_completion_util.dart';
import 'mocks.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(CompletionDomainHandlerGetSuggestionsTest);
    defineReflectiveTests(CompletionDomainHandlerTest);
  });
}

@reflectiveTest
class CompletionDomainHandlerGetSuggestionsTest
    extends AbstractCompletionDomainTest {
  test_ArgumentList_constructor_named_fieldFormalParam() async {
    // https://github.com/dart-lang/sdk/issues/31023
    addTestFile('''
main() { new A(field: ^);}
class A {
  A({this.field: -1}) {}
}
''');
    await getSuggestions();
  }

  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_constructor() async {
    addTestFile('class A {bool foo; A() : ^;}');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'super',
        relevance: DART_RELEVANCE_KEYWORD);
    assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo',
        relevance: DART_RELEVANCE_LOCAL_FIELD);
  }

  test_constructor2() async {
    addTestFile('class A {bool foo; A() : s^;}');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'super',
        relevance: DART_RELEVANCE_KEYWORD);
    assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo',
        relevance: DART_RELEVANCE_LOCAL_FIELD);
  }

  test_constructor3() async {
    addTestFile('class A {bool foo; A() : a=7,^;}');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'super',
        relevance: DART_RELEVANCE_KEYWORD);
    assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo',
        relevance: DART_RELEVANCE_LOCAL_FIELD);
  }

  test_constructor4() async {
    addTestFile('class A {bool foo; A() : a=7,s^;}');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'super',
        relevance: DART_RELEVANCE_KEYWORD);
    assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo',
        relevance: DART_RELEVANCE_LOCAL_FIELD);
  }

  test_constructor5() async {
    addTestFile('class A {bool foo; A() : a=7,s^}');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'super',
        relevance: DART_RELEVANCE_KEYWORD);
    assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo',
        relevance: DART_RELEVANCE_LOCAL_FIELD);
  }

  test_constructor6() async {
    addTestFile('class A {bool foo; A() : a=7,^ void bar() {}}');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'super',
        relevance: DART_RELEVANCE_KEYWORD);
    assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo',
        relevance: DART_RELEVANCE_LOCAL_FIELD);
  }

  test_html() {
    //
    // We no longer support the analysis of non-dart files.
    //
    testFile = convertPath('/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() {
    final filePath = '/project/bin/testA.dart';
    final incompleteImportText = toUriStr('/project/bin/t');
    newFile(filePath, content: 'library libA;');
    addTestFile('''
    import "$incompleteImportText^.dart";
    main() {}''');
    return getSuggestions().then((_) {
      expect(replacementOffset,
          equals(completionOffset - incompleteImportText.length));
      expect(replacementLength, equals(5 + incompleteImportText.length));
      assertHasResult(CompletionSuggestionKind.IMPORT, toUriStr(filePath));
      assertNoResult('test');
    });
  }

  test_imports() {
    addTestFile('''
      import 'dart:html';
      main() {^}
    ''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object',
          elementKind: ElementKind.CLASS);
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement',
          elementKind: ElementKind.CLASS);
      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');
    Future<Response> responseFuture1 = waitResponse(request1);

    // Make another request before the first request completes
    Request request2 =
        new CompletionGetSuggestionsParams(testFile, completionOffset)
            .toRequest('8');
    Future<Response> responseFuture2 = waitResponse(request2);

    // Await first response
    Response response1 = await responseFuture1;
    var result1 = new CompletionGetSuggestionsResult.fromResponse(response1);
    assertValidId(result1.id);

    // Await second response
    Response response2 = await responseFuture2;
    var result2 = new CompletionGetSuggestionsResult.fromResponse(response2);
    assertValidId(result2.id);

    // Wait for all processing to be complete
    await analysisHandler.server.analysisDriverScheduler.waitForIdle();
    await pumpEventQueue();

    // Assert that first request has been aborted
    expect(allSuggestions[result1.id], hasLength(0));

    // Assert valid results for the second request
    expect(allSuggestions[result2.id], same(suggestions));
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'class',
        relevance: DART_RELEVANCE_HIGH);
  }

  @failingTest
  test_imports_aborted_source_changed() async {
    // TODO(brianwilkerson) Figure out whether this test makes sense when
    // running the new driver. It waits for an initial empty notification then
    // waits for a new notification. But I think that under the driver we only
    // ever send one notification.
    addTestFile('''
        class foo { }
        c^''');

    // Make a request for suggestions
    Request request =
        new CompletionGetSuggestionsParams(testFile, completionOffset)
            .toRequest('0');
    Future<Response> responseFuture = waitResponse(request);

    // 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, '')])
    });

    // Await a response
    Response response = await responseFuture;
    completionId = response.id;
    assertValidId(completionId);

    // Wait for all processing to be complete
    await analysisHandler.server.analysisDriverScheduler.waitForIdle();
    await pumpEventQueue();

    // Assert that request has been aborted
    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();
    // wait for response to arrive
    // because although the analysis is complete (waitForTasksFinished)
    // the response may not yet have been processed
    while (replacementOffset == null) {
      await new Future.delayed(new Duration(milliseconds: 5));
    }
    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',
          elementKind: ElementKind.CLASS);
      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 {
    newFile('/testA.dart', content: '''
  part of libA;
  foo(bar) => 0;''');
    addTestFile('''
  library libA;
  part "${toUriStr('/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() {
    addTestFile('''
class A {
  m() {}
}
class B extends A {
  x() {^}
}
''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm');
    });
  }

  test_invalidFilePathFormat_notAbsolute() async {
    var request =
        new CompletionGetSuggestionsParams('test.dart', 0).toRequest('0');
    var response = await waitResponse(request);
    expect(
      response,
      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
    );
  }

  test_invalidFilePathFormat_notNormalized() async {
    var request = new CompletionGetSuggestionsParams(
            convertPath('/foo/../bar/test.dart'), 0)
        .toRequest('0');
    var response = await waitResponse(request);
    expect(
      response,
      isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT),
    );
  }

  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_is_asPrefixedIdentifierStart() async {
    addTestFile('''
class A { var isVisible;}
main(A p) { var v1 = p.is^; }''');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.INVOCATION, 'isVisible',
        relevance: DART_RELEVANCE_DEFAULT);
  }

  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_implicitCreation() async {
    addTestFile('''
class A {
  A();
  A.named();
}
main() {
  ^
}
''');
    await getSuggestions();

    expect(replacementOffset, equals(completionOffset));
    expect(replacementLength, equals(0));

    // The class is suggested.
    assertHasResult(CompletionSuggestionKind.INVOCATION, 'A',
        elementKind: ElementKind.CLASS);

    // Both constructors - default and named, are suggested.
    assertHasResult(CompletionSuggestionKind.INVOCATION, 'A',
        elementKind: ElementKind.CONSTRUCTOR);
    assertHasResult(CompletionSuggestionKind.INVOCATION, 'A.named',
        elementKind: ElementKind.CONSTRUCTOR);
  }

  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() {
    newFile('/project/bin/a.dart', content: 'class A {m() {}}');
    addTestFile('''
import 'a.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_local_shadowClass() async {
    addTestFile('''
class A {
  A();
  A.named();
}
main() {
  int A = 0;
  ^
}
''');
    await getSuggestions();

    expect(replacementOffset, equals(completionOffset));
    expect(replacementLength, equals(0));

    // The class is suggested.
    assertHasResult(CompletionSuggestionKind.INVOCATION, 'A',
        relevance: DART_RELEVANCE_LOCAL_VARIABLE);

    // Class and all its constructors are shadowed by the local variable.
    assertNoResult('A', elementKind: ElementKind.CLASS);
    assertNoResult('A', elementKind: ElementKind.CONSTRUCTOR);
    assertNoResult('A.named', elementKind: ElementKind.CONSTRUCTOR);
  }

  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',
          elementKind: ElementKind.CLASS);
      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',
          elementKind: ElementKind.CLASS);
    });
  }

  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() {
    newFile('/project/bin/a.dart', content: 'class A {m() {}}');
    addTestFile('''
import 'a.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() {
    newFile('/project/bin/a.dart', content: '''
      library libA;
      import 'dart:html';
      part 'test.dart';
      class A { }
    ''');
    addTestFile('''
      part of libA;
      main() {^}''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object',
          elementKind: ElementKind.CLASS);
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement',
          elementKind: ElementKind.CLASS);
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'A',
          elementKind: ElementKind.CLASS);
      assertNoResult('test');
    });
  }

  test_partFile2() {
    newFile('/project/bin/a.dart', content: '''
      part of libA;
      class A { }''');
    addTestFile('''
      library libA;
      part "a.dart";
      import 'dart:html';
      main() {^}
    ''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object',
          elementKind: ElementKind.CLASS);
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement',
          elementKind: ElementKind.CLASS);
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'A',
          elementKind: ElementKind.CLASS);
      assertNoResult('test');
    });
  }

  test_sentToPlugins() async {
    addTestFile('''
      void main() {
        ^
      }
    ''');
    PluginInfo info = new DiscoveredPluginInfo('a', 'b', 'c', null, null);
    plugin.CompletionGetSuggestionsResult result =
        new plugin.CompletionGetSuggestionsResult(
            testFile.indexOf('^'), 0, <CompletionSuggestion>[
      new CompletionSuggestion(CompletionSuggestionKind.IDENTIFIER,
          DART_RELEVANCE_DEFAULT, 'plugin completion', 3, 0, false, false)
    ]);
    pluginManager.broadcastResults = <PluginInfo, Future<plugin.Response>>{
      info: new Future.value(result.toResponse('-', 1))
    };
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'plugin completion',
        selectionOffset: 3);
  }

  test_simple() {
    addTestFile('''
      void main() {
        ^
      }
    ''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object',
          elementKind: ElementKind.CLASS);
      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');
    });
  }
}

@reflectiveTest
class CompletionDomainHandlerTest extends AbstractCompletionDomainTest {
  test_listTokenDetails() async {
    newFile(testFile, content: '''
class A {
  static A b(String s) {}
  c(int i) {}
}
main() {
  A.b('s').c(3);
}
''');
    Request request =
        new CompletionListTokenDetailsParams(testFile).toRequest('0');
    Response response = await waitResponse(request);
    List<Map<String, dynamic>> tokens = response.result['tokens'];
    _expectTokens(tokens, [
      _token('class', 'CLASS', null),
      _token('A', 'STRING_INT', ['declaration']),
      _token('{', 'OPEN_CURLY_BRACKET', null),
      _token('static', 'STATIC', null),
      _token('A', 'STRING_INT', ['identifier']),
      _token('b', 'STRING_INT', ['declaration']),
      _token('(', 'OPEN_PAREN', null),
      _token('String', 'STRING_INT', ['identifier']),
      _token('s', 'STRING_INT', ['declaration']),
      _token(')', 'CLOSE_PAREN', null),
      _token('{', 'OPEN_CURLY_BRACKET', null),
      _token('}', 'CLOSE_CURLY_BRACKET', null),
      _token('c', 'STRING_INT', ['declaration']),
      _token('(', 'OPEN_PAREN', null),
      _token('int', 'STRING_INT', ['identifier']),
      _token('i', 'STRING_INT', ['declaration']),
      _token(')', 'CLOSE_PAREN', null),
      _token('{', 'OPEN_CURLY_BRACKET', null),
      _token('}', 'CLOSE_CURLY_BRACKET', null),
      _token('}', 'CLOSE_CURLY_BRACKET', null),
      _token('main', 'STRING_INT', ['declaration']),
      _token('(', 'OPEN_PAREN', null),
      _token(')', 'CLOSE_PAREN', null),
      _token('{', 'OPEN_CURLY_BRACKET', null),
      _token('A', 'STRING_INT', ['identifier']),
      _token('.', 'PERIOD', null),
      _token('b', 'STRING_INT', ['identifier']),
      _token('(', 'OPEN_PAREN', null),
      _token("'s'", 'STRING', null),
      _token(')', 'CLOSE_PAREN', null),
      _token('.', 'PERIOD', null),
      _token('c', 'STRING_INT', ['identifier']),
      _token('(', 'OPEN_PAREN', null),
      _token('3', 'INT', null),
      _token(')', 'CLOSE_PAREN', null),
      _token(';', 'SEMICOLON', null),
      _token('}', 'CLOSE_CURLY_BRACKET', null),
    ]);
  }

  void _expectTokens(List<Map<String, dynamic>> actualTokens,
      List<TokenDetails> expectedTokens) {
    int length = expectedTokens.length;
    expect(actualTokens, hasLength(length));
    for (int i = 0; i < length; i++) {
      Map<String, dynamic> actual = actualTokens[i];
      TokenDetails expected = expectedTokens[i];
      expect(actual['lexeme'], expected.lexeme);
      expect(actual['type'], expected.type);
      expect(actual['validElementKinds'], expected.validElementKinds);
    }
  }

  TokenDetails _token(String lexeme, String type, List<String> kinds) {
    return new TokenDetails(lexeme, type, validElementKinds: kinds);
  }
}

class MockRelevancySorter implements DartContributionSorter {
  bool enabled = true;

  @override
  Future sort(
      CompletionRequest request, Iterable<CompletionSuggestion> suggestions) {
    if (!enabled) {
      throw 'unexpected sort';
    }
    return new Future.value();
  }
}
