// Copyright (c) 2018, 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/lsp_protocol/protocol.dart';
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/lsp/constants.dart';
import 'package:analysis_server/src/lsp/handlers/handler_completion.dart';
import 'package:analysis_server/src/services/linter/lint_names.dart';
import 'package:analysis_server/src/services/snippets/dart/class_declaration.dart';
import 'package:analysis_server/src/services/snippets/dart/do_statement.dart';
import 'package:analysis_server/src/services/snippets/dart/flutter_stateful_widget.dart';
import 'package:analysis_server/src/services/snippets/dart/flutter_stateful_widget_with_animation.dart';
import 'package:analysis_server/src/services/snippets/dart/flutter_stateless_widget.dart';
import 'package:analysis_server/src/services/snippets/dart/for_in_statement.dart';
import 'package:analysis_server/src/services/snippets/dart/for_statement.dart';
import 'package:analysis_server/src/services/snippets/dart/function_declaration.dart';
import 'package:analysis_server/src/services/snippets/dart/if_else_statement.dart';
import 'package:analysis_server/src/services/snippets/dart/if_statement.dart';
import 'package:analysis_server/src/services/snippets/dart/main_function.dart';
import 'package:analysis_server/src/services/snippets/dart/switch_statement.dart';
import 'package:analysis_server/src/services/snippets/dart/test_definition.dart';
import 'package:analysis_server/src/services/snippets/dart/test_group_definition.dart';
import 'package:analysis_server/src/services/snippets/dart/try_catch_statement.dart';
import 'package:analysis_server/src/services/snippets/dart/while_statement.dart';
import 'package:analyzer/src/test_utilities/test_code_format.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
import 'package:collection/collection.dart';
import 'package:linter/src/rules.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../tool/lsp_spec/matchers.dart';
import '../utils/test_code_extensions.dart';
import 'completion.dart';
import 'server_abstract.dart';

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(CompletionTest);
    defineReflectiveTests(CompletionLabelDetailsTest);
    defineReflectiveTests(CompletionDocumentationResolutionTest);
    defineReflectiveTests(DartSnippetCompletionTest);
    defineReflectiveTests(FlutterSnippetCompletionTest);
  });
}

abstract class AbstractCompletionTest extends AbstractLspAnalysisServerTest
    with CompletionTestMixin {
  AbstractCompletionTest() {
    defaultInitializationOptions = {
      // Default to a high budget for tests because everything is cold and
      // may take longer to return.
      'completionBudgetMilliseconds': 50000
    };
  }

  void expectDocumentation(CompletionItem completion, Matcher matcher) {
    var docs = completion.documentation?.map(
      (markup) => markup.value,
      (string) => string,
    );
    expect(docs, matcher);
  }

  @override
  void setUp() {
    super.setUp();

    // Completion tests have incomplete code.
    failTestOnErrorDiagnostic = false;

    setApplyEditSupport();
  }
}

@reflectiveTest
class CompletionDocumentationResolutionTest extends AbstractCompletionTest {
  late String content;
  late final code = TestCode.parse(content);

  Future<CompletionItem> getCompletionItem(String label) async {
    var completions = await getCompletion(mainFileUri, code.position.position);
    return completions.singleWhere((c) => c.label == label);
  }

  Future<void> initializeServer() async {
    await initialize();
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
  }

  Future<void> test_class() async {
    newFile(
      join(projectFolderPath, 'my_class.dart'),
      '''
/// Class.
class MyClass {}
      ''',
    );

    content = '''
void f() {
  MyClass^
}
''';

    await initializeServer();

    var completion = await getCompletionItem('MyClass');
    expectDocumentation(completion, isNull);

    var resolved = await resolveCompletion(completion);
    expectDocumentation(resolved, contains('Class.'));
  }

  Future<void> test_class_constructor() async {
    newFile(
      join(projectFolderPath, 'my_class.dart'),
      '''
class MyClass {
  /// Constructor.
  MyClass();
}
      ''',
    );

    content = '''
void f() {
  MyClass^
}
''';

    await initializeServer();

    var completion = await getCompletionItem('MyClass()');
    expectDocumentation(completion, isNull);

    var resolved = await resolveCompletion(completion);
    expectDocumentation(resolved, contains('Constructor.'));
  }

  Future<void> test_class_constructorNamed() async {
    newFile(
      join(projectFolderPath, 'my_class.dart'),
      '''
class MyClass {
  /// Named Constructor.
  MyClass.named();
}
      ''',
    );

    content = '''
void f() {
  MyClass^
}
''';

    await initializeServer();

    var completion = await getCompletionItem('MyClass.named()');
    expectDocumentation(completion, isNull);

    var resolved = await resolveCompletion(completion);
    expectDocumentation(resolved, contains('Named Constructor.'));
  }

  Future<void> test_enum() async {
    newFile(
      join(projectFolderPath, 'my_enum.dart'),
      '''
/// Enum.
enum MyEnum {}
      ''',
    );

    content = '''
void f() {
  MyEnum^
}
''';

    await initializeServer();

    var completion = await getCompletionItem('MyEnum');
    expectDocumentation(completion, isNull);

    var resolved = await resolveCompletion(completion);
    expectDocumentation(resolved, contains('Enum.'));
  }

  Future<void> test_enum_member() async {
    // Function used to provide type context in main file without importing
    // the enum.
    newFile(
      join(projectFolderPath, 'lib', 'func.dart'),
      '''
import 'my_enum.dart';
void enumFunc(MyEnum e) {}
      ''',
    );

    newFile(
      join(projectFolderPath, 'lib', 'my_enum.dart'),
      '''
enum MyEnum {
  /// Enum Member.
  one,
}
      ''',
    );

    content = '''
import 'func.dart';
void f() {
  enumFunc(MyEnum^)
}
''';

    await initializeServer();

    var completion = await getCompletionItem('MyEnum.one');
    expectDocumentation(completion, isNull);

    var resolved = await resolveCompletion(completion);
    expectDocumentation(resolved, contains('Enum Member.'));
  }
}

@reflectiveTest
class CompletionLabelDetailsTest extends AbstractCompletionTest {
  late String fileAPath;

  Future<void> expectLabels(
    String content, {
    Uri? completionFileUri,
    // Main label of the completion (eg 'myFunc')
    required String? label,
    // The detail part of the label (shown after label, usually truncated signature)
    required String? labelDetail,
    // Additional label description (usually the auto-import URI)
    required String? labelDescription,
    // Filter text (usually same as label, never with `()` or other suffixes)
    required String? filterText,
    // Main detail (shown in popout, usually full signature)
    required String? detail,
    // Sometimes resolved detail has a prefix added (eg. "Auto-import from").
    String? resolvedDetailPrefix,
  }) async {
    completionFileUri ??= mainFileUri;

    var code = TestCode.parse(content);
    await initialize();
    await openFile(completionFileUri, code.code);

    var completions =
        await getCompletion(completionFileUri, code.position.position);
    var completion = completions.singleWhereOrNull((c) => c.label == label);
    if (completion == null) {
      fail('Did not find completion "$label" in completion results:'
          '\n    ${completions.map((c) => c.label).join('\n    ')}');
    }

    expect(completion.detail, detail);
    expect(completion.filterText, filterText);

    // If both fields are expected to be null, expect the whole object to be
    // null (to reduce payload size).
    if (labelDetail == null && labelDescription == null) {
      expect(completion.labelDetails, isNull);
    } else {
      var labelDetails = completion.labelDetails;
      if (labelDetails == null) {
        fail('Completion "$label" does not have labelDetails');
      }
      expect(labelDetails.detail, labelDetail);
      expect(labelDetails.description, labelDescription);
    }

    // Verify that resolution does not modify these results.
    var resolved = await resolveCompletion(completion);
    expect(resolved.label, completion.label);
    expect(resolved.filterText, completion.filterText);
    expect(
      resolved.detail,
      resolvedDetailPrefix != null
          ? '$resolvedDetailPrefix${completion.detail ?? ''}'
          : completion.detail,
    );
    expect(resolved.labelDetails?.detail, completion.labelDetails?.detail);
    expect(
      resolved.labelDetails?.description,
      completion.labelDetails?.description,
    );
  }

  @override
  void setUp() {
    super.setUp();
    fileAPath = join(projectFolderPath, 'lib', 'a.dart');

    // TODO(dantup): Consider enabling this by default for [CompletionTest] and
    //  changing this class to test support without it (or, subclassing
    //  CompletionTest and inferring the label when labelDetails are not
    //  supported).
    setCompletionItemLabelDetailsSupport();
  }

  Future<void> test_constructor_argument() async {
    var content = '''
var a = Foo(^);

class Foo {
  final int value;
  const Foo({required this.value});
}
''';

    await expectLabels(
      content,
      label: 'value:',
      labelDetail: ' int',
      labelDescription: null,
      filterText: null,
      detail: 'int',
    );
  }

  Future<void> test_constructor_factory_argument() async {
    var content = '''
var a = Foo(^);

class Foo {
  final int value;
  const Foo._({required this.value});
  const factory Foo({required int value}) = Foo._;
}
''';

    await expectLabels(
      content,
      label: 'value:',
      labelDetail: ' int',
      labelDescription: null,
      filterText: null,
      detail: 'int',
    );
  }

  Future<void> test_imported_function_returnType_args() async {
    newFile(fileAPath, '''
String a(String a, {String b}) {}
''');
    var content = '''
import 'a.dart';
void f() {
  a^
}
''';

    await expectLabels(content,
        label: 'a',
        labelDetail: '(…) → String',
        labelDescription: null,
        filterText: null,
        detail: '(String a, {String b}) → String');
  }

  Future<void> test_imported_function_returnType_noArgs() async {
    newFile(fileAPath, '''
String a() {}
''');
    var content = '''
import 'a.dart';
String f() {
  a^
}
''';

    await expectLabels(content,
        label: 'a',
        labelDetail: '() → String',
        labelDescription: null,
        filterText: null,
        detail: '() → String');
  }

  Future<void> test_imported_function_void_args() async {
    newFile(fileAPath, '''
void a(String a, {String b}) {}
''');
    var content = '''
import 'a.dart';
void f() {
  a^
}
''';

    await expectLabels(content,
        label: 'a',
        labelDetail: '(…) → void',
        labelDescription: null,
        filterText: null,
        detail: '(String a, {String b}) → void');
  }

  Future<void> test_imported_function_void_noArgs() async {
    newFile(fileAPath, '''
void a() {}
''');
    var content = '''
import 'a.dart';
void f() {
  a^
}
''';

    await expectLabels(content,
        label: 'a',
        labelDetail: '() → void',
        labelDescription: null,
        filterText: null,
        detail: '() → void');
  }

  Future<void> test_local_function_returnType_args() async {
    var content = '''
String f(String a, {String b}) {
  f^
}
''';
    await expectLabels(content,
        label: 'f',
        labelDetail: '(…) → String',
        labelDescription: null,
        filterText: null,
        detail: '(String a, {String b}) → String');
  }

  Future<void> test_local_function_returnType_noArgs() async {
    var content = '''
String f() {
  f^
}
''';

    await expectLabels(content,
        label: 'f',
        labelDetail: '() → String',
        labelDescription: null,
        filterText: null,
        detail: '() → String');
  }

  Future<void> test_local_function_void_args() async {
    var content = '''
void f(String a, {String b}) {
  f^
}
''';

    await expectLabels(content,
        label: 'f',
        labelDetail: '(…) → void',
        labelDescription: null,
        filterText: null,
        detail: '(String a, {String b}) → void');
  }

  Future<void> test_local_function_void_noArgs() async {
    var content = '''
void f() {
  f^
}
''';

    await expectLabels(content,
        label: 'f',
        labelDetail: '() → void',
        labelDescription: null,
        filterText: null,
        detail: '() → void');
  }

  Future<void> test_local_getter() async {
    var content = '''
String a => '';
void f() {
  a^
}
''';
    await expectLabels(content,
        label: 'a',
        labelDetail: '() → String',
        labelDescription: null,
        filterText: null,
        detail: '() → String');
  }

  Future<void> test_local_getterAndSetter() async {
    var content = '''
set a(String value) {}
String get a => '';
void f() {
  a^
}
''';
    await expectLabels(content,
        label: 'a',
        labelDetail: ' String',
        labelDescription: null,
        filterText: null,
        detail: 'String');
  }

  Future<void> test_local_override_annotation_equals() async {
    var content = '''
class Base {
}

class Derived extends Base {
  @over^
}
''';
    await expectLabels(content,
        label: 'override ==',
        labelDetail: '(…) → bool',
        labelDescription: null,
        filterText: null,
        detail: '(Object other) → bool');
  }

  Future<void> test_local_override_annotation_method() async {
    var content = '''
class Base {
  String aa(String a) => '';
}

class Derived extends Base {
  @over^
}
''';
    await expectLabels(content,
        label: 'override aa',
        labelDetail: '(…) → String',
        labelDescription: null,
        filterText: null,
        detail: '(String a) → String');
  }

  Future<void> test_local_override_name() async {
    var content = '''
class Base {
  String aa(String a) => '';
}

class Derived extends Base {
  a^
}
''';
    await expectLabels(content,
        label: 'aa',
        labelDetail: '(…) → String',
        labelDescription: null,
        filterText: null,
        detail: '(String a) → String');
  }

  Future<void> test_local_setter() async {
    var content = '''
set a(String value) {}
void f() {
  a^
}
''';
    await expectLabels(content,
        label: 'a',
        labelDetail: ' String',
        labelDescription: null,
        filterText: null,
        detail: 'String');
  }

  Future<void> test_notImported_function_returnType_args() async {
    newFile(fileAPath, '''
String a(String a, {String b}) {}
''');
    var content = '''
void f() {
  a^
}
''';

    await expectLabels(content,
        label: 'a',
        labelDetail: '(…) → String',
        labelDescription: 'package:test/a.dart',
        filterText: null,
        detail: '(String a, {String b}) → String',
        resolvedDetailPrefix: "Auto import from 'package:test/a.dart'\n\n");
  }

  Future<void> test_notImported_function_returnType_noArgs() async {
    newFile(fileAPath, '''
String a() {}
''');
    var content = '''
String f() {
  a^
}
''';

    await expectLabels(content,
        label: 'a',
        labelDetail: '() → String',
        labelDescription: 'package:test/a.dart',
        filterText: null,
        detail: '() → String',
        resolvedDetailPrefix: "Auto import from 'package:test/a.dart'\n\n");
  }

  Future<void> test_notImported_function_void_args() async {
    newFile(fileAPath, '''
void a(String a, {String b}) {}
''');
    var content = '''
void f() {
  a^
}
''';

    await expectLabels(content,
        label: 'a',
        labelDetail: '(…) → void',
        labelDescription: 'package:test/a.dart',
        filterText: null,
        detail: '(String a, {String b}) → void',
        resolvedDetailPrefix: "Auto import from 'package:test/a.dart'\n\n");
  }

