// Copyright (c) 2016, 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.

library analyzer.test.src.context.context_builder_test;

import 'dart:io' as io;

import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/context/source.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:package_config/packages.dart';
import 'package:package_config/src/packages_impl.dart';
import 'package:path/path.dart' as path;
import 'package:unittest/unittest.dart';

import '../../generated/test_support.dart';
import '../../reflective_tests.dart';
import '../../source/embedder_test.dart';
import '../../utils.dart';
import 'mock_sdk.dart';

main() {
  initializeTestEnvironment();
  runReflectiveTests(ContextBuilderTest_WithDisk);
  runReflectiveTests(ContextBuilderTest_WithoutDisk);
  runReflectiveTests(EmbedderYamlLocatorTest);
}

@reflectiveTest
class ContextBuilderTest_WithDisk extends EngineTestCase {
  /**
   * The resource provider to be used by tests.
   */
  PhysicalResourceProvider resourceProvider;

  /**
   * The path context used to manipulate file paths.
   */
  path.Context pathContext;

  /**
   * The SDK manager used by the tests;
   */
  DartSdkManager sdkManager;

  /**
   * The content cache used by the tests.
   */
  ContentCache contentCache;

  /**
   * The context builder to be used in the test.
   */
  ContextBuilder builder;

  /**
   * The path to the default SDK, or `null` if the test has not explicitly
   * invoked [createDefaultSdk].
   */
  String defaultSdkPath = null;

  void createDefaultSdk(io.Directory tempDir) {
    defaultSdkPath = pathContext.join(tempDir.path, 'default', 'sdk');
    String librariesFilePath = pathContext.join(defaultSdkPath, 'lib',
        '_internal', 'sdk_library_metadata', 'lib', 'libraries.dart');
    createFile(
        librariesFilePath,
        r'''
const Map<String, LibraryInfo> libraries = const {
  "async": const LibraryInfo("async/async.dart"),
  "core": const LibraryInfo("core/core.dart"),
};
''');
    sdkManager =
        new DartSdkManager(defaultSdkPath, false, (_) => new MockSdk());
    builder = new ContextBuilder(resourceProvider, sdkManager, contentCache);
  }

  void createDirectory(String path) {
    new io.Directory(path).createSync(recursive: true);
  }

  void createFile(String path, String content) {
    new io.File(path)
      ..createSync(recursive: true)
      ..writeAsStringSync(content);
  }

  @override
  void setUp() {
    resourceProvider = PhysicalResourceProvider.INSTANCE;
    pathContext = resourceProvider.pathContext;
    sdkManager = new DartSdkManager('', false, (_) => new MockSdk());
    contentCache = new ContentCache();
    builder = new ContextBuilder(resourceProvider, sdkManager, contentCache);
  }

  @failingTest
  void test_buildContext() {
    fail('Incomplete test');
  }

  void test_createPackageMap_fromPackageDirectory_explicit() {
    withTempDir((io.Directory tempDir) {
      // Use a package directory that is outside the project directory.
      String rootPath = tempDir.path;
      String projectPath = pathContext.join(rootPath, 'project');
      String packageDirPath = pathContext.join(rootPath, 'packages');
      String fooName = 'foo';
      String fooPath = pathContext.join(packageDirPath, fooName);
      String barName = 'bar';
      String barPath = pathContext.join(packageDirPath, barName);
      createDirectory(projectPath);
      createDirectory(fooPath);
      createDirectory(barPath);

      builder.defaultPackagesDirectoryPath = packageDirPath;

      Packages packages = builder.createPackageMap(projectPath);
      expect(packages, isNotNull);
      Map<String, Uri> map = packages.asMap();
      expect(map, hasLength(2));
      expect(map[fooName], new Uri.directory(fooPath));
      expect(map[barName], new Uri.directory(barPath));
    });
  }

