// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:async';

import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/domain_analysis.dart';
import 'package:analysis_server/src/domain_completion.dart';
import 'package:analysis_server/src/plugin/plugin_manager.dart';
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analysis_server/src/services/completion/dart/not_imported_contributor.dart';
import 'package:analysis_server/src/utilities/mocks.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/instrumentation/service.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'domain_completion_util.dart';
import 'mocks.dart';
import 'src/plugin/plugin_manager_test.dart';

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(CompletionDomainHandlerGetSuggestionDetails2Test);
    defineReflectiveTests(CompletionDomainHandlerGetSuggestions2Test);
    defineReflectiveTests(CompletionDomainHandlerGetSuggestionsTest);
  });
}

@reflectiveTest
class CompletionDomainHandlerGetSuggestionDetails2Test
    extends PubPackageAnalysisServerTest {
  Future<void> test_alreadyImported() async {
    await _configureWithWorkspaceRoot();

    var validator = await _getTestCodeDetails('''
import 'dart:math';
void f() {
  Rand^
}
''', completion: 'Random', libraryUri: 'dart:math');
    validator
      ..hasCompletion('Random')
      ..hasChange().assertNoFileEdits();
  }

  Future<void> test_import_dart() async {
    await _configureWithWorkspaceRoot();

    var validator = await _getTestCodeDetails('''
void f() {
  R^
}
''', completion: 'Random', libraryUri: 'dart:math');
    validator
      ..hasCompletion('Random')
      ..hasChange()
          .hasFileEdit(testFilePathPlatform)
          .whenApplied(testFileContent, r'''
import 'dart:math';

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

  Future<void> test_import_package_dependencies() async {
    // TODO(scheglov) Switch to PubspecYamlFileConfig
    newPubspecYamlFile(testPackageRootPath, r'''
name: test
dependencies:
  aaa: any
''');

    var aaaRoot = getFolder('$workspaceRootPath/packages/aaa');
    newFile('${aaaRoot.path}/lib/f.dart', content: '''
class Test {}
''');

    writeTestPackageConfig(
      config: PackageConfigFileBuilder()
        ..add(name: 'aaa', rootPath: aaaRoot.path),
    );

    await _configureWithWorkspaceRoot();

    var validator = await _getTestCodeDetails('''
void f() {
  T^
}
''', completion: 'Test', libraryUri: 'package:aaa/a.dart');
    validator
      ..hasCompletion('Test')
      ..hasChange()
          .hasFileEdit(testFilePathPlatform)
          .whenApplied(testFileContent, r'''
import 'package:aaa/a.dart';

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

  Future<void> test_import_package_this() async {
    newFile('$testPackageLibPath/a.dart', content: '''
class Test {}
''');

    await _configureWithWorkspaceRoot();

    var validator = await _getTestCodeDetails('''
void f() {
  T^
}
''', completion: 'Test', libraryUri: 'package:test/a.dart');
    validator
      ..hasCompletion('Test')
      ..hasChange()
          .hasFileEdit(testFilePathPlatform)
          .whenApplied(testFileContent, r'''
import 'package:test/a.dart';

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

  Future<void> test_invalidLibraryUri() async {
    await _configureWithWorkspaceRoot();

    var request = CompletionGetSuggestionDetails2Params(
            testFilePathPlatform, 0, 'Random', '[foo]:bar')
        .toRequest('0');

    var response = await _handleRequest(request);
    expect(response.error?.code, RequestErrorCode.INVALID_PARAMETER);
    // TODO(scheglov) Check that says "libraryUri".
  }

  Future<void> test_invalidPath() async {
    await _configureWithWorkspaceRoot();

    var request =
        CompletionGetSuggestionDetails2Params('foo', 0, 'Random', 'dart:math')
            .toRequest('0');

    var response = await _handleRequest(request);
    expect(response.error?.code, RequestErrorCode.INVALID_FILE_PATH_FORMAT);
  }

  Future<GetSuggestionDetails2Validator> _getCodeDetails({
    required String path,
    required String content,
    required String completion,
    required String libraryUri,
  }) async {
    var completionOffset = content.indexOf('^');
    expect(completionOffset, isNot(equals(-1)), reason: 'missing ^');

    var nextOffset = content.indexOf('^', completionOffset + 1);
    expect(nextOffset, equals(-1), reason: 'too many ^');

    newFile(path,
        content: content.substring(0, completionOffset) +
            content.substring(completionOffset + 1));

    return await _getDetails(
      path: path,
      completionOffset: completionOffset,
      completion: completion,
      libraryUri: libraryUri,
    );
  }

  Future<GetSuggestionDetails2Validator> _getDetails({
    required String path,
    required int completionOffset,
    required String completion,
    required String libraryUri,
  }) async {
    var request = CompletionGetSuggestionDetails2Params(
      path,
      completionOffset,
      completion,
      libraryUri,
    ).toRequest('0');

    var response = await _handleSuccessfulRequest(request);
    var result = CompletionGetSuggestionDetails2Result.fromResponse(response);
    return GetSuggestionDetails2Validator(result);
  }

  Future<GetSuggestionDetails2Validator> _getTestCodeDetails(
    String content, {
    required String completion,
    required String libraryUri,
  }) async {
    return _getCodeDetails(
      path: convertPath(testFilePath),
      content: content,
      completion: completion,
      libraryUri: libraryUri,
    );
  }
}

@reflectiveTest
class CompletionDomainHandlerGetSuggestions2Test
    extends PubPackageAnalysisServerTest {
  @override
  void setUp() {
    super.setUp();
    completionDomain.budgetDuration = const Duration(seconds: 30);
  }

  void tearDown() {
    NotImportedContributor.onFile = null;
  }

  Future<void> test_notImported_abort() async {
    await _configureWithWorkspaceRoot();

    NotImportedContributor.onFile = (file) {
      if (file.uriStr == 'dart:math') {
        unawaited(
          _getSuggestions(
            path: convertPath(testFilePath),
            completionOffset: 0,
            maxResults: 100,
          ),
        );
      }
    };

    var responseValidator = await _getTestCodeSuggestions('''
void f() {
  Rand^
}
''');

    responseValidator
      ..assertIncomplete()
      ..assertReplacementBack(4)
      ..assertLibrariesToImport(includes: [], excludes: [
        'dart:core',
        'dart:math',
      ]);

    responseValidator.suggestions.assertEmpty();
  }

  Future<void> test_notImported_emptyBudget() async {
    await _configureWithWorkspaceRoot();

    // Empty budget, so no not yet imported libraries.
    completionDomain.budgetDuration = const Duration(milliseconds: 0);

    var responseValidator = await _getTestCodeSuggestions('''
void f() {
  Rand^
}
''');

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(4)
      ..assertLibrariesToImport(includes: [], excludes: [
        'dart:core',
        'dart:math',
      ]);

    responseValidator.suggestions.withElementClass().assertEmpty();
  }

  Future<void> test_notImported_pub_dependencies_inLib() async {
    // TODO(scheglov) Switch to PubspecYamlFileConfig
    newPubspecYamlFile(testPackageRootPath, r'''
name: test
dependencies:
  aaa: any
dev_dependencies:
  bbb: any
''');

    var aaaRoot = getFolder('$workspaceRootPath/packages/aaa');
    newFile('${aaaRoot.path}/lib/f.dart', content: '''
class A01 {}
''');
    newFile('${aaaRoot.path}/lib/src/f.dart', content: '''
class A02 {}
''');

    var bbbRoot = getFolder('$workspaceRootPath/packages/bbb');
    newFile('${bbbRoot.path}/lib/f.dart', content: '''
class A03 {}
''');
    newFile('${bbbRoot.path}/lib/src/f.dart', content: '''
class A04 {}
''');

    writeTestPackageConfig(
      config: PackageConfigFileBuilder()
        ..add(name: 'aaa', rootPath: aaaRoot.path)
        ..add(name: 'bbb', rootPath: bbbRoot.path),
    );

    await _configureWithWorkspaceRoot();

    var responseValidator = await _getTestCodeSuggestions('''
void f() {
  A0^
}
''');

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(2)
      ..assertLibrariesToImport(includes: [
        'package:aaa/f.dart',
      ], excludes: [
        'dart:core',
        'package:bbb/f.dart',
        'package:test/test.dart',
      ]);

    var classes = responseValidator.suggestions.withElementClass();
    classes.assertCompletions(['A01']);
    classes.withCompletion('A01').assertSingle()
      ..assertClass()
      ..assertLibraryToImport('package:aaa/f.dart');
  }

  Future<void> test_notImported_pub_dependencies_inTest() async {
    // TODO(scheglov) Switch to PubspecYamlFileConfig
    newPubspecYamlFile(testPackageRootPath, r'''
name: test
dependencies:
  aaa: any
dev_dependencies:
  bbb: any
''');

    var aaaRoot = getFolder('$workspaceRootPath/packages/aaa');
    newFile('${aaaRoot.path}/lib/f.dart', content: '''
class A01 {}
''');
    newFile('${aaaRoot.path}/lib/src/f.dart', content: '''
class A02 {}
''');

    var bbbRoot = getFolder('$workspaceRootPath/packages/bbb');
    newFile('${bbbRoot.path}/lib/f.dart', content: '''
class A03 {}
''');
    newFile('${bbbRoot.path}/lib/src/f.dart', content: '''
class A04 {}
''');

    writeTestPackageConfig(
      config: PackageConfigFileBuilder()
        ..add(name: 'aaa', rootPath: aaaRoot.path)
        ..add(name: 'bbb', rootPath: bbbRoot.path),
    );

    await _configureWithWorkspaceRoot();

    var test_path = convertPath('$testPackageTestPath/test.dart');
    var responseValidator = await _getCodeSuggestions(
      path: test_path,
      content: '''
void f() {
  A0^
}
''',
    );

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(2)
      ..assertLibrariesToImport(includes: [
        'package:aaa/f.dart',
        'package:bbb/f.dart',
      ], excludes: [
        'dart:core',
        'package:test/test.dart',
      ]);

    var classes = responseValidator.suggestions.withElementClass();
    classes.assertCompletions(['A01', 'A03']);
    classes.withCompletion('A01').assertSingle()
      ..assertClass()
      ..assertLibraryToImport('package:aaa/f.dart');
    classes.withCompletion('A03').assertSingle()
      ..assertClass()
      ..assertLibraryToImport('package:bbb/f.dart');
  }

  /// TODO(scheglov) Only lib/ libraries in lib/, no test/.
  /// TODO(scheglov) Suggestions from available Pub packages.
  Future<void> test_notImported_pub_this() async {
    newFile('$testPackageLibPath/a.dart', content: '''
class A01 {}
''');

    newFile('$testPackageLibPath/b.dart', content: '''
class A02 {}
''');

    await _configureWithWorkspaceRoot();

    var responseValidator = await _getTestCodeSuggestions('''
void f() {
  A0^
}
''');

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(2)
      ..assertLibrariesToImport(includes: [
        'dart:async',
        'dart:math',
        'package:test/a.dart',
        'package:test/b.dart',
      ], excludes: [
        'dart:core',
        'package:test/test.dart',
      ]);

    var classes = responseValidator.suggestions.withElementClass();
    classes.assertCompletions(['A01', 'A02']);
    classes.withCompletion('A01').assertSingle()
      ..assertClass()
      ..assertLibraryToImport('package:test/a.dart');
    classes.withCompletion('A02').assertSingle()
      ..assertClass()
      ..assertLibraryToImport('package:test/b.dart');
  }

  Future<void> test_notImported_pub_this_hasImport() async {
    newFile('$testPackageLibPath/a.dart', content: '''
class A01 {}
class A02 {}
''');

    newFile('$testPackageLibPath/b.dart', content: '''
class A03 {}
''');

    await _configureWithWorkspaceRoot();

    var responseValidator = await _getTestCodeSuggestions('''
import 'a.dart';

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

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(2)
      ..assertLibrariesToImport(includes: [
        'dart:async',
        'dart:math',
        'package:test/b.dart',
      ], excludes: [
        'dart:core',
        'package:test/a.dart',
        'package:test/test.dart',
      ]);

    var classes = responseValidator.suggestions.withElementClass();
    classes.assertCompletions(['A01', 'A02', 'A03']);
    classes.withCompletion('A01').assertSingle()
      ..assertClass()
      ..assertLibraryToImport(isNull);
    classes.withCompletion('A02').assertSingle()
      ..assertClass()
      ..assertLibraryToImport(isNull);
    classes.withCompletion('A03').assertSingle()
      ..assertClass()
      ..assertLibraryToImport('package:test/b.dart');
  }

  Future<void> test_notImported_pub_this_hasImport_hasShow() async {
    newFile('$testPackageLibPath/a.dart', content: '''
class A01 {}
class A02 {}
''');

    newFile('$testPackageLibPath/b.dart', content: '''
class A03 {}
''');

    await _configureWithWorkspaceRoot();

    var responseValidator = await _getTestCodeSuggestions('''
import 'a.dart' show A01;

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

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(2)
      ..assertLibrariesToImport(includes: [
        'dart:async',
        'dart:math',
        'package:test/a.dart',
        'package:test/b.dart',
      ], excludes: [
        'dart:core',
        'package:test/test.dart',
      ]);

    var classes = responseValidator.suggestions.withElementClass();
    classes.assertCompletions(['A01', 'A02', 'A03']);
    classes.withCompletion('A01').assertSingle()
      ..assertClass()
      ..assertLibraryToImport(isNull);
    classes.withCompletion('A02').assertSingle()
      ..assertClass()
      ..assertLibraryToImport('package:test/a.dart');
    classes.withCompletion('A03').assertSingle()
      ..assertClass()
      ..assertLibraryToImport('package:test/b.dart');
  }

  Future<void> test_notImported_pub_this_inLib_excludesTest() async {
    // TODO(scheglov) Switch to PubspecYamlFileConfig
    newPubspecYamlFile(testPackageRootPath, r'''
name: test
''');

    newFile('$testPackageLibPath/a.dart', content: '''
class A01 {}
''');

    var b = newFile('$testPackageTestPath/b.dart', content: '''
class A02 {}
''');

    await _configureWithWorkspaceRoot();

    var responseValidator = await _getTestCodeSuggestions('''
void f() {
  A0^
}
''');

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(2)
      ..assertLibrariesToImport(includes: [
        'package:test/a.dart',
      ], excludes: [
        'dart:core',
        'package:test/test.dart',
        toUriStr(b.path),
      ]);

    var classes = responseValidator.suggestions.withElementClass();
    classes.assertCompletions(['A01']);
    classes.withCompletion('A01').assertSingle()
      ..assertClass()
      ..assertLibraryToImport('package:test/a.dart');
  }

  Future<void> test_notImported_pub_this_inLib_includesThisSrc() async {
    // TODO(scheglov) Switch to PubspecYamlFileConfig
    newPubspecYamlFile(testPackageRootPath, r'''
name: test
''');

    newFile('$testPackageLibPath/f.dart', content: '''
class A01 {}
''');

    newFile('$testPackageLibPath/src/f.dart', content: '''
class A02 {}
''');

    await _configureWithWorkspaceRoot();

    var responseValidator = await _getTestCodeSuggestions('''
void f() {
  A0^
}
''');

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(2)
      ..assertLibrariesToImport(includes: [
        'package:test/f.dart',
        'package:test/src/f.dart',
      ], excludes: [
        'dart:core',
        'package:test/test.dart',
      ]);

    var classes = responseValidator.suggestions.withElementClass();
    classes.assertCompletions(['A01', 'A02']);
    classes.withCompletion('A01').assertSingle()
      ..assertClass()
      ..assertLibraryToImport('package:test/f.dart');
    classes.withCompletion('A02').assertSingle()
      ..assertClass()
      ..assertLibraryToImport('package:test/src/f.dart');
  }

  Future<void> test_notImported_pub_this_inTest_includesTest() async {
    // TODO(scheglov) Switch to PubspecYamlFileConfig
    newPubspecYamlFile(testPackageRootPath, r'''
name: test
''');

    newFile('$testPackageLibPath/a.dart', content: '''
class A01 {}
''');

    var b = newFile('$testPackageTestPath/b.dart', content: '''
class A02 {}
''');
    var b_uriStr = toUriStr(b.path);

    await _configureWithWorkspaceRoot();

    var test_path = convertPath('$testPackageTestPath/test.dart');
    var responseValidator = await _getCodeSuggestions(
      path: test_path,
      content: '''
void f() {
  A0^
}
''',
    );

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(2)
      ..assertLibrariesToImport(includes: [
        'package:test/a.dart',
        b_uriStr,
      ], excludes: [
        'dart:core',
        toUriStr(test_path),
      ]);

    var classes = responseValidator.suggestions.withElementClass();
    classes.assertCompletions(['A01', 'A02']);
    classes.withCompletion('A01').assertSingle()
      ..assertClass()
      ..assertLibraryToImport('package:test/a.dart');
    classes.withCompletion('A02').assertSingle()
      ..assertClass()
      ..assertLibraryToImport(b_uriStr);
  }

  Future<void> test_notImported_pub_this_inTest_includesThisSrc() async {
    // TODO(scheglov) Switch to PubspecYamlFileConfig
    newPubspecYamlFile(testPackageRootPath, r'''
name: test
''');

    newFile('$testPackageLibPath/f.dart', content: '''
class A01 {}
''');

    newFile('$testPackageLibPath/src/f.dart', content: '''
class A02 {}
''');

    await _configureWithWorkspaceRoot();

    var test_path = convertPath('$testPackageTestPath/test.dart');
    var responseValidator = await _getCodeSuggestions(
      path: test_path,
      content: '''
void f() {
  A0^
}
''',
    );

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(2)
      ..assertLibrariesToImport(includes: [
        'package:test/f.dart',
        'package:test/src/f.dart',
      ], excludes: [
        'dart:core',
        'package:test/test.dart',
      ]);

    var classes = responseValidator.suggestions.withElementClass();
    classes.assertCompletions(['A01', 'A02']);
    classes.withCompletion('A01').assertSingle()
      ..assertClass()
      ..assertLibraryToImport('package:test/f.dart');
    classes.withCompletion('A02').assertSingle()
      ..assertClass()
      ..assertLibraryToImport('package:test/src/f.dart');
  }

  Future<void> test_numResults_class_methods() async {
    await _configureWithWorkspaceRoot();

    var responseValidator = await _getTestCodeSuggestions('''
class A {
  void foo01() {}
  void foo02() {}
  void foo03() {}
}

void f(A a) {
  a.foo0^
}
''', maxResults: 2);

    responseValidator
      ..assertIncomplete()
      ..assertReplacementBack(4);

    var suggestionsValidator = responseValidator.suggestions;
    suggestionsValidator.assertCompletions(['foo01', 'foo02']);
  }

  Future<void> test_numResults_topLevelVariables() async {
    await _configureWithWorkspaceRoot();

    var responseValidator = await _getTestCodeSuggestions('''
var foo01 = 0;
var foo02 = 0;
var foo03 = 0;

void f() {
  foo0^
}
''', maxResults: 2);

    responseValidator
      ..assertIncomplete()
      ..assertReplacementBack(4);

    var suggestionsValidator = responseValidator.suggestions;
    suggestionsValidator.assertCompletions(['foo01', 'foo02']);
    suggestionsValidator
        .withCompletion('foo01')
        .assertSingle()
        .assertTopLevelVariable();
    suggestionsValidator
        .withCompletion('foo02')
        .assertSingle()
        .assertTopLevelVariable();
  }

  Future<void> test_numResults_topLevelVariables_imported_withPrefix() async {
    await _configureWithWorkspaceRoot();

    newFile('$testPackageLibPath/a.dart', content: '''
var foo01 = 0;
var foo02 = 0;
var foo03 = 0;
''');

    var responseValidator = await _getTestCodeSuggestions('''
import 'a.dart' as prefix;

void f() {
  prefix.^
}
''', maxResults: 2);

    responseValidator
      ..assertIncomplete()
      ..assertEmptyReplacement();

    var suggestionsValidator = responseValidator.suggestions;
    suggestionsValidator.assertCompletions(['foo01', 'foo02']);
  }

  Future<void> test_prefixed_class_constructors() async {
    await _configureWithWorkspaceRoot();

    var responseValidator = await _getTestCodeSuggestions('''
class A {
  A.foo01();
  A.foo02();
}

void f() {
  A.foo0^
}
''');

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(4);

    var suggestions = responseValidator.suggestions;
    suggestions.assertCompletions(['foo01', 'foo02']);
    suggestions.withCompletion('foo01').assertSingle().assertConstructor();
    suggestions.withCompletion('foo02').assertSingle().assertConstructor();
  }

  Future<void> test_prefixed_class_getters() async {
    await _configureWithWorkspaceRoot();

    var responseValidator = await _getTestCodeSuggestions('''
class A {
  int get foo01 => 0;
  int get foo02 => 0;
}

void f(A a) {
  a.foo0^
}
''');

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(4);

    var suggestions = responseValidator.suggestions;
    suggestions.assertCompletions(['foo01', 'foo02']);
    suggestions.withCompletion('foo01').assertSingle().assertGetter();
    suggestions.withCompletion('foo02').assertSingle().assertGetter();
  }

  Future<void> test_prefixed_class_methods_instance() async {
    await _configureWithWorkspaceRoot();

    var responseValidator = await _getTestCodeSuggestions('''
class A {
  void foo01() {}
  void foo02() {}
}

void f(A a) {
  a.foo0^
}
''');

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(4);

    var suggestions = responseValidator.suggestions;
    suggestions.assertCompletions(['foo01', 'foo02']);
    suggestions.withCompletion('foo01').assertSingle().assertMethod();
    suggestions.withCompletion('foo02').assertSingle().assertMethod();
  }

  Future<void> test_prefixed_class_methods_static() async {
    await _configureWithWorkspaceRoot();

    var responseValidator = await _getTestCodeSuggestions('''
class A {
  static void foo01() {}
  static void foo02() {}
}

void f() {
  A.foo0^
}
''');

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(4);

    var suggestions = responseValidator.suggestions;
    suggestions.assertCompletions(['foo01', 'foo02']);
    suggestions.withCompletion('foo01').assertSingle().assertMethod();
    suggestions.withCompletion('foo02').assertSingle().assertMethod();
  }

  Future<void> test_prefixed_expression_extensionGetters() async {
    await _configureWithWorkspaceRoot();

    var responseValidator = await _getTestCodeSuggestions(r'''
extension E1 on int {
  int get foo01 => 0;
  int get foo02 => 0;
  int get bar => 0;
}

extension E2 on double {
  int get foo03 => 0;
}

void f() {
  0.foo0^
}
''');

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(4);

    var suggestionsValidator = responseValidator.suggestions;
    suggestionsValidator.assertCompletions(['foo01', 'foo02']);

    suggestionsValidator.withCompletion('foo01').assertSingle().assertGetter();
    suggestionsValidator.withCompletion('foo02').assertSingle().assertGetter();
  }

  Future<void> test_prefixed_expression_extensionGetters_notImported() async {
    await _configureWithWorkspaceRoot();

    newFile('$testPackageLibPath/a.dart', content: '''
extension E1 on int {
  int get foo01 => 0;
  int get bar => 0;
}

extension E2 on int {
  int get foo02 => 0;
}

extension E3 on double {
  int get foo03 => 0;
}
''');

    var responseValidator = await _getTestCodeSuggestions(r'''
void f() {
  0.foo0^
}
''');

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(4);

    var suggestionsValidator = responseValidator.suggestions;
    suggestionsValidator.assertCompletions(['foo01', 'foo02']);

    suggestionsValidator.withCompletion('foo01').assertSingle()
      ..assertGetter()
      ..assertLibraryToImport('package:test/a.dart');
    suggestionsValidator.withCompletion('foo02').assertSingle()
      ..assertGetter()
      ..assertLibraryToImport('package:test/a.dart');
  }

  Future<void>
      test_prefixed_expression_extensionGetters_notImported_private() async {
    await _configureWithWorkspaceRoot();

    newFile('$testPackageLibPath/a.dart', content: '''
extension E1 on int {
  int get foo01 => 0;
}

extension _E2 on int {
  int get foo02 => 0;
}

extension on int {
  int get foo03 => 0;
}
''');

    var responseValidator = await _getTestCodeSuggestions(r'''
void f() {
  0.foo0^
}
''');

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(4);

    var suggestionsValidator = responseValidator.suggestions;
    suggestionsValidator.assertCompletions(['foo01']);

    suggestionsValidator.withCompletion('foo01').assertSingle()
      ..assertGetter()
      ..assertLibraryToImport('package:test/a.dart');
  }

  Future<void> test_prefixed_expression_extensionMethods() async {
    await _configureWithWorkspaceRoot();

    var responseValidator = await _getTestCodeSuggestions(r'''
extension E1 on int {
  void foo01() {}
  void foo02() {}
  void bar() {}
}

extension E2 on double {
  void foo03() {}
}

void f() {
  0.foo0^
}
''');

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(4);

    var suggestionsValidator = responseValidator.suggestions;
    suggestionsValidator.assertCompletions(['foo01', 'foo02']);

    suggestionsValidator.withCompletion('foo01').assertSingle().assertMethod();
    suggestionsValidator.withCompletion('foo02').assertSingle().assertMethod();
  }

  Future<void> test_prefixed_expression_extensionMethods_notImported() async {
    await _configureWithWorkspaceRoot();

    newFile('$testPackageLibPath/a.dart', content: '''
extension E1 on int {
  void foo01() {}
  void bar() {}
}

extension E2 on int {
  void foo02() {}
}

extension E3 on double {
  void foo03() {}
}
''');

    var responseValidator = await _getTestCodeSuggestions(r'''
void f() {
  0.foo0^
}
''');

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(4);

    var suggestionsValidator = responseValidator.suggestions;
    suggestionsValidator.assertCompletions(['foo01', 'foo02']);

    suggestionsValidator.withCompletion('foo01').assertSingle()
      ..assertMethod()
      ..assertLibraryToImport('package:test/a.dart');
    suggestionsValidator.withCompletion('foo02').assertSingle()
      ..assertMethod()
      ..assertLibraryToImport('package:test/a.dart');
  }

  Future<void> test_prefixed_expression_extensionSetters() async {
    await _configureWithWorkspaceRoot();

    var responseValidator = await _getTestCodeSuggestions(r'''
extension E1 on int {
  set foo01(int _) {}
  set foo02(int _) {}
  set bar(int _) {}
}

extension E2 on double {
  set foo03(int _) {}
}

void f() {
  0.foo0^
}
''');

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(4);

    var suggestionsValidator = responseValidator.suggestions;
    suggestionsValidator.assertCompletions(['foo01', 'foo02']);

    suggestionsValidator.withCompletion('foo01').assertSingle().assertSetter();
    suggestionsValidator.withCompletion('foo02').assertSingle().assertSetter();
  }

  Future<void> test_prefixed_expression_extensionSetters_notImported() async {
    await _configureWithWorkspaceRoot();

    newFile('$testPackageLibPath/a.dart', content: '''
extension E1 on int {
  set foo01(int _) {}
  set bar(int _) {}
}

extension E2 on int {
  set foo02(int _) {}
}

extension E3 on double {
  set foo03(int _) {}
}
''');

    var responseValidator = await _getTestCodeSuggestions(r'''
void f() {
  0.foo0^
}
''');

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(4);

    var suggestionsValidator = responseValidator.suggestions;
    suggestionsValidator.assertCompletions(['foo01', 'foo02']);

    suggestionsValidator.withCompletion('foo01').assertSingle()
      ..assertSetter()
      ..assertLibraryToImport('package:test/a.dart');
    suggestionsValidator.withCompletion('foo02').assertSingle()
      ..assertSetter()
      ..assertLibraryToImport('package:test/a.dart');
  }

  Future<void>
      test_prefixed_expression_extensionSetters_notImported_private() async {
    await _configureWithWorkspaceRoot();

    newFile('$testPackageLibPath/a.dart', content: '''
extension E1 on int {
  set foo01(int _) {}
}

extension _E2 on int {
  set foo02(int _) {}
}

extension on int {
  set foo03(int _) {}
}
''');

    var responseValidator = await _getTestCodeSuggestions(r'''
void f() {
  0.foo0^
}
''');

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(4);

    var suggestionsValidator = responseValidator.suggestions;
    suggestionsValidator.assertCompletions(['foo01']);

    suggestionsValidator.withCompletion('foo01').assertSingle()
      ..assertSetter()
      ..assertLibraryToImport('package:test/a.dart');
  }

  Future<void> test_prefixed_extensionGetters_imported() async {
    await _configureWithWorkspaceRoot();

    newFile('$testPackageLibPath/a.dart', content: '''
extension E1 on int {
  int get foo01 => 0;
  int get foo02 => 0;
  int get bar => 0;
}

extension E2 on double {
  int get foo03 => 0;
}
''');

    var responseValidator = await _getTestCodeSuggestions(r'''
import 'a.dart';

void f() {
  0.foo0^
}
''');

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(4);

    var suggestionsValidator = responseValidator.suggestions;
    suggestionsValidator.assertCompletions(['foo01', 'foo02']);

    suggestionsValidator.withCompletion('foo01').assertSingle().assertGetter();
    suggestionsValidator.withCompletion('foo02').assertSingle().assertGetter();
  }

  Future<void> test_prefixed_extensionOverride_extensionGetters() async {
    await _configureWithWorkspaceRoot();

    var responseValidator = await _getTestCodeSuggestions(r'''
extension E1 on int {
  int get foo01 => 0;
}

extension E2 on int {
  int get foo02 => 0;
}

void f() {
  E1(0).foo0^
}
''');

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(4);

    var suggestionsValidator = responseValidator.suggestions;
    suggestionsValidator.assertCompletions(['foo01']);
    suggestionsValidator.withCompletion('foo01').assertSingle().assertGetter();
  }

  Future<void> test_prefixed_extensionOverride_extensionMethods() async {
    await _configureWithWorkspaceRoot();

    var responseValidator = await _getTestCodeSuggestions(r'''
extension E1 on int {
  void foo01() {}
}

extension E2 on int {
  void foo01() {}
}

void f() {
  E1(0).foo0^
}
''');

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(4);

    var suggestionsValidator = responseValidator.suggestions;
    suggestionsValidator.assertCompletions(['foo01']);
    suggestionsValidator.withCompletion('foo01').assertSingle().assertMethod();
  }

  Future<void> test_unprefixed_filters() async {
    await _configureWithWorkspaceRoot();

    var responseValidator = await _getTestCodeSuggestions(r'''
var foo01 = 0;
var foo02 = 0;
var bar01 = 0;
var bar02 = 0;

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

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(4);

    var suggestionsValidator = responseValidator.suggestions;
    suggestionsValidator.assertCompletions(['foo01', 'foo02']);

    suggestionsValidator
        .withCompletion('foo01')
        .assertSingle()
        .assertTopLevelVariable();
    suggestionsValidator
        .withCompletion('foo02')
        .assertSingle()
        .assertTopLevelVariable();
    suggestionsValidator.withCompletion('bar01').assertEmpty();
    suggestionsValidator.withCompletion('bar02').assertEmpty();
  }

  Future<void> test_unprefixed_imported_class() async {
    await _configureWithWorkspaceRoot();

    newFile('$testPackageLibPath/a.dart', content: '''
class A01 {}
''');

    newFile('$testPackageLibPath/b.dart', content: '''
class A02 {}
''');

    var responseValidator = await _getTestCodeSuggestions('''
import 'a.dart';
import 'b.dart';

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

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(2);

    var classes = responseValidator.suggestions.withElementClass();
    classes.assertCompletions(['A01', 'A02']);
    classes.withCompletion('A01').assertSingle().assertClass();
    classes.withCompletion('A02').assertSingle().assertClass();
  }

  Future<void> test_unprefixed_imported_topLevelVariable() async {
    await _configureWithWorkspaceRoot();

    newFile('$testPackageLibPath/a.dart', content: '''
var foo01 = 0;
''');

    newFile('$testPackageLibPath/b.dart', content: '''
var foo02 = 0;
''');

    var responseValidator = await _getTestCodeSuggestions('''
import 'a.dart';
import 'b.dart';

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

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(4);

    var suggestionsValidator = responseValidator.suggestions;
    suggestionsValidator.assertCompletions(['foo01', 'foo02']);
    suggestionsValidator
        .withCompletion('foo01')
        .assertSingle()
        .assertTopLevelVariable();
    suggestionsValidator
        .withCompletion('foo02')
        .assertSingle()
        .assertTopLevelVariable();
  }

  Future<void> test_unprefixed_sorts_byScore() async {
    await _configureWithWorkspaceRoot();

    var responseValidator = await _getTestCodeSuggestions(r'''
var fooAB = 0;
var fooBB = 0;

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

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(4);

    var suggestionsValidator = responseValidator.suggestions;
    // `fooBB` has better score than `fooAB` - prefix match
    suggestionsValidator.assertCompletions(['fooBB', 'fooAB']);
  }

  Future<void> test_unprefixed_sorts_byType() async {
    await _configureWithWorkspaceRoot();

    var responseValidator = await _getTestCodeSuggestions(r'''
var foo01 = 0.0;
var foo02 = 0;

void f() {
  int v = foo0^
}
''');

    responseValidator
      ..assertComplete()
      ..assertReplacementBack(4);

    var suggestionsValidator = responseValidator.suggestions;
    // `foo02` has better relevance, its type matches the context type
    suggestionsValidator.assertCompletions(['foo02', 'foo01']);
  }

  Future<CompletionGetSuggestions2ResponseValidator> _getCodeSuggestions({
    required String path,
    required String content,
    int maxResults = 1 << 10,
  }) async {
    var completionOffset = content.indexOf('^');
    expect(completionOffset, isNot(equals(-1)), reason: 'missing ^');

    var nextOffset = content.indexOf('^', completionOffset + 1);
    expect(nextOffset, equals(-1), reason: 'too many ^');

    newFile(path,
        content: content.substring(0, completionOffset) +
            content.substring(completionOffset + 1));

    return await _getSuggestions(
      path: path,
      completionOffset: completionOffset,
      maxResults: maxResults,
    );
  }

  Future<CompletionGetSuggestions2ResponseValidator> _getSuggestions({
    required String path,
    required int completionOffset,
    required int maxResults,
  }) async {
    var request = CompletionGetSuggestions2Params(
      path,
      completionOffset,
      maxResults,
    ).toRequest('0');

    var response = await _handleSuccessfulRequest(request);
    var result = CompletionGetSuggestions2Result.fromResponse(response);
    return CompletionGetSuggestions2ResponseValidator(completionOffset, result);
  }

  Future<CompletionGetSuggestions2ResponseValidator> _getTestCodeSuggestions(
    String content, {
    int maxResults = 1 << 10,
  }) async {
    return _getCodeSuggestions(
      path: convertPath(testFilePath),
      content: content,
      maxResults: maxResults,
    );
  }
}

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

  Future<void> test_ArgumentList_constructor_named_param_label() async {
    addTestFile('void f() { new A(^);}'
        'class A { A({one, two}) {} }');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'one: ');
    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'two: ');
    expect(suggestions, hasLength(2));
  }

  Future<void> test_ArgumentList_factory_named_param_label() async {
    addTestFile('void f() { new A(^);}'
        'class A { factory A({one, two}) => throw 0; }');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'one: ');
    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'two: ');
    expect(suggestions, hasLength(2));
  }

  Future<void>
      test_ArgumentList_function_named_fromPositionalNumeric_withoutSpace() async {
    addTestFile('void f(int a, {int b = 0}) {}'
        'void g() { f(2, ^3); }');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'b: ');
    expect(suggestions, hasLength(1));
    // Ensure we don't try to replace the following arg.
    expect(replacementOffset, equals(completionOffset));
    expect(replacementLength, equals(0));
  }

  Future<void>
      test_ArgumentList_function_named_fromPositionalNumeric_withSpace() async {
    addTestFile('void f(int a, {int b = 0}) {}'
        'void g() { f(2, ^ 3); }');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'b: ');
    expect(suggestions, hasLength(1));
    // Ensure we don't try to replace the following arg.
    expect(replacementOffset, equals(completionOffset));
    expect(replacementLength, equals(0));
  }

  Future<void>
      test_ArgumentList_function_named_fromPositionalVariable_withoutSpace() async {
    addTestFile('void f(int a, {int b = 0}) {}'
        'var foo = 1;'
        'void g() { f(2, ^foo); }');
    await getSuggestions();
    expect(suggestions, hasLength(1));

    // The named arg "b: " should not replace anything.
    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'b: ',
        replacementOffset: null, replacementLength: 0);
  }

  Future<void>
      test_ArgumentList_function_named_fromPositionalVariable_withSpace() async {
    addTestFile('void f(int a, {int b = 0}) {}'
        'var foo = 1;'
        'void g() { f(2, ^ foo); }');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'b: ');
    expect(suggestions, hasLength(1));
    // Ensure we don't try to replace the following arg.
    expect(replacementOffset, equals(completionOffset));
    expect(replacementLength, equals(0));
  }

  Future<void> test_ArgumentList_function_named_partiallyTyped() async {
    addTestFile('''
    class C {
      void m(String firstString, {String secondString}) {}

      void n() {
        m('a', se^'b');
      }
    }
    ''');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'secondString: ');
    expect(suggestions, hasLength(1));
    // Ensure we replace the correct section.
    expect(replacementOffset, equals(completionOffset - 2));
    expect(replacementLength, equals(2));
  }

  Future<void> test_ArgumentList_imported_function_named_param() async {
    addTestFile('void f() { int.parse("16", ^);}');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'radix: ');
    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'onError: ');
    expect(suggestions, hasLength(2));
  }

  Future<void> test_ArgumentList_imported_function_named_param1() async {
    addTestFile('void f() { foo(o^);} foo({one, two}) {}');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'one: ');
    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'two: ');
    expect(suggestions, hasLength(2));
  }

  Future<void> test_ArgumentList_imported_function_named_param2() async {
    addTestFile('void f() {A a = new A(); a.foo(one: 7, ^);}'
        'class A { foo({one, two}) {} }');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'two: ');
    expect(suggestions, hasLength(1));
  }

  Future<void> test_ArgumentList_imported_function_named_param_label1() async {
    addTestFile('void f() { int.parse("16", r^: 16);}');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'radix');
    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'onError');
    expect(suggestions, hasLength(2));
  }

  Future<void> test_ArgumentList_imported_function_named_param_label3() async {
    addTestFile('void f() { int.parse("16", ^: 16);}');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'radix: ');
    assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'onError: ');
    expect(suggestions, hasLength(2));
  }

  Future<void> test_catch() async {
    addTestFile('void f() {try {} ^}');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'on');
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'catch');
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'finally');
    expect(suggestions, hasLength(3));
  }

  Future<void> test_catch2() async {
    addTestFile('void f() {try {} on Foo {} ^}');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'on');
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'catch');
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'finally');
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'for');
    suggestions.firstWhere(
        (CompletionSuggestion suggestion) =>
            suggestion.kind != CompletionSuggestionKind.KEYWORD, orElse: () {
      fail('Expected suggestions other than keyword suggestions');
    });
  }

  Future<void> test_catch3() async {
    addTestFile('void f() {try {} catch (e) {} finally {} ^}');
    await getSuggestions();
    assertNoResult('on');
    assertNoResult('catch');
    assertNoResult('finally');
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'for');
    suggestions.firstWhere(
        (CompletionSuggestion suggestion) =>
            suggestion.kind != CompletionSuggestionKind.KEYWORD, orElse: () {
      fail('Expected suggestions other than keyword suggestions');
    });
  }

  Future<void> test_catch4() async {
    addTestFile('void f() {try {} finally {} ^}');
    await getSuggestions();
    assertNoResult('on');
    assertNoResult('catch');
    assertNoResult('finally');
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'for');
    suggestions.firstWhere(
        (CompletionSuggestion suggestion) =>
            suggestion.kind != CompletionSuggestionKind.KEYWORD, orElse: () {
      fail('Expected suggestions other than keyword suggestions');
    });
  }

  Future<void> test_catch5() async {
    addTestFile('void f() {try {} ^ finally {}}');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'on');
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'catch');
    expect(suggestions, hasLength(2));
  }

  Future<void> test_constructor() async {
    addTestFile('class A {bool foo; A() : ^;}');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'super');
    assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo');
  }

  Future<void> test_constructor2() async {
    addTestFile('class A {bool foo; A() : s^;}');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'super');
    assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo');
  }

  Future<void> test_constructor3() async {
    addTestFile('class A {bool foo; A() : a=7,^;}');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'super');
    assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo');
  }

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

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

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

  Future<void> test_extension() async {
    addTestFile('''
class MyClass {
  void foo() {
    ba^
  }
}

extension MyClassExtension on MyClass {
  void bar() {}
}
''');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.INVOCATION, 'bar');
  }

  Future<void> test_html() {
    //
    // We no longer support the analysis of non-dart files.
    //
    testFile = convertPath('/project/web/test.html');
    addTestFile('''
      <html>^</html>
    ''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      expect(suggestions, hasLength(0));
    });
  }

  Future<void> test_import_uri_with_trailing() {
    final filePath = '/project/bin/testA.dart';
    final incompleteImportText = toUriStr('/project/bin/t');
    newFile(filePath, content: 'library libA;');
    addTestFile('''
    import "$incompleteImportText^.dart";
    void f() {}''');
    return getSuggestions().then((_) {
      expect(replacementOffset,
          equals(completionOffset - incompleteImportText.length));
      expect(replacementLength, equals(5 + incompleteImportText.length));
      assertHasResult(CompletionSuggestionKind.IMPORT, toUriStr(filePath));
      assertNoResult('test');
    });
  }

  Future<void> test_imports() {
    addTestFile('''
      import 'dart:html';
      void f() {^}
    ''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object',
          elementKind: ElementKind.CLASS);
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement',
          elementKind: ElementKind.CLASS);
      assertNoResult('test');
    });
  }

  Future<void> test_imports_aborted_new_request() async {
    addTestFile('''
        class foo { }
        c^''');

    // Make a request for suggestions
    var request1 = CompletionGetSuggestionsParams(testFile, completionOffset)
        .toRequest('7');
    var responseFuture1 = waitResponse(request1);

    // Make another request before the first request completes
    var request2 = CompletionGetSuggestionsParams(testFile, completionOffset)
        .toRequest('8');
    var responseFuture2 = waitResponse(request2);

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

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

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

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

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

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

    // Make a request for suggestions
    var request = CompletionGetSuggestionsParams(testFile, completionOffset)
        .toRequest('0');
    var responseFuture = waitResponse(request);

    // Simulate user deleting text after request but before suggestions returned
    server.updateContent('uc1', {testFile: AddContentOverlay(testCode)});
    server.updateContent('uc2', {
      testFile: ChangeContentOverlay([SourceEdit(completionOffset - 1, 1, '')])
    });

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

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

    // Assert that request has been aborted
    expect(suggestionsDone, isTrue);
    expect(suggestions, hasLength(0));
  }

  Future<void> test_imports_incremental() async {
    addTestFile('''library foo;
      e^
      import "dart:async";
      import "package:foo/foo.dart";
      class foo { }''');
    await waitForTasksFinished();
    server.updateContent('uc1', {testFile: AddContentOverlay(testCode)});
    server.updateContent('uc2', {
      testFile: ChangeContentOverlay([SourceEdit(completionOffset, 0, 'xp')])
    });
    completionOffset += 2;
    await getSuggestions();
    expect(replacementOffset, completionOffset - 3);
    expect(replacementLength, 3);
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'export \'\';',
        selectionOffset: 8);
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'import \'\';',
        selectionOffset: 8);
    assertNoResult('extends');
    assertNoResult('library');
  }

  Future<void> test_imports_partial() async {
    addTestFile('''^
      import "package:foo/foo.dart";
      import "package:bar/bar.dart";
      class Baz { }''');

    // Wait for analysis then edit the content
    await waitForTasksFinished();
    var revisedContent = testCode.substring(0, completionOffset) +
        'i' +
        testCode.substring(completionOffset);
    ++completionOffset;
    server.handleRequest(AnalysisUpdateContentParams(
        {testFile: AddContentOverlay(revisedContent)}).toRequest('add1'));

    // Request code completion immediately after edit
    var response = await waitResponse(
        CompletionGetSuggestionsParams(testFile, completionOffset)
            .toRequest('0'));
    completionId = response.id;
    assertValidId(completionId);
    await waitForTasksFinished();
    // wait for response to arrive
    // because although the analysis is complete (waitForTasksFinished)
    // the response may not yet have been processed
    while (replacementOffset == null) {
      await Future.delayed(Duration(milliseconds: 5));
    }
    expect(replacementOffset, completionOffset - 1);
    expect(replacementLength, 1);
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'library');
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'import \'\';',
        selectionOffset: 8);
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'export \'\';',
        selectionOffset: 8);
    assertHasResult(CompletionSuggestionKind.KEYWORD, 'part \'\';',
        selectionOffset: 6);
    assertNoResult('extends');
  }

  Future<void> test_imports_prefixed() {
    addTestFile('''
      import 'dart:html' as foo;
      void f() {^}
    ''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object',
          elementKind: ElementKind.CLASS);
      assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'foo');
      assertNoResult('HtmlElement');
      assertNoResult('test');
    });
  }

  Future<void> test_imports_prefixed2() {
    addTestFile('''
      import 'dart:html' as foo;
      void f() {foo.^}
    ''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement');
      assertNoResult('test');
    });
  }

  Future<void> test_inComment_block_beforeNode() async {
    addTestFile('''
  void f(aaa, bbb) {
    /* text ^ */
    print(42);
  }
  ''');
    await getSuggestions();
    expect(suggestions, isEmpty);
  }

  Future<void> test_inComment_endOfFile_withNewline() async {
    addTestFile('''
    // text ^
  ''');
    await getSuggestions();
    expect(suggestions, isEmpty);
  }

  Future<void> test_inComment_endOfFile_withoutNewline() async {
    addTestFile('// text ^');
    await getSuggestions();
    expect(suggestions, isEmpty);
  }

  Future<void> test_inComment_endOfLine_beforeNode() async {
    addTestFile('''
  void f(aaa, bbb) {
    // text ^
    print(42);
  }
  ''');
    await getSuggestions();
    expect(suggestions, isEmpty);
  }

  Future<void> test_inComment_endOfLine_beforeToken() async {
    addTestFile('''
  void f(aaa, bbb) {
    // text ^
  }
  ''');
    await getSuggestions();
    expect(suggestions, isEmpty);
  }

  Future<void> test_inDartDoc1() async {
    addTestFile('''
  /// ^
  void f(aaa, bbb) {}
  ''');
    await getSuggestions();
    expect(suggestions, isEmpty);
  }

  Future<void> test_inDartDoc2() async {
    addTestFile('''
  /// Some text^
  void f(aaa, bbb) {}
  ''');
    await getSuggestions();
    expect(suggestions, isEmpty);
  }

  Future<void> test_inDartDoc3() async {
    addTestFile('''
class MyClass {
  /// ^
  void foo() {}

  void bar() {}
}

extension MyClassExtension on MyClass {
  void baz() {}
}
  ''');
    await getSuggestions();
    expect(suggestions, isEmpty);
  }

  Future<void> test_inDartDoc_reference1() async {
    newFile('/testA.dart', content: '''
  part of libA;
  foo(bar) => 0;''');
    addTestFile('''
  library libA;
  part "${toUriStr('/testA.dart')}";
  import "dart:math";
  /// The [^]
  void f(aaa, bbb) {}
  ''');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'f');
    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'foo');
    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'min');
  }

  Future<void> test_inDartDoc_reference2() async {
    addTestFile('''
  /// The [m^]
  void f(aaa, bbb) {}
  ''');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'f');
  }

  Future<void> test_inDartDoc_reference3() async {
    addTestFile('''
class MyClass {
  /// [^]
  void foo() {}

  void bar() {}
}

extension MyClassExtension on MyClass {
  void baz() {}
}
  ''');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'bar');
    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'baz');
  }

  Future<void> test_inherited() {
    addTestFile('''
class A {
  m() {}
}
class B extends A {
  x() {^}
}
''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm');
    });
  }

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

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

  Future<void> test_invocation() {
    addTestFile('class A {b() {}} void f() {A a; a.^}');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
    });
  }

  Future<void> test_invocation_withTrailingStmt() {
    addTestFile('class A {b() {}} void f() {A a; a.^ int x = 7;}');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
    });
  }

  Future<void> test_is_asPrefixedIdentifierStart() async {
    addTestFile('''
class A { var isVisible;}
void f(A p) { var v1 = p.is^; }''');
    await getSuggestions();
    assertHasResult(CompletionSuggestionKind.INVOCATION, 'isVisible');
  }

  Future<void> test_keyword() {
    addTestFile('library A; cl^');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset - 2));
      expect(replacementLength, equals(2));
      assertHasResult(CompletionSuggestionKind.KEYWORD, 'export \'\';',
          selectionOffset: 8);
      assertHasResult(CompletionSuggestionKind.KEYWORD, 'class');
    });
  }

  Future<void> test_local_implicitCreation() async {
    addTestFile('''
class A {
  A();
  A.named();
}
void f() {
  ^
}
''');
    await getSuggestions();

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

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

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

  Future<void> test_local_named_constructor() {
    addTestFile('class A {A.c(); x() {new A.^}}');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'c');
      assertNoResult('A');
    });
  }

  Future<void> test_local_override() {
    newFile('/project/bin/a.dart', content: 'class A {m() {}}');
    addTestFile('''
import 'a.dart';
class B extends A {
  m() {}
  x() {^}
}
''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm');
    });
  }

  Future<void> test_local_shadowClass() async {
    addTestFile('''
class A {
  A();
  A.named();
}
void f() {
  int A = 0;
  ^
}
''');
    await getSuggestions();

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

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

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

  Future<void> test_locals() {
    addTestFile('class A {var a; x() {var b;^}} class DateTime { }');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'A',
          elementKind: ElementKind.CLASS);
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'a');
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'x');
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'DateTime',
          elementKind: ElementKind.CLASS);
    });
  }

  Future<void> test_offset_past_eof() async {
    addTestFile('void f() { }', offset: 300);
    var request = CompletionGetSuggestionsParams(testFile, completionOffset)
        .toRequest('0');
    var response = await waitResponse(request);
    expect(response.id, '0');
    expect(response.error!.code, RequestErrorCode.INVALID_PARAMETER);
  }

  Future<void> test_overrides() {
    newFile('/project/bin/a.dart', content: 'class A {m() {}}');
    addTestFile('''
import 'a.dart';
class B extends A {m() {^}}
''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm');
    });
  }

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

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

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

  Future<void> test_simple() {
    addTestFile('''
      void f() {
        ^
      }
    ''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset));
      expect(replacementLength, equals(0));
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object',
          elementKind: ElementKind.CLASS);
      assertNoResult('HtmlElement');
      assertNoResult('test');
    });
  }

  Future<void> test_static() async {
    addTestFile('class A {static b() {} c() {}} void f() {A.^}');
    await getSuggestions();
    expect(replacementOffset, equals(completionOffset));
    expect(replacementLength, equals(0));
    assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
    assertNoResult('c');
  }

  Future<void> test_topLevel() {
    addTestFile('''
      typedef foo();
      var test = '';
      void f() {tes^t}
    ''');
    return getSuggestions().then((_) {
      expect(replacementOffset, equals(completionOffset - 3));
      expect(replacementLength, equals(4));
      // Suggestions based upon imported elements are partially filtered
      //assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
      assertHasResult(CompletionSuggestionKind.INVOCATION, 'test');
      assertNoResult('HtmlElement');
    });
  }
}

class CompletionGetSuggestions2ResponseValidator {
  final int completionOffset;
  final CompletionGetSuggestions2Result result;

  CompletionGetSuggestions2ResponseValidator(
    this.completionOffset,
    this.result,
  );

  SuggestionsValidator get suggestions {
    return SuggestionsValidator(
      result.suggestions,
      libraryUrisToImport: result.libraryUrisToImport,
    );
  }

  void assertComplete() {
    expect(result.isIncomplete, isFalse);
  }

  void assertEmptyReplacement() {
    assertReplacement(completionOffset, 0);
  }

  void assertIncomplete() {
    expect(result.isIncomplete, isTrue);
  }

  void assertLibrariesToImport({
    required List<String> includes,
    List<String>? excludes,
  }) {
    expect(result.libraryUrisToImport, containsAll(includes));
    if (excludes != null) {
      for (var exclude in excludes) {
        expect(result.libraryUrisToImport, isNot(contains(exclude)));
      }
    }
  }

  void assertReplacement(int offset, int length) {
    expect(result.replacementOffset, offset);
    expect(result.replacementLength, length);
  }

  void assertReplacementBack(int length) {
    assertReplacement(completionOffset - length, length);
  }
}

class GetSuggestionDetails2Validator {
  final CompletionGetSuggestionDetails2Result result;

  GetSuggestionDetails2Validator(this.result);

  SourceChangeValidator hasChange() {
    return SourceChangeValidator(result.change);
  }

  void hasCompletion(Object completion) {
    expect(result.completion, completion);
  }
}

class PubPackageAnalysisServerTest with ResourceProviderMixin {
  late final MockServerChannel serverChannel;
  late final AnalysisServer server;

  AnalysisDomainHandler get analysisDomain {
    return server.handlers.whereType<AnalysisDomainHandler>().single;
  }

  CompletionDomainHandler get completionDomain {
    return server.handlers.whereType<CompletionDomainHandler>().single;
  }

  String get testFileContent => getFile(testFilePath).readAsStringSync();

  String get testFilePath => '$testPackageLibPath/test.dart';

  String get testFilePathPlatform => convertPath(testFilePath);

  String get testPackageLibPath => '$testPackageRootPath/lib';

  Folder get testPackageRoot => getFolder(testPackageRootPath);

  String get testPackageRootPath => '$workspaceRootPath/test';

  String get testPackageTestPath => '$testPackageRootPath/test';

  String get workspaceRootPath => '/home';

  Future<void> setRoots({
    required List<String> included,
    required List<String> excluded,
  }) async {
    var includedConverted = included.map(convertPath).toList();
    var excludedConverted = excluded.map(convertPath).toList();
    await _handleSuccessfulRequest(
      AnalysisSetAnalysisRootsParams(
        includedConverted,
        excludedConverted,
        packageRoots: {},
      ).toRequest('0'),
    );
  }

  void setUp() {
    serverChannel = MockServerChannel();

    var sdkRoot = newFolder('/sdk');
    createMockSdk(
      resourceProvider: resourceProvider,
      root: sdkRoot,
    );

    writeTestPackageConfig();

    server = AnalysisServer(
      serverChannel,
      resourceProvider,
      AnalysisServerOptions(),
      DartSdkManager(sdkRoot.path),
      CrashReportingAttachmentsBuilder.empty,
      InstrumentationService.NULL_SERVICE,
    );

    completionDomain.budgetDuration = const Duration(seconds: 30);
  }

  void writePackageConfig(Folder root, PackageConfigFileBuilder config) {
    newPackageConfigJsonFile(
      root.path,
      content: config.toContent(toUriStr: toUriStr),
    );
  }

  void writeTestPackageConfig({
    PackageConfigFileBuilder? config,
    String? languageVersion,
  }) {
    if (config == null) {
      config = PackageConfigFileBuilder();
    } else {
      config = config.copy();
    }

    config.add(
      name: 'test',
      rootPath: testPackageRootPath,
      languageVersion: languageVersion,
    );

    writePackageConfig(testPackageRoot, config);
  }

  Future<void> _configureWithWorkspaceRoot() async {
    await setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;
  }

  Future<Response> _handleRequest(Request request) async {
    return await serverChannel.sendRequest(request);
  }

  /// Validates that the given [request] is handled successfully.
  Future<Response> _handleSuccessfulRequest(Request request) async {
    var response = await _handleRequest(request);
    expect(response, isResponseSuccess(request.id));
    return response;
  }
}

class SingleSuggestionValidator {
  final CompletionSuggestion suggestion;
  final List<String>? libraryUrisToImport;

  SingleSuggestionValidator(
    this.suggestion, {
    this.libraryUrisToImport,
  });

  void assertClass() {
    expect(suggestion.kind, CompletionSuggestionKind.INVOCATION);
    expect(suggestion.element?.kind, ElementKind.CLASS);
  }

  void assertConstructor() {
    expect(suggestion.kind, CompletionSuggestionKind.INVOCATION);
    expect(suggestion.element?.kind, ElementKind.CONSTRUCTOR);
  }

  void assertGetter() {
    expect(suggestion.kind, CompletionSuggestionKind.INVOCATION);
    expect(suggestion.element?.kind, ElementKind.GETTER);
  }

  void assertLibraryToImport(Object matcher) {
    final libraryUrisToImport = this.libraryUrisToImport;
    final index = suggestion.libraryUriToImportIndex;
    var libraryUri = libraryUrisToImport != null && index != null
        ? libraryUrisToImport[index]
        : null;
    expect(libraryUri, matcher);
  }

  void assertMethod() {
    expect(suggestion.kind, CompletionSuggestionKind.INVOCATION);
    expect(suggestion.element?.kind, ElementKind.METHOD);
  }

  void assertSetter() {
    expect(suggestion.kind, CompletionSuggestionKind.INVOCATION);
    expect(suggestion.element?.kind, ElementKind.SETTER);
  }

  void assertTopLevelVariable() {
    expect(suggestion.kind, CompletionSuggestionKind.INVOCATION);
    expect(suggestion.element?.kind, ElementKind.TOP_LEVEL_VARIABLE);
  }
}

class SourceChangeValidator {
  final SourceChange change;

  SourceChangeValidator(this.change);

  void assertNoFileEdits() {
    expect(change.edits, isEmpty);
  }

  SourceFileEditValidator hasFileEdit(String path) {
    var edit = change.edits.singleWhere((e) => e.file == path);
    return SourceFileEditValidator(edit);
  }
}

class SourceFileEditValidator {
  final SourceFileEdit edit;

  SourceFileEditValidator(this.edit);

  void whenApplied(String applyTo, Object expected) {
    var actual = SourceEdit.applySequence(applyTo, edit.edits);
    expect(actual, expected);
  }
}

class SuggestionsValidator {
  final List<CompletionSuggestion> suggestions;
  final List<String>? libraryUrisToImport;

  SuggestionsValidator(
    this.suggestions, {
    this.libraryUrisToImport,
  });

  int get length => suggestions.length;

  /// Assert that this has suggestions with exactly the given completions,
  /// with the exact order.
  ///
  /// Does not check suggestion kinds, elements, etc.
  void assertCompletions(Iterable<String> completions) {
    var actual = suggestions.map((e) => e.completion).toList();
    expect(actual, completions);
  }

  void assertEmpty() {
    expect(suggestions, isEmpty);
  }

  void assertLength(Object matcher) {
    expect(suggestions, hasLength(matcher));
  }

  SingleSuggestionValidator assertSingle() {
    assertLength(1);
    return SingleSuggestionValidator(
      suggestions.single,
      libraryUrisToImport: libraryUrisToImport,
    );
  }

  SuggestionsValidator withCompletion(String completion) {
    return SuggestionsValidator(
      suggestions.where((suggestion) {
        return suggestion.completion == completion;
      }).toList(),
      libraryUrisToImport: libraryUrisToImport,
    );
  }

  SuggestionsValidator withElementClass() {
    return withElementKind(ElementKind.CLASS);
  }

  SuggestionsValidator withElementConstructor() {
    return withElementKind(ElementKind.CONSTRUCTOR);
  }

  SuggestionsValidator withElementGetter() {
    return withElementKind(ElementKind.GETTER);
  }

  SuggestionsValidator withElementKind(ElementKind kind) {
    return SuggestionsValidator(
      suggestions.where((suggestion) {
        return suggestion.element?.kind == kind;
      }).toList(),
      libraryUrisToImport: libraryUrisToImport,
    );
  }
}
