// Copyright (c) 2015, 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:io';

import 'package:analyzer/error/error.dart';
import 'package:analyzer/source/error_processor.dart';
import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/util/sdk.dart';
import 'package:analyzer_cli/src/ansi.dart' as ansi;
import 'package:analyzer_cli/src/driver.dart';
import 'package:analyzer_cli/src/options.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:yaml/src/yaml_node.dart';

import 'utils.dart';

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(BuildModeTest);
    defineReflectiveTests(BuildModeSummaryDependenciesTest);
    defineReflectiveTests(ExitCodesTest);
    defineReflectiveTests(LinterTest);
    defineReflectiveTests(NonDartFilesTest);
    defineReflectiveTests(OptionsTest);
  }, name: 'Driver');
}

class AbstractBuildModeTest extends BaseTest {
  List<String> get _sdkSummaryArguments {
    var sdkPath = path.dirname(
      path.dirname(
        Platform.resolvedExecutable,
      ),
    );

    var dartSdkSummaryPath = path.join(
      sdkPath,
      'lib',
      '_internal',
      'strong.sum',
    );

    return ['--dart-sdk-summary', dartSdkSummaryPath];
  }

  Future<void> _doDrive(
    String filePath, {
    String sourceArgument,
    String fileUri,
    List<String> additionalArgs = const [],
  }) async {
    filePath = _posixToPlatformPath(filePath);

    var optionsFileName = AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE;
    var options =
        _posixToPlatformPath('data/options_tests_project/' + optionsFileName);

    var args = <String>[];
    args.add('--build-mode');
    args.add('--format=machine');

    args.addAll(_sdkSummaryArguments);
    args.addAll(additionalArgs);

    if (sourceArgument == null) {
      fileUri ??= 'file:///test_file.dart';
      sourceArgument = '$fileUri|$filePath';
    }

    await drive(sourceArgument, args: args, options: options);
  }
}

class BaseTest {
  static const emptyOptionsFile = 'data/empty_options.yaml';

  StringSink _savedOutSink, _savedErrorSink;
  int _savedExitCode;
  ExitHandler _savedExitHandler;

  Driver driver;

  AnalysisOptions get analysisOptions => driver.analysisDriver.analysisOptions;

  /// Normalize text with bullets.
  String bulletToDash(StringSink item) => '$item'.replaceAll('•', '-');

  /// Start a driver for the given [source], optionally providing additional
  /// [args] and an [options] file path. The value of [options] defaults to an
  /// empty options file to avoid unwanted configuration from an otherwise
  /// discovered options file.
  Future<void> drive(
    String source, {
    String options = emptyOptionsFile,
    List<String> args = const <String>[],
  }) {
    return driveMany([source], options: options, args: args);
  }

  /// Like [drive], but takes an array of sources.
  Future<void> driveMany(
    List<String> sources, {
    String options = emptyOptionsFile,
    List<String> args = const <String>[],
  }) async {
    options = _posixToPlatformPath(options);

    driver = Driver();
    var cmd = <String>[];
    if (options != null) {
      cmd = <String>[
        '--options',
        path.join(testDirectory, options),
      ];
    }
    cmd..addAll(sources.map(_adjustFileSpec))..addAll(args);

    await driver.start(cmd);
  }

  void setUp() {
    ansi.runningTests = true;
    _savedOutSink = outSink;
    _savedErrorSink = errorSink;
    _savedExitHandler = exitHandler;
    _savedExitCode = exitCode;
    exitHandler = (code) => exitCode = code;
    outSink = StringBuffer();
    errorSink = StringBuffer();
  }

  void tearDown() {
    outSink = _savedOutSink;
    errorSink = _savedErrorSink;
    exitCode = _savedExitCode;
    exitHandler = _savedExitHandler;
    ansi.runningTests = false;
  }

  /// Convert a file specification from a relative path to an absolute path.
  /// Handles the case where the file specification is of the form "$uri|$path".
  String _adjustFileSpec(String fileSpec) {
    var uriPrefixLength = fileSpec.indexOf('|') + 1;
    var uriPrefix = fileSpec.substring(0, uriPrefixLength);
    var relativePath = fileSpec.substring(uriPrefixLength);
    return '$uriPrefix${path.join(testDirectory, relativePath)}';
  }