  void test_createPackageMap_fromPackageDirectory_inRoot() {
    withTempDir((io.Directory tempDir) {
      // Use a package directory that is inside the project directory.
      String projectPath = tempDir.path;
      String packageDirPath = pathContext.join(projectPath, 'packages');
      String fooName = 'foo';
      String fooPath = pathContext.join(packageDirPath, fooName);
      String barName = 'bar';
      String barPath = pathContext.join(packageDirPath, barName);
      createDirectory(fooPath);
      createDirectory(barPath);

      Packages packages = builder.createPackageMap(projectPath);
      expect(packages, isNotNull);
      Map<String, Uri> map = packages.asMap();
      expect(map, hasLength(2));
      expect(map[fooName], new Uri.directory(fooPath));
      expect(map[barName], new Uri.directory(barPath));
    });
  }

  void test_createPackageMap_fromPackageFile_explicit() {
    withTempDir((io.Directory tempDir) {
      // Use a package file that is outside the project directory's hierarchy.
      String rootPath = tempDir.path;
      String projectPath = pathContext.join(rootPath, 'project');
      String packageFilePath = pathContext.join(rootPath, 'child', '.packages');
      createDirectory(projectPath);
      createFile(
          packageFilePath,
          r'''
foo:/pkg/foo
bar:/pkg/bar
''');

      builder.defaultPackageFilePath = packageFilePath;
      Packages packages = builder.createPackageMap(projectPath);
      expect(packages, isNotNull);
      Map<String, Uri> map = packages.asMap();
      expect(map, hasLength(2));
      expect(map['foo'], new Uri.directory('/pkg/foo'));
      expect(map['bar'], new Uri.directory('/pkg/bar'));
    });
  }

  void test_createPackageMap_fromPackageFile_inParentOfRoot() {
    withTempDir((io.Directory tempDir) {
      // Use a package file that is inside the parent of the project directory.
      String rootPath = tempDir.path;
      String projectPath = pathContext.join(rootPath, 'project');
      String packageFilePath = pathContext.join(rootPath, '.packages');
      createDirectory(projectPath);
      createFile(
          packageFilePath,
          r'''
foo:/pkg/foo
bar:/pkg/bar
''');

      Packages packages = builder.createPackageMap(projectPath);
      expect(packages, isNotNull);
      Map<String, Uri> map = packages.asMap();
      expect(map, hasLength(2));
      expect(map['foo'], new Uri.directory('/pkg/foo'));
      expect(map['bar'], new Uri.directory('/pkg/bar'));
    });
  }

  void test_createPackageMap_fromPackageFile_inRoot() {
    withTempDir((io.Directory tempDir) {
      // Use a package file that is inside the project directory.
      String rootPath = tempDir.path;
      String projectPath = pathContext.join(rootPath, 'project');
      String packageFilePath = pathContext.join(projectPath, '.packages');
      createDirectory(projectPath);
      createFile(
          packageFilePath,
          r'''
foo:/pkg/foo
bar:/pkg/bar
''');

      Packages packages = builder.createPackageMap(projectPath);
      expect(packages, isNotNull);
      Map<String, Uri> map = packages.asMap();
      expect(map, hasLength(2));
      expect(map['foo'], new Uri.directory('/pkg/foo'));
      expect(map['bar'], new Uri.directory('/pkg/bar'));
    });
  }

  void test_createPackageMap_none() {
    withTempDir((io.Directory tempDir) {
      Packages packages = builder.createPackageMap(tempDir.path);
      expect(packages, same(Packages.noPackages));
    });
  }

  void test_createSourceFactory_fileProvider() {
    withTempDir((io.Directory tempDir) {
      createDefaultSdk(tempDir);
      String rootPath = tempDir.path;
      String projectPath = pathContext.join(rootPath, 'project');
      String packageFilePath = pathContext.join(projectPath, '.packages');
      String packageA = pathContext.join(rootPath, 'pkgs', 'a');
      String packageB = pathContext.join(rootPath, 'pkgs', 'b');
      createFile(
          packageFilePath,
          '''
a:${pathContext.toUri(packageA)}
b:${pathContext.toUri(packageB)}
''');
      AnalysisOptionsImpl options = new AnalysisOptionsImpl();
      UriResolver resolver = new ResourceUriResolver(resourceProvider);
      builder.fileResolverProvider = (folder) => resolver;
      SourceFactoryImpl factory =
          builder.createSourceFactory(projectPath, options);
      expect(factory.resolvers, contains(same(resolver)));
    });
  }