  Future<void> test_notImported_function_void_noArgs() async {
    newFile(fileAPath, '''
void a() {}
''');
    var content = '''
void f() {
  a^
}
''';

    await expectLabels(content,
        label: 'a',
        labelDetail: '() → void',
        labelDescription: 'package:test/a.dart',
        filterText: null,
        detail: '() → void',
        resolvedDetailPrefix: "Auto import from 'package:test/a.dart'\n\n");
  }

  Future<void> test_notImported_outsideLib_relativePath() async {
    var testMainFilePath = join(projectFolderPath, 'test', 'main.dart');
    var testFileAPath = join(projectFolderPath, 'test', 'a.dart');

    newFile(testFileAPath, '''
void a(String a, {String b}) {}
''');
    var content = '''
void f() {
  a^
}
''';

    await expectLabels(content,
        completionFileUri: toUri(testMainFilePath),
        label: 'a',
        labelDetail: '(…) → void',
        labelDescription: 'a.dart',
        filterText: null,
        detail: '(String a, {String b}) → void',
        resolvedDetailPrefix: "Auto import from 'a.dart'\n\n");
  }

  Future<void> test_nullNotEmpty() async {
    var content = '''
bool a = ^
''';

    /// expectLabels verifies the whole labelDetails object is null if
    /// both fields are expected to be null.
    await expectLabels(
      content,
      label: 'true',
      labelDetail: null,
      labelDescription: null,
      filterText: null,
      detail: null,
    );
  }

  Future<void> test_record() async {
    var content = r'''
void f((int, int) record) {
  record.$^
}
''';

    await expectLabels(content,
        label: r'$1',
        labelDetail: ' int',
        labelDescription: null,
        filterText: null,
        detail: 'int');
  }

  Future<void> test_variable() async {
    var content = r'''
void f(int variable) {
  varia^
}
''';

    await expectLabels(content,
        label: 'variable',
        labelDetail: ' int',
        labelDescription: null,
        filterText: null,
        detail: 'int');
  }
}

@reflectiveTest
class CompletionTest extends AbstractCompletionTest {
  /// Checks whether the correct types of documentation are returned for
  /// completions based on [preference].
  Future<void> assertDocumentation(
    String? preference, {
    required bool includesSummary,
    required bool includesFull,
  }) async {
    var content = '''
/// Summary.
///
/// Full.
class A {}

A^
''';

    await provideConfig(
      initialize,
      {
        if (preference != null) 'documentation': preference,
      },
    );
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletion(mainFileUri, code.position.position);
    var completion = res.singleWhere((c) => c.label == 'A');

    if (includesSummary) {
      expectDocumentation(completion, contains('Summary.'));
    } else {
      expectDocumentation(completion, isNot(contains('Summary.')));
    }

    if (includesFull) {
      expectDocumentation(completion, contains('Full.'));
    } else {
      expectDocumentation(completion, isNot(contains('Full.')));
    }
  }

  /// Checks whether the correct types of documentation are returned during
  /// `completionItem/resolve` based on [preference].
  Future<void> assertResolvedDocumentation(
    String? preference, {
    required bool includesSummary,
    required bool includesFull,
  }) async {
    newFile(
      join(projectFolderPath, 'other_file.dart'),
      '''
      /// Summary.
      ///
      /// Full.
      class InOtherFile {}
      ''',
    );

    var content = '''
void f() {
  InOtherF^
}
''';

    await provideConfig(
      initialize,
      {
        if (preference != null) 'documentation': preference,
      },
    );
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletion(mainFileUri, code.position.position);
    var completion = res.singleWhere((c) => c.label == 'InOtherFile');

    // Expect no docs in original response and correct type of docs added
    // during resolve.
    expectDocumentation(completion, isNull);
    var resolved = await resolveCompletion(completion);

    if (includesSummary) {
      expectDocumentation(resolved, contains('Summary.'));
    } else {
      expectDocumentation(resolved, isNot(contains('Summary.')));
    }

    if (includesFull) {
      expectDocumentation(resolved, contains('Full.'));
    } else {
      expectDocumentation(resolved, isNot(contains('Full.')));
    }
  }

  Future<void> checkCompleteFunctionCallInsertText(
    String content,
    String completion, {
    required String? editText,
    InsertTextFormat? insertTextFormat,
  }) async {
    setCompletionItemSnippetSupport();
    await provideConfig(initialize, {'completeFunctionCalls': true});
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    var item = res.singleWhere(
      (c) => c.label == completion,
      orElse: () =>
          throw 'Did not find $completion in ${res.map((r) => r.label).toList()}',
    );

    expect(item.insertTextFormat, equals(insertTextFormat));
    // We always expect `insertText` to be `null` now, as we always use
    // `textEdit`.
    expect(item.insertText, isNull);

    // And the expected text should be in the `textEdit`.
    var textEdit = toTextEdit(item.textEdit!);
    expect(textEdit.newText, equals(editText));
    expect(textEdit.range, equals(code.range.range));
  }

  void expectAutoImportCompletion(List<CompletionItem> items, String file) {
    expect(
      items.singleWhereOrNull(
          (c) => c.detail?.contains("Auto import from '$file'") ?? false),
      isNotNull,
    );
  }

  /// Verifies a color completion with text [label] for the code [content] that
  /// includes a prefix for [colorHex] in the description.
  Future<void> expectColorCompletion(
    String content,
    String label,
    String colorHex,
  ) async {
    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    var completion = res.singleWhere((c) => c.label == label);

    // Verify correct kind for color preview.
    expect(completion.kind, CompletionItemKind.Color);

    // Verify the docs are either entirely the hex code, or end with it.
    // VS Code's regex only allows the hex code at the start or end to show the
    // preview.
    var docs = completion.documentation?.map(
      (markup) => markup.value,
      (string) => string,
    );
    expect(
      docs,
      anyOf(equals(colorHex), endsWith('\n\n$colorHex')),
    );
  }

  /// Expect [item] to use the default edit range, inserting the value [text].
  void expectUsesDefaultEditRange(CompletionItem item, String text) {
    expect(item.textEditText ?? item.label, text);
    expect(item.insertText, isNull);
    expect(item.textEdit, isNull);
  }

  @override
  void setUp() {
    super.setUp();
    writeTestPackageConfig(
      flutter: true,
    );
  }

  Future<void> test_annotation_beforeMember() async {
    var content = '''
class B {
  @^
  int a = 1;
}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var completions = await getCompletion(mainFileUri, code.position.position);
    var labels = completions.map((c) => c.label).toList();
    expect(labels, contains('override'));
    expect(labels, contains('deprecated'));
    expect(labels, contains('Deprecated(…)'));
  }

  Future<void> test_annotation_endOfClass() async {
    var content = '''
class B {
  @^
}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var completions = await getCompletion(mainFileUri, code.position.position);
    var labels = completions.map((c) => c.label).toList();
    expect(labels, contains('override'));
    expect(labels, contains('deprecated'));
    expect(labels, contains('Deprecated(…)'));
  }

  Future<void> test_closure() async {
    var content = '''
void f({void Function(int a, String b) closure}) {}

void g() {
  f(closure: ^);
}
''';

    var expectedContent = '''
void f({void Function(int a, String b) closure}) {}

void g() {
  f(closure: (a, b) => ^,);
}
''';

    await verifyCompletions(
      mainFileUri,
      content,
      expectCompletions: ['(a, b) {}', '(a, b) =>'],
      applyEditsFor: '(a, b) =>',
      expectedContent: expectedContent,
    );
  }

  Future<void> test_closure_requiredNamed() async {
    var content = '''
void f({void Function({int a, required String b}) closure}) {}

void g() {
  f(closure: ^);
}
''';

    var expectedContent = '''
void f({void Function({int a, required String b}) closure}) {}

void g() {
  f(closure: ({a, required b}) => ^,);
}
''';

    await verifyCompletions(
      mainFileUri,
      content,
      // Display text does not contain 'required' because it makes the
      // completion much longer, we just include it in the completion text.
      expectCompletions: ['({a, b}) {}', '({a, b}) =>'],
      applyEditsFor: '({a, b}) =>',
      expectedContent: expectedContent,
    );
  }

  Future<void> test_color_material() async {
    var content = '''
import 'package:flutter/material.dart';
var a = Colors.re^
''';

    await expectColorCompletion(content, 'red', '#FF0000');
  }

  Future<void> test_color_materialAccent() async {
    var content = '''
import 'package:flutter/material.dart';
var a = Colors.redAcce^
''';

    await expectColorCompletion(content, 'redAccent', '#FFAA00');
  }