  /// Convert the given posix [filePath] to conform to to the platform style.
  ///
  /// This is a utility method for testing; paths passed in to other methods in
  /// this class are never converted automatically.
  String _posixToPlatformPath(String filePath) {
    if (filePath == null) {
      return null;
    }
    if (path.style == path.windows.style) {
      filePath = filePath.replaceAll(
        path.posix.separator,
        path.windows.separator,
      );
    }
    return filePath;
  }
}

@reflectiveTest
class BuildModeSummaryDependenciesTest extends AbstractBuildModeTest {
  String tempDir;

  /// Any direct export is a dependency.
  Future<void> test_export_direct() async {
    await _withTempDir(() async {
      var a = await _buildPackage('a', [], 'class A {}');
      await _assertDependencies('c', [a], '''
export 'package:a/a.dart';
''', [a]);
    });
  }

  /// Imports of dependencies are not necessary dependencies.
  /// Here our dependency does not use its dependency.
  Future<void> test_import2_notUsed() async {
    await _withTempDir(() async {
      var a = await _buildPackage('a', [], '');
      var b = await _buildPackage('b', [a], '''
import 'package:a/a.dart';
''');
      await _assertDependencies('c', [a, b], '''
import 'package:b/b.dart';
''', [b]);
    });
  }

  Future<void> test_import2_usedAsFieldType() async {
    await _withTempDir(() async {
      var a = await _buildPackage('a', [], 'class A {}');
      var b = await _buildPackage('b', [a], '''
import 'package:a/a.dart';
class B {
  A f;
}
''');

      // We don't use `f`, so don't depend on "a".
      await _assertDependencies('c', [a, b], '''
import 'package:b/b.dart';
var x = B();
''', [b]);

      // We use `f` for type inference.
      // So, dependency on "a".
      await _assertDependencies('c', [a, b], '''
import 'package:b/b.dart';
var x = B().f;
''', [a, b]);

      // We reference `f` in initializer, but not for type inference.
      // So, no dependency on "a".
      await _assertDependencies('c', [a, b], '''
import 'package:b/b.dart';
Object x = B().f;
''', [b]);

      // We perform full analysis, so request the type of `f`;
      // So, dependency on "a".
      await _assertDependencies(
        'c',
        [a, b],
        '''
import 'package:b/b.dart';
Object x = B().f;
''',
        [a, b],
        summaryOnly: false,
      );
    });
  }

  Future<void> test_import2_usedAsSupertype() async {
    await _withTempDir(() async {
      var a = await _buildPackage('a', [], 'class A {}');
      var b = await _buildPackage('b', [a], '''
import 'package:a/a.dart';
class B extends A {}
''');

      // We don't invoke anything on class `B`, so don't ask its supertype.
      // So, no dependency on "a".
      await _assertDependencies('c', [a, b], '''
import 'package:b/b.dart';
B x;
''', [b]);

      // We infer the type of `x` to `B`.
      // But we don't ask `B` for its supertype.
      // So, no dependency on "a".
      await _assertDependencies('c', [a, b], '''
import 'package:b/b.dart';
var x = B();
''', [b]);

      // We perform full analysis, and check that `new B()` is assignable
      // to `B x`. This is trivially true, we don't need the supertype of `B`.
      // So, no dependency on "a".
      await _assertDependencies(
        'c',
        [a, b],
        '''
import 'package:b/b.dart';
var x = B();
''',
        [b],
        summaryOnly: false,
      );
    });
  }

  Future<void> test_import2_usedAsTopLevelVariableType() async {
    await _withTempDir(() async {
      var a = await _buildPackage('a', [], 'class A {}');
      var b = await _buildPackage('b', [a], '''
import 'package:a/a.dart';
A v;
''');

      // We don't use `v`.
      // So, no dependency on "a".
      await _assertDependencies('c', [a, b], '''
import 'package:b/b.dart';
''', [b]);

      // We use `v` for type inference.
      // So, dependency on "a".
      await _assertDependencies('c', [a, b], '''
import 'package:b/b.dart';
var x = v;
''', [a, b]);

      // We don't use `v` for type inference.
      // So, no dependency on "a".
      await _assertDependencies('c', [a, b], '''
import 'package:b/b.dart';
Object x = v;
''', [b]);

      // We perform full analysis, and request the type of `v`.
      // So, dependency on "a".
      await _assertDependencies(
        'c',
        [a, b],
        '''
import 'package:b/b.dart';
Object x = v;
''',
        [a, b],
        summaryOnly: false,
      );

      // We use `v` in a method body.
      // So, no dependency on "a".
      await _assertDependencies('c', [a, b], '''
import 'package:b/b.dart';
main() {
  v;
}
''', [b]);

      // We perform full analysis, so ask for the type of `v`.
      // So, dependency on "a".
      await _assertDependencies(
        'c',
        [a, b],
        '''
import 'package:b/b.dart';
main() {
  v;
}
''',
        [a, b],
        summaryOnly: false,
      );
    });
  }