  void test_createSourceFactory_noProvider_packages_embedder_extensions() {
    withTempDir((io.Directory tempDir) {
      createDefaultSdk(tempDir);
      String rootPath = tempDir.path;
      String projectPath = pathContext.join(rootPath, 'project');
      String packageFilePath = pathContext.join(projectPath, '.packages');
      String packageA = pathContext.join(rootPath, 'pkgs', 'a');
      String embedderPath = pathContext.join(packageA, '_embedder.yaml');
      String packageB = pathContext.join(rootPath, 'pkgs', 'b');
      String extensionPath = pathContext.join(packageB, '_sdkext');
      createFile(
          packageFilePath,
          '''
a:${pathContext.toUri(packageA)}
b:${pathContext.toUri(packageB)}
''');
      String asyncPath = pathContext.join(packageA, 'sdk', 'async.dart');
      String corePath = pathContext.join(packageA, 'sdk', 'core.dart');
      createFile(
          embedderPath,
          '''
embedded_libs:
  "dart:async": ${_relativeUri(asyncPath, from: packageA)}
  "dart:core": ${_relativeUri(corePath, from: packageA)}
''');
      String fooPath = pathContext.join(packageB, 'ext', 'foo.dart');
      createFile(
          extensionPath,
          '''{
"dart:foo": "${_relativeUri(fooPath, from: packageB)}"
}''');
      AnalysisOptionsImpl options = new AnalysisOptionsImpl();

      SourceFactory factory = builder.createSourceFactory(projectPath, options);

      Source asyncSource = factory.forUri('dart:async');
      expect(asyncSource, isNotNull);
      expect(asyncSource.fullName, asyncPath);

      Source fooSource = factory.forUri('dart:foo');
      expect(fooSource, isNotNull);
      expect(fooSource.fullName, fooPath);

      Source packageSource = factory.forUri('package:b/b.dart');
      expect(packageSource, isNotNull);
      expect(packageSource.fullName, pathContext.join(packageB, 'b.dart'));
    });
  }

  void test_createSourceFactory_noProvider_packages_embedder_noExtensions() {
    withTempDir((io.Directory tempDir) {
      createDefaultSdk(tempDir);
      String rootPath = tempDir.path;
      String projectPath = pathContext.join(rootPath, 'project');
      String packageFilePath = pathContext.join(projectPath, '.packages');
      String packageA = pathContext.join(rootPath, 'pkgs', 'a');
      String embedderPath = pathContext.join(packageA, '_embedder.yaml');
      String packageB = pathContext.join(rootPath, 'pkgs', 'b');
      createFile(
          packageFilePath,
          '''
a:${pathContext.toUri(packageA)}
b:${pathContext.toUri(packageB)}
''');
      String asyncPath = pathContext.join(packageA, 'sdk', 'async.dart');
      String corePath = pathContext.join(packageA, 'sdk', 'core.dart');
      createFile(
          embedderPath,
          '''
embedded_libs:
  "dart:async": ${_relativeUri(asyncPath, from: packageA)}
  "dart:core": ${_relativeUri(corePath, from: packageA)}
''');
      AnalysisOptionsImpl options = new AnalysisOptionsImpl();

      SourceFactory factory = builder.createSourceFactory(projectPath, options);

      Source dartSource = factory.forUri('dart:async');
      expect(dartSource, isNotNull);
      expect(dartSource.fullName, asyncPath);

      Source packageSource = factory.forUri('package:b/b.dart');
      expect(packageSource, isNotNull);
      expect(packageSource.fullName, pathContext.join(packageB, 'b.dart'));
    });
  }

  @failingTest
  void test_createSourceFactory_noProvider_packages_noEmbedder_extensions() {
    fail('Incomplete test');
  }