  Future<void> test_comment() async {
    var content = '''
    // foo ^
    void f() {}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res, isEmpty);
  }

  Future<void> test_comment_endOfFile_withNewline() async {
    // Checks for a previous bug where invoking completion inside a comment
    // at the end of a file would return results.
    var content = '''
    // foo ^
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res, isEmpty);
  }

  Future<void> test_comment_endOfFile_withoutNewline() async {
    // Checks for a previous bug where invoking completion inside a comment
    // at the very end of a file with no trailing newline would return results.
    var content = '// foo ^';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res, isEmpty);
  }

  Future<void> test_commitCharacter_dynamicRegistration() async {
    var registrations = <Registration>[];
    // Provide empty config and collect dynamic registrations during
    // initialization.
    setDidChangeConfigurationDynamicRegistration();
    setAllSupportedTextDocumentDynamicRegistrations();
    await monitorDynamicRegistrations(
      registrations,
      () => provideConfig(initialize, {}),
    );

    Registration registration(Method method) =>
        registrationForDart(registrations, method);

    // By default, there should be no commit characters.
    var reg = registration(Method.textDocument_completion);
    var options = CompletionRegistrationOptions.fromJson(
        reg.registerOptions as Map<String, Object?>);
    expect(options.allCommitCharacters, isNull);

    // When we change config, we should get a re-registration (unregister then
    // register) for completion which now includes the commit characters.
    await monitorDynamicReregistration(
      registrations,
      () => updateConfig({'previewCommitCharacters': true}),
    );
    reg = registration(Method.textDocument_completion);
    options = CompletionRegistrationOptions.fromJson(
        reg.registerOptions as Map<String, Object?>);
    expect(options.allCommitCharacters, equals(dartCompletionCommitCharacters));
  }

  Future<void> test_completeFunctionCalls_constructor() =>
      checkCompleteFunctionCallInsertText(
        '''
        class Aaaaa {
          Aaaaa(int a);
        }
        void f(int aaa) {
          var a = new [!Aaa^!]
        }
        ''',
        'Aaaaa(…)',
        insertTextFormat: InsertTextFormat.Snippet,
        editText: r'Aaaaa(${0:a})',
      );

  Future<void> test_completeFunctionCalls_escapesDollarArgs() =>
      checkCompleteFunctionCallInsertText(
        r'''
        int myFunction(String a$a, int b, {String c}) {
          var a = [!myFu^!]
        }
        ''',
        'myFunction(…)',
        insertTextFormat: InsertTextFormat.Snippet,
        // The dollar should have been escaped.
        editText: r'myFunction(${1:a\$a}, ${2:b})',
      );

  Future<void> test_completeFunctionCalls_escapesDollarName() =>
      checkCompleteFunctionCallInsertText(
        r'''
        int myFunc$tion(String a, int b, {String c}) {
          var a = [!myFu^!]
        }
        ''',
        r'myFunc$tion(…)',
        insertTextFormat: InsertTextFormat.Snippet,
        // The dollar should have been escaped.
        editText: r'myFunc\$tion(${1:a}, ${2:b})',
      );

  Future<void> test_completeFunctionCalls_existingArgList_constructor() =>
      checkCompleteFunctionCallInsertText(
        '''
        class Aaaaa {
          Aaaaa(int a);
        }
        void f(int aaa) {
          var a = new [!Aaa^!]()
        }
        ''',
        'Aaaaa(…)',
        editText: 'Aaaaa',
      );

  Future<void> test_completeFunctionCalls_existingArgList_expression() =>
      checkCompleteFunctionCallInsertText(
        '''
        int myFunction(String a, int b, {String c}) {
          var a = [!myFu^!]()
        }
        ''',
        'myFunction(…)',
        editText: 'myFunction',
      );

  Future<void> test_completeFunctionCalls_existingArgList_member_noPrefix() =>
      // https://github.com/Dart-Code/Dart-Code/issues/3672
      checkCompleteFunctionCallInsertText(
        '''
        class Aaaaa {
          static foo(int a) {}
        }
        void f() {
          Aaaaa.[!^!]()
        }
        ''',
        'foo(…)',
        editText: 'foo',
      );

  Future<void> test_completeFunctionCalls_existingArgList_namedConstructor() =>
      checkCompleteFunctionCallInsertText(
        '''
        class Aaaaa {
          Aaaaa.foo(int a);
        }
        void f() {
          var a = new Aaaaa.[!foo^!]()
        }
        ''',
        'foo(…)',
        editText: 'foo',
      );

  Future<void> test_completeFunctionCalls_existingArgList_statement() =>
      checkCompleteFunctionCallInsertText(
        '''
        void f(int a) {
          [!f^!]()
        }
        ''',
        'f(…)',
        editText: 'f',
      );

  Future<void> test_completeFunctionCalls_existingArgList_suggestionSets() =>
      checkCompleteFunctionCallInsertText(
        '''
        void f(int a) {
          [!pri^!]()
        }
        ''',
        'print(…)',
        editText: 'print',
      );

  Future<void> test_completeFunctionCalls_existingPartialArgList() =>
      checkCompleteFunctionCallInsertText(
        '''
        class Aaaaa {
          Aaaaa(int a);
        }
        void f(int aaa) {
          var a = new [!Aaa^!](
        }
        ''',
        'Aaaaa(…)',
        editText: 'Aaaaa',
      );

  Future<void> test_completeFunctionCalls_expression() =>
      checkCompleteFunctionCallInsertText(
        '''
        int myFunction(String a, int b, {String c}) {
          var a = [!myFu^!]
        }
        ''',
        'myFunction(…)',
        insertTextFormat: InsertTextFormat.Snippet,
        editText: r'myFunction(${1:a}, ${2:b})',
      );

  Future<void> test_completeFunctionCalls_flutterSetState() async {
    // Flutter's setState method has special handling inside SuggestionBuilder
    // that already adds in a selection (which overlaps with completeFunctionCalls).
    // Ensure we don't end up with two sets of parens/placeholders in this case.
    var content = '''
import 'package:flutter/material.dart';

class MyWidget extends StatefulWidget {
  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  @override
  Widget build(BuildContext context) {
    [!setSt^!]
    return const Placeholder();
  }
}
''';

    setCompletionItemSnippetSupport();
    await provideConfig(initialize, {'completeFunctionCalls': true});
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    var item = res.singleWhere((c) => c.label.startsWith('setState('));

    // Usually the label would be "setState(…)" but here it's slightly different
    // to indicate a full statement is being inserted.
    expect(item.label, equals('setState(() {});'));

    // Ensure the snippet comes through in the expected format with the expected
    // placeholders.
    expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
    expect(item.insertText, isNull);
    var textEdit = toTextEdit(item.textEdit!);
    expect(textEdit.newText, 'setState(() {\n      \$0\n    });');
    expect(textEdit.range, equals(code.range.range));
  }

  Future<void> test_completeFunctionCalls_namedConstructor() =>
      checkCompleteFunctionCallInsertText(
        '''
        class Aaaaa {
          Aaaaa.foo(int a);
        }
        void f() {
          var a = new Aaaaa.[!foo^!]
        }
        ''',
        'foo(…)',
        insertTextFormat: InsertTextFormat.Snippet,
        editText: r'foo(${0:a})',
      );

  Future<void> test_completeFunctionCalls_noParameters() async {
    var content = '''
    void myFunction() {}

    void f() {
      [!myFu^!]
    }
''';

    await checkCompleteFunctionCallInsertText(
      content,
      'myFunction()',
      editText: 'myFunction()',
      insertTextFormat: InsertTextFormat.Snippet,
    );
  }

  Future<void> test_completeFunctionCalls_optionalParameters() async {
    var content = '''
    void myFunction({int a}) {}

    void f() {
      [!myFu^!]
    }
''';

    await checkCompleteFunctionCallInsertText(
      content,
      'myFunction(…)',
      // With optional params, there should still be parens/tab stop inside.
      editText: r'myFunction($0)',
      insertTextFormat: InsertTextFormat.Snippet,
    );
  }

  Future<void> test_completeFunctionCalls_requiredNamed() async {
    var content = '''
    void myFunction(String a, int b, {required String c, String d = ''}) {}

    void f() {
      [!myFu^!]
    }
''';

    setCompletionItemSnippetSupport();
    await provideConfig(initialize, {'completeFunctionCalls': true});
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    var item = res.singleWhere((c) => c.label == 'myFunction(…)');
    // Ensure the snippet comes through in the expected format with the expected
    // placeholders.
    expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
    expect(item.insertText, isNull);
    var textEdit = toTextEdit(item.textEdit!);
    expect(textEdit.newText, r'myFunction(${1:a}, ${2:b}, c: ${3:c})');
    expect(textEdit.range, equals(code.range.range));
  }

  Future<void> test_completeFunctionCalls_requiredNamed_suggestionSet() async {
    var otherFile = join(projectFolderPath, 'lib', 'other.dart');
    newFile(
      otherFile,
      "void myFunction(String a, int b, {required String c, String d = ''}) {}",
    );
    var content = '''
    void f() {
      [!myFu^!]
    }
''';

    setCompletionItemSnippetSupport();
    await provideConfig(initialize, {'completeFunctionCalls': true});
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletion(mainFileUri, code.position.position);
    var item = res.singleWhere((c) => c.label == 'myFunction(…)');
    // Ensure the snippet comes through in the expected format with the expected
    // placeholders.
    expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
    expect(item.insertText, isNull);
    expect(item.textEdit, isNotNull);
    var originalTextEdit = item.textEdit;

    // Ensure the item can be resolved and retains the correct textEdit (since
    // textEdit may be recomputed during resolve).
    var resolved = await resolveCompletion(item);
    expect(resolved.insertText, isNull);
    expect(resolved.textEdit, originalTextEdit);
    var textEdit = toTextEdit(resolved.textEdit!);
    expect(textEdit.newText, r'myFunction(${1:a}, ${2:b}, c: ${3:c})');
    expect(textEdit.range, equals(code.range.range));
  }

  Future<void>
      test_completeFunctionCalls_resolve_producesCorrectEditWithoutInsertText() async {
    // Ensure our `resolve` call does not rely on the presence of `insertText`
    // to compute the correct edits. This is something we did incorrectly in the
    // past and broke with
    // https://github.com/dart-lang/sdk/commit/40e25ebad0bd008615b1c1d8021cb27839f00dcd
    // because the way these are combined in the VS Code LSP client means we are
    // not provided both `insertText` and `textEdit` back in the resolve call.
    //
    // Now, we never supply `insertText` and always use `textEdit`.
    var content = '''
final a = Stri^
''';

    /// Helper to verify a completion is as expected.
    void expectCorrectCompletion(CompletionItem item) {
      // Ensure this completion looks as we'd expect.
      expect(item.label, 'String.fromCharCode(…)');
      expect(item.insertText, isNull);
      expect(
        item.textEdit!.map((edit) => edit.newText, (edit) => edit.newText),
        r'String.fromCharCode(${0:charCode})',
      );
    }

    setCompletionItemSnippetSupport();
    await provideConfig(initialize, {'completeFunctionCalls': true});
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletion(mainFileUri, code.position.position);

    var completion =
        res.singleWhere((c) => c.label == 'String.fromCharCode(…)');
    expectCorrectCompletion(completion);

    var resolved = await resolveCompletion(completion);
    expectCorrectCompletion(resolved);
  }

  Future<void> test_completeFunctionCalls_show() async {
    var content = '''
    import 'dart:math' show mi^
''';

    setCompletionItemSnippetSupport();
    await provideConfig(initialize, {'completeFunctionCalls': true});
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    var item = res.singleWhere((c) => c.label == 'min(…)');
    // The insert text should be a simple string with no parens/args and
    // no need for snippets.
    expect(item.insertTextFormat, isNull);
    expect(item.insertText, isNull);
    var textEdit = toTextEdit(item.textEdit!);
    expect(textEdit.newText, r'min');
  }

  Future<void> test_completeFunctionCalls_statement() =>
      checkCompleteFunctionCallInsertText(
        '''
        void f(int a) {
          [!f^!]
        }
        ''',
        'f(…)',
        insertTextFormat: InsertTextFormat.Snippet,
        editText: r'f(${0:a})',
      );

  Future<void> test_completeFunctionCalls_suggestionSets() =>
      checkCompleteFunctionCallInsertText(
        '''
        void f(int a) {
          [!pri^!]
        }
        ''',
        'print(…)',
        insertTextFormat: InsertTextFormat.Snippet,
        editText: r'print(${0:object})',
      );

  Future<void> test_completionKinds_default() async {
    newFile(join(projectFolderPath, 'file.dart'), '');
    newFolder(join(projectFolderPath, 'folder'));

    var content = "import '^';";

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);

    var file = res.singleWhere((c) => c.label == 'file.dart');
    var folder = res.singleWhere((c) => c.label == 'folder/');
    var builtin = res.singleWhere((c) => c.label == 'dart:core');
    // Default capabilities include File + Module but not Folder.
    expect(file.kind, equals(CompletionItemKind.File));
    // We fall back to Module if Folder isn't supported.
    expect(folder.kind, equals(CompletionItemKind.Module));
    expect(builtin.kind, equals(CompletionItemKind.Module));
  }

  Future<void> test_completionKinds_imports() async {
    // Tell the server we support some specific CompletionItemKinds.
    setCompletionItemKinds([
      CompletionItemKind.File,
      CompletionItemKind.Folder,
      CompletionItemKind.Module,
    ]);

    var content = "import '^';";

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);

    var file = res.singleWhere((c) => c.label == 'file.dart');
    var folder = res.singleWhere((c) => c.label == 'folder/');
    var builtin = res.singleWhere((c) => c.label == 'dart:core');
    expect(file.kind, equals(CompletionItemKind.File));
    expect(folder.kind, equals(CompletionItemKind.Folder));
    expect(builtin.kind, equals(CompletionItemKind.Module));
  }

  Future<void> test_completionKinds_supportedSubset() async {
    // Tell the server we only support the Field CompletionItemKind.
    setCompletionItemKinds([CompletionItemKind.Field]);

    var content = '''
    class MyClass {
      String abcdefghij;
    }

    void f() {
      MyClass a;
      a.abc^
    }
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    var kinds = res.map((item) => item.kind).toList();

    // Ensure we only get nulls or Fields (the sample code contains Classes).
    expect(
      kinds,
      everyElement(anyOf(isNull, equals(CompletionItemKind.Field))),
    );
  }

  Future<void> test_completionTrigger_brace_block() async {
    // Brace should not trigger completion if a normal code block.
    var content = r'''
    main () {^}
''';
    await _checkResultsForTriggerCharacters(content, ['{'], isEmpty);
  }

  Future<void>
      test_completionTrigger_brace_interpolatedStringExpression() async {
    // Brace should trigger completion if at the start of an interpolated expression
    var content = r'''
    var a = '${^';
''';
    await _checkResultsForTriggerCharacters(content, [r'{'], isNotEmpty);
  }

  Future<void> test_completionTrigger_brace_rawString() async {
    // Brace should not trigger completion if in a raw string.
    var content = r'''
    var a = r'${^';
''';
    await _checkResultsForTriggerCharacters(content, [r'{'], isEmpty);
  }

  Future<void> test_completionTrigger_brace_string() async {
    // Brace should not trigger completion if not at the start of an interpolated
    // expression.
    var content = r'''
    var a = '{^';
''';
    await _checkResultsForTriggerCharacters(content, [r'{'], isEmpty);
  }

  Future<void> test_completionTrigger_colon_argument() async {
    // Colons should trigger completion after argument names.
    var content = r'''
void f({int? a}) {
  f(a:^
}
''';
    await _checkResultsForTriggerCharacters(content, [r':'], isNotEmpty);
  }

  Future<void> test_completionTrigger_colon_case() async {
    // Colons should not trigger completion in a switch case.
    var content = r'''
void f(int a) {
  switch (a) {
    case:^
  }
}
''';
    await _checkResultsForTriggerCharacters(content, [r':'], isEmpty);
  }

  Future<void> test_completionTrigger_colon_default() async {
    // Colons should not trigger completion in a switch case.
    var content = r'''
void f(int a) {
  switch (a) {
    default:^
  }
}
''';
    await _checkResultsForTriggerCharacters(content, [r':'], isEmpty);
  }

  Future<void> test_completionTrigger_colon_import() async {
    // Colons should trigger completion after argument names.
    var content = r'''
import 'package:^';
''';
    await _checkResultsForTriggerCharacters(content, [r':'], isNotEmpty);
  }

  Future<void> test_completionTrigger_quotes_endingString() async {
    // Completion triggered by a quote ending a string should not return results.
    var content = "foo(''^);";
    await _checkResultsForTriggerCharacters(content, ["'", '"'], isEmpty);
  }

  Future<void> test_completionTrigger_quotes_startingImport() async {
    // Completion triggered by a quote for import should return results.
    var content = "import '^'";
    await _checkResultsForTriggerCharacters(content, ["'", '"'], isNotEmpty);
  }

  Future<void> test_completionTrigger_quotes_startingString() async {
    // Completion triggered by a quote for normal string should not return results.
    var content = "foo('^');";
    await _checkResultsForTriggerCharacters(content, ["'", '"'], isEmpty);
  }

  Future<void> test_completionTrigger_quotes_terminatingImport() async {
    // Completion triggered by a quote ending an import should not return results.
    var content = "import ''^";
    await _checkResultsForTriggerCharacters(content, ["'", '"'], isEmpty);
  }

  Future<void> test_completionTrigger_slash_directivePath() async {
    // Slashes should trigger completion when typing in directive paths, eg.
    // after typing 'package:foo/' completion should give the next folder segments.
    var content = r'''
    import 'package:test/^';
''';
    await _checkResultsForTriggerCharacters(content, [r'/'], isNotEmpty);
  }

  Future<void> test_completionTrigger_slash_divide() async {
    // Slashes should not trigger completion when typing in a normal expression.
    var content = r'''
    var a = 1 /^
''';
    await _checkResultsForTriggerCharacters(content, [r'/'], isEmpty);
  }

  Future<void> test_completionTriggerKinds_invalidParams() async {
    await initialize();

    var invalidTriggerKind = CompletionTriggerKind.fromJson(-1);
    var request = getCompletion(
      mainFileUri,
      Position(line: 0, character: 0),
      context: CompletionContext(
          triggerKind: invalidTriggerKind, triggerCharacter: 'A'),
    );

    await expectLater(
        request, throwsA(isResponseError(ErrorCodes.InvalidParams)));
  }

  Future<void> test_concurrentRequestsCancellation() async {
    // We expect a new completion request to cancel any in-flight request so
    // send multiple without awaiting, then check only the last one completes.
    var code = TestCode.empty;

    await initialize();
    await openFile(mainFileUri, code.code);
    var position = code.position.position;

    // Use a completer to force the requests to overlap without races.
    var completer = Completer<void>();
    CompletionHandler.delayAfterResolveForTests = completer.future;
    try {
      var responseFutures = [
        getCompletion(mainFileUri, position),
        getCompletion(mainFileUri, position),
        getCompletion(mainFileUri, position),
      ];

      // Ensure all requests started, then let them continue.
      await pumpEventQueue(times: 5000);
      completer.complete();

      expect(responseFutures[0],
          throwsA(isResponseError(ErrorCodes.RequestCancelled)));
      expect(responseFutures[1],
          throwsA(isResponseError(ErrorCodes.RequestCancelled)));
      var results = await responseFutures[2];
      expect(results, isNotEmpty);
    } finally {
      CompletionHandler.delayAfterResolveForTests = null;
    }
  }

  Future<void> test_dartDocPreference_full() =>
      assertDocumentation('full', includesSummary: true, includesFull: true);

  Future<void> test_dartDocPreference_none() =>
      assertDocumentation('none', includesSummary: false, includesFull: false);

  Future<void> test_dartDocPreference_summary() =>
      assertDocumentation('summary',
          includesSummary: true, includesFull: false);

  /// No preference should result in full docs.
  Future<void> test_dartDocPreference_unset() =>
      assertDocumentation(null, includesSummary: true, includesFull: true);

  Future<void> test_filterText_constructorParens() async {
    // Constructor parens should not be included in filterText.
    var content = '''
class MyClass {}

void f() {
  MyClass a = new MyCla^
}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res.any((c) => c.label == 'MyClass()'), isTrue);
    var item = res.singleWhere((c) => c.label == 'MyClass()');

    // filterText is set explicitly because it's not the same as label.
    expect(item.filterText, 'MyClass');

    // The text in the edit should also not contain the parens.
    var textEdit = toTextEdit(item.textEdit!);
    expect(textEdit.newText, 'MyClass');
  }

  Future<void> test_filterText_override_getter() async {
    // Some completions (eg. overrides) have additional text that is not part
    // of the label. That text should _not_ appear in filterText as it will
    // affect the editors relevance ranking as the user types.
    // https://github.com/dart-lang/sdk/issues/45157
    var content = '''
abstract class Person {
  String get name;
}

class Student extends Person {
  nam^
}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    var item = res.singleWhere((c) => c.label == 'name => …');
    // filterText is set explicitly because it's not the same as label.
    expect(item.filterText, 'name');
  }

  Future<void> test_filterText_override_method() async {
    // Some completions (eg. overrides) have additional text that is not part
    // of the label. That text should _not_ appear in filterText as it will
    // affect the editors relevance ranking as the user types.
    // https://github.com/dart-lang/sdk/issues/45157
    var content = '''
abstract class Base {
  void myMethod() {};
}

class BaseImpl extends Base {
  myMet^
}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    var item = res.singleWhere((c) => c.label == 'myMethod() { … }');
    // filterText is set explicitly because it's not the same as label.
    expect(item.filterText, 'myMethod');
  }

  Future<void> test_fromPlugin_dartFile() async {
    if (!AnalysisServer.supportsPlugins) return;
    var code = TestCode.parse('''
    void f() {
      var x = '';
      print(^);
    }
''');

    var pluginResult = plugin.CompletionGetSuggestionsResult(
      code.position.offset,
      0,
      [
        plugin.CompletionSuggestion(
          plugin.CompletionSuggestionKind.INVOCATION,
          100,
          'x.toUpperCase()',
          -1,
          -1,
          false,
          false,
        ),
      ],
    );
    configureTestPlugin(respondWith: pluginResult);

    await initialize();
    await openFile(mainFileUri, code.code);

    var res = await getCompletion(mainFileUri, code.position.position);
    var fromServer = res.singleWhere((c) => c.label == 'x');
    var fromPlugin = res.singleWhere((c) => c.label == 'x.toUpperCase()');

    expect(fromServer.kind, equals(CompletionItemKind.Variable));
    expect(fromPlugin.kind, equals(CompletionItemKind.Method));
  }

  Future<void> test_fromPlugin_dartFile_withImports() async {
    if (!AnalysisServer.supportsPlugins) return;
    var code = TestCode.parse('''
void f() {
  ^
}
''');

    var pluginResult = plugin.CompletionGetSuggestionsResult(
      code.position.offset,
      0,
      [
        plugin.CompletionSuggestion(
          plugin.CompletionSuggestionKind.IDENTIFIER,
          100,
          'fooFromDartIO',
          -1,
          -1,
          false,
          false,
          libraryUri: 'dart:io',
          isNotImported: true,
        ),
      ],
    );
    configureTestPlugin(respondWith: pluginResult);

    await initialize();
    await openFile(mainFileUri, code.code);

    var items = await getCompletion(mainFileUri, code.position.position);
    var item = items.singleWhere((c) => c.label == 'fooFromDartIO');
    var resolved = await resolveCompletion(item);

    // Apply both the main completion edit and the additionalTextEdits atomically.
    var newContent = applyTextEdits(
      code.code,
      [toTextEdit(resolved.textEdit!)]
          .followedBy(resolved.additionalTextEdits!)
          .toList(),
    );

    // Ensure the plugin-supplied import was added.
    expect(newContent, equals('''
import 'dart:io';

void f() {
  fooFromDartIO
}
'''));
  }

  Future<void> test_fromPlugin_nonDartFile() async {
    if (!AnalysisServer.supportsPlugins) return;
    var pluginAnalyzedFilePath = join(projectFolderPath, 'lib', 'foo.foo');
    var pluginAnalyzedFileUri = pathContext.toUri(pluginAnalyzedFilePath);
    var code = TestCode.parse('''
    CREATE TABLE foo (
      id INTEGER NOT NULL PRIMARY KEY
    );

    query: SELECT ^ FROM foo;
''');

    var pluginResult = plugin.CompletionGetSuggestionsResult(
      code.position.offset,
      0,
      [
        plugin.CompletionSuggestion(
          plugin.CompletionSuggestionKind.IDENTIFIER,
          100,
          'id',
          -1,
          -1,
          false,
          false,
        ),
      ],
    );
    configureTestPlugin(respondWith: pluginResult);

    await initialize();
    await openFile(pluginAnalyzedFileUri, code.code);
    var res =
        await getCompletion(pluginAnalyzedFileUri, code.position.position);

    expect(res, hasLength(1));
    var suggestion = res.single;

    expect(suggestion.kind, CompletionItemKind.Variable);
    expect(suggestion.label, equals('id'));
  }

  Future<void> test_fromPlugin_tooSlow() async {
    if (!AnalysisServer.supportsPlugins) return;
    var code = TestCode.parse('''
    void f() {
      var x = '';
      print(^);
    }
''');

    var pluginResult = plugin.CompletionGetSuggestionsResult(
      code.position.offset,
      0,
      [
        plugin.CompletionSuggestion(
          plugin.CompletionSuggestionKind.INVOCATION,
          100,
          'x.toUpperCase()',
          -1,
          -1,
          false,
          false,
        ),
      ],
    );
    configureTestPlugin(
      respondWith: pluginResult,
      // Don't respond within an acceptable time
      respondAfter: Duration(seconds: 1),
    );

    await initialize();
    await openFile(mainFileUri, code.code);

    var res = await getCompletion(mainFileUri, code.position.position);
    var fromServer = res.singleWhere((c) => c.label == 'x');
    var fromPlugin = res.singleWhereOrNull((c) => c.label == 'x.toUpperCase()');

    // Server results should still be included.
    expect(fromServer.kind, equals(CompletionItemKind.Variable));
    // Plugin results are not because they didn't arrive in time.
    expect(fromPlugin, isNull);
  }

  /// Check that narrowing a type from String? to String in a subclass includes
  /// the correct narrowed type in the `detail` field.
  ///
  /// https://github.com/Dart-Code/Dart-Code/issues/4499
  Future<void> test_getter_narrowedBySubclass() async {
    var content = '''
void f(MyItem item) {
  item.na^
}

abstract class NullableName {
  String? get name;
}

abstract class NotNullableName implements NullableName {
  @override
  String get name;
}

abstract class MyItem implements NotNullableName, NullableName {}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    var name = res.singleWhere((c) => c.label == 'name');
    expect(name.detail, equals('String'));
  }

  Future<void> test_gettersAndSetters() async {
    var content = '''
    class MyClass {
      String get justGetter => '';
      set justSetter(String value) {}
      String get getterAndSetter => '';
      set getterAndSetter(String value) {}
    }

    void f() {
      MyClass a;
      a.^
    }
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    var getter = res.singleWhere((c) => c.label == 'justGetter');
    var setter = res.singleWhere((c) => c.label == 'justSetter');
    var both = res.singleWhere((c) => c.label == 'getterAndSetter');
    expect(getter.detail, equals('String'));
    expect(setter.detail, equals('String'));
    expect(both.detail, equals('String'));
    for (var item in [getter, setter, both]) {
      expect(item.kind, equals(CompletionItemKind.Property));
    }
  }

  Future<void> test_import() async {
    var content = '''
import '^';
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res.any((c) => c.label == 'dart:async'), isTrue);
  }

  Future<void> test_import_configuration() async {
    var content = '''
import 'dart:core' if (dart.library.io) '^';
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res.any((c) => c.label == 'dart:async'), isTrue);
  }

  Future<void> test_import_configuration_eof() async {
    var content = '''
import 'dart:core' if (dart.library.io) '^
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res.any((c) => c.label == 'dart:async'), isTrue);
  }

  Future<void> test_import_configuration_partial() async {
    var content = '''
import 'dart:core' if (dart.library.io) 'dart:^';
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res.any((c) => c.label == 'dart:async'), isTrue);
  }

  Future<void> test_import_eof() async {
    var content = '''
import '^
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res.any((c) => c.label == 'dart:async'), isTrue);
  }

  Future<void> test_import_partial() async {
    var content = '''
import 'dart:^';
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res.any((c) => c.label == 'dart:async'), isTrue);
  }

  Future<void> test_insertReplaceRanges() async {
    setCompletionItemInsertReplaceSupport();

    var content = '''
    class MyClass {
      String abcdefghij;
    }

    void f() {
      MyClass a;
      a.abc^def
    }
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res.any((c) => c.label == 'abcdefghij'), isTrue);
    var item = res.singleWhere((c) => c.label == 'abcdefghij');
    // When using the replacement range, we should get exactly the symbol
    // we expect.
    var replaced = applyTextEdits(
      code.code,
      [textEditForReplace(item.textEdit!)],
    );
    expect(replaced, contains('a.abcdefghij\n'));
    // When using the insert range, we should retain what was after the caret
    // ("def" in this case).
    var inserted = applyTextEdits(
      code.code,
      [textEditForInsert(item.textEdit!)],
    );
    expect(inserted, contains('a.abcdefghijdef\n'));
  }

  Future<void> test_insertTextMode_multiline() async {
    setCompletionItemInsertTextModeSupport();
    var content = '''
    import 'package:flutter/material.dart';

    class _MyWidgetState extends State<MyWidget> {
      @override
      Widget build(BuildContext context) {
        [!setSt^!]
        return const Placeholder();
      }
    }
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    var item = res.singleWhere((c) => c.label.startsWith('setState'));

    // Multiline completions should always set insertTextMode.asIs.
    expect(item.insertText, isNull);
    var textEdit = toTextEdit(item.textEdit!);
    expect(textEdit.newText, contains('\n'));
    expect(item.insertTextMode, equals(InsertTextMode.asIs));
  }

  Future<void> test_insertTextMode_singleLine() async {
    setCompletionItemInsertTextModeSupport();

    var content = '''
    void foo() {
      ^
    }
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    var item = res.singleWhere((c) => c.label.startsWith('foo'));

    // Single line completions should never set insertTextMode.asIs to
    // avoid bloating payload size where it wouldn't matter.
    expect(item.insertText, isNull);
    var textEdit = toTextEdit(item.textEdit!);
    expect(textEdit.newText, isNot(contains('\n')));
    expect(item.insertTextMode, isNull);
  }

  Future<void> test_insideString() async {
    var content = '''
    var a = "This is ^a test"
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res, isEmpty);
  }

  Future<void> test_isDeprecated_notSupported() async {
    var content = '''
    class MyClass {
      @deprecated
      String abcdefghij;
    }

    void f() {
      MyClass a;
      a.abc^
    }
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    var item = res.singleWhere((c) => c.label == 'abcdefghij');
    expect(item.deprecated, isNull);
    // If the does not say it supports the deprecated flag, we should show
    // '(deprecated)' in the details.
    expect(item.detail!.toLowerCase(), contains('deprecated'));
  }

  Future<void> test_isDeprecated_supportedFlag() async {
    setCompletionItemDeprecatedFlagSupport();
    var content = '''
    class MyClass {
      @deprecated
      String abcdefghij;
    }

    void f() {
      MyClass a;
      a.abc^
    }
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    var item = res.singleWhere((c) => c.label == 'abcdefghij');
    expect(item.deprecated, isTrue);
    // If the client says it supports the deprecated flag, we should not show
    // deprecated in the details.
    expect(item.detail, isNot(contains('deprecated')));
  }

  Future<void> test_isDeprecated_supportedTag() async {
    setCompletionItemTagSupport([CompletionItemTag.Deprecated]);

    var content = '''
    class MyClass {
      @deprecated
      String abcdefghij;
    }

    void f() {
      MyClass a;
      a.abc^
    }
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    var item = res.singleWhere((c) => c.label == 'abcdefghij');
    expect(item.tags, contains(CompletionItemTag.Deprecated));
    // If the client says it supports the deprecated tag, we should not show
    // deprecated in the details.
    expect(item.detail, isNot(contains('deprecated')));
  }

  Future<void> test_isIncomplete_falseIfAllIncluded() async {
    var content = '''
import 'a.dart';
void f() {
  A a = A();
  a.^
}
''';
    var code = TestCode.parse(content);

    // Create a class with fields aaa1 to aaa500 in the other file.
    newFile(
      join(projectFolderPath, 'lib', 'a.dart'),
      [
        'class A {',
        for (var i = 1; i <= 500; i++) 'String get aaa$i => "";',
        '}',
      ].join('\n'),
    );

    await initialize();
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletionList(mainFileUri, code.position.position);

    // Expect everything (hashCode etc. will take it over 500).
    expect(res.items, hasLength(greaterThanOrEqualTo(500)));
    expect(res.isIncomplete, isFalse);
  }

  Future<void> test_isIncomplete_trueIfNotAllIncluded() async {
    var content = '''
import 'a.dart';
void f() {
  A a = A();
  a.^
}
''';
    var code = TestCode.parse(content);

    // Create a class with fields aaa1 to aaa500 in the other file.
    newFile(
      join(projectFolderPath, 'lib', 'a.dart'),
      [
        'class A {',
        for (var i = 1; i <= 500; i++) '  String get aaa$i => "";',
        '  String get aaa => "";',
        '}',
      ].join('\n'),
    );

    await provideConfig(initialize, {'maxCompletionItems': 200});
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletionList(mainFileUri, code.position.position);

    // Should be capped at 200 and marked as incomplete.
    expect(res.items, hasLength(200));
    expect(res.isIncomplete, isTrue);

    // Also ensure 'aaa' is included, since relevance sorting should have
    // put it at the top.
    expect(res.items.map((item) => item.label).contains('aaa'), isTrue);
  }

  Future<void> test_itemDefaults_editRange() async {
    setCompletionItemInsertReplaceSupport();
    setCompletionListDefaults(['editRange']);

    var content = '''
void myFunction() {
  [!myFunctio^!]
}
''';
    var code = TestCode.parse(content);

    await initialize();
    await openFile(mainFileUri, code.code);
    var list = await getCompletionList(mainFileUri, code.position.position);
    var item = list.items.singleWhere((c) => c.label.startsWith('myFunction'));
    var defaultEditRange = list.itemDefaults!.editRange!.map(
      (insertReplace) => throw 'Expected Range, got CompletionItemEditRange',
      (range) => range,
    );

    // Range covers the ranged marked with [!braces!] in `content`.
    expect(defaultEditRange, code.range.range);

    // Item should use the default range.
    expectUsesDefaultEditRange(item, 'myFunction');
  }

  Future<void> test_itemDefaults_editRange_includesNonDefaultItem() async {
    setCompletionItemInsertReplaceSupport();
    setCompletionListDefaults(['editRange']);

    // In this code, we will get two completions with different edit ranges:
    //
    //   - 'b: ' will have a zero-width range because names don't replace args
    //   -  'a' will replace 'b'
    //
    // Therefore we expect 'a' to use the default range (and not have its own)
    // but 'b'` to have its own.
    //
    // Additionally, because the caret is before the identifier, we will have
    // separate default insert/replace ranges.
    var content = '''
void f(String a, {String? b}) {
  f([!^b!]);
}
''';
    var code = TestCode.parse(content);

    await initialize();
    await openFile(mainFileUri, code.code);
    var list = await getCompletionList(mainFileUri, code.position.position);
    var itemA = list.items.singleWhere((c) => c.label == 'a');
    var itemB = list.items.singleWhere((c) => c.label == 'b: ');

    // Default replace range should span `b`.
    var expectedRange = code.range.range;
    var defaultEditRange = list.itemDefaults!.editRange!.map(
      (insertReplace) => insertReplace,
      (range) => throw 'Expected Range, got CompletionItemEditRange',
    );
    expect(defaultEditRange.replace, equals(expectedRange));

    // Default insert range should be in front of `b`.
    expect(
      defaultEditRange.insert,
      Range(start: expectedRange.start, end: expectedRange.start),
    );

    // And item A should use that default.
    expectUsesDefaultEditRange(itemA, 'a');

    // Item B should have its own range, which is a single range for both
    // insert and replace that matches the insert range (in front of `b`) of
    // the default.
    var itemBTextEdit = toTextEdit(itemB.textEdit!);
    expect(itemBTextEdit.range, defaultEditRange.insert);
    expect(itemBTextEdit.newText, 'b: ');
  }

  Future<void> test_itemDefaults_textMode() async {
    setCompletionItemInsertTextModeSupport();
    setCompletionListDefaults(['insertTextMode']);

    // We only normally set InsertTextMode on multiline completions (where it
    // matters), so ensure there's a multiline completion in the results for
    // testing.
    var content = '''
import 'package:flutter/material.dart';

class _MyWidgetState extends State<MyWidget> {
  @override
  Widget build(BuildContext context) {
    [!setSt^!]
    return const Placeholder();
  }
}
''';
    var code = TestCode.parse(content);

    await initialize();
    await openFile(mainFileUri, code.code);
    var list = await getCompletionList(mainFileUri, code.position.position);
    var item = list.items.singleWhere((c) => c.label.startsWith('setState'));

    // Default should be set.
    expect(list.itemDefaults?.insertTextMode, InsertTextMode.asIs);
    // Item should not.
    expect(item.insertTextMode, isNull);
  }

  /// Exact matches should always be included when completion lists are
  /// truncated, even if they ranked poorly.
  Future<void> test_maxCompletionItems_doesNotExcludeExactMatches() async {
    var content = '''
import 'a.dart';
void f() {
  var a = Item^
}
''';
    var code = TestCode.parse(content);

    // Create classes `Item1` to `Item20` along with a field named `item`.
    // The classes will rank higher in the position above and push
    // the field out without an exception to include exact matches.
    newFile(
      join(projectFolderPath, 'lib', 'a.dart'),
      [
        'String item = "";',
        for (var i = 1; i <= 20; i++) 'class Item$i {}',
      ].join('\n'),
    );

    await provideConfig(initialize, {'maxCompletionItems': 10});
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletionList(mainFileUri, code.position.position);

    // We expect 11 items, because the exact match was not in the top 10 and
    // was included additionally.
    expect(res.items, hasLength(11));
    expect(res.isIncomplete, isTrue);

    // Ensure the 'Item' field is included.
    expect(
      res.items.map((item) => item.label),
      contains('item'),
    );
  }

  /// Snippet completions should be kept when maxCompletionItems truncates
  /// because they are not ranked like other completions and might be
  /// truncated when they are exactly what the user wants.
  Future<void> test_maxCompletionItems_doesNotExcludeSnippets() async {
    var content = '''
import 'a.dart';
void f() {
  fo^
}
''';
    var code = TestCode.parse(content);

    // Create fields for1 to for20 in the other file.
    newFile(
      join(projectFolderPath, 'lib', 'a.dart'),
      [
        for (var i = 1; i <= 20; i++) 'String for$i = ' ';',
      ].join('\n'),
    );

    setCompletionItemSnippetSupport();
    await provideConfig(initialize, {'maxCompletionItems': 10});
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletionList(mainFileUri, code.position.position);

    // Should be capped at 10 and marked as incomplete.
    expect(res.items, hasLength(10));
    expect(res.isIncomplete, isTrue);

    // Ensure the 'for' snippet is included.
    expect(
      res.items
          .where((item) => item.kind == CompletionItemKind.Snippet)
          .map((item) => item.label)
          .contains('for'),
      isTrue,
    );
  }

  Future<void> test_namedArg_flutterChildren() async {
    var content = '''
import 'package:flutter/widgets.dart';

final a = Flex(c^);
''';

    var expectedContent = '''
import 'package:flutter/widgets.dart';

final a = Flex(children: [^],);
''';

    await verifyCompletions(
      mainFileUri,
      content,
      expectCompletions: ['children: []'],
      applyEditsFor: 'children: []',
      expectedContent: expectedContent,
    );
  }

  Future<void> test_namedArg_flutterChildren_existingValue() async {
    // Flutter's widget classes have special handling that adds `[]` after the
    // children named arg, but this should not occur if there's already a value
    // for this named arg.
    var content = '''
import 'package:flutter/widgets.dart';

final a = Flex(c^: []);
''';

    var expectedContent = '''
import 'package:flutter/widgets.dart';

final a = Flex(children: []);
''';

    await verifyCompletions(
      mainFileUri,
      content,
      expectCompletions: ['children'],
      applyEditsFor: 'children',
      expectedContent: expectedContent,
    );
  }

  Future<void> test_namedArg_insertReplaceRanges() async {
    /// Helper to check multiple completions in the same template file.
    Future<void> check(
      String code,
      String expectedLabel, {
      required String expectedReplace,
      required String expectedInsert,
    }) async {
      var content = '''
class A { const A({int argOne, int argTwo, String argThree}); }
final varOne = '';
$code
void f() { }
''';
      var expectedReplaced = '''
class A { const A({int argOne, int argTwo, String argThree}); }
final varOne = '';
$expectedReplace
void f() { }
''';
      var expectedInserted = '''
class A { const A({int argOne, int argTwo, String argThree}); }
final varOne = '';
$expectedInsert
void f() { }
''';

      await verifyCompletions(
        mainFileUri,
        content,
        expectCompletions: [expectedLabel],
        applyEditsFor: expectedLabel,
        verifyInsertReplaceRanges: true,
        expectedContent: expectedReplaced,
        expectedContentIfInserting: expectedInserted,
      );
    }

    // When at the start of the identifier, it will be set as the replacement
    // range so we don't expect the ': ,'
    await check(
      '@A(^argOne: 1)',
      'argTwo',
      expectedReplace: '@A(argTwo: 1)',
      expectedInsert: '@A(argTwoargOne: 1)',
    );

    // When adding a name to an existing value, it should always insert.
    await check(
      '@A(^1)',
      'argOne: ',
      expectedReplace: '@A(argOne: 1)',
      expectedInsert: '@A(argOne: 1)',
    );

    // When adding a name to an existing variable, it should always insert.
    await check(
      '@A(argOne: 1, ^varOne)',
      'argTwo: ',
      expectedReplace: '@A(argOne: 1, argTwo: varOne)',
      expectedInsert: '@A(argOne: 1, argTwo: varOne)',
    );

    // // Inside the identifier also should be expected to replace.
    await check(
      '@A(arg^One: 1)',
      'argTwo',
      expectedReplace: '@A(argTwo: 1)',
      expectedInsert: '@A(argTwoOne: 1)',
    );

    // If there's a space, there's no replacement range so we should still get
    // the colon/comma since this is always an insert (and both operations will
    // produce the same text).
    await check(
      '@A(^ argOne: 1)',
      'argTwo: ',
      expectedReplace: '@A(argTwo: ^, argOne: 1)',
      expectedInsert: '@A(argTwo: ^, argOne: 1)',
    );

    // Partially typed names in front of values (that aren't considered part of
    // the same identifier) should also suggest name labels.
    await check(
      '''@A(argOne: 1, argTh^'Foo')''',
      'argThree: ',
      expectedReplace: '''@A(argOne: 1, argThree: 'Foo')''',
      expectedInsert: '''@A(argOne: 1, argThree: 'Foo')''',
    );
  }

  Future<void> test_namedArg_offsetBeforeCompletionTarget() async {
    // This test checks for a previous bug where the completion target was a
    // symbol far after the cursor offset (`aaaa` here) and caused the whole
    // identifier to be used as the `targetPrefix` which would filter out
    // other symbol.
    // https://github.com/Dart-Code/Dart-Code/issues/2672#issuecomment-666085575
    var content = '''
    void f() {
      myFunction(
        ^
        aaaa: '',
      );
    }

    void myFunction({String aaaa, String aaab, String aaac}) {}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res.any((c) => c.label == 'aaab: '), isTrue);
  }

  Future<void> test_namedArg_plainText() async {
    var content = '''
    class A { const A({int one}); }
    @A(^)
    void f() { }
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res.any((c) => c.label == 'one: '), isTrue);
    var item = res.singleWhere((c) => c.label == 'one: ');
    expect(item.insertTextFormat,
        anyOf(equals(InsertTextFormat.PlainText), isNull));
    expect(item.insertText, isNull);
    var textEdit = toTextEdit(item.textEdit!);
    expect(textEdit.newText, item.label);
    var updated = applyTextEdits(
      code.code,
      [toTextEdit(item.textEdit!)],
    );
    expect(updated, contains('one: '));
  }

  Future<void> test_namedArg_snippetStringSelection_endOfString() async {
    var content = '''
    class A { const A({int one}); }
    @A(^)
    void f() { }
''';

    setCompletionItemSnippetSupport();
    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res.any((c) => c.label == 'one: '), isTrue);
    var item = res.singleWhere((c) => c.label == 'one: ');
    // As the selection is the end of the string, there's no need for a snippet
    // here. Since the insert text is also the same as the label, it does not
    // need to be provided.
    expect(item.insertTextFormat, isNull);
    expect(item.insertText, isNull);
    var textEdit = toTextEdit(item.textEdit!);
    expect(textEdit.newText, equals('one: '));
    expect(
      textEdit.range,
      equals(Range(start: code.position.position, end: code.position.position)),
    );
  }

  Future<void>
      test_namedArgTrailing_snippetStringSelection_insideString() async {
    var content = '''
    void f({int one, int two}) {
      f(
        ^
        two: 2,
      );
    }
''';

    setCompletionItemSnippetSupport();
    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res.any((c) => c.label == 'one: '), isTrue);
    var item = res.singleWhere((c) => c.label == 'one: ');
    // Ensure the snippet comes through in the expected format with the expected
    // placeholder.
    expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
    expect(item.insertText, isNull);
    var textEdit = toTextEdit(item.textEdit!);
    expect(textEdit.newText, equals(r'one: $0,'));
    expect(
      textEdit.range,
      equals(Range(start: code.position.position, end: code.position.position)),
    );
  }

  Future<void> test_nonAnalyzedFile() async {
    var readmeFilePath = convertPath(join(projectFolderPath, 'README.md'));
    newFile(readmeFilePath, '');
    await initialize();

    var res =
        await getCompletion(pathContext.toUri(readmeFilePath), startOfDocPos);
    expect(res, isEmpty);
  }

  Future<void> test_nullableTypes() async {
    var content = '''
    String? foo(int? a, [int b = 1]) {}

    void f() {
      fo^
    }
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletion(mainFileUri, code.position.position);

    var completion = res.singleWhere((c) => c.label.startsWith('foo'));
    expect(completion.detail, '(int? a, [int b = 1]) → String?');
  }

  Future<void> test_plainText() async {
    var content = '''
    class MyClass {
      String abcdefghij;
    }

    void f() {
      MyClass a;
      a.abc^
    }
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res.any((c) => c.label == 'abcdefghij'), isTrue);
    var item = res.singleWhere((c) => c.label == 'abcdefghij');
    expect(item.insertTextFormat,
        anyOf(equals(InsertTextFormat.PlainText), isNull));
    expect(item.insertText, anyOf(equals('abcdefghij'), isNull));
    var updated = applyTextEdits(
      code.code,
      [toTextEdit(item.textEdit!)],
    );
    expect(updated, contains('a.abcdefghij'));
  }

  Future<void> test_prefixed_enumMember() async {
    var content = '''
import 'main.dart' as self;

enum MyEnum {
  one,
  two,
}

void main() {
  final x = self.MyEnum.^
}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res.any((c) => c.label == 'one'), isTrue);
  }

  Future<void> test_prefixFilter_endOfSymbol() async {
    var content = '''
    class UniqueNamedClassForLspOne {}
    class UniqueNamedClassForLspTwo {}
    class UniqueNamedClassForLspThree {}

    void f() {
      // Should match only Two and Three
      UniqueNamedClassForLspT^
    }
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res.any((c) => c.label == 'UniqueNamedClassForLspOne'), isFalse);
    expect(res.any((c) => c.label == 'UniqueNamedClassForLspTwo'), isTrue);
    expect(res.any((c) => c.label == 'UniqueNamedClassForLspThree'), isTrue);
  }

  Future<void> test_prefixFilter_midSymbol() async {
    var content = '''
    class UniqueNamedClassForLspOne {}
    class UniqueNamedClassForLspTwo {}
    class UniqueNamedClassForLspThree {}

    void f() {
      // Should match only Two and Three
      UniqueNamedClassForLspT^hree
    }
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res.any((c) => c.label == 'UniqueNamedClassForLspOne'), isFalse);
    expect(res.any((c) => c.label == 'UniqueNamedClassForLspTwo'), isTrue);
    expect(res.any((c) => c.label == 'UniqueNamedClassForLspThree'), isTrue);
  }

  Future<void> test_prefixFilter_startOfSymbol() async {
    var content = '''
    class UniqueNamedClassForLspOne {}
    class UniqueNamedClassForLspTwo {}
    class UniqueNamedClassForLspThree {}

    void f() {
      // Should match all three
      ^UniqueNamedClassForLspT
    }
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res.any((c) => c.label == 'UniqueNamedClassForLspOne'), isTrue);
    expect(res.any((c) => c.label == 'UniqueNamedClassForLspTwo'), isTrue);
    expect(res.any((c) => c.label == 'UniqueNamedClassForLspThree'), isTrue);
  }

  Future<void> test_setters() async {
    var content = '''
    class MyClass {
      set stringSetter(String a) {}
      set noArgSetter() {}
      set multiArgSetter(a, b) {}
      set functionSetter(String Function(int a, int b) foo) {}
    }

    void f() {
      MyClass a;
      a.^
    }
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    var setters = res
        .where((c) => c.label.endsWith('Setter'))
        .map((c) => c.detail != null ? '${c.label} (${c.detail})' : c.label)
        .toList();
    expect(
      setters,
      [
        'stringSetter (String)',
        'noArgSetter',
        'multiArgSetter',
        // Because of how we extract the type name, we don't currently support
        // this.
        'functionSetter',
      ],
    );
  }

  Future<void> test_sort_sortsByRelevance() async {
    var content = '''
class UniquePrefixABC {}
class UniquePrefixAaBbCc {}

final a = UniquePrefixab^
''';

    await verifyCompletions(
      mainFileUri,
      content,
      expectCompletions: [
        // Constructors should all come before the class names, as they have
        // higher relevance in this position.
        'UniquePrefixABC()',
        'UniquePrefixAaBbCc()',
        'UniquePrefixABC',
        'UniquePrefixAaBbCc',
      ],
    );
  }

  Future<void> test_sort_truncatesByFuzzyScore() async {
    var content = '''
class UniquePrefixABC {}
class UniquePrefixAaBbCc {}

final a = UniquePrefixab^
''';

    // Enable truncation after 2 items so we can verify which
    // items were dropped.
    await provideConfig(initialize, {'maxCompletionItems': 2});
    await verifyCompletions(
      mainFileUri,
      content,
      expectNoAdditionalItems: true,
      expectCompletions: [
        // Although constructors are more relevant, when truncating we will use
        // fuzzy score, so the closer matches are kept instead and we'll get
        // constructor+class from the closer match.
        'UniquePrefixABC()',
        'UniquePrefixABC',
      ],
    );
  }

  Future<void> test_unimportedSymbols() async {
    newFile(
      join(projectFolderPath, 'other_file.dart'),
      '''
      /// This class is in another file.
      class InOtherFile {}
      ''',
    );

    var content = '''
void f() {
  InOtherF^
}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletion(mainFileUri, code.position.position);

    // Find the completion for the class in the other file.
    var completion = res.singleWhere((c) => c.label == 'InOtherFile');
    expect(completion, isNotNull);
    expect(completion.textEdit, isNotNull);
    var originalTextEdit = completion.textEdit;

    // Expect no docs, this is added during resolve.
    expectDocumentation(completion, isNull);

    // Resolve the completion item (via server) to get any additional edits.
    // This is LSP's equiv of getSuggestionDetails() and is invoked by LSP
    // clients to populate additional info (in our case, any additional edits
    // for inserting the import).
    var resolved = await resolveCompletion(completion);
    expect(resolved, isNotNull);

    // Ensure the detail field was update to show this will auto-import.
    expect(
      resolved.detail,
      startsWith("Auto import from '../other_file.dart'"),
    );

    // Ensure the doc comment was added.
    expectDocumentation(resolved, equals('This class is in another file.'));

    // Ensure the edit did not change.
    expect(resolved.textEdit, originalTextEdit);

    // There should be no command for this item because it doesn't need imports
    // in other files. Same-file completions are in additionalEdits.
    expect(resolved.command, isNull);

    // Apply both the main completion edit and the additionalTextEdits atomically.
    var newContent = applyTextEdits(
      code.code,
      [toTextEdit(resolved.textEdit!)]
          .followedBy(resolved.additionalTextEdits!)
          .toList(),
    );

    // Ensure both edits were made - the completion, and the inserted import.
    expect(newContent, equals('''
import '../other_file.dart';

void f() {
  InOtherFile
}
'''));
  }

  Future<void> test_unimportedSymbols_dartDocPreference_full() =>
      assertResolvedDocumentation('full',
          includesSummary: true, includesFull: true);

  Future<void> test_unimportedSymbols_dartDocPreference_none() =>
      assertResolvedDocumentation('none',
          includesSummary: false, includesFull: false);

  Future<void> test_unimportedSymbols_dartDocPreference_summary() =>
      assertResolvedDocumentation('summary',
          includesSummary: true, includesFull: false);

  /// No preference should result in full docs.
  Future<void> test_unimportedSymbols_dartDocPreference_unset() =>
      assertResolvedDocumentation(null,
          includesSummary: true, includesFull: true);

  Future<void>
      test_unimportedSymbols_doesNotDuplicate_importedViaMultipleLibraries() async {
    // An item that's already imported through multiple libraries that
    // export it should not result in multiple entries.
    newFile(
      join(projectFolderPath, 'lib/source_file.dart'),
      '''
      class MyExportedClass {}
      ''',
    );
    newFile(
      join(projectFolderPath, 'lib/reexport1.dart'),
      '''
      export 'source_file.dart';
      ''',
    );
    newFile(
      join(projectFolderPath, 'lib/reexport2.dart'),
      '''
      export 'source_file.dart';
      ''',
    );

    var content = '''
import 'reexport1.dart';
import 'reexport2.dart';

void f() {
  MyExported^
}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletion(mainFileUri, code.position.position);
    var completions = res.where((c) => c.label == 'MyExportedClass').toList();
    expect(completions, hasLength(1));
  }

  Future<void>
      test_unimportedSymbols_doesNotDuplicate_importedViaSingleLibrary() async {
    // An item that's already imported through a library that exports it
    // should not result in multiple entries.
    newFile(
      join(projectFolderPath, 'lib/source_file.dart'),
      '''
      class MyExportedClass {}
      ''',
    );
    newFile(
      join(projectFolderPath, 'lib/reexport1.dart'),
      '''
      export 'source_file.dart';
      ''',
    );
    newFile(
      join(projectFolderPath, 'lib/reexport2.dart'),
      '''
      export 'source_file.dart';
      ''',
    );

    var content = '''
import 'reexport1.dart';

void f() {
  MyExported^
}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletion(mainFileUri, code.position.position);

    var completions = res.where((c) => c.label == 'MyExportedClass').toList();
    expect(completions, hasLength(1));
  }

  Future<void> test_unimportedSymbols_doesNotFilterSymbolsWithSameName() async {
    // Classes here are not re-exports, so should not be filtered out.
    newFile(
      join(projectFolderPath, 'source_file1.dart'),
      'class MyDuplicatedClass {}',
    );
    newFile(
      join(projectFolderPath, 'source_file2.dart'),
      'class MyDuplicatedClass {}',
    );
    newFile(
      join(projectFolderPath, 'source_file3.dart'),
      'class MyDuplicatedClass {}',
    );

    var content = '''
void f() {
  MyDuplicated^
}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletion(mainFileUri, code.position.position);

    var completions = res.where((c) => c.label == 'MyDuplicatedClass').toList();
    expect(completions, hasLength(3));

    // Resolve the completions so we can get the auto-import text.
    var resolvedCompletions =
        await Future.wait(completions.map(resolveCompletion));

    expectAutoImportCompletion(resolvedCompletions, '../source_file1.dart');
    expectAutoImportCompletion(resolvedCompletions, '../source_file2.dart');
    expectAutoImportCompletion(resolvedCompletions, '../source_file3.dart');
  }

  Future<void> test_unimportedSymbols_enumValues() async {
    // Enum values only show up in contexts with their types, so we need two
    // extra files - one with the Enum definition, and one with a function that
    // accepts the Enum type that is imported into the test files.
    newFile(
      join(projectFolderPath, 'lib', 'enum.dart'),
      '''
        enum MyExportedEnum { One, Two }
      ''',
    );
    newFile(
      join(projectFolderPath, 'lib', 'function_x.dart'),
      '''
        import 'package:test/enum.dart';
        void x(MyExportedEnum e) {}
      ''',
    );

    var content = '''
import 'package:test/function_x.dart';

void f() {
  x(MyExported^
}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletion(mainFileUri, code.position.position);

    var enumCompletions =
        res.where((c) => c.label.startsWith('MyExportedEnum')).toList();
    expect(
        enumCompletions.map((c) => c.label),
        unorderedEquals(
            ['MyExportedEnum', 'MyExportedEnum.One', 'MyExportedEnum.Two']));

    var completion =
        enumCompletions.singleWhere((c) => c.label == 'MyExportedEnum.One');

    // Resolve the completion item (via server) to get its edits. This is the
    // LSP's equiv of getSuggestionDetails() and is invoked by LSP clients to
    // populate additional info (in our case, the additional edits for inserting
    // the import).
    var resolved = await resolveCompletion(completion);
    expect(resolved, isNotNull);

    // Ensure the detail field was update to show this will auto-import.
    expect(
      resolved.detail,
      startsWith("Auto import from 'package:test/enum.dart'"),
    );

    // Ensure the edit was added on.
    expect(resolved.textEdit, isNotNull);

    // Apply both the main completion edit and the additionalTextEdits atomically.
    var newContent = applyTextEdits(
      code.code,
      [toTextEdit(resolved.textEdit!)]
          .followedBy(resolved.additionalTextEdits!)
          .toList(),
    );

    // Ensure both edits were made - the completion, and the inserted import.
    expect(newContent, equals('''
import 'package:test/enum.dart';
import 'package:test/function_x.dart';

void f() {
  x(MyExportedEnum.One
}
'''));
  }

  Future<void> test_unimportedSymbols_enumValuesAlreadyImported() async {
    newFile(
      join(projectFolderPath, 'lib', 'enum.dart'),
      '''
      enum MyExportedEnum { One, Two }
      ''',
    );
    newFile(
      join(projectFolderPath, 'lib', 'reexport1.dart'),
      '''
      import 'enum.dart';
      export 'enum.dart';
      void x(MyExportedEnum e) {}
      ''',
    );
    newFile(
      join(projectFolderPath, 'lib', 'reexport2.dart'),
      '''
      export 'enum.dart';
      ''',
    );

    var content = '''
import 'reexport1.dart';

void f() {
  x(MyExported^
}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletion(mainFileUri, code.position.position);

    var completions =
        res.where((c) => c.label == 'MyExportedEnum.One').toList();
    expect(completions, hasLength(1));
    var resolved = await resolveCompletion(completions.first);
    // It should not include auto-import text since it's already imported.
    expect(resolved.detail, isNot(contains('Auto import from')));
  }

  /// Verify extensions can be auto-imported if not already in-scope.
  Future<void> test_unimportedSymbols_extension() async {
    // Define extensions in 'extensions.dart'.
    newFile(
      join(projectFolderPath, 'lib', 'extensions.dart'),
      '''
extension StringExtensions on String {
  String get empty => '';
}
''',
    );

    // Also import the extensions into an unrelated file to ensure this doesn't
    // cause extra suggestions (https://github.com/dart-lang/sdk/issues/56320).
    newFile(
      join(projectFolderPath, 'lib', 'other.dart'),
      'import "extensions.dart";',
    );

    var content = '''
void f(String a) {
  a.empt^
}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletion(mainFileUri, code.position.position);

    // Expect only a single entry for the 'empty' extension member.
    var completions = res.where((c) => c.label == 'empty');
    expect(completions, hasLength(1));

    // Expect it to auto-import from 'extensions.dart'.
    var resolved = await resolveCompletion(completions.single);
    expect(
      resolved.detail,
      startsWith("Auto import from 'package:test/extensions.dart'"),
    );

    // Verify the edits.
    var newContent = applyTextEdits(
      code.code,
      [toTextEdit(resolved.textEdit!)]
          .followedBy(resolved.additionalTextEdits!)
          .toList(),
    );
    expect(newContent, equals('''
import 'package:test/extensions.dart';

void f(String a) {
  a.empty
}
'''));
  }

  Future<void> test_unimportedSymbols_filtersOutAlreadyImportedSymbols() async {
    newFile(
      join(projectFolderPath, 'lib', 'source_file.dart'),
      '''
      class MyExportedClass {}
      ''',
    );
    newFile(
      join(projectFolderPath, 'lib', 'reexport1.dart'),
      '''
      export 'source_file.dart';
      ''',
    );
    newFile(
      join(projectFolderPath, 'lib', 'reexport2.dart'),
      '''
      export 'source_file.dart';
      ''',
    );

    var content = '''
import 'reexport1.dart';

void f() {
  MyExported^
}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletion(mainFileUri, code.position.position);

    var completions = res.where((c) => c.label == 'MyExportedClass').toList();
    expect(completions, hasLength(1));
    var resolved = await resolveCompletion(completions.first);
    // It should not include auto-import text since it's already imported.
    expect(resolved.detail, isNull);
  }

  Future<void> test_unimportedSymbols_importsPackageUri() async {
    newFile(
      join(projectFolderPath, 'lib', 'my_class.dart'),
      'class MyClass {}',
    );

    var content = '''
void f() {
  MyClas^
}
''';

    var expectedContent = '''
import 'package:test/my_class.dart';

void f() {
  MyClass
}
''';

    var completionLabel = 'MyClass';

    await _checkCompletionEdits(
      mainFileUri,
      content,
      completionLabel,
      expectedContent,
    );
  }

  Future<void>
      test_unimportedSymbols_importsPackageUri_extensionMember() async {
    newFile(join(projectFolderPath, 'lib', 'my_extension.dart'), '''
extension MyExtension on String {
  void myExtensionMethod() {}
}
      ''');

    var content = '''
void f() {
  ''.myExtensionMet^
}
''';

    var expectedContent = '''
import 'package:test/my_extension.dart';

void f() {
  ''.myExtensionMethod
}
''';

    var completionLabel = 'myExtensionMethod()';
    await _checkCompletionEdits(
      mainFileUri,
      content,
      completionLabel,
      expectedContent,
    );
  }

  Future<void>
      test_unimportedSymbols_includesReexportedSymbolsForEachFile() async {
    newFile(
      join(projectFolderPath, 'source_file.dart'),
      '''
      class MyExportedClass {}
      ''',
    );
    newFile(
      join(projectFolderPath, 'reexport1.dart'),
      '''
      export 'source_file.dart';
      ''',
    );
    newFile(
      join(projectFolderPath, 'reexport2.dart'),
      '''
      export 'source_file.dart';
      ''',
    );

    var content = '''
void f() {
  MyExported^
}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletion(mainFileUri, code.position.position);

    var completions = res.where((c) => c.label == 'MyExportedClass').toList();
    expect(completions, hasLength(3));

    // Resolve the completions so we can get the auto-import text.
    var resolvedCompletions =
        await Future.wait(completions.map(resolveCompletion));

    expectAutoImportCompletion(resolvedCompletions, '../source_file.dart');
    expectAutoImportCompletion(resolvedCompletions, '../reexport1.dart');
    expectAutoImportCompletion(resolvedCompletions, '../reexport2.dart');
  }

  Future<void> test_unimportedSymbols_insertReplaceRanges() async {
    setCompletionItemInsertReplaceSupport();

    newFile(
      join(projectFolderPath, 'other_file.dart'),
      '''
      /// This class is in another file.
      class InOtherFile {}
      ''',
    );

    var content = '''
void f() {
  InOtherF^il
}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletion(mainFileUri, code.position.position);

    // Find the completion for the class in the other file.
    var completion = res.singleWhere((c) => c.label == 'InOtherFile');
    expect(completion, isNotNull);
    expect(completion.textEdit, isNotNull);
    var originalTextEdit = completion.textEdit;

    // Expect no docs, this is added during resolve.
    expectDocumentation(completion, isNull);

    // Resolve the completion item (via server) to get any additional edits.
    // This is LSP's equiv of getSuggestionDetails() and is invoked by LSP
    // clients to populate additional info (in our case, any additional edits
    // for inserting the import).
    var resolved = await resolveCompletion(completion);
    expect(resolved, isNotNull);

    // Ensure the detail field was update to show this will auto-import.
    expect(
      resolved.detail,
      startsWith("Auto import from '../other_file.dart'"),
    );

    // Ensure the doc comment was added.
    expectDocumentation(resolved, equals('This class is in another file.'));

    // Ensure the edit did not change.
    expect(resolved.textEdit, originalTextEdit);

    // There should be no command for this item because it doesn't need imports
    // in other files. Same-file completions are in additionalEdits.
    expect(resolved.command, isNull);

    // Apply both the main completion edit and the additionalTextEdits atomically
    // then check the contents.

    var newContentReplaceMode = applyTextEdits(
      code.code,
      [textEditForReplace(resolved.textEdit!)]
          .followedBy(resolved.additionalTextEdits!)
          .toList(),
    );
    var newContentInsertMode = applyTextEdits(
      code.code,
      [textEditForInsert(resolved.textEdit!)]
          .followedBy(resolved.additionalTextEdits!)
          .toList(),
    );

    // Ensure both edits were made - the completion, and the inserted import.
    expect(newContentReplaceMode, equals('''
import '../other_file.dart';

void f() {
  InOtherFile
}
'''));
    // In insert mode, we'd have the trailing "il" still after the caret.
    expect(newContentInsertMode, equals('''
import '../other_file.dart';

void f() {
  InOtherFileil
}
'''));
  }

  Future<void> test_unimportedSymbols_insertsIntoPartFiles() async {
    // File we'll be adding an import for.
    newFile(
      join(projectFolderPath, 'other_file.dart'),
      ''''
class InOtherFile {}
''',
    );

    // File that will have the import added.
    var parentContent = '''
part 'main.dart';
''';
    newFile(
      join(projectFolderPath, 'lib', 'parent.dart'),
      parentContent,
    );

    // File that we're invoking completion in.
    var content = '''
part of 'parent.dart';
void f() {
  InOtherF^
}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletion(mainFileUri, code.position.position);

    var completion = res.singleWhere((c) => c.label == 'InOtherFile');
    expect(completion, isNotNull);

    // Resolve the completion item to get its edits.
    var resolved = await resolveCompletion(completion);
    expect(resolved, isNotNull);
    // Ensure it has a command, since it will need to make edits in other files
    // and that's done by telling the server to send a workspace/applyEdit. LSP
    // doesn't currently support these other-file edits in the completion.
    // See https://github.com/microsoft/language-server-protocol/issues/749
    expect(resolved.command, isNotNull);

    // Apply all current-document edits.
    var newContent = applyTextEdits(
      code.code,
      [toTextEdit(resolved.textEdit!)]
          .followedBy(resolved.additionalTextEdits!)
          .toList(),
    );
    expect(newContent, equals('''
part of 'parent.dart';
void f() {
  InOtherFile
}
'''));

    await verifyCommandEdits(resolved.command!, '''
>>>>>>>>>> lib/parent.dart
import '../other_file.dart';

part 'main.dart';
''');
  }

  Future<void>
      test_unimportedSymbols_isIncompleteNotSetIfBudgetNotExhausted() async {
    var content = '''
void f() {
  InOtherF^
}
''';
    var code = TestCode.parse(content);

    await initialize(
      initializationOptions: {
        ...?defaultInitializationOptions,
        // Set budget high to ensure it completes.
        'completionBudgetMilliseconds': 100000,
      },
    );
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletionList(mainFileUri, code.position.position);

    // Ensure we flagged that we returned everything.
    expect(res.isIncomplete, isFalse);
  }

  Future<void> test_unimportedSymbols_isIncompleteSetIfBudgetExhausted() async {
    newFile(
      join(projectFolderPath, 'lib', 'other_file.dart'),
      'class InOtherFile {}',
    );

    var content = '''
void f() {
  InOtherF^
}
''';
    var code = TestCode.parse(content);

    await initialize(
      initializationOptions: {
        ...?defaultInitializationOptions,
        // Set budget low to ensure we don't complete.
        'completionBudgetMilliseconds': 0,
      },
    );
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletionList(mainFileUri, code.position.position);

    // Ensure we flagged that we did not return everything.
    expect(res.items, hasLength(0));
    expect(res.isIncomplete, isTrue);
  }

  /// This test reproduces a bug where the pathKey hash used in
  /// available_declarations.dart would not change with the contents of the file
  /// (as it always used 0 as the modification stamp) which would prevent
  /// completion including items from files that were open (had overlays).
  /// https://github.com/Dart-Code/Dart-Code/issues/2286#issuecomment-658597532
  Future<void> test_unimportedSymbols_modifiedFiles() async {
    var otherFilePath = join(projectFolderPath, 'lib', 'other_file.dart');
    var otherFileUri = pathContext.toUri(otherFilePath);

    var mainFileCode = TestCode.parse('MyOtherClass^');
    await initialize();
    await openFile(mainFileUri, mainFileCode.code);
    await initialAnalysis;

    // Start with a blank file.
    newFile(otherFilePath, '');
    await openFile(otherFileUri, '');
    await pumpEventQueue(times: 5000);

    // Reopen the file with a class definition.
    await closeFile(otherFileUri);
    await openFile(otherFileUri, 'class MyOtherClass {}');
    await pumpEventQueue(times: 5000);

    // Ensure the class appears in completion.
    var completions =
        await getCompletion(mainFileUri, mainFileCode.position.position);
    var matching = completions.where((c) => c.label == 'MyOtherClass').toList();
    expect(matching, hasLength(1));
  }

  Future<void> test_unimportedSymbols_namedConstructors() async {
    newFile(
      join(projectFolderPath, 'other_file.dart'),
      '''
      /// This class is in another file.
      class InOtherFile {
        InOtherFile.fromJson() {}
      }
      ''',
    );

    var content = '''
void f() {
  var a = InOtherF^
}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletion(mainFileUri, code.position.position);

    // Find the completion for the class in the other file.
    var completion =
        res.singleWhere((c) => c.label == 'InOtherFile.fromJson()');
    expect(completion, isNotNull);
    expect(completion.textEdit, isNotNull);

    // Expect no docs, this is added during resolve.
    expectDocumentation(completion, isNull);

    // Resolve the completion item (via server) to get any additional edits.
    // This is LSP's equiv of getSuggestionDetails() and is invoked by LSP
    // clients to populate additional info (in our case, any additional edits
    // for inserting the import).
    var resolved = await resolveCompletion(completion);
    expect(resolved, isNotNull);

    // Apply both the main completion edit and the additionalTextEdits atomically.
    var newContent = applyTextEdits(
      code.code,
      [toTextEdit(resolved.textEdit!)]
          .followedBy(resolved.additionalTextEdits!)
          .toList(),
    );

    // Ensure both edits were made - the completion, and the inserted import.
    expect(newContent, equals('''
import '../other_file.dart';

void f() {
  var a = InOtherFile.fromJson
}
'''));
  }

  Future<void> test_unimportedSymbols_overrides() async {
    newFile(join(projectFolderPath, 'lib', 'a.dart'), 'class A {}');
    newFile(join(projectFolderPath, 'lib', 'b.dart'), 'class B {}');
    newFile(join(projectFolderPath, 'lib', 'c.dart'), 'class C {}');
    newFile(join(projectFolderPath, 'lib', 'd.dart'), 'class D {}');

    newFile(
      join(projectFolderPath, 'lib', 'base.dart'),
      '''
import 'a.dart';
import 'b.dart';
import 'c.dart';
import 'd.dart';

abstract class Base {
  D? myMethod(A a, B b, C c) => null;
}
      ''',
    );

    // A will already be imported
    // B will already be imported but with a prefix
    // C & D are not imported and need importing (return + parameter types)
    var content = '''
import 'package:test/a.dart';
import 'package:test/b.dart' as b;
import 'package:test/base.dart';

class BaseImpl extends Base {
  myMet^
}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletion(mainFileUri, code.position.position);

    var completion =
        res.singleWhere((c) => c.label == 'myMethod(A a, b.B b, C c) { … }');
    var resolved = await resolveCompletion(completion);

    var newContent = applyTextEdits(
      code.code,
      [toTextEdit(resolved.textEdit!)]
          .followedBy(resolved.additionalTextEdits!)
          .toList(),
    );

    expect(newContent, equals('''
import 'package:test/a.dart';
import 'package:test/b.dart' as b;
import 'package:test/base.dart';
import 'package:test/c.dart';
import 'package:test/d.dart';

class BaseImpl extends Base {
  @override
  D? myMethod(A a, b.B b, C c) {
    // TODO: implement myMethod
    return super.myMethod(a, b, c);
  }
}
'''));
  }

  Future<void>
      test_unimportedSymbols_preferRelativeImportsLib_insideLib() async {
    _enableLints([LintNames.prefer_relative_imports]);
    var importingFilePath =
        join(projectFolderPath, 'lib', 'nested1', 'main.dart');
    var importingFileUri = pathContext.toUri(importingFilePath);
    var importedFilePath =
        join(projectFolderPath, 'lib', 'nested2', 'imported.dart');

    // Create a file that will be auto-imported from completion.
    newFile(importedFilePath, 'class MyClass {}');

    var content = '''
void f() {
  MyClas^
}
''';

    var expectedContent = '''
import '../nested2/imported.dart';

void f() {
  MyClass
}
''';

    var completionLabel = 'MyClass';

    await _checkCompletionEdits(
      importingFileUri,
      content,
      completionLabel,
      expectedContent,
    );
  }

  Future<void>
      test_unimportedSymbols_preferRelativeImportsLib_outsideLib() async {
    // Files outside of the lib folder should still get absolute imports to
    // files inside lib, even with the lint enabled.
    _enableLints([LintNames.prefer_relative_imports]);
    var importingFilePath =
        join(projectFolderPath, 'bin', 'nested1', 'main.dart');
    var importingFileUri = pathContext.toUri(importingFilePath);
    var importedFilePath =
        join(projectFolderPath, 'lib', 'nested2', 'imported.dart');

    // Create a file that will be auto-imported from completion.
    newFile(importedFilePath, 'class MyClass {}');

    var content = '''
void f() {
  MyClas^
}
''';

    var expectedContent = '''
import 'package:test/nested2/imported.dart';

void f() {
  MyClass
}
''';

    var completionLabel = 'MyClass';

    await _checkCompletionEdits(
      importingFileUri,
      content,
      completionLabel,
      expectedContent,
    );
  }

  Future<void> test_unimportedSymbols_unavailableIfDisabled() async {
    newFile(
      join(projectFolderPath, 'other_file.dart'),
      'class InOtherFile {}',
    );

    var content = '''
void f() {
  InOtherF^
}
''';

    // applyEdit is supported in setUp, but explicitly disable the suggestions.
    await initialize(
      initializationOptions: {
        ...?defaultInitializationOptions,
        'suggestFromUnimportedLibraries': false,
      },
    );
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletion(mainFileUri, code.position.position);

    // Ensure the item doesn't appear in the results (because we might not
    // be able to execute the import edits if they're in another file).
    var completion = res.singleWhereOrNull((c) => c.label == 'InOtherFile');
    expect(completion, isNull);
  }

  Future<void> test_unimportedSymbols_unavailableWithoutApplyEdit() async {
    // If client doesn't advertise support for workspace/applyEdit, we won't
    // include suggestion sets.
    setApplyEditSupport(false);

    newFile(
      join(projectFolderPath, 'other_file.dart'),
      'class InOtherFile {}',
    );

    var content = '''
void f() {
  InOtherF^
}
''';

    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    await initialAnalysis;
    var res = await getCompletion(mainFileUri, code.position.position);

    // Ensure the item doesn't appear in the results (because we might not
    // be able to execute the import edits if they're in another file).
    var completion = res.singleWhereOrNull((c) => c.label == 'InOtherFile');
    expect(completion, isNull);
  }

  Future<void> test_unopenFile() async {
    var content = '''
    class MyClass {
      String abcdefghij;
    }

    void f() {
      MyClass a;
      a.abc^
    }
''';
    var code = TestCode.parse(content);

    newFile(mainFilePath, code.code);
    await initialize();
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res.any((c) => c.label == 'abcdefghij'), isTrue);
    var item = res.singleWhere((c) => c.label == 'abcdefghij');
    expect(item.insertTextFormat,
        anyOf(equals(InsertTextFormat.PlainText), isNull));
    expect(item.insertText, anyOf(equals('abcdefghij'), isNull));
    var updated = applyTextEdits(
      code.code,
      [toTextEdit(item.textEdit!)],
    );
    expect(updated, contains('a.abcdefghij'));
  }

  /// Sets up the server with a file containing [content] and checks that
  /// accepting a specific completion produces [expectedContent].
  ///
  /// [content] should contain a `^` at the location where completion should be
  /// invoked/accepted.
  Future<void> _checkCompletionEdits(
    Uri fileUri,
    String content,
    String completionLabel,
    String expectedContent,
  ) async {
    var code = TestCode.parse(content);
    await initialize();
    await openFile(fileUri, code.code);
    await initialAnalysis;
    var res = await getCompletion(fileUri, code.position.position);

    var completion = res.where((c) => c.label == completionLabel).single;
    var resolvedCompletion = await resolveCompletion(completion);

    // Apply both the main completion edit and the additionalTextEdits atomically.
    var newContent = applyTextEdits(
      code.code,
      [toTextEdit(resolvedCompletion.textEdit!)]
          .followedBy(resolvedCompletion.additionalTextEdits!)
          .toList(),
    );

    expect(newContent, equals(expectedContent));
  }

  Future<void> _checkResultsForTriggerCharacters(String content,
      List<String> triggerCharacters, Matcher expectedResults) async {
    var code = TestCode.parse(content);
    await initialize();
    await openFile(mainFileUri, code.code);

    for (var triggerCharacter in triggerCharacters) {
      var context = CompletionContext(
          triggerKind: CompletionTriggerKind.TriggerCharacter,
          triggerCharacter: triggerCharacter);
      var res = await getCompletion(mainFileUri, code.position.position,
          context: context);
      expect(
        res,
        expectedResults,
        reason: 'No completions when using $triggerCharacter',
      );
    }
  }

  void _enableLints(List<String> lintNames) {
    registerLintRules();
    var lintsYaml = lintNames.map((name) => '    - $name\n').join();
    newFile(analysisOptionsPath, '''
linter:
  rules:
$lintsYaml
''');
  }
}

@reflectiveTest
class DartSnippetCompletionTest extends SnippetCompletionTest {
  Future<void> test_snippets_class() async {
    var content = '''
clas^
''';

    await initialize();
    var updated = await expectAndApplySnippet(
      content,
      prefix: ClassDeclaration.prefix,
      label: ClassDeclaration.label,
    );

    expect(updated, r'''
class ${1:ClassName} {
  $0
}
''');
  }

  /// Checks that the `enableSnippets` setting can disable snippets even if the
  /// client supports them.
  Future<void> test_snippets_disabled() async {
    var content = '^';

    // Support is set in setUp, but here we disable the user preference.
    await provideConfig(initialize, {'enableSnippets': false});

    await expectNoSnippets(content);
  }

  Future<void> test_snippets_doWhile() async {
    var content = '''
void f() {
  do^
}
''';

    await initialize();
    var updated = await expectAndApplySnippet(
      content,
      prefix: DoStatement.prefix,
      label: DoStatement.label,
    );

    expect(updated, r'''
void f() {
  do {
    $0
  } while (${1:condition});
}
''');
  }

  /// Snippets completions may abort if documents are modified (because they
  /// need to obtain resolved units when building edits) but they should not
  /// prevent non-Snippet completion results from being returned (because this
  /// happens frequently while typing).
  Future<void> test_snippets_failureDoesNotPreventNonSnippets() async {
    var content = '''
void f() {
  ^
}
''';
    var code = TestCode.parse(content);

    await initialize();
    await openFile(mainFileUri, code.code);
    await initialAnalysis;

    // Use a Completer to control when the completion handler starts computing.
    var completer = Completer<void>();
    CompletionHandler.delayAfterResolveForTests = completer.future;
    try {
      // Start the completion request but don't await it yet.
      var completionRequest =
          getCompletionList(mainFileUri, code.position.position);
      // Modify the document to ensure the snippet requests will fail to build
      // edits and then allow the handler to continue.
      await replaceFile(222, mainFileUri, '');
      completer.complete();

      // Wait for the results.
      var result = await completionRequest;

      // Ensure we flagged that we did not return everything but we still got
      // results.
      expect(result.isIncomplete, isTrue);
      expect(result.items, isNotEmpty);
    } finally {
      // Ensure we never leave an incomplete future if anything above throws.
      CompletionHandler.delayAfterResolveForTests = null;
    }
  }

  Future<void>
      test_snippets_flutterStateless_notAvailable_notFlutterProject() async {
    var content = '''
class A {}

stle^

class B {}
''';

    await initialize();
    await expectNoSnippet(
      content,
      FlutterStatelessWidget.prefix,
    );
  }

  Future<void> test_snippets_for() async {
    var content = '''
void f() {
  for^
}
''';

    await initialize();
    var updated = await expectAndApplySnippet(
      content,
      prefix: ForStatement.prefix,
      label: ForStatement.label,
    );

    expect(updated, r'''
void f() {
  for (var i = 0; i < ${1:count}; i++) {
    $0
  }
}
''');
  }

  Future<void> test_snippets_forIn() async {
    var content = '''
void f() {
  forin^
}
''';

    await initialize();
    var updated = await expectAndApplySnippet(
      content,
      prefix: ForInStatement.prefix,
      label: ForInStatement.label,
    );

    expect(updated, r'''
void f() {
  for (var ${1:element} in ${2:collection}) {
    $0
  }
}
''');
  }

  Future<void> test_snippets_functionClassMember() async {
    var content = '''
class A {
  fun^
}
''';

    await initialize();
    var updated = await expectAndApplySnippet(
      content,
      prefix: FunctionDeclaration.prefix,
      label: FunctionDeclaration.label,
    );

    expect(updated, r'''
class A {
  ${1:void} ${2:name}(${3:params}) {
    $0
  }
}
''');
  }

  Future<void> test_snippets_functionNested() async {
    var content = '''
void a() {
  fun^
}
''';

    await initialize();
    var updated = await expectAndApplySnippet(
      content,
      prefix: FunctionDeclaration.prefix,
      label: FunctionDeclaration.label,
    );

    expect(updated, r'''
void a() {
  ${1:void} ${2:name}(${3:params}) {
    $0
  }
}
''');
  }

  Future<void> test_snippets_functionTopLevel() async {
    var content = '''
fun^
''';

    await initialize();
    var updated = await expectAndApplySnippet(
      content,
      prefix: FunctionDeclaration.prefix,
      label: FunctionDeclaration.label,
    );

    expect(updated, r'''
${1:void} ${2:name}(${3:params}) {
  $0
}
''');
  }

  Future<void> test_snippets_if() async {
    var content = '''
void f() {
  if^
}
''';

    await initialize();
    var updated = await expectAndApplySnippet(
      content,
      prefix: IfStatement.prefix,
      label: IfStatement.label,
    );

    expect(updated, r'''
void f() {
  if (${1:condition}) {
    $0
  }
}
''');
  }

  Future<void> test_snippets_ifElse() async {
    var content = '''
void f() {
  if^
}
''';

    await initialize();
    var updated = await expectAndApplySnippet(
      content,
      prefix: IfElseStatement.prefix,
      label: IfElseStatement.label,
    );
    var fourSpaces = '    ';
    expect(updated, '''
void f() {
  if (\${1:condition}) {
    \$0
  } else {
$fourSpaces
  }
}
''');
  }

  /// Fetch snippets with itemDefaults enabled to ensure we don't return any
  /// values that match the defaults and that using the default range applies
  /// correctly.
  Future<void> test_snippets_itemDefaults() async {
    setCompletionListDefaults(
        ['editRange', 'insertTextMode', 'insertTextFormat']);
    var content = '''
fu^
''';

    await initialize();
    var updated = await expectAndApplySnippet(
      content,
      prefix: FunctionDeclaration.prefix,
      label: FunctionDeclaration.label,
    );

    expect(updated, r'''
${1:void} ${2:name}(${3:params}) {
  $0
}
''');
  }

  Future<void> test_snippets_mainFunction() async {
    var content = '''
class A {}

main^

class B {}
''';

    await initialize();
    var updated = await expectAndApplySnippet(
      content,
      prefix: MainFunction.prefix,
      label: MainFunction.label,
    );

    expect(updated, r'''
class A {}

void main(List<String> args) {
  $0
}

class B {}
''');
  }

  Future<void> test_snippets_notSupported() async {
    var content = '^';

    // If we don't send support for Snippet CompletionItem kinds, we don't
    // expect any snippets at all.
    setCompletionItemSnippetSupport(false);
    await initialize();
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    expect(res.any((c) => c.kind == CompletionItemKind.Snippet), isFalse);
  }

  Future<void> test_snippets_switch() async {
    var content = '''
void f() {
  swi^
}
''';

    await initialize();
    var updated = await expectAndApplySnippet(
      content,
      prefix: SwitchStatement.prefix,
      label: SwitchStatement.label,
    );

    expect(updated, r'''
void f() {
  switch (${1:expression}) {
    case ${2:value}:
      $0
      break;
    default:
  }
}
''');
  }

  Future<void> test_snippets_testBlock() async {
    mainFilePath = join(projectFolderPath, 'test', 'foo_test.dart');
    var content = '''
void f() {
  test^
}
''';

    await initialize();
    var updated = await expectAndApplySnippet(
      content,
      prefix: TestDefinition.prefix,
      label: TestDefinition.label,
    );

    expect(updated, r'''
void f() {
  test('${1:test name}', () {
    $0
  });
}
''');
  }

  Future<void> test_snippets_testGroupBlock() async {
    mainFilePath = join(projectFolderPath, 'test', 'foo_test.dart');
    var content = '''
void f() {
  group^
}
''';

    await initialize();
    var updated = await expectAndApplySnippet(
      content,
      prefix: TestGroupDefinition.prefix,
      label: TestGroupDefinition.label,
    );

    expect(updated, r'''
void f() {
  group('${1:group name}', () {
    $0
  });
}
''');
  }

  Future<void> test_snippets_tryCatch() async {
    var content = '''
void f() {
  tr^
}
''';

    await initialize();
    var updated = await expectAndApplySnippet(
      content,
      prefix: TryCatchStatement.prefix,
      label: TryCatchStatement.label,
    );
    var fourSpaces = '    ';
    expect(updated, '''
void f() {
  try {
    \$0
  } catch (\${1:e}) {
$fourSpaces
  }
}
''');
  }

  Future<void> test_snippets_while() async {
    var content = '''
void f() {
  while^
}
''';

    await initialize();
    var updated = await expectAndApplySnippet(
      content,
      prefix: WhileStatement.prefix,
      label: WhileStatement.label,
    );

    expect(updated, r'''
void f() {
  while (${1:condition}) {
    $0
  }
}
''');
  }
}

@reflectiveTest
class FlutterSnippetCompletionTest extends SnippetCompletionTest {
  /// Standard import statements expected for basic Widgets.
  String get expectedImports => '''
import 'package:flutter/widgets.dart';''';

  /// Constructor params expected on Widget classes.
  String get expectedWidgetConstructorParams => '({super.key})';

  @override
  void setUp() {
    super.setUp();
    writeTestPackageConfig(
      flutter: true,
    );
  }

  Future<void> test_snippets_flutterStateful() async {
    var content = '''
import 'package:flutter/widgets.dart';

class A {}

stful^

class B {}
''';

    await initialize();
    var updated = await expectAndApplySnippet(
      content,
      prefix: FlutterStatefulWidget.prefix,
      label: FlutterStatefulWidget.label,
    );

    expect(updated, '''
import 'package:flutter/widgets.dart';

class A {}

class \${1:MyWidget} extends StatefulWidget {
  const \${1:MyWidget}$expectedWidgetConstructorParams;

  @override
  State<\${1:MyWidget}> createState() => _\${1:MyWidget}State();
}

class _\${1:MyWidget}State extends State<\${1:MyWidget}> {
  @override
  Widget build(BuildContext context) {
    return \${0:const Placeholder()};
  }
}

class B {}
''');
  }

  Future<void> test_snippets_flutterStatefulWithAnimationController() async {
    var content = '''
import 'package:flutter/widgets.dart';

class A {}

stanim^

class B {}
''';

    await initialize();
    var updated = await expectAndApplySnippet(
      content,
      prefix: FlutterStatefulWidgetWithAnimationController.prefix,
      label: FlutterStatefulWidgetWithAnimationController.label,
    );

    expect(updated, '''
import 'package:flutter/widgets.dart';

class A {}

class \${1:MyWidget} extends StatefulWidget {
  const \${1:MyWidget}$expectedWidgetConstructorParams;

  @override
  State<\${1:MyWidget}> createState() => _\${1:MyWidget}State();
}

class _\${1:MyWidget}State extends State<\${1:MyWidget}>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this);
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return \${0:const Placeholder()};
  }
}

