// 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.

// @dart = 2.9

import 'dart:async';

import 'package:analysis_server/protocol/protocol.dart';
import 'package:analysis_server/protocol/protocol_constants.dart';
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/domain_analysis.dart';
import 'package:analysis_server/src/server/crash_reporting_attachments.dart';
import 'package:analysis_server/src/utilities/mocks.dart';
import 'package:analyzer/instrumentation/instrumentation.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_common.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
import 'package:meta/meta.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'analysis_abstract.dart';
import 'mocks.dart';

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(AnalysisDomainTest);
    defineReflectiveTests(AnalysisDomainHandlerTest);
    defineReflectiveTests(SetSubscriptionsTest);
  });
}

@reflectiveTest
class AnalysisDomainHandlerTest extends AbstractAnalysisTest {
  Future<void> outOfRangeTest(SourceEdit edit) async {
    var helper = AnalysisTestHelper();
    helper.createSingleFileProject('library A;');
    await helper.onAnalysisComplete;
    helper.sendContentChange(AddContentOverlay('library B;'));
    await helper.onAnalysisComplete;
    var contentChange = ChangeContentOverlay([edit]);
    var request = AnalysisUpdateContentParams({helper.testFile: contentChange})
        .toRequest('0');
    var response = helper.handler.handleRequest(request);
    expect(response,
        isResponseFailure('0', RequestErrorCode.INVALID_OVERLAY_CHANGE));
  }

  Future<void> test_setAnalysisRoots_excludedFolder() async {
    newFile('/project/aaa/a.dart', content: '// a');
    newFile('/project/bbb/b.dart', content: '// b');
    var excludedPath = join(projectPath, 'bbb');
    var response = testSetAnalysisRoots([projectPath], [excludedPath]);
    expect(response, isResponseSuccess('0'));
  }

  Future<void> test_setAnalysisRoots_included_newFolder() async {
    newPubspecYamlFile('/project', 'name: project');
    var file = newFile('/project/bin/test.dart', content: 'main() {}').path;
    var response = testSetAnalysisRoots([projectPath], []);
    var serverRef = server;
    expect(response, isResponseSuccess('0'));
    // verify that unit is resolved eventually
    await server.onAnalysisComplete;
    var resolvedUnit = await serverRef.getResolvedUnit(file);
    expect(resolvedUnit, isNotNull);
  }

  Future<void> test_setAnalysisRoots_included_nonexistentFolder() async {
    var projectA = convertPath('/project_a');
    var projectB = convertPath('/project_b');
    var fileB = newFile('/project_b/b.dart', content: '// b').path;
    var response = testSetAnalysisRoots([projectA, projectB], []);
    var serverRef = server;
    expect(response, isResponseSuccess('0'));
    // Non-existence of /project_a should not prevent files in /project_b
    // from being analyzed.
    await server.onAnalysisComplete;
    var resolvedUnit = await serverRef.getResolvedUnit(fileB);
    expect(resolvedUnit, isNotNull);
  }