  void test_createSourceFactory_noProvider_packages_noEmbedder_noExtensions() {
    withTempDir((io.Directory tempDir) {
      createDefaultSdk(tempDir);
      String rootPath = tempDir.path;
      String projectPath = pathContext.join(rootPath, 'project');
      String packageFilePath = pathContext.join(projectPath, '.packages');
      String packageA = pathContext.join(rootPath, 'pkgs', 'a');
      String packageB = pathContext.join(rootPath, 'pkgs', 'b');
      createFile(
          packageFilePath,
          '''
a:${pathContext.toUri(packageA)}
b:${pathContext.toUri(packageB)}
''');
      AnalysisOptionsImpl options = new AnalysisOptionsImpl();

      SourceFactory factory = builder.createSourceFactory(projectPath, options);

      Source dartSource = factory.forUri('dart:core');
      expect(dartSource, isNotNull);
      expect(dartSource.fullName, '$defaultSdkPath/lib/core/core.dart');

      Source packageSource = factory.forUri('package:a/a.dart');
      expect(packageSource, isNotNull);
      expect(packageSource.fullName, pathContext.join(packageA, 'a.dart'));
    });
  }

  void test_createSourceFactory_packageProvider() {
    withTempDir((io.Directory tempDir) {
      createDefaultSdk(tempDir);
      String rootPath = tempDir.path;
      String projectPath = pathContext.join(rootPath, 'project');
      AnalysisOptionsImpl options = new AnalysisOptionsImpl();
      UriResolver resolver = new PackageMapUriResolver(resourceProvider, {});
      builder.packageResolverProvider = (folder) => resolver;
      SourceFactoryImpl factory =
          builder.createSourceFactory(projectPath, options);
      expect(factory.resolvers, contains(same(resolver)));
    });
  }

  @failingTest
  void test_findSdk_embedder_extensions() {
    // See test_createSourceFactory_noProvider_packages_embedder_extensions
    fail('Incomplete test');
  }

  @failingTest
  void test_findSdk_embedder_noExtensions() {
    // See test_createSourceFactory_noProvider_packages_embedder_noExtensions
    fail('Incomplete test');
  }

  @failingTest
  void test_findSdk_noEmbedder_extensions() {
    // See test_createSourceFactory_noProvider_packages_noEmbedder_extensions
    fail('Incomplete test');
  }

  @failingTest
  void test_findSdk_noEmbedder_noExtensions() {
    // See test_createSourceFactory_noProvider_packages_noEmbedder_noExtensions
    fail('Incomplete test');
  }

  /**
   * Execute the [test] function with a temporary [directory]. The test function
   * can perform any disk operations within the directory and the directory (and
   * its content) will be removed after the function returns.
   */
  void withTempDir(test(io.Directory directory)) {
    io.Directory directory =
        io.Directory.systemTemp.createTempSync('analyzer_');
    try {
      test(directory);
    } finally {
      directory.deleteSync(recursive: true);
    }
  }

  Uri _relativeUri(String path, {String from}) {
    String relativePath = pathContext.relative(path, from: from);
    return pathContext.toUri(relativePath);
  }
}

@reflectiveTest
class ContextBuilderTest_WithoutDisk extends EngineTestCase {
  /**
   * The resource provider to be used by tests.
   */
  MemoryResourceProvider resourceProvider;

  /**
   * The SDK manager used by the tests;
   */
  DartSdkManager sdkManager;

  /**
   * The content cache used by the tests.
   */
  ContentCache contentCache;

  /**
   * The context builder to be used in the test.
   */
  ContextBuilder builder;

  @override
  void setUp() {
    resourceProvider = new MemoryResourceProvider();
    sdkManager = new DartSdkManager('', false, (_) => new MockSdk());
    contentCache = new ContentCache();
    builder = new ContextBuilder(resourceProvider, sdkManager, contentCache);
  }

  void test_convertPackagesToMap_noPackages() {
    expect(builder.convertPackagesToMap(Packages.noPackages), isNull);
  }

  void test_convertPackagesToMap_null() {
    expect(builder.convertPackagesToMap(null), isNull);
  }

  void test_convertPackagesToMap_packages() {
    String fooName = 'foo';
    String fooPath = '/pkg/foo';
    Uri fooUri = new Uri.directory(fooPath);
    String barName = 'bar';
    String barPath = '/pkg/bar';
    Uri barUri = new Uri.directory(barPath);

    MapPackages packages = new MapPackages({fooName: fooUri, barName: barUri});
    Map<String, List<Folder>> result = builder.convertPackagesToMap(packages);
    expect(result, isNotNull);
    expect(result, hasLength(2));
    expect(result[fooName], hasLength(1));
    expect(result[fooName][0].path, fooPath);
    expect(result[barName], hasLength(1));
    expect(result[barName][0].path, barPath);
  }