class B {}
''');
  }

  Future<void> test_snippets_flutterStateless() async {
    var content = '''
import 'package:flutter/widgets.dart';

class A {}

stle^

class B {}
''';

    await initialize();
    var updated = await expectAndApplySnippet(
      content,
      prefix: FlutterStatelessWidget.prefix,
      label: FlutterStatelessWidget.label,
    );

    expect(updated, '''
import 'package:flutter/widgets.dart';

class A {}

class \${1:MyWidget} extends StatelessWidget {
  const \${1:MyWidget}$expectedWidgetConstructorParams;

  @override
  Widget build(BuildContext context) {
    return \${0:const Placeholder()};
  }
}

class B {}
''');
  }

  Future<void> test_snippets_flutterStateless_addsImports() async {
    var content = '''
class A {}

stle^

class B {}
''';

    await initialize();
    var updated = await expectAndApplySnippet(
      content,
      prefix: FlutterStatelessWidget.prefix,
      label: FlutterStatelessWidget.label,
    );

    expect(updated, '''
$expectedImports

class A {}

class \${1:MyWidget} extends StatelessWidget {
  const \${1:MyWidget}$expectedWidgetConstructorParams;

  @override
  Widget build(BuildContext context) {
    return \${0:const Placeholder()};
  }
}