  Future<void> test_setAnalysisRoots_included_notAbsolute() async {
    var response = testSetAnalysisRoots(['foo/bar'], []);
    expect(response,
        isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
  }

  Future<void> test_setAnalysisRoots_included_notNormalized() async {
    var response = testSetAnalysisRoots(['/foo/../bar'], []);
    expect(response,
        isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
  }

  Future<void> test_setAnalysisRoots_notAbsolute() async {
    var response = testSetAnalysisRoots([], ['foo/bar']);
    expect(response,
        isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
  }

  Future<void> test_setAnalysisRoots_notNormalized() async {
    var response = testSetAnalysisRoots([], ['/foo/../bar']);
    expect(response,
        isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
  }

  void test_setPriorityFiles_invalid() {
    var request = AnalysisSetPriorityFilesParams(
      [convertPath('/project/lib.dart')],
    ).toRequest('0');
    var response = handler.handleRequest(request);
    expect(response, isResponseSuccess('0'));
  }

  void test_setPriorityFiles_valid() {
    var p1 = convertPath('/p1');
    var p2 = convertPath('/p2');
    var aPath = convertPath('/p1/a.dart');
    var bPath = convertPath('/p2/b.dart');
    var cPath = convertPath('/p2/c.dart');
    newFile(aPath, content: 'library a;');
    newFile(bPath, content: 'library b;');
    newFile(cPath, content: 'library c;');

    var setRootsRequest =
        AnalysisSetAnalysisRootsParams([p1, p2], []).toRequest('0');
    var setRootsResponse = handler.handleRequest(setRootsRequest);
    expect(setRootsResponse, isResponseSuccess('0'));

    void setPriorityFiles(List<String> fileList) {
      var request = AnalysisSetPriorityFilesParams(fileList).toRequest('0');
      var response = handler.handleRequest(request);
      expect(response, isResponseSuccess('0'));
      // TODO(brianwilkerson) Enable the line below after getPriorityFiles
      // has been implemented.
      // expect(server.getPriorityFiles(), unorderedEquals(fileList));
    }

    setPriorityFiles([aPath, bPath]);
    setPriorityFiles([bPath, cPath]);
    setPriorityFiles([]);
  }

  Future<void> test_updateContent_badType() async {
    var helper = AnalysisTestHelper();
    helper.createSingleFileProject('// empty');
    await helper.onAnalysisComplete;
    var request = Request('0', ANALYSIS_REQUEST_UPDATE_CONTENT, {
      ANALYSIS_REQUEST_UPDATE_CONTENT_FILES: {
        helper.testFile: {
          'type': 'foo',
        }
      }
    });
    var response = helper.handler.handleRequest(request);
    expect(response, isResponseFailure('0'));
  }

  Future<void> test_updateContent_changeOnDisk_duringOverride() async {
    var helper = AnalysisTestHelper();
    helper.createSingleFileProject('library A;');
    await helper.onAnalysisComplete;
    // update code
    helper.sendContentChange(AddContentOverlay('library B;'));
    // There should be no errors
    await helper.onAnalysisComplete;
    expect(helper.getTestErrors(), hasLength(0));
    // Change file on disk, adding a syntax error.
    helper.resourceProvider.modifyFile(helper.testFile, 'library lib');
    // There should still be no errors (file should not have been reread).
    await helper.onAnalysisComplete;
    expect(helper.getTestErrors(), hasLength(0));
    // Send a content change with a null content param--file should be
    // reread from disk.
    helper.sendContentChange(RemoveContentOverlay());
    // There should be errors now.
    await helper.onAnalysisComplete;
    expect(helper.getTestErrors(), hasLength(1));
  }

  Future<void> test_updateContent_changeOnDisk_normal() async {
    var helper = AnalysisTestHelper();
    helper.createSingleFileProject('library A;');
    await helper.onAnalysisComplete;
    // There should be no errors
    expect(helper.getTestErrors(), hasLength(0));
    // Change file on disk, adding a syntax error.
    helper.resourceProvider.modifyFile(helper.testFile, 'library lib');
    // There should be errors now.
    await pumpEventQueue();
    await helper.onAnalysisComplete;
    expect(helper.getTestErrors(), hasLength(1));
  }

  Future<void> test_updateContent_fullContent() async {
    var helper = AnalysisTestHelper();
    helper.createSingleFileProject('// empty');
    await helper.onAnalysisComplete;
    // no errors initially
    var errors = helper.getTestErrors();
    expect(errors, isEmpty);
    // update code
    helper.sendContentChange(AddContentOverlay('library lib'));
    // wait, there is an error
    await helper.onAnalysisComplete;
    errors = helper.getTestErrors();
    expect(errors, hasLength(1));
  }

  Future<void> test_updateContent_incremental() async {
    var helper = AnalysisTestHelper();
    var initialContent = 'library A;';
    helper.createSingleFileProject(initialContent);
    await helper.onAnalysisComplete;
    // no errors initially
    var errors = helper.getTestErrors();
    expect(errors, isEmpty);
    // Add the file to the cache
    helper.sendContentChange(AddContentOverlay(initialContent));
    // update code
    helper.sendContentChange(ChangeContentOverlay(
        [SourceEdit('library '.length, 'A;'.length, 'lib')]));
    // wait, there is an error
    await helper.onAnalysisComplete;
    errors = helper.getTestErrors();
    expect(errors, hasLength(1));
  }

  Future<void> test_updateContent_outOfRange_beyondEnd() {
    return outOfRangeTest(SourceEdit(6, 6, 'foo'));
  }

  Future<void> test_updateContent_outOfRange_negativeLength() {
    return outOfRangeTest(SourceEdit(3, -1, 'foo'));
  }

  Future<void> test_updateContent_outOfRange_negativeOffset() {
    return outOfRangeTest(SourceEdit(-1, 3, 'foo'));
  }

  void test_updateOptions_invalid() {
    var request = Request('0', ANALYSIS_REQUEST_UPDATE_OPTIONS, {
      ANALYSIS_REQUEST_UPDATE_OPTIONS_OPTIONS: {'not-an-option': true}
    });
    var response = handler.handleRequest(request);
    // Invalid options should be silently ignored.
    expect(response, isResponseSuccess('0'));
  }

  void test_updateOptions_null() {
    // null is allowed as a synonym for {}.
    var request = Request('0', ANALYSIS_REQUEST_UPDATE_OPTIONS,
        {ANALYSIS_REQUEST_UPDATE_OPTIONS_OPTIONS: null});
    var response = handler.handleRequest(request);
    expect(response, isResponseSuccess('0'));
  }

  Response testSetAnalysisRoots(List<String> included, List<String> excluded) {
    var request =
        AnalysisSetAnalysisRootsParams(included, excluded).toRequest('0');
    return handler.handleRequest(request);
  }

  Future<void> xtest_getReachableSources_invalidSource() async {
    // TODO(brianwilkerson) Re-enable this test if we re-enable the
    // analysis.getReachableSources request.
    newFile('/project/a.dart', content: 'import "b.dart";');
    server.setAnalysisRoots('0', ['/project/'], []);

    await server.onAnalysisComplete;

    var request = AnalysisGetReachableSourcesParams('/does/not/exist.dart')
        .toRequest('0');
    var response = handler.handleRequest(request);
    expect(response.error, isNotNull);
    expect(response.error.code,
        RequestErrorCode.GET_REACHABLE_SOURCES_INVALID_FILE);
  }

  Future<void> xtest_getReachableSources_validSources() async {
    // TODO(brianwilkerson) Re-enable this test if we re-enable the
    // analysis.getReachableSources request.
    var fileA = newFile('/project/a.dart', content: 'import "b.dart";').path;
    newFile('/project/b.dart');

    server.setAnalysisRoots('0', ['/project/'], []);

    await server.onAnalysisComplete;

    var request = AnalysisGetReachableSourcesParams(fileA).toRequest('0');
    var response = handler.handleRequest(request);

    Map json = response.toJson()[Response.RESULT];

    // Sanity checks.
    expect(json['sources'], hasLength(6));
    expect(json['sources']['file:///project/a.dart'],
        unorderedEquals(['dart:core', 'file:///project/b.dart']));
    expect(json['sources']['file:///project/b.dart'], ['dart:core']);
  }
}

@reflectiveTest
class AnalysisDomainTest extends AbstractAnalysisTest {
  final Map<String, List<AnalysisError>> filesErrors = {};

  /// The files for which `analysis.flushResults` was received.
  final List<String> flushResults = [];

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

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

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

  String get workspaceRootPath => '/home';

  void assertHasErrors(String path) {
    path = convertPath(path);
    expect(filesErrors[path], isNotEmpty, reason: path);
  }

  void assertNoErrors(String path) {
    path = convertPath(path);
    expect(filesErrors[path], isEmpty, reason: path);
  }

  void assertNoErrorsNotification(String path) {
    path = convertPath(path);
    expect(filesErrors[path], isNull, reason: path);
  }

  void forgetReceivedErrors() {
    filesErrors.clear();
  }

  @override
  void processNotification(Notification notification) {
    if (notification.event == ANALYSIS_NOTIFICATION_FLUSH_RESULTS) {
      var decoded = AnalysisFlushResultsParams.fromNotification(notification);
      flushResults.addAll(decoded.files);
      decoded.files.forEach(filesErrors.remove);
    }
    if (notification.event == ANALYSIS_NOTIFICATION_ERRORS) {
      var decoded = AnalysisErrorsParams.fromNotification(notification);
      filesErrors[decoded.file] = decoded.errors;
    }
  }

  Future<void> test_fileSystem_addFile_analysisOptions() async {
    var a_path = '$testPackageLibPath/a.dart';
    var b_path = '$testPackageLibPath/b.dart';

    _createFilesWithErrors([a_path, b_path]);

    setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // Both a.dart and b.dart are analyzed.
    _assertAnalyzedFiles(
      hasErrors: [a_path, b_path],
      notAnalyzed: [],
    );

    // Write the options file that excludes b.dart
    newFile('$testPackageRootPath/analysis_options.yaml', content: r'''
analyzer:
  exclude:
    - lib/b.dart
''');

    await pumpEventQueue();
    await server.onAnalysisComplete;

    // Errors for all files were flushed, and only a.dart is reported again.
    _assertFlushedResults([a_path, b_path]);
    _assertAnalyzedFiles(
      hasErrors: [a_path],
      notAnalyzed: [b_path],
    );
  }

  Future<void> test_fileSystem_addFile_analysisOptions_analysis() async {
    var a_path = '$testPackageLibPath/a.dart';
    var options_path = '$testPackageRootPath/analysis_options.yaml';

    newFile(a_path, content: 'error');

    setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // a.dart was analyzed
    _assertAnalyzedFiles(
      hasErrors: [a_path],
      notAnalyzed: [options_path],
    );

    // Add 'analysis_options.yaml' that has an error.
    newFile(options_path, content: '''
analyzer:
  error:
''');
    await pumpEventQueue();
    await server.onAnalysisComplete;

    // Both files were analyzed.
    _assertAnalyzedFiles(
      hasErrors: [a_path, options_path],
      notAnalyzed: [],
    );
  }

  Future<void> test_fileSystem_addFile_androidManifestXml() async {
    var path = '$testPackageRootPath/AndroidManifest.xml';

    newFile('$testPackageLibPath/a.dart', content: '');

    newFile('$testPackageRootPath/analysis_options.yaml', content: '''
analyzer:
  optional-checks:
    chrome-os-manifest-checks: true
''');

    setRoots(included: [workspaceRootPath], excluded: []);

    newFile(path, content: '<manifest/>');
    await pumpEventQueue();
    await server.onAnalysisComplete;

    // No touch-screen.
    assertHasErrors(path);
  }

  Future<void> test_fileSystem_addFile_dart() async {
    var a_path = '$testPackageLibPath/a.dart';

    // We have to create the folder, otherwise there is nothing to watch.
    newFolder(testPackageLibPath);

    setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // We don't have a.dart yet.
    assertNoErrorsNotification(a_path);

    _createFilesWithErrors([a_path]);
    await pumpEventQueue();
    await server.onAnalysisComplete;

    // We created a.dart, so it should be analyzed.
    assertHasErrors(a_path);
  }

  Future<void> test_fileSystem_addFile_dart_dotFolder() async {
    var a_path = '$projectPath/lib/.foo/a.dart';
    var b_path = '$projectPath/lib/b.dart';

    newFile(b_path, content: r'''
import '.foo/a.dart';
void f(A a) {}
''');

    createProject();
    await pumpEventQueue();
    await server.onAnalysisComplete;

    // We don't have a.dart, so the import cannot be resolved.
    assertHasErrors(b_path);

    newFile(a_path, content: r'''
class A {}
''');
    await pumpEventQueue();
    await server.onAnalysisComplete;

    // 'a.dart' is in a dot-folder, so excluded from analysis.
    assertNoErrorsNotification(a_path);

    // We added a.dart with `A`, so no errors.
    assertNoErrors(b_path);
  }

  Future<void> test_fileSystem_addFile_dart_excluded() async {
    var a_path = '$projectPath/lib/a.dart';
    var b_path = '$projectPath/lib/b.dart';

    newFile('$projectPath/analysis_options.yaml', content: r'''
analyzer:
  exclude:
    - "**/a.dart"
''');

    newFile(b_path, content: r'''
import 'a.dart';
void f(A a) {}
''');

    createProject();
    await pumpEventQueue();
    await server.onAnalysisComplete;

    // We don't have a.dart, so the import cannot be resolved.
    assertHasErrors(b_path);

    newFile(a_path, content: r'''
class A {}
''');
    await pumpEventQueue();
    await server.onAnalysisComplete;

    // We excluded 'a.dart' from analysis, no errors notification for it.
    assertNoErrorsNotification(a_path);

    // We added a.dart with `A`, so no errors.
    assertNoErrors(b_path);
  }

  Future<void> test_fileSystem_addFile_dotPackagesFile() async {
    var aaaLibPath = '/packages/aaa/lib';
    var a_path = '$aaaLibPath/a.dart';

    newFile(a_path, content: '''
class A {}
''');

    newFile(testFilePath, content: '''
import 'package:aaa/a.dart';
void f(A a) {}
''');

    setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // We cannot resolve `package:aaa/a.dart`
    assertHasErrors(testFilePath);

    // Write `.packages`, recreate analysis contexts.
    newFile('$testPackageRootPath/.packages', content: '''
aaa:${toUriStr(aaaLibPath)}
''');

    await pumpEventQueue();
    await server.onAnalysisComplete;

    // We have `A` in 'package:aaa/a.dart', so no errors.
    assertNoErrors(testFilePath);

    // errors are not reported for packages
    assertNoErrorsNotification(a_path);
  }

  Future<void> test_fileSystem_addFile_fixDataYaml() async {
    var path = '$testPackageLibPath/fix_data.yaml';

    newFile('$testPackageLibPath/a.dart', content: '');

    // Make sure that it is a package.
    writePackageConfig(
      '$testPackageRootPath/.dart_tool/package_config.json',
      PackageConfigFileBuilder(),
    );

    setRoots(included: [workspaceRootPath], excluded: []);

    // No `fix_data.yaml` to analyze yet.
    assertNoErrorsNotification(path);

    // Create it, will be analyzed.
    newFile(path, content: '0: 1');
    await pumpEventQueue();
    await server.onAnalysisComplete;

    // And it has errors.
    assertHasErrors(path);

    // We don't recreate analysis contexts.
    _assertFlushedResults([]);
  }

  Future<void> test_fileSystem_addFile_packageConfigJsonFile() async {
    var aaaRootPath = '/packages/aaa';
    var a_path = '$aaaRootPath/lib/a.dart';

    newFile(a_path, content: '''
class A {}
''');

    newFile(testFilePath, content: '''
import 'package:aaa/a.dart';
void f(A a) {}
''');

    setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // We cannot resolve `package:aaa/a.dart`
    assertHasErrors(testFilePath);

    // Write `package_config.json`, recreate analysis contexts.
    writePackageConfig(
      '$testPackageRootPath/.dart_tool/package_config.json',
      PackageConfigFileBuilder()..add(name: 'aaa', rootPath: aaaRootPath),
    );

    await pumpEventQueue();
    await server.onAnalysisComplete;

    // We have `A` in 'package:aaa/a.dart', so no errors.
    assertNoErrors(testFilePath);

    // errors are not reported for packages
    assertNoErrorsNotification(a_path);
  }

  Future<void> test_fileSystem_addFile_pubspec_analysis() async {
    var a_path = '$testPackageLibPath/a.dart';
    var pubspec_path = '$testPackageRootPath/pubspec.yaml';

    newFile(a_path, content: 'error');

    // Write an empty file to force a new analysis context.
    // We look for `pubspec.yaml` files only in analysis context roots.
    newFile('$testPackageRootPath/analysis_options.yaml', content: '');

    setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // a.dart was analyzed
    _assertAnalyzedFiles(
      hasErrors: [a_path],
      notAnalyzed: [pubspec_path],
    );

    // Add a non-Dart file that we know how to analyze.
    newFile(pubspec_path, content: '''
name: sample
dependencies: true
''');
    await pumpEventQueue();
    await server.onAnalysisComplete;

    // Both files were analyzed.
    _assertAnalyzedFiles(
      hasErrors: [a_path, pubspec_path],
      notAnalyzed: [],
    );
  }

  Future<void> test_fileSystem_addFile_unrelated() async {
    var a_path = '$testPackageLibPath/a.dart';
    var unrelated_path = '$testPackageRootPath/unrelated.txt';

    newFile(a_path, content: 'error');

    setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // a.dart was analyzed
    _assertAnalyzedFiles(
      hasErrors: [a_path],
      notAnalyzed: [unrelated_path],
    );

    // Add an unrelated file, no analysis.
    newFile(unrelated_path, content: 'anything');
    await pumpEventQueue();
    await server.onAnalysisComplete;

    // No analysis.
    _assertFlushedResults([]);
    _assertAnalyzedFiles(hasErrors: [], notAnalyzed: [a_path]);
  }

  Future<void> test_fileSystem_changeFile_analysisOptions() async {
    var options_path = '$testPackageRootPath/analysis_options.yaml';
    var a_path = '$testPackageLibPath/a.dart';
    var b_path = '$testPackageLibPath/b.dart';
    var c_path = '$testPackageLibPath/c.dart';

    _createFilesWithErrors([a_path, b_path, c_path]);

    // Exclude b.dart from analysis.
    newFile(options_path, content: r'''
analyzer:
  exclude:
    - lib/b.dart
''');

    setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // Only a.dart is analyzed, because b.dart is excluded.
    _assertAnalyzedFiles(
      hasErrors: [a_path, c_path],
      notAnalyzed: [b_path],
    );

    // Exclude c.dart from analysis.
    newFile(options_path, content: r'''
analyzer:
  exclude:
    - lib/c.dart
''');

    await pumpEventQueue();
    await server.onAnalysisComplete;

    // Errors for all files were flushed, a.dart and b.dart analyzed.
    _assertFlushedResults([options_path, a_path, c_path]);
    _assertAnalyzedFiles(
      hasErrors: [a_path, b_path],
      noErrors: [options_path],
      notAnalyzed: [c_path],
    );
  }

  Future<void> test_fileSystem_changeFile_androidManifestXml() async {
    var path = '$testPackageRootPath/AndroidManifest.xml';

    newFile('$testPackageLibPath/a.dart', content: '');

    // Has an error - no touch screen.
    newFile(path, content: '<manifest/>');

    newFile('$testPackageRootPath/analysis_options.yaml', content: '''
analyzer:
  optional-checks:
    chrome-os-manifest-checks: true
''');

    setRoots(included: [workspaceRootPath], excluded: []);

    // Forget and check that we did.
    forgetReceivedErrors();
    assertNoErrorsNotification(path);

    // Update the file, so analyze it.
    newFile(path, content: '<manifest/>');
    await pumpEventQueue();
    await server.onAnalysisComplete;

    // An error was reported.
    assertHasErrors(path);
  }

  Future<void> test_fileSystem_changeFile_dart() async {
    var a_path = '$testPackageLibPath/a.dart';
    var b_path = '$testPackageLibPath/b.dart';

    newFile(a_path, content: r'''
class A2 {}
''');

    newFile(b_path, content: r'''
import 'a.dart';
void f(A a) {}
''');

    setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    assertNoErrors(a_path);
    assertHasErrors(b_path);
    forgetReceivedErrors();

    // Update a.dart so that b.dart has no error.
    newFile(a_path, content: 'class A {}');
    await pumpEventQueue();
    await server.onAnalysisComplete;

    // The update of a.dart fixed the error in b.dart
    assertNoErrors(a_path);
    assertNoErrors(b_path);
  }

  Future<void> test_fileSystem_changeFile_dart_dotFolder() async {
    var a_path = '$testPackageLibPath/.foo/a.dart';
    var b_path = '$testPackageLibPath/b.dart';

    newFile(a_path, content: r'''
class B {}
''');

    newFile(b_path, content: r'''
import '.foo/a.dart';
void f(A a) {}
''');

    setRoots(included: [workspaceRootPath], excluded: []);
    await pumpEventQueue();
    await server.onAnalysisComplete;

    // 'a.dart' is in a dot-folder, so excluded from analysis.
    assertNoErrorsNotification(a_path);

    // We have `B`, not `A`, in a.dart, so has errors.
    assertHasErrors(b_path);

    newFile(a_path, content: r'''
class A {}
''');
    await pumpEventQueue();
    await server.onAnalysisComplete;

    // 'a.dart' is in a dot-folder, so excluded from analysis.
    assertNoErrorsNotification(a_path);

    // We changed a.dart, to have `A`, so no errors.
    assertNoErrors(b_path);
  }

  Future<void> test_fileSystem_changeFile_dart_excluded() async {
    var a_path = '$testPackageLibPath/a.dart';
    var b_path = '$testPackageLibPath/b.dart';

    newFile('$testPackageRootPath/analysis_options.yaml', content: r'''
analyzer:
  exclude:
    - "**/a.dart"
''');

    newFile(a_path, content: r'''
class B {}
''');

    newFile(b_path, content: r'''
import 'a.dart';
void f(A a) {}
''');

    setRoots(included: [workspaceRootPath], excluded: []);
    await pumpEventQueue();
    await server.onAnalysisComplete;

    // We excluded 'a.dart' from analysis, no errors notification for it.
    assertNoErrorsNotification(a_path);

    // We have `B`, not `A`, in a.dart, so has errors.
    assertHasErrors(b_path);

    newFile(a_path, content: r'''
class A {}
''');
    await pumpEventQueue();
    await server.onAnalysisComplete;

    // We changed a.dart, to have `A`, so no errors.
    assertNoErrors(b_path);
  }

  Future<void> test_fileSystem_changeFile_dotPackagesFile() async {
    var aaaLibPath = '/packages/aaa/lib';
    var a_path = '$aaaLibPath/a.dart';

    newFile(a_path, content: '''
class A {}
''');

    // Write `.packages` empty, without `package:aaa`.
    newFile('$testPackageRootPath/.packages', content: '');

    newFile(testFilePath, content: '''
import 'package:aaa/a.dart';
void f(A a) {}
''');

    setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // We cannot resolve `package:aaa/a.dart`
    assertHasErrors(testFilePath);

    // Write `.packages`, recreate analysis contexts.
    newFile('$testPackageRootPath/.packages', content: '''
aaa:${toUriStr(aaaLibPath)}
''');

    await pumpEventQueue();
    await server.onAnalysisComplete;

    // We have `A` in 'package:aaa/a.dart', so no errors.
    assertNoErrors(testFilePath);

    // errors are not reported for packages
    assertNoErrorsNotification(a_path);
  }

  Future<void> test_fileSystem_changeFile_fixDataYaml() async {
    var path = '$testPackageLibPath/fix_data.yaml';

    newFile('$testPackageLibPath/a.dart', content: '');

    // Make sure that it is a package.
    writePackageConfig(
      '$testPackageRootPath/.dart_tool/package_config.json',
      PackageConfigFileBuilder(),
    );

    // This file has an error.
    newFile(path, content: '0: 1');

    setRoots(included: [workspaceRootPath], excluded: []);

    // The file was analyzed.
    assertHasErrors(path);

    // Replace with the context that does not have errors.
    newFile(path, content: r'''
version: 1
transforms: []
''');
    await pumpEventQueue();
    await server.onAnalysisComplete;

    // And it has errors.
    assertNoErrors(path);

    // We don't recreate analysis contexts.
    _assertFlushedResults([]);
  }

  Future<void> test_fileSystem_changeFile_packageConfigJsonFile() async {
    var aaaRootPath = '/packages/aaa';
    var a_path = '$aaaRootPath/lib/a.dart';

    newFile(a_path, content: '''
class A {}
''');

    // Write the empty file, without `package:aaa`.
    writePackageConfig(
      '$testPackageRootPath/.dart_tool/package_config.json',
      PackageConfigFileBuilder(),
    );

    newFile(testFilePath, content: '''
import 'package:aaa/a.dart';
void f(A a) {}
''');

    setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // We cannot resolve `package:aaa/a.dart`
    assertHasErrors(testFilePath);

    // Write `package_config.json`, recreate analysis contexts.
    writePackageConfig(
      '$testPackageRootPath/.dart_tool/package_config.json',
      PackageConfigFileBuilder()..add(name: 'aaa', rootPath: aaaRootPath),
    );

    await pumpEventQueue();
    await server.onAnalysisComplete;

    // We have `A` in 'package:aaa/a.dart', so no errors.
    assertNoErrors(testFilePath);

    // errors are not reported for packages
    assertNoErrorsNotification(a_path);
  }

  Future<void> test_fileSystem_deleteFile_analysisOptions() async {
    var options_path = '$testPackageRootPath/analysis_options.yaml';
    var a_path = '$testPackageLibPath/a.dart';
    var b_path = '$testPackageLibPath/b.dart';

    _createFilesWithErrors([a_path, b_path]);

    // Exclude b.dart from analysis.
    newFile(options_path, content: r'''
analyzer:
  exclude:
    - lib/b.dart
''');

    setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // Only a.dart is analyzed, because b.dart is excluded.
    _assertAnalyzedFiles(
      hasErrors: [a_path],
      notAnalyzed: [b_path],
    );

    // Delete the options file.
    deleteFile(options_path);

    await pumpEventQueue();
    await server.onAnalysisComplete;

    // Errors for a.dart were flushed, a.dart and b.dart analyzed.
    _assertFlushedResults([options_path, a_path]);
    _assertAnalyzedFiles(
      hasErrors: [a_path, b_path],
      notAnalyzed: [options_path],
    );
  }

  Future<void> test_fileSystem_deleteFile_androidManifestXml() async {
    var path = '$testPackageRootPath/AndroidManifest.xml';

    newFile('$testPackageLibPath/a.dart', content: '');

    // Has an error - no touch screen.
    newFile(path, content: '<manifest/>');

    newFile('$testPackageRootPath/analysis_options.yaml', content: '''
analyzer:
  optional-checks:
    chrome-os-manifest-checks: true
''');

    setRoots(included: [workspaceRootPath], excluded: []);

    // An error was reported.
    _assertAnalyzedFiles(hasErrors: [path], notAnalyzed: []);

    // Delete the file.
    deleteFile(path);
    await pumpEventQueue();

    // We received a flush notification.
    _assertAnalyzedFiles(hasErrors: [], notAnalyzed: [path]);
  }

  Future<void> test_fileSystem_deleteFile_dart() async {
    var a_path = '$testPackageLibPath/a.dart';

    _createFilesWithErrors([a_path]);

    setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // a.dart was analyzed
    assertHasErrors(a_path);

    deleteFile(a_path);
    await pumpEventQueue();
    await server.onAnalysisComplete;

    // We deleted a.dart, its errors should be flushed.
    _assertFlushedResults([a_path]);
    assertNoErrorsNotification(a_path);
  }

  Future<void> test_fileSystem_deleteFile_dart_excluded() async {
    var a_path = '$testPackageLibPath/a.dart';
    var b_path = '$testPackageLibPath/b.dart';

    newFile('$testPackageRootPath/analysis_options.yaml', content: r'''
analyzer:
  exclude:
    - "**/a.dart"
''');

    newFile(a_path, content: r'''
class A {}
''');

    newFile(b_path, content: r'''
import 'a.dart';
void f(A a) {}
''');

    setRoots(included: [workspaceRootPath], excluded: []);
    await pumpEventQueue();
    await server.onAnalysisComplete;

    // We excluded 'a.dart' from analysis, no errors notification for it.
    assertNoErrorsNotification(a_path);

    // We have `A` in a.dart, so no errors.
    assertNoErrors(b_path);

    deleteFile(a_path);
    await pumpEventQueue();
    await server.onAnalysisComplete;

    // We deleted a.dart, so `A` cannot be resolved.
    assertHasErrors(b_path);
  }

  Future<void> test_fileSystem_deleteFile_dotPackagesFile() async {
    var aaaLibPath = '/packages/aaa/lib';
    var a_path = '$aaaLibPath/a.dart';

    newFile(a_path, content: '''
class A {}
''');

    newFile('$testPackageRootPath/.packages', content: '''
aaa:${toUriStr(aaaLibPath)}
''');

    newFile(testFilePath, content: '''
import 'package:aaa/a.dart';
void f(A a) {}
''');

    setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // We have `A` in 'package:aaa/a.dart', so no errors.
    assertNoErrors(testFilePath);

    // Write `.packages`, recreate analysis contexts.
    deleteFile('$testPackageRootPath/.packages');

    await pumpEventQueue();
    await server.onAnalysisComplete;

    // We cannot resolve `package:aaa/a.dart`
    assertHasErrors(testFilePath);

    // errors are not reported for packages
    assertNoErrorsNotification(a_path);
  }

  Future<void> test_fileSystem_deleteFile_fixDataYaml() async {
    var path = '$testPackageLibPath/fix_data.yaml';

    newFile('$testPackageLibPath/a.dart', content: '');

    // Make sure that it is a package.
    writePackageConfig(
      '$testPackageRootPath/.dart_tool/package_config.json',
      PackageConfigFileBuilder(),
    );

    // This file has an error.
    newFile(path, content: '0: 1');

    setRoots(included: [workspaceRootPath], excluded: []);

    // The file was analyzed.
    _assertAnalyzedFiles(hasErrors: [path], notAnalyzed: []);

    // Delete the file.
    deleteFile(path);
    await pumpEventQueue();

    // We received a flush notification.
    _assertAnalyzedFiles(hasErrors: [], notAnalyzed: [path]);
  }

  Future<void> test_fileSystem_deleteFile_packageConfigJsonFile() async {
    var aaaRootPath = '/packages/aaa';
    var a_path = '$aaaRootPath/lib/a.dart';

    newFile(a_path, content: '''
class A {}
''');

    // Write the empty file, without `package:aaa`.
    writePackageConfig(
      '$testPackageRootPath/.dart_tool/package_config.json',
      PackageConfigFileBuilder()..add(name: 'aaa', rootPath: aaaRootPath),
    );

    newFile(testFilePath, content: '''
import 'package:aaa/a.dart';
void f(A a) {}
''');

    setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // We have `A` in 'package:aaa/a.dart', so no errors.
    assertNoErrors(testFilePath);

    // Delete `package_config.json`, recreate analysis contexts.
    deleteFile(
      '$testPackageRootPath/.dart_tool/package_config.json',
    );

    await pumpEventQueue();
    await server.onAnalysisComplete;

    // We cannot resolve 'package:aaa/a.dart', so errors.
    assertHasErrors(testFilePath);

    // errors are not reported for packages
    assertNoErrorsNotification(a_path);
  }

  Future<void> test_setRoots_dotPackagesFile() async {
    var aaaLibPath = '/packages/aaa/lib';
    var a_path = '$aaaLibPath/a.dart';

    newFile(a_path, content: '''
class A {}
''');

    newFile('$testPackageRootPath/.packages', content: '''
aaa:${toUriStr(aaaLibPath)}
''');

    newFile(testFilePath, content: '''
import 'package:aaa/a.dart';
void f(A a) {}
''');

    // create project and wait for analysis
    setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // We have `A` in 'package:aaa/a.dart', so no errors.
    assertNoErrors(testFilePath);

    // errors are not reported for packages
    assertNoErrorsNotification(a_path);
  }

  Future<void> test_setRoots_includedFile() async {
    var a_path = '$testPackageLibPath/a.dart';
    var b_path = '$testPackageLibPath/b.dart';

    _createFilesWithErrors([a_path, b_path]);

    setRoots(included: [a_path], excluded: []);

    // Only a.dart is included, so b.dart is not analyzed.
    await server.onAnalysisComplete;
    _assertAnalyzedFiles(
      hasErrors: [a_path],
      notAnalyzed: [b_path],
    );
  }

  Future<void> test_setRoots_includedFile_setRoots() async {
    var a_path = '$testPackageLibPath/a.dart';
    var b_path = '$testPackageLibPath/b.dart';

    _createFilesWithErrors([a_path, b_path]);

    // Include only single file.
    setRoots(included: [a_path], excluded: []);
    await server.onAnalysisComplete;

    // So, only a.dart is analyzed, and b.dart is not.
    _assertAnalyzedFiles(
      hasErrors: [a_path],
      notAnalyzed: [b_path],
    );

    // Include the folder that contains both a.dart and b.dart
    setRoots(included: [testPackageRootPath], excluded: []);
    await server.onAnalysisComplete;

    // So, both a.dart and b.dart are analyzed.
    _assertAnalyzedFiles(
      hasErrors: [a_path, b_path],
      notAnalyzed: [],
    );
  }

  Future<void> test_setRoots_includedFileFolder() async {
    var includedFile = '$testPackageLibPath/a.dart';
    var includedFolder = '$testPackageLibPath/foo';
    var includedFolderFile1 = '$includedFolder/1.dart';
    var includedFolderFile2 = '$includedFolder/2.dart';
    var notIncludedFile = '$testPackageLibPath/b.dart';

    _createFilesWithErrors([
      includedFile,
      includedFolderFile1,
      includedFolderFile2,
      notIncludedFile,
    ]);

    setRoots(included: [includedFile, includedFolder], excluded: []);
    await server.onAnalysisComplete;

    // We can combine a file, and a folder as included paths.
    // And the file that is not in there is not analyzed.
    _assertAnalyzedFiles(hasErrors: [
      includedFile,
      includedFolderFile1,
      includedFolderFile2,
    ], notAnalyzed: [
      notIncludedFile,
    ]);
  }

  Future<void> test_setRoots_includedFolder_analysisOptions_exclude() async {
    var a_path = '$testPackageLibPath/a.dart';
    var b_path = '$testPackageLibPath/b.dart';

    newAnalysisOptionsYamlFile(testPackageRootPath, content: '''
analyzer:
  exclude:
    - "**/b.dart"
''');

    _createFilesWithErrors([a_path, b_path]);

    setRoots(included: [workspaceRootPath], excluded: []);

    // b.dart is excluded using the options file.
    await server.onAnalysisComplete;
    _assertAnalyzedFiles(
      hasErrors: [a_path],
      notAnalyzed: [b_path],
    );
  }

  @FailingTest(reason: 'Not implemented in ContextLocator')
  Future<void> test_setRoots_includedFolder_excludedFile() async {
    var a_path = '$testPackageLibPath/a.dart';
    var excluded_path = '$testPackageRootPath/excluded/b.dart';

    _createFilesWithErrors([a_path, excluded_path]);

    setRoots(
      included: [workspaceRootPath],
      excluded: [excluded_path],
    );
    await server.onAnalysisComplete;

    _assertAnalyzedFiles(
      hasErrors: [a_path],
      notAnalyzed: [excluded_path],
    );
  }

  Future<void> test_setRoots_includedFolder_excludedFolder() async {
    var a_path = '$testPackageLibPath/a.dart';
    var excluded_path = '$testPackageRootPath/excluded/b.dart';

    _createFilesWithErrors([a_path, excluded_path]);

    setRoots(
      included: [workspaceRootPath],
      excluded: ['$testPackageRootPath/excluded'],
    );
    await server.onAnalysisComplete;

    // a.dart is analyzed, but b.dart is in the excluded folder.
    _assertAnalyzedFiles(
      hasErrors: [a_path],
      notAnalyzed: [excluded_path],
    );
  }

  Future<void> test_setRoots_notDartFile_androidManifestXml() async {
    var path = '$testPackageRootPath/AndroidManifest.xml';

    newFile('$testPackageLibPath/a.dart', content: '');

    newFile('$testPackageRootPath/analysis_options.yaml', content: '''
analyzer:
  optional-checks:
    chrome-os-manifest-checks: true
''');

    newFile(path, content: '<manifest/>');

    setRoots(included: [workspaceRootPath], excluded: []);

    // No touch-screen.
    assertHasErrors(path);
  }

  Future<void> test_setRoots_notDartFile_fixDataYaml() async {
    var path = '$testPackageLibPath/fix_data.yaml';

    // Make sure that it is a package.
    writePackageConfig(
      '$testPackageRootPath/.dart_tool/package_config.json',
      PackageConfigFileBuilder(),
    );

    // So, `lib/fix_data.yaml` will be analyzed.
    newFile(path, content: '0: 1');

    setRoots(included: [workspaceRootPath], excluded: []);

    assertHasErrors(path);
  }

  Future<void> test_setRoots_packageConfigJsonFile() async {
    var aaaRootPath = '/packages/aaa';
    var a_path = '$aaaRootPath/lib/a.dart';

    newFile(a_path, content: '''
class A {}
''');

    writePackageConfig(
      '$testPackageRootPath/.dart_tool/package_config.json',
      PackageConfigFileBuilder()..add(name: 'aaa', rootPath: aaaRootPath),
    );

    newFile(testFilePath, content: '''
import 'package:aaa/a.dart';
void f(A a) {}
''');

    // create project and wait for analysis
    setRoots(included: [workspaceRootPath], excluded: []);
    await server.onAnalysisComplete;

    // We have `A` in 'package:aaa/a.dart', so no errors.
    assertNoErrors(testFilePath);

    // errors are not reported for packages
    assertNoErrorsNotification(a_path);
  }

  void writePackageConfig(String path, PackageConfigFileBuilder config) {
    newFile(path, content: config.toContent(toUriStr: toUriStr));
  }

  void _assertAnalyzedFiles({
    @required List<String> hasErrors,
    List<String> noErrors = const [],
    @required List<String> notAnalyzed,
  }) {
    for (var path in hasErrors) {
      assertHasErrors(path);
    }

    for (var path in noErrors) {
      assertNoErrors(path);
    }

    for (var path in notAnalyzed) {
      assertNoErrorsNotification(path);
    }

    filesErrors.clear();
  }

  void _assertFlushedResults(List<String> paths) {
    var convertedPaths = paths.map(convertPath).toList();
    expect(flushResults, unorderedEquals(convertedPaths));
    flushResults.clear();
  }

  /// Create files with a content that has a compile time error.
  /// So, when analyzed, these files will satisfy [assertHasErrors].
  void _createFilesWithErrors(List<String> paths) {
    for (var path in paths) {
      newFile(path, content: 'error');
    }
  }
}

/// A helper to test 'analysis.*' requests.
class AnalysisTestHelper with ResourceProviderMixin {
  MockServerChannel serverChannel;
  AnalysisServer server;
  AnalysisDomainHandler handler;

  Map<AnalysisService, List<String>> analysisSubscriptions = {};

  Map<String, List<AnalysisError>> filesErrors = {};
  Map<String, List<HighlightRegion>> filesHighlights = {};
  Map<String, List<NavigationRegion>> filesNavigation = {};

  String projectPath;
  String testFile;
  String testCode;

  AnalysisTestHelper() {
    projectPath = convertPath('/project');
    testFile = convertPath('/project/bin/test.dart');
    serverChannel = MockServerChannel();
    // Create an SDK in the mock file system.
    MockSdk(resourceProvider: resourceProvider);
    server = AnalysisServer(
        serverChannel,
        resourceProvider,
        AnalysisServerOptions(),
        DartSdkManager(convertPath('/sdk')),
        CrashReportingAttachmentsBuilder.empty,
        InstrumentationService.NULL_SERVICE);
    handler = AnalysisDomainHandler(server);
    // listen for notifications
    var notificationStream = serverChannel.notificationController.stream;
    notificationStream.listen((Notification notification) {
      if (notification.event == ANALYSIS_NOTIFICATION_ERRORS) {
        var decoded = AnalysisErrorsParams.fromNotification(notification);
        filesErrors[decoded.file] = decoded.errors;
      }
      if (notification.event == ANALYSIS_NOTIFICATION_HIGHLIGHTS) {
        var params = AnalysisHighlightsParams.fromNotification(notification);
        filesHighlights[params.file] = params.regions;
      }
      if (notification.event == ANALYSIS_NOTIFICATION_NAVIGATION) {
        var params = AnalysisNavigationParams.fromNotification(notification);
        filesNavigation[params.file] = params.regions;
      }
    });
  }

  /// Returns a [Future] that completes when the server's analysis is complete.
  Future get onAnalysisComplete {
    return server.onAnalysisComplete;
  }

  void addAnalysisSubscription(AnalysisService service, String file) {
    // add file to subscription
    var files = analysisSubscriptions[service];
    if (files == null) {
      files = <String>[];
      analysisSubscriptions[service] = files;
    }
    files.add(file);
    // set subscriptions
    var request =
        AnalysisSetSubscriptionsParams(analysisSubscriptions).toRequest('0');
    handleSuccessfulRequest(request);
  }

  void addAnalysisSubscriptionHighlights(String file) {
    addAnalysisSubscription(AnalysisService.HIGHLIGHTS, file);
  }

  void addAnalysisSubscriptionNavigation(String file) {
    addAnalysisSubscription(AnalysisService.NAVIGATION, file);
  }

  /// Creates an empty project `/project`.
  void createEmptyProject() {
    newFolder(projectPath);
    var request =
        AnalysisSetAnalysisRootsParams([projectPath], []).toRequest('0');
    handleSuccessfulRequest(request);
  }

  /// Creates a project with a single Dart file `/project/bin/test.dart` with
  /// the given [code].
  void createSingleFileProject(code) {
    testCode = _getCodeString(code);
    newFolder(projectPath);
    newFile(testFile, content: testCode);
    var request =
        AnalysisSetAnalysisRootsParams([projectPath], []).toRequest('0');
    handleSuccessfulRequest(request);
  }

  /// Returns the offset of [search] in [testCode].
  /// Fails if not found.
  int findOffset(String search) {
    var offset = testCode.indexOf(search);
    expect(offset, isNot(-1));
    return offset;
  }

  /// Returns [AnalysisError]s recorded for the given [file].
  /// May be empty, but not `null`.
  List<AnalysisError> getErrors(String file) {
    var errors = filesErrors[file];
    if (errors != null) {
      return errors;
    }
    return <AnalysisError>[];
  }

  /// Returns highlights recorded for the given [file].
  /// May be empty, but not `null`.
  List<HighlightRegion> getHighlights(String file) {
    var highlights = filesHighlights[file];
    if (highlights != null) {
      return highlights;
    }
    return [];
  }

  /// Returns navigation regions recorded for the given [file].
  /// May be empty, but not `null`.
  List<NavigationRegion> getNavigation(String file) {
    var navigation = filesNavigation[file];
    if (navigation != null) {
      return navigation;
    }
    return [];
  }

  /// Returns [AnalysisError]s recorded for the [testFile].
  /// May be empty, but not `null`.
  List<AnalysisError> getTestErrors() {
    return getErrors(testFile);
  }

  /// Returns highlights recorded for the given [testFile].
  /// May be empty, but not `null`.
  List<HighlightRegion> getTestHighlights() {
    return getHighlights(testFile);
  }

  /// Returns navigation information recorded for the given [testFile].
  /// May be empty, but not `null`.
  List<NavigationRegion> getTestNavigation() {
    return getNavigation(testFile);
  }

  /// Validates that the given [request] is handled successfully.
  void handleSuccessfulRequest(Request request) {
    var response = handler.handleRequest(request);
    expect(response, isResponseSuccess('0'));
  }

  /// Send an `updateContent` request for [testFile].
  void sendContentChange(dynamic contentChange) {
    var request =
        AnalysisUpdateContentParams({testFile: contentChange}).toRequest('0');
    handleSuccessfulRequest(request);
  }

  /// Stops the associated server.
  void stopServer() {
    server.done();
  }

  static String _getCodeString(code) {
    if (code is List<String>) {
      code = code.join('\n');
    }
    return code as String;
  }
}

@reflectiveTest
class SetSubscriptionsTest extends AbstractAnalysisTest {
  Map<String, List<HighlightRegion>> filesHighlights = {};

  final Completer<void> _resultsAvailable = Completer();

  @override
  void processNotification(Notification notification) {
    if (notification.event == ANALYSIS_NOTIFICATION_HIGHLIGHTS) {
      var params = AnalysisHighlightsParams.fromNotification(notification);
      filesHighlights[params.file] = params.regions;
      _resultsAvailable.complete();
    }
  }

  Future<void> test_afterAnalysis() async {
    addTestFile('int V = 42;');
    createProject();
    // wait for analysis, no results initially
    await waitForTasksFinished();
    expect(filesHighlights[testFile], isNull);
    // subscribe
    addAnalysisSubscription(AnalysisService.HIGHLIGHTS, testFile);
    await _resultsAvailable.future;
    // there are results
    expect(filesHighlights[testFile], isNotEmpty);
  }

  Future<void> test_afterAnalysis_noSuchFile() async {
    var file = convertPath('/no-such-file.dart');
    addTestFile('// no matter');
    createProject();
    // wait for analysis, no results initially
    await waitForTasksFinished();
    expect(filesHighlights[testFile], isNull);
    // subscribe
    addAnalysisSubscription(AnalysisService.HIGHLIGHTS, file);
    await _resultsAvailable.future;
    // there are results
    expect(filesHighlights[file], isEmpty);
  }

  Future<void> test_afterAnalysis_packageFile_external() async {
    var pkgFile = newFile('/packages/pkgA/lib/libA.dart', content: '''
library lib_a;
class A {}
''').path;
    newFile('/project/.packages', content: 'pkgA:file:///packages/pkgA/lib');
    //
    addTestFile('''
import 'package:pkgA/libA.dart';
main() {
  new A();
}
''');
    createProject();
    // wait for analysis, no results initially
    await waitForTasksFinished();
    expect(filesHighlights[pkgFile], isNull);
    // subscribe
    addAnalysisSubscription(AnalysisService.HIGHLIGHTS, pkgFile);
    await _resultsAvailable.future;
    // there are results
    expect(filesHighlights[pkgFile], isNotEmpty);
  }

  Future<void> test_afterAnalysis_packageFile_inRoot() async {
    var pkgA = convertPath('/pkgA');
    var pkgB = convertPath('/pkgA');
    var pkgFileA = newFile('$pkgA/lib/libA.dart', content: '''
library lib_a;
class A {}
''').path;
    newFile('$pkgA/lib/libB.dart', content: '''
import 'package:pkgA/libA.dart';
main() {
  new A();
}
''');
    // add 'pkgA' and 'pkgB' as projects
    newFolder(projectPath);
    handleSuccessfulRequest(
        AnalysisSetAnalysisRootsParams([pkgA, pkgB], []).toRequest('0'));
    // wait for analysis, no results initially
    await waitForTasksFinished();
    expect(filesHighlights[pkgFileA], isNull);
    // subscribe
    addAnalysisSubscription(AnalysisService.HIGHLIGHTS, pkgFileA);
    await _resultsAvailable.future;
    // there are results
    expect(filesHighlights[pkgFileA], isNotEmpty);
  }

  Future<void> test_afterAnalysis_packageFile_notUsed() async {
    var pkgFile = newFile('/packages/pkgA/lib/libA.dart', content: '''
library lib_a;
class A {}
''').path;
    newFile('/project/.packages', content: 'pkgA:/packages/pkgA/lib');
    //
    addTestFile('// no "pkgA" reference');
    createProject();
    // wait for analysis, no results initially
    await waitForTasksFinished();
    expect(filesHighlights[pkgFile], isNull);
    // make it a priority file, so make analyzable
    server.setPriorityFiles('0', [pkgFile]);
    // subscribe
    addAnalysisSubscription(AnalysisService.HIGHLIGHTS, pkgFile);
    await _resultsAvailable.future;
    // there are results
    expect(filesHighlights[pkgFile], isNotEmpty);
  }

  Future<void> test_afterAnalysis_sdkFile() async {
    var file = convertPath('/sdk/lib/core/core.dart');
    addTestFile('// no matter');
    createProject();
    // wait for analysis, no results initially
    await waitForTasksFinished();
    expect(filesHighlights[file], isNull);
    // subscribe
    addAnalysisSubscription(AnalysisService.HIGHLIGHTS, file);
    await _resultsAvailable.future;
    // there are results
    expect(filesHighlights[file], isNotEmpty);
  }

  Future<void> test_beforeAnalysis() async {
    addTestFile('int V = 42;');
    createProject();
    // subscribe
    addAnalysisSubscription(AnalysisService.HIGHLIGHTS, testFile);
    // wait for analysis
    await waitForTasksFinished();
    expect(filesHighlights[testFile], isNotEmpty);
  }

  Future<void> test_sentToPlugins() async {
    addTestFile('int V = 42;');
    createProject();
    // subscribe
    addAnalysisSubscription(AnalysisService.HIGHLIGHTS, testFile);
    // wait for analysis
    await waitForTasksFinished();
    var params = pluginManager.analysisSetSubscriptionsParams;
    expect(params, isNotNull);
    var subscriptions = params.subscriptions;
    expect(subscriptions, hasLength(1));
    var files = subscriptions[plugin.AnalysisService.HIGHLIGHTS];
    expect(files, [testFile]);
  }
}