  void test_createDefaultOptions_default() {
    // Invert a subset of the options to ensure that the default options are
    // being returned.
    AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl();
    defaultOptions.dart2jsHint = !defaultOptions.dart2jsHint;
    defaultOptions.enableAssertMessage = !defaultOptions.enableAssertMessage;
    defaultOptions.enableAsync = !defaultOptions.enableAsync;
    defaultOptions.enableGenericMethods = !defaultOptions.enableGenericMethods;
    defaultOptions.enableStrictCallChecks =
        !defaultOptions.enableStrictCallChecks;
    defaultOptions.enableSuperMixins = !defaultOptions.enableSuperMixins;
    builder.defaultOptions = defaultOptions;
    AnalysisOptions options = builder.createDefaultOptions();
    _expectEqualOptions(options, defaultOptions);
  }

  void test_createDefaultOptions_noDefault() {
    AnalysisOptions options = builder.createDefaultOptions();
    _expectEqualOptions(options, new AnalysisOptionsImpl());
  }

  void test_declareVariables_emptyMap() {
    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
    Iterable<String> expected = context.declaredVariables.variableNames;
    builder.declaredVariables = <String, String>{};

    builder.declareVariables(context);
    expect(context.declaredVariables.variableNames, unorderedEquals(expected));
  }

  void test_declareVariables_nonEmptyMap() {
    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
    List<String> expected = context.declaredVariables.variableNames.toList();
    expect(expected, isNot(contains('a')));
    expect(expected, isNot(contains('b')));
    expected.addAll(['a', 'b']);
    builder.declaredVariables = <String, String>{'a': 'a', 'b': 'b'};

    builder.declareVariables(context);
    expect(context.declaredVariables.variableNames, unorderedEquals(expected));
  }

  void test_declareVariables_null() {
    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
    Iterable<String> expected = context.declaredVariables.variableNames;

    builder.declareVariables(context);
    expect(context.declaredVariables.variableNames, unorderedEquals(expected));
  }

  void test_findSdk_noPackageMap() {
    DartSdk sdk = builder.findSdk(null, new AnalysisOptionsImpl());
    expect(sdk, isNotNull);
  }

  void test_getAnalysisOptions_default_noOverrides() {
    AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl();
    defaultOptions.enableGenericMethods = true;
    builder.defaultOptions = defaultOptions;
    AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
    expected.enableGenericMethods = true;
    String path = '/some/directory/path';
    String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
    resourceProvider.newFile(
        filePath,
        '''
linter:
  rules:
    - empty_constructor_bodies
''');

    AnalysisOptions options = builder.getAnalysisOptions(path);
    _expectEqualOptions(options, expected);
  }

  void test_getAnalysisOptions_default_overrides() {
    AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl();
    defaultOptions.enableGenericMethods = true;
    builder.defaultOptions = defaultOptions;
    AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
    expected.enableAsync = true;
    expected.enableGenericMethods = true;
    String path = '/some/directory/path';
    String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
    resourceProvider.newFile(
        filePath,
        '''
analyzer:
  enableAsync : true
''');

    AnalysisOptions options = builder.getAnalysisOptions(path);
    _expectEqualOptions(options, expected);
  }

  void test_getAnalysisOptions_noDefault_noOverrides() {
    String path = '/some/directory/path';
    String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
    resourceProvider.newFile(
        filePath,
        '''
linter:
  rules:
    - empty_constructor_bodies
''');

    AnalysisOptions options = builder.getAnalysisOptions(path);
    _expectEqualOptions(options, new AnalysisOptionsImpl());
  }

  void test_getAnalysisOptions_noDefault_overrides() {
    AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
    expected.enableAsync = true;
    String path = '/some/directory/path';
    String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
    resourceProvider.newFile(
        filePath,
        '''
analyzer:
  enableAsync : true
''');

    AnalysisOptions options = builder.getAnalysisOptions(path);
    _expectEqualOptions(options, expected);
  }