  /// Any direct import is a dependency.
  Future<void> test_import_direct() async {
    await _withTempDir(() async {
      var a = await _buildPackage('a', [], '');
      var b = await _buildPackage('b', [], '');
      await _assertDependencies('c', [a, b], '''
import 'package:a/a.dart';
import 'package:b/b.dart';
''', [a, b]);
    });
  }

  /// Exports of dependencies are dependencies.
  Future<void> test_import_export() async {
    await _withTempDir(() async {
      var a = await _buildPackage('a', [], 'class A {}');
      var b = await _buildPackage('b', [a], '''
export 'package:a/a.dart';
''');
      await _assertDependencies('c', [a, b], '''
import 'package:b/b.dart';
''', [a, b]);
    });
  }

  Future<void> _assertDependencies(
    String name,
    List<_DependencyPackage> inputPackages,
    String content,
    List<_DependencyPackage> expectedPackages, {
    bool summaryOnly = true,
  }) async {
    var pkg = await _buildPackage(name, inputPackages, content,
        summaryOnly: summaryOnly);

    var depString = File(pkg.dep).readAsStringSync();
    var expectedList = expectedPackages.map((p) => p.sum).toList();
    expect(depString.split('\n'), unorderedEquals(expectedList));
  }

  Future<_DependencyPackage> _buildPackage(
    String name,
    List<_DependencyPackage> inputPackages,
    String content, {
    bool summaryOnly = true,
  }) async {
    var filePath = path.join(tempDir, '$name.dart');
    File(filePath).writeAsStringSync(content);
    var pkg = _DependencyPackage(
      name: name,
      path: filePath,
      uri: 'package:$name/$name.dart',
      sum: path.join(tempDir, '$name.sum'),
      dep: path.join(tempDir, '$name.dep'),
    );

    var args = <String>[];
    if (summaryOnly) {
      args.add('--build-summary-only');
    }
    for (var input in inputPackages) {
      args.add('--build-summary-input=${input.sum}');
    }
    args.add('--build-summary-output=${pkg.sum}');
    args.add('--summary-deps-output=${pkg.dep}');

    await _doDrive(pkg.path, fileUri: pkg.uri, additionalArgs: args);
    expect(exitCode, 0);

    return pkg;
  }

  Future<void> _withTempDir(Future<void> Function() f) async {
    await withTempDirAsync((tempDir) async {
      this.tempDir = tempDir;
      await f();
    });
  }
}

@reflectiveTest
class BuildModeTest extends AbstractBuildModeTest {
  Future<void> test_buildLinked() async {
    await withTempDirAsync((tempDir) async {
      var outputPath = path.join(tempDir, 'test_file.dart.sum');
      await _doDrive(path.join('data', 'test_file.dart'), additionalArgs: [
        '--build-summary-only',
        '--build-summary-output=$outputPath'
      ]);
      var output = File(outputPath);
      expect(output.existsSync(), isTrue);
      var bundle = PackageBundle.fromBuffer(await output.readAsBytes());
      var testFileUri = 'file:///test_file.dart';

      var bundle2 = bundle.bundle2;
      expect(_linkedLibraryUriList(bundle2), [testFileUri]);
      expect(
        _linkedLibraryUnitUriList(bundle2, testFileUri),
        [testFileUri],
      );

      expect(exitCode, 0);
    });
  }

  Future<void> test_buildLinked_invalidPartUri() async {
    await withTempDirAsync((tempDir) async {
      var aDart = path.join(tempDir, 'a.dart');

      var aUri = 'package:aaa/a.dart';

      var aSum = path.join(tempDir, 'a.sum');

      File(aDart).writeAsStringSync('''
part '[invalid]';
''');

      await _doDrive(aDart,
          fileUri: aUri, additionalArgs: ['--build-summary-output=$aSum']);
      expect(exitCode, ErrorSeverity.ERROR.ordinal);
      var bytes = File(aSum).readAsBytesSync();
      var bundle = PackageBundle.fromBuffer(bytes);
      var bundle2 = bundle.bundle2;
      expect(_linkedLibraryUriList(bundle2), [aUri]);
      expect(_linkedLibraryUnitUriList(bundle2, aUri), [aUri, '']);
    });
  }