class B {}
''');
  }

  Future<void> test_snippets_flutterStateless_addsImports_onlyPrefix() async {
    var content = '''
stless^
''';

    await initialize();
    var updated = await expectAndApplySnippet(
      content,
      prefix: FlutterStatelessWidget.prefix,
      label: FlutterStatelessWidget.label,
    );

    expect(updated, '''
$expectedImports

class \${1:MyWidget} extends StatelessWidget {
  const \${1:MyWidget}$expectedWidgetConstructorParams;

  @override
  Widget build(BuildContext context) {
    return \${0:const Placeholder()};
  }
}
''');
  }

  Future<void> test_snippets_flutterStateless_addsImports_zeroOffset() async {
    var content = '''
^
'''; // Deliberate trailing newline to ensure imports aren't inserted at "end".

    await initialize();
    var updated = await expectAndApplySnippet(
      content,
      prefix: FlutterStatelessWidget.prefix,
      label: FlutterStatelessWidget.label,
    );

    expect(updated, '''
$expectedImports

class \${1:MyWidget} extends StatelessWidget {
  const \${1:MyWidget}$expectedWidgetConstructorParams;

  @override
  Widget build(BuildContext context) {
    return \${0:const Placeholder()};
  }
}
''');
  }

  Future<void> test_snippets_flutterStateless_notAvailable_notTopLevel() async {
    var content = '''