  void test_getOptionsFile_explicit() {
    String path = '/some/directory/path';
    String filePath = '/options/analysis.yaml';
    resourceProvider.newFile(filePath, '');

    builder.defaultAnalysisOptionsFilePath = filePath;
    File result = builder.getOptionsFile(path);
    expect(result, isNotNull);
    expect(result.path, filePath);
  }

  void test_getOptionsFile_inParentOfRoot_new() {
    String parentPath = '/some/directory';
    String path = '$parentPath/path';
    String filePath =
        '$parentPath/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
    resourceProvider.newFile(filePath, '');

    File result = builder.getOptionsFile(path);
    expect(result, isNotNull);
    expect(result.path, filePath);
  }

  void test_getOptionsFile_inParentOfRoot_old() {
    String parentPath = '/some/directory';
    String path = '$parentPath/path';
    String filePath = '$parentPath/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}';
    resourceProvider.newFile(filePath, '');

    File result = builder.getOptionsFile(path);
    expect(result, isNotNull);
    expect(result.path, filePath);
  }

  void test_getOptionsFile_inRoot_new() {
    String path = '/some/directory/path';
    String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
    resourceProvider.newFile(filePath, '');

    File result = builder.getOptionsFile(path);
    expect(result, isNotNull);
    expect(result.path, filePath);
  }

  void test_getOptionsFile_inRoot_old() {
    String path = '/some/directory/path';
    String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}';
    resourceProvider.newFile(filePath, '');

    File result = builder.getOptionsFile(path);
    expect(result, isNotNull);
    expect(result.path, filePath);
  }

  void _expectEqualOptions(
      AnalysisOptionsImpl actual, AnalysisOptionsImpl expected) {
    // TODO(brianwilkerson) Consider moving this to AnalysisOptionsImpl.==.
    expect(actual.analyzeFunctionBodiesPredicate,
        same(expected.analyzeFunctionBodiesPredicate));
    expect(actual.cacheSize, expected.cacheSize);
    expect(actual.dart2jsHint, expected.dart2jsHint);
    expect(actual.enableAssertMessage, expected.enableAssertMessage);
    expect(actual.enableAsync, expected.enableAsync);
    expect(actual.enableStrictCallChecks, expected.enableStrictCallChecks);
    expect(actual.enableGenericMethods, expected.enableGenericMethods);
    expect(actual.enableSuperMixins, expected.enableSuperMixins);
    expect(actual.enableTiming, expected.enableTiming);
    expect(actual.generateImplicitErrors, expected.generateImplicitErrors);
    expect(actual.generateSdkErrors, expected.generateSdkErrors);
    expect(actual.hint, expected.hint);
    expect(actual.incremental, expected.incremental);
    expect(actual.incrementalApi, expected.incrementalApi);
    expect(actual.incrementalValidation, expected.incrementalValidation);
    expect(actual.lint, expected.lint);
    expect(actual.preserveComments, expected.preserveComments);
    expect(actual.strongMode, expected.strongMode);
    expect(actual.strongModeHints, expected.strongModeHints);
    expect(actual.implicitCasts, expected.implicitCasts);
    expect(actual.implicitDynamic, expected.implicitDynamic);
    expect(actual.trackCacheDependencies, expected.trackCacheDependencies);
    expect(actual.finerGrainedInvalidation, expected.finerGrainedInvalidation);
  }
}

@reflectiveTest
class EmbedderYamlLocatorTest extends EmbedderRelatedTest {
  void test_empty() {
    EmbedderYamlLocator locator = new EmbedderYamlLocator({
      'fox': [pathTranslator.getResource('/empty')]
    });
    expect(locator.embedderYamls, hasLength(0));
  }

  void test_invalid() {
    EmbedderYamlLocator locator = new EmbedderYamlLocator(null);
    locator.addEmbedderYaml(null, r'''{{{,{{}}},}}''');
    expect(locator.embedderYamls, hasLength(0));
  }

  void test_valid() {
    EmbedderYamlLocator locator = new EmbedderYamlLocator({
      'fox': [pathTranslator.getResource('/tmp')]
    });
    expect(locator.embedderYamls, hasLength(1));
  }
}