  Future<void> test_buildSuppressExitCode_fail_whenFileNotFound() async {
    await _doDrive(path.join('data', 'non_existent_file.dart'),
        additionalArgs: ['--build-suppress-exit-code']);
    expect(exitCode, isNot(0));
  }

  Future<void> test_buildSuppressExitCode_success_evenIfHasError() async {
    await _doDrive(path.join('data', 'file_with_error.dart'),
        additionalArgs: ['--build-suppress-exit-code']);
    expect(exitCode, 0);
  }

  Future<void> test_consumeLinked() async {
    await withTempDirAsync((tempDir) async {
      var aDart = path.join(tempDir, 'a.dart');
      var bDart = path.join(tempDir, 'b.dart');
      var cDart = path.join(tempDir, 'c.dart');

      var aUri = 'package:aaa/a.dart';
      var bUri = 'package:bbb/b.dart';
      var cUri = 'package:ccc/c.dart';

      var aSum = path.join(tempDir, 'a.sum');
      var bSum = path.join(tempDir, 'b.sum');
      var cSum = path.join(tempDir, 'c.sum');

      File(aDart).writeAsStringSync('class A {}');
      File(bDart).writeAsStringSync('''
export 'package:aaa/a.dart';
class B {}
''');
      File(cDart).writeAsStringSync('''
import 'package:bbb/b.dart';
var a = new A();
var b = new B();
''');

      // Analyze package:aaa/a.dart and compute summary.
      {
        await _doDrive(aDart,
            fileUri: aUri, additionalArgs: ['--build-summary-output=$aSum']);
        expect(exitCode, 0);
        var bytes = File(aSum).readAsBytesSync();
        var bundle = PackageBundle.fromBuffer(bytes);
        var bundle2 = bundle.bundle2;
        expect(_linkedLibraryUriList(bundle2), [aUri]);
        expect(_linkedLibraryUnitUriList(bundle2, aUri), [aUri]);
      }

      // Analyze package:bbb/b.dart and compute summary.
      {
        await _doDrive(bDart, fileUri: bUri, additionalArgs: [
          '--build-summary-input=$aSum',
          '--build-summary-output=$bSum'
        ]);
        expect(exitCode, 0);
        var bytes = File(bSum).readAsBytesSync();
        var bundle = PackageBundle.fromBuffer(bytes);
        var bundle2 = bundle.bundle2;
        expect(_linkedLibraryUriList(bundle2), [bUri]);
        expect(_linkedLibraryUnitUriList(bundle2, bUri), [bUri]);
      }

      // Analyze package:ccc/c.dart and compute summary.
      {
        await _doDrive(cDart, fileUri: cUri, additionalArgs: [
          '--build-summary-input=$aSum,$bSum',
          '--build-summary-output=$cSum'
        ]);
        expect(exitCode, 0);
        var bytes = File(cSum).readAsBytesSync();
        var bundle = PackageBundle.fromBuffer(bytes);
        var bundle2 = bundle.bundle2;
        expect(_linkedLibraryUriList(bundle2), [cUri]);
        expect(_linkedLibraryUnitUriList(bundle2, cUri), [cUri]);
      }
    });
  }

  Future<void> test_error_notUriPipePath() async {
    await withTempDirAsync((tempDir) async {
      var testDart = path.join(tempDir, 'test.dart');
      File(testDart).writeAsStringSync('var v = 42;');

      // We pass just path, not "uri|path", this is a fatal error.
      await _doDrive(
        testDart,
        additionalArgs: ['--build-mode', '--format=machine'],
        sourceArgument: testDart,
      );
      expect(exitCode, ErrorSeverity.ERROR.ordinal);
    });
  }

  Future<void> test_fail_whenHasError() async {
    await _doDrive(path.join('data', 'file_with_error.dart'));
    expect(exitCode, isNot(0));
  }