class A {

  stle^

}
''';

    await initialize();
    await expectNoSnippet(
      content,
      FlutterStatelessWidget.prefix,
    );
  }

  Future<void> test_snippets_flutterStateless_outsideAnalysisRoot() async {
    var content = '''
stle^
''';
    var code = TestCode.parse(content);

    await initialize();
    var otherFileUri = pathContext.toUri(convertPath('/other/file.dart'));
    await openFile(otherFileUri, code.code);
    var res = await getCompletion(otherFileUri, code.position.position);
    var snippetItems = res.where((c) => c.kind == CompletionItemKind.Snippet);
    expect(snippetItems, hasLength(0));
  }
}

abstract class SnippetCompletionTest extends AbstractLspAnalysisServerTest
    with CompletionTestMixin {
  /// Expect that there is a snippet for [prefix] at [position] with the label
  /// [label] and return the results of applying it to [content].
  Future<String> expectAndApplySnippet(
    String content, {
    required String prefix,
    required String label,
  }) async {
    var code = TestCode.parse(content);
    var (snippet: snippet, defaults: defaults) = await expectSnippet(
      code,
      prefix: prefix,
      label: label,
    );

    var textEdit = snippet.textEdit;
    var textEditText = snippet.textEditText;
    var additionalTextEdits = snippet.additionalTextEdits;

    var edits = [
      // Additional TextEdits come first, because if they have the same offset
      // as edits in the normal edit, they will be inserted first.
      // https://github.com/microsoft/vscode/issues/143888.
      ...?additionalTextEdits,
      // Then we also either have an edit itself or we just have textEditText
      // and a default range.
      if (textEdit != null)
        toTextEdit(textEdit)
      else
        TextEdit(
          newText: textEditText!,
          range: defaults!.editRange!.map(
            (ranges) =>
                throw 'Unexpected snippet with different insert/replace ranges',
            (range) => range,
          ),
        )
    ];

    // Also apply the edit and check that it went in the right place with the
    // correct formatting. Edit groups will just appear in the raw textmate
    // snippet syntax here, as we don't do any special handling of them (and
    // assume what's coded here is correct, and that the client will correctly
    // interpret them).
    var updated = applyTextEdits(code.code, edits);
    return updated;
  }

  /// Expect that there is no snippet for [prefix] at the position of `^` within
  /// [content].
  Future<void> expectNoSnippet(
    String content,
    String prefix,
  ) async {
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    var hasSnippet = res.any((c) => c.filterText == prefix);
    expect(hasSnippet, isFalse);
  }

  /// Expect that there are no snippets at the position of `^` within [content].
  Future<void> expectNoSnippets(String content) async {
    var code = TestCode.parse(content);
    await openFile(mainFileUri, code.code);
    var res = await getCompletion(mainFileUri, code.position.position);
    var hasAnySnippet = res.any((c) => c.kind == CompletionItemKind.Snippet);
    expect(hasAnySnippet, isFalse);
  }

  /// Expect that there is a snippet for [prefix] with the label [label] at
  /// [position] in [content].
  Future<({CompletionItem snippet, CompletionListItemDefaults? defaults})>
      expectSnippet(
    TestCode code, {
    required String prefix,
    required String label,
  }) async {
    await openFile(mainFileUri, code.code);
    var res = await getCompletionList(mainFileUri, code.position.position);
    var item = res.items.singleWhere(
      (c) =>
          c.kind == CompletionItemKind.Snippet &&
          (c.filterText ?? c.label) == prefix &&
          c.label == label,
    );
    expect(item.insertTextFormat, InsertTextFormat.Snippet);
    expect(item.insertText, isNull);
    // We either expect textEdit (if we had a range) or textEditText (or we did
    // not), but never both.
    expect(item.textEdit == null, item.textEditText != null);
    expect(item.textEditText != null, res.itemDefaults?.editRange != null);
    return (snippet: item, defaults: res.itemDefaults);
  }

  @override
  void setUp() {
    super.setUp();

    // Snippet completion tests have incomplete code.
    failTestOnErrorDiagnostic = false;

    setCompletionItemSnippetSupport();
  }
}