  Future<void> test_noInputs() async {
    await withTempDirAsync((tempDir) async {
      var outputPath = path.join(tempDir, 'test.sum');

      await driveMany([], args: [
        '--build-mode',
        '--format=machine',
        ..._sdkSummaryArguments,
        '--build-summary-only',
        '--build-summary-output=$outputPath',
      ]);

      var output = File(outputPath);
      expect(output.existsSync(), isTrue);

      expect(exitCode, 0);
    });
  }

  Future<void> test_noStatistics() async {
    await _doDrive(path.join('data', 'test_file.dart'));
    // Should not print statistics summary.
    expect(outSink.toString(), isEmpty);
    expect(errorSink.toString(), isEmpty);
    expect(exitCode, 0);
  }

  Future<void> test_onlyErrors_partFirst() async {
    await withTempDirAsync((tempDir) async {
      var aDart = path.join(tempDir, 'a.dart');
      var bDart = path.join(tempDir, 'b.dart');

      var aUri = 'package:aaa/a.dart';
      var bUri = 'package:aaa/b.dart';

      File(aDart).writeAsStringSync(r'''
library lib;
part 'b.dart';
class A {}
''');
      File(bDart).writeAsStringSync('''
part of lib;
class B {}
var a = new A();
var b = new B();
''');

      // Analyze b.dart (part) and then a.dart (its library).
      // No errors should be reported - the part should know its library.
      await _doDrive(bDart, fileUri: bUri, additionalArgs: ['$aUri|$aDart']);
      expect(errorSink, isEmpty);
    });
  }

  Future<void> test_packageConfig_packagesOptions() async {
    await withTempDirAsync((tempDir) async {
      var packagesPath = path.join(tempDir, 'aaa.packages');

      var aaaRoot = path.join(tempDir, 'packages', 'aaa');
      var aPath = path.join(aaaRoot, 'lib', 'a.dart');

      var aUri = 'package:aaa/a.dart';

      File(packagesPath).createSync(recursive: true);
      File(packagesPath).writeAsStringSync('''
{
  "configVersion": 2,
  "packages": [
    {
      "name": "aaa",
      "rootUri": "${path.toUri(aaaRoot)}",
      "packageUri": "lib/",
      "languageVersion": "2.4"
    }
  ]
}
''');

      File(aPath).createSync(recursive: true);
      File(aPath).writeAsStringSync(r'''
extension E on int {}
''');

      // Analyze package:aaa/a.dart and compute errors.
      await _doDrive(
        aPath,
        fileUri: aUri,
        additionalArgs: [
          '--packages=$packagesPath',
        ],
      );
      expect(exitCode, ErrorSeverity.ERROR.ordinal);
      expect(errorSink.toString(), contains('extension-methods'));
    });
  }

  Future<void> test_packageConfig_relativeToFile() async {
    await withTempDirAsync((tempDir) async {
      var packagesPath = path.join(tempDir, '.dart_tool/package_config.json');

      var aaaRoot = path.join(tempDir, 'packages', 'aaa');
      var aPath = path.join(aaaRoot, 'lib', 'a.dart');

      var aUri = 'package:aaa/a.dart';

      File(packagesPath).createSync(recursive: true);
      File(packagesPath).writeAsStringSync('''
{
  "configVersion": 2,
  "packages": [
    {
      "name": "aaa",
      "rootUri": "${path.toUri(aaaRoot)}",
      "packageUri": "lib/",
      "languageVersion": "2.4"
    }
  ]
}
''');

      File(aPath).createSync(recursive: true);
      File(aPath).writeAsStringSync(r'''
extension E on int {}
''');

      // Analyze package:aaa/a.dart and compute errors.
      await _doDrive(
        aPath,
        fileUri: aUri,
        additionalArgs: [],
      );
      expect(exitCode, ErrorSeverity.ERROR.ordinal);
      expect(errorSink.toString(), contains('extension-methods'));
    });
  }

  Iterable<String> _linkedLibraryUnitUriList(
    LinkedNodeBundle bundle2,
    String libraryUriStr,
  ) {
    var libraries = bundle2.libraries;
    var library = libraries.singleWhere((l) => l.uriStr == libraryUriStr);
    return library.units.map((u) => u.uriStr).toList();
  }

  Iterable<String> _linkedLibraryUriList(LinkedNodeBundle bundle2) {
    var libraries = bundle2.libraries;
    return libraries.map((l) => l.uriStr).toList();
  }
}

@reflectiveTest
class ExitCodesTest extends BaseTest {
  @SkippedTest(reason: 'Fails on bots, passes locally. Do not know why.')
  Future<void> test_bazelWorkspace_relativePath() async {
    // Copy to temp dir so that existing analysis options
    // in the test directory hierarchy do not interfere
    await withTempDirAsync((String tempDirPath) async {
      var dartSdkPath = path.absolute(getSdkPath());
      await recursiveCopy(
          Directory(path.join(testDirectory, 'data', 'bazel')), tempDirPath);
      var origWorkingDir = Directory.current;
      try {
        Directory.current = path.join(tempDirPath, 'proj');
        var driver = Driver();
        try {
          await driver.start([
            path.join('lib', 'file.dart'),
            '--dart-sdk',
            dartSdkPath,
          ]);
        } catch (e) {
          print('=== debug info ===');
          print('dartSdkPath: $dartSdkPath');
          print('stderr:\n${errorSink.toString()}');
          rethrow;
        }
        expect(errorSink.toString(), isEmpty);
        expect(outSink.toString(), contains('No issues found'));
        expect(exitCode, 0);
      } finally {
        Directory.current = origWorkingDir;
      }
    });
  }

  Future<void> test_fatalErrors() async {
    await drive('data/file_with_error.dart');
    expect(exitCode, 3);
  }

  Future<void> test_fatalHints() async {
    await drive('data/file_with_hint.dart', args: ['--fatal-hints']);
    expect(exitCode, 1);
  }

  Future<void> test_missingDartFile() async {
    await drive('data/NO_DART_FILE_HERE.dart');
    expect(exitCode, 3);
  }

  Future<void> test_missingOptionsFile() async {
    await drive('data/test_file.dart', options: 'data/NO_OPTIONS_HERE');
    expect(exitCode, 3);
  }

  Future<void> test_notFatalHints() async {
    await drive('data/file_with_hint.dart');
    expect(exitCode, 0);
  }

  Future<void> test_partFile() async {
    await driveMany([
      path.join(testDirectory, 'data/library_and_parts/lib.dart'),
      path.join(testDirectory, 'data/library_and_parts/part1.dart')
    ]);
    expect(exitCode, 0);
  }

  Future<void> test_partFile_dangling() async {
    await drive('data/library_and_parts/part2.dart');
    expect(exitCode, 3);
  }

  Future<void> test_partFile_extra() async {
    await driveMany([
      path.join(testDirectory, 'data/library_and_parts/lib.dart'),
      path.join(testDirectory, 'data/library_and_parts/part1.dart'),
      path.join(testDirectory, 'data/library_and_parts/part2.dart')
    ]);
    expect(exitCode, 3);
  }

  Future<void> test_partFile_reversed() async {
    var driver = Driver();
    await driver.start([
      path.join(testDirectory, 'data/library_and_parts/part1.dart'),
      path.join(testDirectory, 'data/library_and_parts/lib.dart')
    ]);
    expect(exitCode, 0);
  }
}

@reflectiveTest
class LinterTest extends BaseTest {
  String get optionsFileName => AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE;

  Future<void> test_containsLintRuleEntry() async {
    var options = _parseOptions('''
linter:
  rules:
    - foo
        ''');
    expect(containsLintRuleEntry(options), true);
    options = _parseOptions('''
        ''');
    expect(containsLintRuleEntry(options), false);
    options = _parseOptions('''
linter:
  rules:
    # - foo
        ''');
    expect(containsLintRuleEntry(options), true);
    options = _parseOptions('''
linter:
  # rules:
    # - foo
        ''');
    expect(containsLintRuleEntry(options), false);
  }

  Future<void> test_defaultLints_generatedLints() async {
    await _runLinter_defaultLints();
    expect(bulletToDash(outSink),
        contains('lint - Name types using UpperCamelCase'));
  }

  Future<void> test_defaultLints_getsDefaultLints() async {
    await _runLinter_defaultLints();

    /// Lints should be enabled.
    expect(analysisOptions.lint, isTrue);

    /// Default list should include camel_case_types.
    var lintNames = analysisOptions.lintRules.map((r) => r.name);
    expect(lintNames, contains('camel_case_types'));
  }

  Future<void> test_lintsInOptions_generatedLints() async {
    await _runLinter_lintsInOptions();
    expect(bulletToDash(outSink),
        contains('lint - Name types using UpperCamelCase'));
  }

  Future<void> test_lintsInOptions_getAnalysisOptions() async {
    await _runLinter_lintsInOptions();

    /// Lints should be enabled.
    expect(analysisOptions.lint, isTrue);

    /// The analysis options file specifies 'camel_case_types' and 'sort_pub_dependencies'.
    var lintNames = analysisOptions.lintRules.map((r) => r.name);
    expect(lintNames,
        orderedEquals(['camel_case_types', 'sort_pub_dependencies']));
  }

  Future<void> test_noLints_lintsDisabled() async {
    await _runLinter_noLintsFlag();
    expect(analysisOptions.lint, isFalse);
  }

  Future<void> test_noLints_noGeneratedWarnings() async {
    await _runLinter_noLintsFlag();
    expect(outSink.toString(), contains('No issues found'));
  }

  Future<void> test_noLints_noRegisteredLints() async {
    await _runLinter_noLintsFlag();
    expect(analysisOptions.lintRules, isEmpty);
  }

  Future<void> test_pubspec_lintsInOptions_generatedLints() async {
    await drive('data/linter_project/pubspec.yaml',
        options: 'data/linter_project/$optionsFileName');
    expect(bulletToDash(outSink), contains('lint - Sort pub dependencies'));
  }

  YamlMap _parseOptions(String src) =>
      AnalysisOptionsProvider().getOptionsFromString(src);

  Future<void> _runLinter_defaultLints() async {
    await drive('data/linter_project/test_file.dart',
        options: 'data/linter_project/$optionsFileName', args: ['--lints']);
  }

  Future<void> _runLinter_lintsInOptions() async {
    await drive('data/linter_project/test_file.dart',
        options: 'data/linter_project/$optionsFileName', args: ['--lints']);
  }

  Future<void> _runLinter_noLintsFlag() async {
    await drive('data/no_lints_project/test_file.dart',
        options: 'data/no_lints_project/$optionsFileName');
  }
}

@reflectiveTest
class NonDartFilesTest extends BaseTest {
  Future<void> test_analysisOptionsYaml() async {
    await withTempDirAsync((tempDir) async {
      var filePath =
          path.join(tempDir, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
      File(filePath).writeAsStringSync('''
analyzer:
  string-mode: true
''');
      await drive(filePath);
      expect(
          bulletToDash(outSink),
          contains(
              "warning - The option 'string-mode' isn't supported by 'analyzer'"));
      expect(exitCode, 0);
    });
  }

  Future<void> test_manifestFileChecks() async {
    await withTempDirAsync((tempDir) async {
      var filePath =
          path.join(tempDir, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
      File(filePath).writeAsStringSync('''
analyzer:
  optional-checks:
    chrome-os-manifest-checks: true
''');
      var manifestPath =
          path.join(tempDir, AnalysisEngine.ANDROID_MANIFEST_FILE);
      File(manifestPath).writeAsStringSync('''
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
    <uses-feature android:name="android.software.home_screen" />
</manifest>
''');
      await drive(manifestPath, options: filePath);
      expect(
          bulletToDash(outSink),
          contains(
              'warning - The feature android.software.home_screen is not supported on Chrome OS'));
      expect(exitCode, 0);
    });
  }

  Future<void> test_pubspecYaml() async {
    await withTempDirAsync((tempDir) async {
      var filePath = path.join(tempDir, AnalysisEngine.PUBSPEC_YAML_FILE);
      File(filePath).writeAsStringSync('''
name: foo
flutter:
  assets:
    doesNotExist.gif
''');
      await drive(filePath);
      expect(
          bulletToDash(outSink),
          contains(
              "warning - The value of the 'asset' field is expected to be a list of relative file paths"));
      expect(exitCode, 0);
    });
  }
}

@reflectiveTest
class OptionsTest extends BaseTest {
  String get optionsFileName => AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE;

  List<ErrorProcessor> get processors => analysisOptions.errorProcessors;

  ErrorProcessor processorFor(AnalysisError error) =>
      processors.firstWhere((p) => p.appliesTo(error));

  Future<void> test_analysisOptions_excludes() async {
    await drive('data/exclude_test_project',
        options: 'data/exclude_test_project/$optionsFileName');
    _expectUndefinedClassErrorsWithoutExclusions();
  }

  Future<void>
      test_analysisOptions_excludesRelativeToAnalysisOptions_explicit() async {
    // The exclude is relative to the project, not/ the analyzed path, and it
    // has to then understand that.
    await drive('data/exclude_test_project',
        options: 'data/exclude_test_project/$optionsFileName');
    _expectUndefinedClassErrorsWithoutExclusions();
  }

  Future<void>
      test_analysisOptions_excludesRelativeToAnalysisOptions_inferred() async {
    // By passing no options, and the path `lib`, it should discover the
    // analysis_options above lib. The exclude is relative to the project, not
    // the analyzed path, and it has to then understand that.
    await drive('data/exclude_test_project/lib', options: null);
    _expectUndefinedClassErrorsWithoutExclusions();
  }

  Future<void> test_analyzeFilesInDifferentContexts() async {
    await driveMany([
      'data/linter_project/test_file.dart',
      'data/no_lints_project/test_file.dart',
    ], options: null);

    // Should have the lint in the project with lint rules enabled.
    expect(
        bulletToDash(outSink),
        contains(path.join('linter_project', 'test_file.dart') +
            ':7:7 - camel_case_types'));
    // Should be just one lint in total.
    expect(outSink.toString(), contains('1 lint found.'));
  }

  Future<void> test_basic_filters() async {
    await _driveBasic();
    expect(processors, hasLength(3));

    // unused_local_variable: ignore
    var unused_local_variable =
        AnalysisError(TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
      ['x']
    ]);
    expect(processorFor(unused_local_variable).severity, isNull);

    // missing_return: error
    var missing_return =
        AnalysisError(TestSource(), 0, 1, HintCode.MISSING_RETURN, [
      ['x']
    ]);
    expect(processorFor(missing_return).severity, ErrorSeverity.ERROR);
    expect(bulletToDash(outSink),
        contains("error - This function has a return type of 'int'"));
    expect(outSink.toString(), contains('1 error and 1 warning found.'));
  }

  Future<void> test_includeDirective() async {
    var testDir = path.join(
        testDirectory, 'data', 'options_include_directive_tests_project');
    await drive(
      path.join(testDir, 'lib', 'test_file.dart'),
      args: [
        '--fatal-warnings',
        '--packages',
        path.join(testDir, '_packages'),
      ],
      options: path.join(testDir, 'analysis_options.yaml'),
    );
    expect(exitCode, 3);
    expect(outSink.toString(), contains('Unnecessary cast.'));
    expect(outSink.toString(), contains('isn\'t defined'));
    expect(outSink.toString(), contains('Avoid empty else statements'));
  }

  Future<void> test_todo() async {
    await drive('data/file_with_todo.dart');
    expect(outSink.toString().contains('[info]'), isFalse);
  }

  Future<void> test_withFlags_overrideFatalWarning() async {
    await drive('data/options_tests_project/test_file.dart',
        args: ['--fatal-warnings'],
        options: 'data/options_tests_project/$optionsFileName');

    // missing_return: error
    var undefined_function = AnalysisError(
        TestSource(), 0, 1, CompileTimeErrorCode.UNDEFINED_FUNCTION, [
      ['x']
    ]);
    expect(processorFor(undefined_function).severity, ErrorSeverity.WARNING);
    // Should not be made fatal by `--fatal-warnings`.
    expect(bulletToDash(outSink),
        contains("warning - The function 'baz' isn't defined"));
    expect(outSink.toString(), contains('1 error and 1 warning found.'));
  }

  Future<void> _driveBasic() async {
    await drive('data/options_tests_project/test_file.dart',
        options: 'data/options_tests_project/$optionsFileName');
  }

  void _expectUndefinedClassErrorsWithoutExclusions() {
    expect(bulletToDash(outSink),
        contains("error - Undefined class 'IncludedUndefinedClass'"));
    expect(bulletToDash(outSink),
        isNot(contains("error - Undefined class 'ExcludedUndefinedClass'")));
    expect(outSink.toString(), contains('1 error found.'));
  }
}

class TestSource implements Source {
  TestSource();

  @override
  String get fullName => '/package/lib/test.dart';

  @override
  dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

class _DependencyPackage {
  final String name;
  final String path;
  final String uri;
  final String sum;
  final String dep;

  _DependencyPackage({this.name, this.path, this.uri, this.sum, this.dep});
}
