blob: c928026a38eeef69fcca3ed6e59dfe81d4a1fe3b [file] [log] [blame]
// 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.
library test.context.directory.manager;
import 'dart:collection';
import 'package:analysis_server/src/context_manager.dart';
import 'package:analysis_server/src/utilities/null_string_sink.dart';
import 'package:analyzer/context/context_root.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/source/error_processor.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult;
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/services/lint.dart';
import 'package:analyzer/src/summary/summary_file_builder.dart';
import 'package:analyzer/src/util/glob.dart';
import 'package:linter/src/rules.dart';
import 'package:linter/src/rules/avoid_as.dart';
import 'package:path/path.dart' as path;
import 'package:plugin/manager.dart';
import 'package:plugin/plugin.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'mock_sdk.dart';
import 'mocks.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(AbstractContextManagerTest);
defineReflectiveTests(ContextManagerWithNewOptionsTest);
defineReflectiveTests(ContextManagerWithOldOptionsTest);
});
}
@reflectiveTest
class AbstractContextManagerTest extends ContextManagerTest {
void test_contextsInAnalysisRoot_nestedContext() {
String subProjPath = path.posix.join(projPath, 'subproj');
Folder subProjFolder = resourceProvider.newFolder(subProjPath);
resourceProvider.newFile(
path.posix.join(subProjPath, 'pubspec.yaml'), 'contents');
String subProjFilePath = path.posix.join(subProjPath, 'file.dart');
resourceProvider.newFile(subProjFilePath, 'contents');
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// Make sure that there really are contexts for both the main project and
// the subproject.
Folder projectFolder = resourceProvider.getFolder(projPath);
ContextInfo projContextInfo = manager.getContextInfoFor(projectFolder);
expect(projContextInfo, isNotNull);
expect(projContextInfo.folder, projectFolder);
ContextInfo subProjContextInfo = manager.getContextInfoFor(subProjFolder);
expect(subProjContextInfo, isNotNull);
expect(subProjContextInfo.folder, subProjFolder);
if (enableAnalysisDriver) {
expect(projContextInfo.analysisDriver,
isNot(equals(subProjContextInfo.analysisDriver)));
// Check that getDriversInAnalysisRoot() works.
List<AnalysisDriver> drivers =
manager.getDriversInAnalysisRoot(projectFolder);
expect(drivers, isNotNull);
expect(drivers, hasLength(2));
expect(drivers, contains(projContextInfo.analysisDriver));
expect(drivers, contains(subProjContextInfo.analysisDriver));
} else {
expect(projContextInfo.context != subProjContextInfo.context, isTrue);
// Check that contextsInAnalysisRoot() works.
List<AnalysisContext> contexts =
manager.contextsInAnalysisRoot(projectFolder);
expect(contexts, hasLength(2));
expect(contexts, contains(projContextInfo.context));
expect(contexts, contains(subProjContextInfo.context));
}
}
test_embedder_added() async {
// Create files.
String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
newFile([libPath, 'main.dart']);
newFile([libPath, 'nope.dart']);
String embedderPath = newFolder([projPath, 'embedder']);
newFile([embedderPath, 'entry.dart']);
String embedderSrcPath = newFolder([projPath, 'embedder', 'src']);
newFile([embedderSrcPath, 'part.dart']);
// Setup _embedder.yaml.
newFile(
[libPath, '_embedder.yaml'],
r'''
embedded_libs:
"dart:foobar": "../embedder/entry.dart"
"dart:typed_data": "../embedder/src/part"
''');
Folder projectFolder = resourceProvider.newFolder(projPath);
// NOTE that this is Not in our package path yet.
// Setup context.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
await pumpEventQueue();
// Confirm that one driver / context was created.
if (enableAnalysisDriver) {
List<AnalysisDriver> drivers =
manager.getDriversInAnalysisRoot(projectFolder);
expect(drivers, isNotNull);
expect(drivers, hasLength(1));
} else {
List<AnalysisContext> contexts =
manager.contextsInAnalysisRoot(projectFolder);
expect(contexts, isNotNull);
expect(contexts, hasLength(1));
}
// No embedded libs yet.
expect(sourceFactory.forUri('dart:typed_data'), isNull);
// Add .packages file that introduces a dependency with embedded libs.
newFile(
[projPath, '.packages'],
r'''
test_pack:lib/''');
await pumpEventQueue();
// Confirm that we still have just one driver / context.
if (enableAnalysisDriver) {
List<AnalysisDriver> drivers =
manager.getDriversInAnalysisRoot(projectFolder);
expect(drivers, isNotNull);
expect(drivers, hasLength(1));
} else {
List<AnalysisContext> contexts =
manager.contextsInAnalysisRoot(projectFolder);
expect(contexts, isNotNull);
expect(contexts, hasLength(1));
}
// Embedded lib should be defined now.
expect(sourceFactory.forUri('dart:typed_data'), isNotNull);
}
test_embedder_packagespec() async {
// Create files.
String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
newFile([libPath, 'main.dart']);
newFile([libPath, 'nope.dart']);
String sdkExtPath = newFolder([projPath, 'sdk_ext']);
newFile([sdkExtPath, 'entry.dart']);
String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
newFile([sdkExtSrcPath, 'part.dart']);
// Setup _embedder.yaml.
newFile(
[libPath, '_embedder.yaml'],
r'''
embedded_libs:
"dart:foobar": "../sdk_ext/entry.dart"
"dart:typed_data": "../sdk_ext/src/part"
''');
// Setup .packages file
newFile(
[projPath, '.packages'],
r'''
test_pack:lib/''');
// Setup context.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
await pumpEventQueue();
// Confirm that one context was created.
var contexts =
manager.contextsInAnalysisRoot(resourceProvider.newFolder(projPath));
expect(contexts, isNotNull);
expect(contexts.length, equals(1));
var source = sourceFactory.forUri('dart:foobar');
expect(source, isNotNull);
expect(source.fullName, '/my/proj/sdk_ext/entry.dart');
// We can't find dart:core because we didn't list it in our
// embedded_libs map.
expect(sourceFactory.forUri('dart:core'), isNull);
// We can find dart:typed_data because we listed it in our
// embedded_libs map.
expect(sourceFactory.forUri('dart:typed_data'), isNotNull);
}
test_ignoreFilesInPackagesFolder() {
// create a context with a pubspec.yaml file
String pubspecPath = path.posix.join(projPath, 'pubspec.yaml');
resourceProvider.newFile(pubspecPath, 'pubspec');
// create a file in the "packages" folder
String filePath1 = path.posix.join(projPath, 'packages', 'file1.dart');
resourceProvider.newFile(filePath1, 'contents');
// "packages" files are ignored initially
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
expect(callbacks.currentFilePaths, isEmpty);
// "packages" files are ignored during watch
String filePath2 = path.posix.join(projPath, 'packages', 'file2.dart');
resourceProvider.newFile(filePath2, 'contents');
return pumpEventQueue().then((_) {
expect(callbacks.currentFilePaths, isEmpty);
});
}
void test_isInAnalysisRoot_excluded() {
// prepare paths
String project = '/project';
String excludedFolder = '$project/excluded';
// set roots
resourceProvider.newFolder(project);
resourceProvider.newFolder(excludedFolder);
manager.setRoots(
<String>[project], <String>[excludedFolder], <String, String>{});
// verify
expect(manager.isInAnalysisRoot('$excludedFolder/test.dart'), isFalse);
}
void test_isInAnalysisRoot_inNestedContext() {
String subProjPath = path.posix.join(projPath, 'subproj');
Folder subProjFolder = resourceProvider.newFolder(subProjPath);
resourceProvider.newFile(
path.posix.join(subProjPath, 'pubspec.yaml'), 'contents');
String subProjFilePath = path.posix.join(subProjPath, 'file.dart');
resourceProvider.newFile(subProjFilePath, 'contents');
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// Make sure that there really is a context for the subproject.
ContextInfo subProjContextInfo = manager.getContextInfoFor(subProjFolder);
expect(subProjContextInfo, isNotNull);
expect(subProjContextInfo.folder, subProjFolder);
// Check that isInAnalysisRoot() works.
expect(manager.isInAnalysisRoot(subProjFilePath), isTrue);
}
void test_isInAnalysisRoot_inRoot() {
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
expect(manager.isInAnalysisRoot('$projPath/test.dart'), isTrue);
}
void test_isInAnalysisRoot_notInRoot() {
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
expect(manager.isInAnalysisRoot('/test.dart'), isFalse);
}
test_path_filter() async {
// Setup context.
Folder root = resourceProvider.newFolder(projPath);
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
expect(callbacks.currentFilePaths, isEmpty);
// Set ignore patterns for context.
ContextInfo rootInfo = manager.getContextInfoFor(root);
manager.setIgnorePatternsForContext(
rootInfo, ['sdk_ext/**', 'lib/ignoreme.dart']);
// Start creating files.
newFile([projPath, ContextManagerImpl.PUBSPEC_NAME]);
String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
newFile([libPath, 'main.dart']);
newFile([libPath, 'ignoreme.dart']);
String sdkExtPath = newFolder([projPath, 'sdk_ext']);
newFile([sdkExtPath, 'entry.dart']);
String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
newFile([sdkExtSrcPath, 'part.dart']);
// Pump event loop so new files are discovered and added to context.
await pumpEventQueue();
// Verify that ignored files were ignored.
Iterable<String> filePaths = callbacks.currentFilePaths;
expect(filePaths, hasLength(1));
expect(filePaths, contains('/my/proj/lib/main.dart'));
}
test_refresh_folder_with_packagespec() {
// create a context with a .packages file
String packagespecFile = path.posix.join(projPath, '.packages');
resourceProvider.newFile(packagespecFile, '');
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
return pumpEventQueue().then((_) {
expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
callbacks.now++;
manager.refresh(null);
return pumpEventQueue().then((_) {
expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
expect(callbacks.currentContextTimestamps[projPath], callbacks.now);
});
});
}
// TODO(paulberry): This test only tests PackagesFileDisposition.
// Once http://dartbug.com/23909 is fixed, add a test for sdk extensions
// and PackageMapDisposition.
test_refresh_folder_with_packagespec_subfolders() {
// Create a folder with no .packages file, containing two subfolders with
// .packages files.
String subdir1Path = path.posix.join(projPath, 'subdir1');
String subdir2Path = path.posix.join(projPath, 'subdir2');
String packagespec1Path = path.posix.join(subdir1Path, '.packages');
String packagespec2Path = path.posix.join(subdir2Path, '.packages');
resourceProvider.newFile(packagespec1Path, '');
resourceProvider.newFile(packagespec2Path, '');
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
return pumpEventQueue().then((_) {
expect(callbacks.currentContextRoots,
unorderedEquals([subdir1Path, subdir2Path, projPath]));
callbacks.now++;
manager.refresh(null);
return pumpEventQueue().then((_) {
expect(callbacks.currentContextRoots,
unorderedEquals([subdir1Path, subdir2Path, projPath]));
expect(callbacks.currentContextTimestamps[projPath], callbacks.now);
expect(callbacks.currentContextTimestamps[subdir1Path], callbacks.now);
expect(callbacks.currentContextTimestamps[subdir2Path], callbacks.now);
});
});
}
test_refresh_folder_with_pubspec() {
// create a context with a pubspec.yaml file
String pubspecPath = path.posix.join(projPath, 'pubspec.yaml');
resourceProvider.newFile(pubspecPath, 'pubspec');
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
return pumpEventQueue().then((_) {
expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
callbacks.now++;
manager.refresh(null);
return pumpEventQueue().then((_) {
expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
expect(callbacks.currentContextTimestamps[projPath], callbacks.now);
});
});
}
test_refresh_folder_with_pubspec_subfolders() {
// Create a folder with no pubspec.yaml, containing two subfolders with
// pubspec.yaml files.
String subdir1Path = path.posix.join(projPath, 'subdir1');
String subdir2Path = path.posix.join(projPath, 'subdir2');
String pubspec1Path = path.posix.join(subdir1Path, 'pubspec.yaml');
String pubspec2Path = path.posix.join(subdir2Path, 'pubspec.yaml');
resourceProvider.newFile(pubspec1Path, 'pubspec');
resourceProvider.newFile(pubspec2Path, 'pubspec');
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
return pumpEventQueue().then((_) {
expect(callbacks.currentContextRoots,
unorderedEquals([subdir1Path, subdir2Path, projPath]));
callbacks.now++;
manager.refresh(null);
return pumpEventQueue().then((_) {
expect(callbacks.currentContextRoots,
unorderedEquals([subdir1Path, subdir2Path, projPath]));
expect(callbacks.currentContextTimestamps[projPath], callbacks.now);
expect(callbacks.currentContextTimestamps[subdir1Path], callbacks.now);
expect(callbacks.currentContextTimestamps[subdir2Path], callbacks.now);
});
});
}
test_refresh_oneContext() {
// create two contexts with pubspec.yaml files
String pubspecPath = path.posix.join(projPath, 'pubspec.yaml');
resourceProvider.newFile(pubspecPath, 'pubspec1');
String proj2Path = '/my/proj2';
resourceProvider.newFolder(proj2Path);
String pubspec2Path = path.posix.join(proj2Path, 'pubspec.yaml');
resourceProvider.newFile(pubspec2Path, 'pubspec2');
List<String> roots = <String>[projPath, proj2Path];
manager.setRoots(roots, <String>[], <String, String>{});
return pumpEventQueue().then((_) {
expect(callbacks.currentContextRoots, unorderedEquals(roots));
int then = callbacks.now;
callbacks.now++;
manager.refresh([resourceProvider.getResource(proj2Path)]);
return pumpEventQueue().then((_) {
expect(callbacks.currentContextRoots, unorderedEquals(roots));
expect(callbacks.currentContextTimestamps[projPath], then);
expect(callbacks.currentContextTimestamps[proj2Path], callbacks.now);
});
});
}
test_sdk_ext_packagespec() async {
// Create files.
String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
newFile([libPath, 'main.dart']);
newFile([libPath, 'nope.dart']);
String sdkExtPath = newFolder([projPath, 'sdk_ext']);
newFile([sdkExtPath, 'entry.dart']);
String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
newFile([sdkExtSrcPath, 'part.dart']);
// Setup sdk extension mapping.
newFile(
[libPath, '_sdkext'],
r'''
{
"dart:foobar": "../sdk_ext/entry.dart"
}
''');
// Setup .packages file
newFile(
[projPath, '.packages'],
r'''
test_pack:lib/''');
// Setup context.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// Confirm that one context was created.
var contexts =
manager.contextsInAnalysisRoot(resourceProvider.newFolder(projPath));
expect(contexts, isNotNull);
expect(contexts.length, equals(1));
var source = sourceFactory.forUri('dart:foobar');
expect(source.fullName, equals('/my/proj/sdk_ext/entry.dart'));
}
void test_setRoots_addFolderWithDartFile() {
String filePath = path.posix.join(projPath, 'foo.dart');
resourceProvider.newFile(filePath, 'contents');
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// verify
Iterable<String> filePaths = callbacks.currentFilePaths;
expect(filePaths, hasLength(1));
expect(filePaths, contains(filePath));
if (enableAnalysisDriver) {
List<AnalysisDriver> drivers = manager
.getDriversInAnalysisRoot(resourceProvider.newFolder(projPath));
expect(drivers, hasLength(1));
expect(drivers[0], isNotNull);
} else {
List<AnalysisContext> contextsInAnalysisRoot =
manager.contextsInAnalysisRoot(resourceProvider.newFolder(projPath));
expect(contextsInAnalysisRoot, hasLength(1));
expect(contextsInAnalysisRoot[0], isNotNull);
}
Source result = sourceFactory.forUri('dart:async');
expect(result, isNotNull);
}
void test_setRoots_addFolderWithDartFileInSubfolder() {
String filePath = path.posix.join(projPath, 'foo', 'bar.dart');
resourceProvider.newFile(filePath, 'contents');
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// verify
Iterable<String> filePaths = callbacks.currentFilePaths;
expect(filePaths, hasLength(1));
expect(filePaths, contains(filePath));
}
void test_setRoots_addFolderWithDummyLink() {
String filePath = path.posix.join(projPath, 'foo.dart');
resourceProvider.newDummyLink(filePath);
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// verify
expect(callbacks.currentFilePaths, isEmpty);
}
void test_setRoots_addFolderWithNestedPackageSpec() {
String examplePath = newFolder([projPath, ContextManagerTest.EXAMPLE_NAME]);
String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME]);
newFile([libPath, 'main.dart']);
newFile([examplePath, ContextManagerImpl.PACKAGE_SPEC_NAME]);
newFile([examplePath, 'example.dart']);
packageMapProvider.packageMap['proj'] = <Folder>[
resourceProvider.getResource(libPath)
];
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
expect(callbacks.currentContextRoots, hasLength(2));
expect(callbacks.currentContextRoots, contains(projPath));
Iterable<Source> projSources = callbacks.currentFileSources(projPath);
expect(projSources, hasLength(1));
expect(projSources.first.uri.toString(), 'file:///my/proj/lib/main.dart');
expect(callbacks.currentContextRoots, contains(examplePath));
Iterable<Source> exampleSources = callbacks.currentFileSources(examplePath);
expect(exampleSources, hasLength(1));
expect(exampleSources.first.uri.toString(),
'file:///my/proj/example/example.dart');
}
void test_setRoots_addFolderWithNestedPubspec() {
String examplePath = newFolder([projPath, ContextManagerTest.EXAMPLE_NAME]);
String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
newFile([projPath, ContextManagerImpl.PUBSPEC_NAME]);
newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME], 'proj:lib/');
newFile([libPath, 'main.dart']);
newFile([examplePath, ContextManagerImpl.PUBSPEC_NAME]);
newFile([examplePath, 'example.dart']);
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
expect(callbacks.currentContextRoots, hasLength(2));
expect(callbacks.currentContextRoots, contains(projPath));
Iterable<Source> projSources = callbacks.currentFileSources(projPath);
expect(projSources, hasLength(1));
expect(projSources.first.uri.toString(), 'package:proj/main.dart');
expect(callbacks.currentContextRoots, contains(examplePath));
Iterable<Source> exampleSources = callbacks.currentFileSources(examplePath);
expect(exampleSources, hasLength(1));
expect(exampleSources.first.uri.toString(),
'file:///my/proj/example/example.dart');
}
void test_setRoots_addFolderWithoutPubspec() {
packageMapProvider.packageMap = null;
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// verify
expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
expect(callbacks.currentFilePaths, hasLength(0));
}
void test_setRoots_addFolderWithPackagespec() {
String packagespecPath = path.posix.join(projPath, '.packages');
resourceProvider.newFile(packagespecPath,
'unittest:file:///home/somebody/.pub/cache/unittest-0.9.9/lib/');
String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
File mainFile =
resourceProvider.newFile(path.posix.join(libPath, 'main.dart'), '');
Source source = mainFile.createSource();
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// verify
expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
expect(callbacks.currentFilePaths, hasLength(1));
// smoketest resolution
Source resolvedSource =
sourceFactory.resolveUri(source, 'package:unittest/unittest.dart');
expect(resolvedSource, isNotNull);
expect(resolvedSource.fullName,
equals('/home/somebody/.pub/cache/unittest-0.9.9/lib/unittest.dart'));
}
void test_setRoots_addFolderWithPackagespecAndPackageRoot() {
// The package root should take priority.
String packagespecPath = path.posix.join(projPath, '.packages');
resourceProvider.newFile(packagespecPath,
'unittest:file:///home/somebody/.pub/cache/unittest-0.9.9/lib/');
String packageRootPath = '/package/root/';
manager.setRoots(<String>[projPath], <String>[],
<String, String>{projPath: packageRootPath});
expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
_checkPackageRoot(projPath, packageRootPath);
}
void test_setRoots_addFolderWithPubspec() {
String pubspecPath = path.posix.join(projPath, 'pubspec.yaml');
resourceProvider.newFile(pubspecPath, 'pubspec');
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// verify
expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
expect(callbacks.currentFilePaths, hasLength(0));
}
void test_setRoots_addFolderWithPubspec_andPackagespec() {
String pubspecPath = path.posix.join(projPath, 'pubspec.yaml');
String packagespecPath = path.posix.join(projPath, '.packages');
resourceProvider.newFile(pubspecPath, 'pubspec');
resourceProvider.newFile(packagespecPath, '');
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// verify
callbacks.assertContextPaths([projPath]);
}
void test_setRoots_addFolderWithPubspecAndLib() {
String binPath = newFolder([projPath, ContextManagerTest.BIN_NAME]);
String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
String srcPath = newFolder([libPath, ContextManagerTest.SRC_NAME]);
String testPath = newFolder([projPath, ContextManagerTest.TEST_NAME]);
newFile([projPath, ContextManagerImpl.PUBSPEC_NAME]);
newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME], 'proj:lib/');
String appPath = newFile([binPath, 'app.dart']);
newFile([libPath, 'main.dart']);
newFile([srcPath, 'internal.dart']);
String testFilePath = newFile([testPath, 'main_test.dart']);
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
Iterable<Source> sources = callbacks.currentFileSources(projPath);
expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
expect(sources, hasLength(4));
List<String> uris =
sources.map((Source source) => source.uri.toString()).toList();
expect(uris, contains('file://$appPath'));
expect(uris, contains('package:proj/main.dart'));
expect(uris, contains('package:proj/src/internal.dart'));
expect(uris, contains('file://$testFilePath'));
}
void test_setRoots_addFolderWithPubspecAndPackagespecFolders() {
// prepare paths
String root = '/root';
String rootFile = '$root/root.dart';
String subProjectA = '$root/sub/aaa';
String subProjectB = '$root/sub/sub2/bbb';
String subProjectA_file = '$subProjectA/bin/a.dart';
String subProjectB_file = '$subProjectB/bin/b.dart';
// create files
resourceProvider.newFile('$subProjectA/pubspec.yaml', 'pubspec');
resourceProvider.newFile('$subProjectB/pubspec.yaml', 'pubspec');
resourceProvider.newFile('$subProjectA/.packages', '');
resourceProvider.newFile('$subProjectB/.packages', '');
resourceProvider.newFile(rootFile, 'library root;');
resourceProvider.newFile(subProjectA_file, 'library a;');
resourceProvider.newFile(subProjectB_file, 'library b;');
// set roots
manager.setRoots(<String>[root], <String>[], <String, String>{});
callbacks.assertContextPaths([root, subProjectA, subProjectB]);
// verify files
callbacks.assertContextFiles(root, [rootFile]);
callbacks.assertContextFiles(subProjectA, [subProjectA_file]);
callbacks.assertContextFiles(subProjectB, [subProjectB_file]);
}
void test_setRoots_addFolderWithPubspecFolders() {
// prepare paths
String root = '/root';
String rootFile = '$root/root.dart';
String projectA = '$root/sub/aaa';
String projectALib = '$root/sub/aaa/lib';
String subProjectA_file = '$projectA/bin/a.dart';
String projectB = '$root/sub/sub2/bbb';
String projectBLib = '$root/sub/sub2/bbb/lib';
String subProjectB_file = '$projectB/bin/b.dart';
// create files
newFile([projectA, ContextManagerImpl.PUBSPEC_NAME]);
newFile([projectA, ContextManagerImpl.PACKAGE_SPEC_NAME], 'foo:lib/');
newFile([projectB, ContextManagerImpl.PUBSPEC_NAME]);
newFile([projectB, ContextManagerImpl.PACKAGE_SPEC_NAME], 'bar:lib/');
resourceProvider.newFile(rootFile, 'library root;');
resourceProvider.newFile(subProjectA_file, 'library a;');
resourceProvider.newFile(subProjectB_file, 'library b;');
// set roots
manager.setRoots(<String>[root], <String>[], <String, String>{});
callbacks.assertContextPaths([root, projectA, projectB]);
// verify files
callbacks.assertContextFiles(root, [rootFile]);
callbacks.assertContextFiles(projectA, [subProjectA_file]);
callbacks.assertContextFiles(projectB, [subProjectB_file]);
// verify package maps
expect(_packageMap(root), isEmpty);
expect(
_packageMap(projectA),
equals({
'foo': [resourceProvider.getFolder(projectALib)]
}));
expect(
_packageMap(projectB),
equals({
'bar': [resourceProvider.getFolder(projectBLib)]
}));
}
void test_setRoots_addPackageRoot() {
String packagePathFoo = '/package1/foo';
String packageRootPath = '/package2/foo';
newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME],
'foo:file:///package1/foo');
Folder packageFolder = resourceProvider.newFolder(packagePathFoo);
List<String> includedPaths = <String>[projPath];
List<String> excludedPaths = <String>[];
manager.setRoots(includedPaths, excludedPaths, <String, String>{});
expect(
_currentPackageMap,
equals({
'foo': [packageFolder]
}));
manager.setRoots(includedPaths, excludedPaths,
<String, String>{projPath: packageRootPath});
_checkPackageRoot(projPath, equals(packageRootPath));
}
void test_setRoots_changePackageRoot() {
String packageRootPath1 = '/package1';
String packageRootPath2 = '/package2';
List<String> includedPaths = <String>[projPath];
List<String> excludedPaths = <String>[];
manager.setRoots(includedPaths, excludedPaths,
<String, String>{projPath: packageRootPath1});
_checkPackageRoot(projPath, equals(packageRootPath1));
manager.setRoots(includedPaths, excludedPaths,
<String, String>{projPath: packageRootPath2});
_checkPackageRoot(projPath, equals(packageRootPath2));
}
void test_setRoots_exclude_newRoot_withExcludedFile() {
// prepare paths
String project = '/project';
String file1 = '$project/file1.dart';
String file2 = '$project/file2.dart';
// create files
resourceProvider.newFile(file1, '// 1');
resourceProvider.newFile(file2, '// 2');
// set roots
manager.setRoots(<String>[project], <String>[file1], <String, String>{});
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [file2]);
}
void test_setRoots_exclude_newRoot_withExcludedFolder() {
// prepare paths
String project = '/project';
String folderA = '$project/aaa';
String folderB = '$project/bbb';
String fileA = '$folderA/a.dart';
String fileB = '$folderB/b.dart';
// create files
resourceProvider.newFile(fileA, 'library a;');
resourceProvider.newFile(fileB, 'library b;');
// set roots
manager.setRoots(<String>[project], <String>[folderB], <String, String>{});
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [fileA]);
}
void test_setRoots_exclude_sameRoot_addExcludedFile() {
// prepare paths
String project = '/project';
String file1 = '$project/file1.dart';
String file2 = '$project/file2.dart';
// create files
resourceProvider.newFile(file1, '// 1');
resourceProvider.newFile(file2, '// 2');
// set roots
manager.setRoots(<String>[project], <String>[], <String, String>{});
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [file1, file2]);
// exclude "2"
manager.setRoots(<String>[project], <String>[file2], <String, String>{});
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [file1]);
}
void test_setRoots_exclude_sameRoot_addExcludedFolder() {
// prepare paths
String project = '/project';
String folderA = '$project/aaa';
String folderB = '$project/bbb';
String fileA = '$folderA/a.dart';
String fileB = '$folderB/b.dart';
// create files
resourceProvider.newFile(fileA, 'library a;');
resourceProvider.newFile(fileB, 'library b;');
// initially both "aaa/a" and "bbb/b" are included
manager.setRoots(<String>[project], <String>[], <String, String>{});
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [fileA, fileB]);
// exclude "bbb/"
manager.setRoots(<String>[project], <String>[folderB], <String, String>{});
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [fileA]);
}
void test_setRoots_exclude_sameRoot_removeExcludedFile() {
// prepare paths
String project = '/project';
String file1 = '$project/file1.dart';
String file2 = '$project/file2.dart';
// create files
resourceProvider.newFile(file1, '// 1');
resourceProvider.newFile(file2, '// 2');
// set roots
manager.setRoots(<String>[project], <String>[file2], <String, String>{});
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [file1]);
// stop excluding "2"
manager.setRoots(<String>[project], <String>[], <String, String>{});
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [file1, file2]);
}
void test_setRoots_exclude_sameRoot_removeExcludedFile_inFolder() {
// prepare paths
String project = '/project';
String file1 = '$project/bin/file1.dart';
String file2 = '$project/bin/file2.dart';
// create files
resourceProvider.newFile(file1, '// 1');
resourceProvider.newFile(file2, '// 2');
// set roots
manager.setRoots(<String>[project], <String>[file2], <String, String>{});
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [file1]);
// stop excluding "2"
manager.setRoots(<String>[project], <String>[], <String, String>{});
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [file1, file2]);
}
void test_setRoots_exclude_sameRoot_removeExcludedFolder() {
// prepare paths
String project = '/project';
String folderA = '$project/aaa';
String folderB = '$project/bbb';
String fileA = '$folderA/a.dart';
String fileB = '$folderB/b.dart';
// create files
resourceProvider.newFile(fileA, 'library a;');
resourceProvider.newFile(fileB, 'library b;');
// exclude "bbb/"
manager.setRoots(<String>[project], <String>[folderB], <String, String>{});
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [fileA]);
// stop excluding "bbb/"
manager.setRoots(<String>[project], <String>[], <String, String>{});
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [fileA, fileB]);
}
void test_setRoots_ignoreDocFolder() {
String project = '/project';
String fileA = '$project/foo.dart';
String fileB = '$project/lib/doc/bar.dart';
String fileC = '$project/doc/bar.dart';
resourceProvider.newFile(fileA, '');
resourceProvider.newFile(fileB, '');
resourceProvider.newFile(fileC, '');
manager.setRoots(<String>[project], <String>[], <String, String>{});
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [fileA, fileB]);
}
void test_setRoots_nested_includedByOuter_innerFirst() {
String project = '/project';
String projectPubspec = '$project/pubspec.yaml';
String example = '$project/example';
String examplePubspec = '$example/pubspec.yaml';
// create files
resourceProvider.newFile(projectPubspec, 'name: project');
resourceProvider.newFile(examplePubspec, 'name: example');
manager
.setRoots(<String>[example, project], <String>[], <String, String>{});
// verify
{
ContextInfo rootInfo = manager.rootInfo;
expect(rootInfo.children, hasLength(1));
{
ContextInfo projectInfo = rootInfo.children[0];
expect(projectInfo.folder.path, project);
expect(projectInfo.children, hasLength(1));
{
ContextInfo exampleInfo = projectInfo.children[0];
expect(exampleInfo.folder.path, example);
expect(exampleInfo.children, isEmpty);
}
}
}
expect(callbacks.currentContextRoots, unorderedEquals([project, example]));
}
void test_setRoots_nested_includedByOuter_outerPubspec() {
String project = '/project';
String projectPubspec = '$project/pubspec.yaml';
String example = '$project/example';
// create files
resourceProvider.newFile(projectPubspec, 'name: project');
resourceProvider.newFolder(example);
manager
.setRoots(<String>[project, example], <String>[], <String, String>{});
// verify
{
ContextInfo rootInfo = manager.rootInfo;
expect(rootInfo.children, hasLength(1));
{
ContextInfo projectInfo = rootInfo.children[0];
expect(projectInfo.folder.path, project);
expect(projectInfo.children, isEmpty);
}
}
expect(callbacks.currentContextRoots, unorderedEquals([project]));
}
void test_setRoots_nested_includedByOuter_twoPubspecs() {
String project = '/project';
String projectPubspec = '$project/pubspec.yaml';
String example = '$project/example';
String examplePubspec = '$example/pubspec.yaml';
// create files
resourceProvider.newFile(projectPubspec, 'name: project');
resourceProvider.newFile(examplePubspec, 'name: example');
manager
.setRoots(<String>[project, example], <String>[], <String, String>{});
// verify
{
ContextInfo rootInfo = manager.rootInfo;
expect(rootInfo.children, hasLength(1));
{
ContextInfo projectInfo = rootInfo.children[0];
expect(projectInfo.folder.path, project);
expect(projectInfo.children, hasLength(1));
{
ContextInfo exampleInfo = projectInfo.children[0];
expect(exampleInfo.folder.path, example);
expect(exampleInfo.children, isEmpty);
}
}
}
expect(callbacks.currentContextRoots, unorderedEquals([project, example]));
}
void test_setRoots_newFolderWithPackageRoot() {
String packageRootPath = '/package';
manager.setRoots(<String>[projPath], <String>[],
<String, String>{projPath: packageRootPath});
_checkPackageRoot(projPath, equals(packageRootPath));
}
void test_setRoots_newlyAddedFoldersGetProperPackageMap() {
String packagePath = '/package/foo';
newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME],
'foo:file:///package/foo');
Folder packageFolder = resourceProvider.newFolder(packagePath);
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
expect(
_currentPackageMap,
equals({
'foo': [packageFolder]
}));
}
void test_setRoots_noContext_excludedFolder() {
// prepare paths
String project = '/project';
String excludedFolder = '$project/excluded';
String excludedPubspec = '$excludedFolder/pubspec.yaml';
// create files
resourceProvider.newFile(excludedPubspec, 'name: ignore-me');
// set "/project", and exclude "/project/excluded"
manager.setRoots(
<String>[project], <String>[excludedFolder], <String, String>{});
callbacks.assertContextPaths([project]);
}
void test_setRoots_noContext_inDotFolder() {
String pubspecPath = path.posix.join(projPath, '.pub', 'pubspec.yaml');
resourceProvider.newFile(pubspecPath, 'name: test');
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// verify
expect(callbacks.currentContextRoots, hasLength(1));
expect(callbacks.currentContextRoots, contains(projPath));
expect(callbacks.currentFilePaths, hasLength(0));
}
void test_setRoots_noContext_inPackagesFolder() {
String pubspecPath = path.posix.join(projPath, 'packages', 'pubspec.yaml');
resourceProvider.newFile(pubspecPath, 'name: test');
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// verify
expect(callbacks.currentContextRoots, hasLength(1));
expect(callbacks.currentContextRoots, contains(projPath));
expect(callbacks.currentFilePaths, hasLength(0));
}
void test_setRoots_packageResolver() {
String filePath = path.posix.join(projPath, 'lib', 'foo.dart');
newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME], 'foo:lib/');
resourceProvider.newFile(filePath, 'contents');
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
if (enableAnalysisDriver) {
var drivers = manager
.getDriversInAnalysisRoot(resourceProvider.newFolder(projPath));
expect(drivers, hasLength(1));
expect(drivers[0], isNotNull);
} else {
List<AnalysisContext> contextsInAnalysisRoot =
manager.contextsInAnalysisRoot(resourceProvider.newFolder(projPath));
expect(contextsInAnalysisRoot, hasLength(1));
expect(contextsInAnalysisRoot[0], isNotNull);
}
Source result = sourceFactory.forUri('package:foo/foo.dart');
expect(result.fullName, filePath);
}
void test_setRoots_pathContainsDotFile() {
// If the path to a file (relative to the context root) contains a folder
// whose name begins with '.', then the file is ignored.
String project = '/project';
String fileA = '$project/foo.dart';
String fileB = '$project/.pub/bar.dart';
resourceProvider.newFile(fileA, '');
resourceProvider.newFile(fileB, '');
manager.setRoots(<String>[project], <String>[], <String, String>{});
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [fileA]);
}
void test_setRoots_removeFolderWithoutPubspec() {
packageMapProvider.packageMap = null;
// add one root - there is a context
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
expect(callbacks.currentContextRoots, hasLength(1));
// set empty roots - no contexts
manager.setRoots(<String>[], <String>[], <String, String>{});
expect(callbacks.currentContextRoots, hasLength(0));
expect(callbacks.currentFilePaths, hasLength(0));
}
void test_setRoots_removeFolderWithPackagespec() {
// create a pubspec
String pubspecPath = path.posix.join(projPath, '.packages');
resourceProvider.newFile(pubspecPath, '');
// add one root - there is a context
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
expect(manager.changeSubscriptions, hasLength(1));
expect(callbacks.currentContextRoots, hasLength(1));
// set empty roots - no contexts
manager.setRoots(<String>[], <String>[], <String, String>{});
expect(manager.changeSubscriptions, hasLength(0));
expect(callbacks.currentContextRoots, hasLength(0));
expect(callbacks.currentFilePaths, hasLength(0));
}
void test_setRoots_removeFolderWithPackagespecFolder() {
// prepare paths
String projectA = '/projectA';
String projectB = '/projectB';
String subProjectA = '$projectA/sub';
String subProjectB = '$projectB/sub';
String projectA_file = '$projectA/a.dart';
String projectB_file = '$projectB/a.dart';
String subProjectA_pubspec = '$subProjectA/.packages';
String subProjectB_pubspec = '$subProjectB/.packages';
String subProjectA_file = '$subProjectA/bin/sub_a.dart';
String subProjectB_file = '$subProjectB/bin/sub_b.dart';
// create files
resourceProvider.newFile(projectA_file, '// a');
resourceProvider.newFile(projectB_file, '// b');
resourceProvider.newFile(subProjectA_pubspec, '');
resourceProvider.newFile(subProjectB_pubspec, '');
resourceProvider.newFile(subProjectA_file, '// sub-a');
resourceProvider.newFile(subProjectB_file, '// sub-b');
// set roots
manager
.setRoots(<String>[projectA, projectB], <String>[], <String, String>{});
callbacks
.assertContextPaths([projectA, subProjectA, projectB, subProjectB]);
callbacks.assertContextFiles(projectA, [projectA_file]);
callbacks.assertContextFiles(projectB, [projectB_file]);
callbacks.assertContextFiles(subProjectA, [subProjectA_file]);
callbacks.assertContextFiles(subProjectB, [subProjectB_file]);
// remove "projectB"
manager.setRoots(<String>[projectA], <String>[], <String, String>{});
callbacks.assertContextPaths([projectA, subProjectA]);
callbacks.assertContextFiles(projectA, [projectA_file]);
callbacks.assertContextFiles(subProjectA, [subProjectA_file]);
}
void test_setRoots_removeFolderWithPubspec() {
// create a pubspec
String pubspecPath = path.posix.join(projPath, 'pubspec.yaml');
resourceProvider.newFile(pubspecPath, 'pubspec');
// add one root - there is a context
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
expect(callbacks.currentContextRoots, hasLength(1));
// set empty roots - no contexts
manager.setRoots(<String>[], <String>[], <String, String>{});
expect(callbacks.currentContextRoots, hasLength(0));
expect(callbacks.currentFilePaths, hasLength(0));
}
void test_setRoots_removeFolderWithPubspecFolder() {
// prepare paths
String projectA = '/projectA';
String projectB = '/projectB';
String subProjectA = '$projectA/sub';
String subProjectB = '$projectB/sub';
String projectA_file = '$projectA/a.dart';
String projectB_file = '$projectB/a.dart';
String subProjectA_pubspec = '$subProjectA/pubspec.yaml';
String subProjectB_pubspec = '$subProjectB/pubspec.yaml';
String subProjectA_file = '$subProjectA/bin/sub_a.dart';
String subProjectB_file = '$subProjectB/bin/sub_b.dart';
// create files
resourceProvider.newFile(projectA_file, '// a');
resourceProvider.newFile(projectB_file, '// b');
resourceProvider.newFile(subProjectA_pubspec, 'pubspec');
resourceProvider.newFile(subProjectB_pubspec, 'pubspec');
resourceProvider.newFile(subProjectA_file, '// sub-a');
resourceProvider.newFile(subProjectB_file, '// sub-b');
// set roots
manager
.setRoots(<String>[projectA, projectB], <String>[], <String, String>{});
callbacks
.assertContextPaths([projectA, subProjectA, projectB, subProjectB]);
callbacks.assertContextFiles(projectA, [projectA_file]);
callbacks.assertContextFiles(projectB, [projectB_file]);
callbacks.assertContextFiles(subProjectA, [subProjectA_file]);
callbacks.assertContextFiles(subProjectB, [subProjectB_file]);
// remove "projectB"
manager.setRoots(<String>[projectA], <String>[], <String, String>{});
callbacks.assertContextPaths([projectA, subProjectA]);
callbacks.assertContextFiles(projectA, [projectA_file]);
callbacks.assertContextFiles(subProjectA, [subProjectA_file]);
}
void test_setRoots_removePackageRoot() {
String packagePathFoo = '/package1/foo';
String packageRootPath = '/package2/foo';
Folder packageFolder = resourceProvider.newFolder(packagePathFoo);
newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME],
'foo:file:///package1/foo');
List<String> includedPaths = <String>[projPath];
List<String> excludedPaths = <String>[];
manager.setRoots(includedPaths, excludedPaths,
<String, String>{projPath: packageRootPath});
_checkPackageRoot(projPath, equals(packageRootPath));
manager.setRoots(includedPaths, excludedPaths, <String, String>{});
expect(
_currentPackageMap,
equals({
'foo': [packageFolder]
}));
}
void test_setRoots_rootPathContainsDotFile() {
// If the path to the context root itself contains a folder whose name
// begins with '.', then that is not sufficient to cause any files in the
// context to be ignored.
String project = '/.pub/project';
String fileA = '$project/foo.dart';
resourceProvider.newFile(fileA, '');
manager.setRoots(<String>[project], <String>[], <String, String>{});
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [fileA]);
}
test_watch_addDummyLink() {
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// empty folder initially
expect(callbacks.currentFilePaths, isEmpty);
// add link
String filePath = path.posix.join(projPath, 'foo.dart');
resourceProvider.newDummyLink(filePath);
// the link was ignored
return pumpEventQueue().then((_) {
expect(callbacks.currentFilePaths, isEmpty);
});
}
test_watch_addFile() {
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// empty folder initially
expect(callbacks.currentFilePaths, hasLength(0));
// add file
String filePath = path.posix.join(projPath, 'foo.dart');
resourceProvider.newFile(filePath, 'contents');
// the file was added
return pumpEventQueue().then((_) {
Iterable<String> filePaths = callbacks.currentFilePaths;
expect(filePaths, hasLength(1));
expect(filePaths, contains(filePath));
});
}
test_watch_addFile_excluded() {
// prepare paths
String project = '/project';
String folderA = '$project/aaa';
String folderB = '$project/bbb';
String fileA = '$folderA/a.dart';
String fileB = '$folderB/b.dart';
// create files
resourceProvider.newFile(fileA, 'library a;');
// set roots
manager.setRoots(<String>[project], <String>[folderB], <String, String>{});
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [fileA]);
// add a file, ignored as excluded
resourceProvider.newFile(fileB, 'library b;');
return pumpEventQueue().then((_) {
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [fileA]);
});
}
test_watch_addFile_inDocFolder_inner() {
// prepare paths
String project = '/project';
String fileA = '$project/a.dart';
String fileB = '$project/lib/doc/b.dart';
// create files
resourceProvider.newFile(fileA, '');
// set roots
manager.setRoots(<String>[project], <String>[], <String, String>{});
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [fileA]);
// add a "lib/doc" file, it is not ignored
resourceProvider.newFile(fileB, '');
return pumpEventQueue().then((_) {
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [fileA, fileB]);
});
}
test_watch_addFile_inDocFolder_topLevel() {
// prepare paths
String project = '/project';
String fileA = '$project/a.dart';
String fileB = '$project/doc/b.dart';
// create files
resourceProvider.newFile(fileA, '');
// set roots
manager.setRoots(<String>[project], <String>[], <String, String>{});
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [fileA]);
// add a "doc" file, it is ignored
resourceProvider.newFile(fileB, '');
return pumpEventQueue().then((_) {
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [fileA]);
});
}
test_watch_addFile_pathContainsDotFile() async {
// If a file is added and the path to it (relative to the context root)
// contains a folder whose name begins with '.', then the file is ignored.
String project = '/project';
String fileA = '$project/foo.dart';
String fileB = '$project/.pub/bar.dart';
resourceProvider.newFile(fileA, '');
manager.setRoots(<String>[project], <String>[], <String, String>{});
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [fileA]);
resourceProvider.newFile(fileB, '');
await pumpEventQueue();
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [fileA]);
}
test_watch_addFile_rootPathContainsDotFile() async {
// If a file is added and the path to the context contains a folder whose
// name begins with '.', then the file is not ignored.
String project = '/.pub/project';
String fileA = '$project/foo.dart';
String fileB = '$project/bar/baz.dart';
resourceProvider.newFile(fileA, '');
manager.setRoots(<String>[project], <String>[], <String, String>{});
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [fileA]);
resourceProvider.newFile(fileB, '');
await pumpEventQueue();
callbacks.assertContextPaths([project]);
callbacks.assertContextFiles(project, [fileA, fileB]);
}
test_watch_addFileInSubfolder() {
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// empty folder initially
expect(callbacks.currentFilePaths, hasLength(0));
// add file in subfolder
String filePath = path.posix.join(projPath, 'foo', 'bar.dart');
resourceProvider.newFile(filePath, 'contents');
// the file was added
return pumpEventQueue().then((_) {
Iterable<String> filePaths = callbacks.currentFilePaths;
expect(filePaths, hasLength(1));
expect(filePaths, contains(filePath));
});
}
test_watch_addPackagespec_toRoot() {
// prepare paths
String root = '/root';
String rootFile = '$root/root.dart';
String rootPackagespec = '$root/.packages';
// create files
resourceProvider.newFile(rootFile, 'library root;');
// set roots
manager.setRoots(<String>[root], <String>[], <String, String>{});
callbacks.assertContextPaths([root]);
// verify files
callbacks.assertContextFiles(root, [rootFile]);
// add packagespec - still just one root
resourceProvider.newFile(rootPackagespec, '');
return pumpEventQueue().then((_) {
callbacks.assertContextPaths([root]);
callbacks.assertContextFiles(root, [rootFile]);
// TODO(pquitslund): verify that a new source factory is created --
// likely this will need to happen in a corresponding ServerContextManagerTest.
});
}
test_watch_addPackagespec_toSubFolder() {
// prepare paths
String root = '/root';
String rootFile = '$root/root.dart';
String subProject = '$root/sub/aaa';
String subPubspec = '$subProject/.packages';
String subFile = '$subProject/bin/a.dart';
// create files
resourceProvider.newFile(rootFile, 'library root;');
resourceProvider.newFile(subFile, 'library a;');
// set roots
manager.setRoots(<String>[root], <String>[], <String, String>{});
callbacks.assertContextPaths([root]);
// verify files
callbacks.assertContextFiles(root, [rootFile, subFile]);
// add .packages
resourceProvider.newFile(subPubspec, '');
return pumpEventQueue().then((_) {
callbacks.assertContextPaths([root, subProject]);
callbacks.assertContextFiles(root, [rootFile]);
callbacks.assertContextFiles(subProject, [subFile]);
});
}
test_watch_addPackagespec_toSubFolder_ofSubFolder() {
// prepare paths
String root = '/root';
String rootFile = '$root/root.dart';
String subProject = '$root/sub';
String subPubspec = '$subProject/.packages';
String subFile = '$subProject/bin/sub.dart';
String subSubPubspec = '$subProject/subsub/.packages';
// create files
resourceProvider.newFile(rootFile, 'library root;');
resourceProvider.newFile(subPubspec, '');
resourceProvider.newFile(subFile, 'library sub;');
// set roots
manager.setRoots(<String>[root], <String>[], <String, String>{});
callbacks.assertContextPaths([root, subProject]);
callbacks.assertContextFiles(root, [rootFile]);
callbacks.assertContextFiles(subProject, [subFile]);
// add pubspec - ignore, because is already in a packagespec-based context
resourceProvider.newFile(subSubPubspec, '');
return pumpEventQueue().then((_) {
callbacks.assertContextPaths([root, subProject]);
callbacks.assertContextFiles(root, [rootFile]);
callbacks.assertContextFiles(subProject, [subFile]);
});
}
test_watch_addPackagespec_toSubFolder_withPubspec() {
// prepare paths
String root = '/root';
String rootFile = '$root/root.dart';
String subProject = '$root/sub/aaa';
String subPackagespec = '$subProject/.packages';
String subPubspec = '$subProject/pubspec.yaml';
String subFile = '$subProject/bin/a.dart';
// create files
resourceProvider.newFile(subPubspec, 'pubspec');
resourceProvider.newFile(rootFile, 'library root;');
resourceProvider.newFile(subFile, 'library a;');
// set roots
manager.setRoots(<String>[root], <String>[], <String, String>{});
callbacks.assertContextPaths([root, subProject]);
// verify files
callbacks.assertContextFiles(root, [rootFile]);
callbacks.assertContextFiles(subProject, [subFile]);
// add .packages
resourceProvider.newFile(subPackagespec, '');
return pumpEventQueue().then((_) {
// Should NOT create another context.
callbacks.assertContextPaths([root, subProject]);
callbacks.assertContextFiles(root, [rootFile]);
callbacks.assertContextFiles(subProject, [subFile]);
});
}
test_watch_addPubspec_toRoot() {
// prepare paths
String root = '/root';
String rootFile = '$root/root.dart';
String rootPubspec = '$root/pubspec.yaml';
// create files
resourceProvider.newFile(rootFile, 'library root;');
// set roots
manager.setRoots(<String>[root], <String>[], <String, String>{});
callbacks.assertContextPaths([root]);
// verify files
callbacks.assertContextFiles(root, [rootFile]);
// add pubspec - still just one root
resourceProvider.newFile(rootPubspec, 'pubspec');
return pumpEventQueue().then((_) {
callbacks.assertContextPaths([root]);
callbacks.assertContextFiles(root, [rootFile]);
});
}
test_watch_addPubspec_toSubFolder() {
// prepare paths
String root = '/root';
String rootFile = '$root/root.dart';
String subProject = '$root/sub/aaa';
String subPubspec = '$subProject/pubspec.yaml';
String subFile = '$subProject/bin/a.dart';
// create files
resourceProvider.newFile(rootFile, 'library root;');
resourceProvider.newFile(subFile, 'library a;');
// set roots
manager.setRoots(<String>[root], <String>[], <String, String>{});
callbacks.assertContextPaths([root]);
// verify files
callbacks.assertContextFiles(root, [rootFile, subFile]);
// add pubspec
resourceProvider.newFile(subPubspec, 'pubspec');
return pumpEventQueue().then((_) {
callbacks.assertContextPaths([root, subProject]);
callbacks.assertContextFiles(root, [rootFile]);
callbacks.assertContextFiles(subProject, [subFile]);
});
}
test_watch_addPubspec_toSubFolder_ofSubFolder() {
// prepare paths
String root = '/root';
String rootFile = '$root/root.dart';
String subProject = '$root/sub';
String subPubspec = '$subProject/pubspec.yaml';
String subFile = '$subProject/bin/sub.dart';
String subSubPubspec = '$subProject/subsub/pubspec.yaml';
// create files
resourceProvider.newFile(rootFile, 'library root;');
resourceProvider.newFile(subPubspec, 'pubspec');
resourceProvider.newFile(subFile, 'library sub;');
// set roots
manager.setRoots(<String>[root], <String>[], <String, String>{});
callbacks.assertContextPaths([root, subProject]);
callbacks.assertContextFiles(root, [rootFile]);
callbacks.assertContextFiles(subProject, [subFile]);
// add pubspec - ignore, because is already in a pubspec-based context
resourceProvider.newFile(subSubPubspec, 'pubspec');
return pumpEventQueue().then((_) {
callbacks.assertContextPaths([root, subProject]);
callbacks.assertContextFiles(root, [rootFile]);
callbacks.assertContextFiles(subProject, [subFile]);
});
}
test_watch_deleteFile() {
String filePath = path.posix.join(projPath, 'foo.dart');
// add root with a file
File file = resourceProvider.newFile(filePath, 'contents');
Folder projFolder = file.parent;
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// the file was added
Iterable<String> filePaths = callbacks.currentFilePaths;
expect(filePaths, hasLength(1));
expect(filePaths, contains(filePath));
expect(file.exists, isTrue);
expect(projFolder.exists, isTrue);
// delete the file
resourceProvider.deleteFile(filePath);
return pumpEventQueue().then((_) {
expect(file.exists, isFalse);
expect(projFolder.exists, isTrue);
return expect(callbacks.currentFilePaths, hasLength(0));
});
}
test_watch_deleteFolder() {
String filePath = path.posix.join(projPath, 'foo.dart');
// add root with a file
File file = resourceProvider.newFile(filePath, 'contents');
Folder projFolder = file.parent;
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// the file was added
Iterable<String> filePaths = callbacks.currentFilePaths;
expect(filePaths, hasLength(1));
expect(filePaths, contains(filePath));
expect(file.exists, isTrue);
expect(projFolder.exists, isTrue);
// delete the folder
resourceProvider.deleteFolder(projPath);
return pumpEventQueue().then((_) {
expect(file.exists, isFalse);
expect(projFolder.exists, isFalse);
return expect(callbacks.currentFilePaths, hasLength(0));
});
}
test_watch_deletePackagespec_fromRoot() {
// prepare paths
String root = '/root';
String rootPubspec = '$root/.packages';
String rootFile = '$root/root.dart';
// create files
resourceProvider.newFile(rootPubspec, '');
resourceProvider.newFile(rootFile, 'library root;');
// set roots
manager.setRoots(<String>[root], <String>[], <String, String>{});
callbacks.assertContextPaths([root]);
callbacks.assertContextFiles(root, [rootFile]);
// delete the pubspec
resourceProvider.deleteFile(rootPubspec);
return pumpEventQueue().then((_) {
callbacks.assertContextPaths([root]);
callbacks.assertContextFiles(root, [rootFile]);
});
}
test_watch_deletePackagespec_fromSubFolder() {
// prepare paths
String root = '/root';
String rootFile = '$root/root.dart';
String subProject = '$root/sub/aaa';
String subPubspec = '$subProject/.packages';
String subFile = '$subProject/bin/a.dart';
// create files
resourceProvider.newFile(subPubspec, '');
resourceProvider.newFile(rootFile, 'library root;');
resourceProvider.newFile(subFile, 'library a;');
// set roots
manager.setRoots(<String>[root], <String>[], <String, String>{});
callbacks.assertContextPaths([root, subProject]);
// verify files
callbacks.assertContextFiles(root, [rootFile]);
callbacks.assertContextFiles(subProject, [subFile]);
// delete the pubspec
resourceProvider.deleteFile(subPubspec);
return pumpEventQueue().then((_) {
callbacks.assertContextPaths([root]);
callbacks.assertContextFiles(root, [rootFile, subFile]);
});
}
test_watch_deletePackagespec_fromSubFolder_withPubspec() {
// prepare paths:
//
// root
// root.dart
// sub
// aaa
// .packages
// pubspec.yaml
// bin
// a.dart
//
String root = '/root';
String rootFile = '$root/root.dart';
String subProject = '$root/sub/aaa';
String subPackagespec = '$subProject/.packages';
String subPubspec = '$subProject/pubspec.yaml';
String subFile = '$subProject/bin/a.dart';
// create files
resourceProvider.newFile(subPackagespec, '');
resourceProvider.newFile(subPubspec, 'pubspec');
resourceProvider.newFile(rootFile, 'library root;');
resourceProvider.newFile(subFile, 'library a;');
// set roots
manager.setRoots(<String>[root], <String>[], <String, String>{});
callbacks.assertContextPaths([root, subProject]);
// verify files
callbacks.assertContextFiles(root, [rootFile]);
callbacks.assertContextFiles(subProject, [subFile]);
// delete the packagespec
resourceProvider.deleteFile(subPackagespec);
return pumpEventQueue().then((_) {
// Should NOT merge
callbacks.assertContextPaths([root, subProject]);
callbacks.assertContextFiles(subProject, [subFile]);
});
}
test_watch_deletePubspec_fromRoot() {
// prepare paths
String root = '/root';
String rootPubspec = '$root/pubspec.yaml';
String rootFile = '$root/root.dart';
// create files
resourceProvider.newFile(rootPubspec, 'pubspec');
resourceProvider.newFile(rootFile, 'library root;');
// set roots
manager.setRoots(<String>[root], <String>[], <String, String>{});
callbacks.assertContextPaths([root]);
callbacks.assertContextFiles(root, [rootFile]);
// delete the pubspec
resourceProvider.deleteFile(rootPubspec);
return pumpEventQueue().then((_) {
callbacks.assertContextPaths([root]);
callbacks.assertContextFiles(root, [rootFile]);
});
}
test_watch_deletePubspec_fromSubFolder() {
// prepare paths
String root = '/root';
String rootFile = '$root/root.dart';
String subProject = '$root/sub/aaa';
String subPubspec = '$subProject/pubspec.yaml';
String subFile = '$subProject/bin/a.dart';
// create files
resourceProvider.newFile(subPubspec, 'pubspec');
resourceProvider.newFile(rootFile, 'library root;');
resourceProvider.newFile(subFile, 'library a;');
// set roots
manager.setRoots(<String>[root], <String>[], <String, String>{});
callbacks.assertContextPaths([root, subProject]);
// verify files
callbacks.assertContextFiles(root, [rootFile]);
callbacks.assertContextFiles(subProject, [subFile]);
// delete the pubspec
resourceProvider.deleteFile(subPubspec);
return pumpEventQueue().then((_) {
callbacks.assertContextPaths([root]);
callbacks.assertContextFiles(root, [rootFile, subFile]);
});
}
test_watch_modifyFile() {
String filePath = path.posix.join(projPath, 'foo.dart');
// add root with a file
resourceProvider.newFile(filePath, 'contents');
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// the file was added
if (enableAnalysisDriver) {
Iterable<String> filePaths = callbacks.currentFilePaths;
expect(filePaths, hasLength(1));
expect(filePaths, contains(filePath));
// TODO(brianwilkerson) Test when the file was modified
} else {
Map<String, int> filePaths = callbacks.currentContextFilePaths[projPath];
expect(filePaths, hasLength(1));
expect(filePaths, contains(filePath));
expect(filePaths[filePath], equals(callbacks.now));
}
// update the file
callbacks.now++;
resourceProvider.modifyFile(filePath, 'new contents');
return pumpEventQueue().then((_) {
if (enableAnalysisDriver) {
// TODO(brianwilkerson) Test when the file was modified
return null;
}
Map<String, int> filePaths = callbacks.currentContextFilePaths[projPath];
return expect(filePaths[filePath], equals(callbacks.now));
});
}
test_watch_modifyPackageMapDependency_fail() async {
// create a dependency file
String dependencyPath = path.posix.join(projPath, 'dep');
resourceProvider.newFile(dependencyPath, 'contents');
packageMapProvider.dependencies.add(dependencyPath);
// create a Dart file
String dartFilePath = path.posix.join(projPath, 'main.dart');
resourceProvider.newFile(dartFilePath, 'contents');
// the created context has the expected empty package map
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
expect(_currentPackageMap, isEmpty);
// Change the package map dependency so that the packageMapProvider is
// re-run, and arrange for it to return null from computePackageMap().
packageMapProvider.packageMap = null;
resourceProvider.modifyFile(dependencyPath, 'new contents');
await pumpEventQueue();
// The package map should have been changed to null.
expect(_currentPackageMap, isEmpty);
}
test_watch_modifyPackagespec() {
String packagesPath = '$projPath/.packages';
String filePath = '$projPath/bin/main.dart';
resourceProvider.newFile(packagesPath, '');
resourceProvider.newFile(filePath, 'library main;');
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
Iterable<String> filePaths = callbacks.currentFilePaths;
expect(filePaths, hasLength(1));
expect(filePaths, contains(filePath));
expect(_currentPackageMap, isEmpty);
// update .packages
callbacks.now++;
resourceProvider.modifyFile(packagesPath, 'main:./lib/');
return pumpEventQueue().then((_) {
// verify new package info
expect(_currentPackageMap.keys, unorderedEquals(['main']));
});
}
/**
* Verify that package URI's for source files in [path] will be resolved
* using a package root matching [expectation].
*/
void _checkPackageRoot(String path, expectation) {
// TODO(brianwilkerson) Figure out how to test this. Possibly by comparing
// the contents of the package map (although that approach doesn't work at
// the moment).
// FolderDisposition disposition = callbacks.currentContextDispositions[path];
// expect(disposition.packageRoot, expectation);
// TODO(paulberry): we should also verify that the package map itself is
// correct. See dartbug.com/23909.
}
}
abstract class ContextManagerTest {
/**
* The name of the 'bin' directory.
*/
static const String BIN_NAME = 'bin';
/**
* The name of the 'example' directory.
*/
static const String EXAMPLE_NAME = 'example';
/**
* The name of the 'lib' directory.
*/
static const String LIB_NAME = 'lib';
/**
* The name of the 'src' directory.
*/
static const String SRC_NAME = 'src';
/**
* The name of the 'test' directory.
*/
static const String TEST_NAME = 'test';
ContextManagerImpl manager;
TestContextManagerCallbacks callbacks;
MemoryResourceProvider resourceProvider;
MockPackageMapProvider packageMapProvider;
UriResolver packageResolver = null;
String projPath = '/my/proj';
AnalysisError missing_required_param = new AnalysisError(
new TestSource(), 0, 1, HintCode.MISSING_REQUIRED_PARAM, [
['x']
]);
AnalysisError missing_return =
new AnalysisError(new TestSource(), 0, 1, HintCode.MISSING_RETURN, [
['x']
]);
AnalysisError invalid_assignment_error =
new AnalysisError(new TestSource(), 0, 1, HintCode.INVALID_ASSIGNMENT, [
['x'],
['y']
]);
AnalysisError unused_local_variable = new AnalysisError(
new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
['x']
]);
List<Glob> get analysisFilesGlobs {
List<String> patterns = <String>[
'**/*.${AnalysisEngine.SUFFIX_DART}',
'**/*.${AnalysisEngine.SUFFIX_HTML}',
'**/*.${AnalysisEngine.SUFFIX_HTM}',
'**/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}',
'**/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}'
];
return patterns
.map((pattern) => new Glob(path.posix.separator, pattern))
.toList();
}
AnalysisOptions get analysisOptions => callbacks.analysisOptions;
bool get enableAnalysisDriver => false;
List<ErrorProcessor> get errorProcessors => analysisOptions.errorProcessors;
List<Linter> get lints => analysisOptions.lintRules;
SourceFactory get sourceFactory => callbacks.sourceFactory;
Map<String, List<Folder>> get _currentPackageMap => _packageMap(projPath);
void deleteFile(List<String> pathComponents) {
String filePath = path.posix.joinAll(pathComponents);
resourceProvider.deleteFile(filePath);
}
/**
* TODO(brianwilkerson) This doesn't add the strong mode processor when using
* the new analysis driver.
*/
ErrorProcessor getProcessor(AnalysisError error) =>
callbacks.currentDriver == null
? ErrorProcessor.getProcessor(
callbacks.currentContext.analysisOptions, error)
: errorProcessors.firstWhere((ErrorProcessor p) => p.appliesTo(error),
orElse: () => null);
String newFile(List<String> pathComponents, [String content = '']) {
String filePath = path.posix.joinAll(pathComponents);
resourceProvider.newFile(filePath, content);
return filePath;
}
String newFileFromBytes(List<String> pathComponents, List<int> bytes) {
String filePath = path.posix.joinAll(pathComponents);
resourceProvider.newFileWithBytes(filePath, bytes);
return filePath;
}
String newFolder(List<String> pathComponents) {
String folderPath = path.posix.joinAll(pathComponents);
resourceProvider.newFolder(folderPath);
return folderPath;
}
void processRequiredPlugins() {
List<Plugin> plugins = <Plugin>[];
plugins.addAll(AnalysisEngine.instance.requiredPlugins);
ExtensionManager manager = new ExtensionManager();
manager.processPlugins(plugins);
registerLintRules();
}
UriResolver providePackageResolver(Folder folder) => packageResolver;
void setUp() {
processRequiredPlugins();
resourceProvider = new MemoryResourceProvider();
resourceProvider.newFolder(projPath);
packageMapProvider = new MockPackageMapProvider();
// Create an SDK in the mock file system.
new MockSdk(generateSummaryFiles: true, resourceProvider: resourceProvider);
DartSdkManager sdkManager = new DartSdkManager('/', true);
manager = new ContextManagerImpl(
resourceProvider,
sdkManager,
providePackageResolver,
packageMapProvider,
analysisFilesGlobs,
InstrumentationService.NULL_SERVICE,
new AnalysisOptionsImpl(),
enableAnalysisDriver);
PerformanceLog logger = new PerformanceLog(new NullStringSink());
AnalysisDriverScheduler scheduler = new AnalysisDriverScheduler(logger);
callbacks = new TestContextManagerCallbacks(
resourceProvider, sdkManager, logger, scheduler);
manager.callbacks = callbacks;
}
/**
* Verify that package URI's for source files in [path] will be resolved
* using a package root matching [expectation].
*/
void _checkPackageRoot(String path, expectation) {
// TODO(brianwilkerson) Figure out how to test this. Possibly by comparing
// the contents of the package map (although that approach doesn't work at
// the moment).
// FolderDisposition disposition = callbacks.currentContextDispositions[path];
// expect(disposition.packageRoot, expectation);
// TODO(paulberry): we should also verify that the package map itself is
// correct. See dartbug.com/23909.
}
Map<String, List<Folder>> _packageMap(String contextPath) {
Folder folder = resourceProvider.getFolder(contextPath);
if (enableAnalysisDriver) {
ContextInfo info = manager.getContextInfoFor(folder);
return info.analysisDriver.sourceFactory?.packageMap;
} else {
return manager.folderMap[folder]?.sourceFactory?.packageMap;
}
}
}
@reflectiveTest
class ContextManagerWithNewOptionsTest extends ContextManagerWithOptionsTest {
String get optionsFileName => AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE;
}
@reflectiveTest
class ContextManagerWithOldOptionsTest extends ContextManagerWithOptionsTest {
String get optionsFileName => AnalysisEngine.ANALYSIS_OPTIONS_FILE;
}
abstract class ContextManagerWithOptionsTest extends ContextManagerTest {
String get optionsFileName;
test_analysis_options_file_delete() async {
// Setup analysis options
newFile(
[projPath, optionsFileName],
r'''
embedded_libs:
"dart:foobar": "../sdk_ext/entry.dart"
analyzer:
language:
enableStrictCallChecks: true
errors:
unused_local_variable: false
linter:
rules:
- camel_case_types
''');
// Setup context.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
await pumpEventQueue();
// Verify options were set.
expect(errorProcessors, hasLength(1));
expect(lints, hasLength(1));
expect(analysisOptions.enableStrictCallChecks, isTrue);
// Remove options.
deleteFile([projPath, optionsFileName]);
await pumpEventQueue();
// Verify defaults restored.
expect(errorProcessors, isEmpty);
expect(lints, isEmpty);
expect(analysisOptions.enableStrictCallChecks, isFalse);
}
test_analysis_options_file_delete_with_embedder() async {
// Setup _embedder.yaml.
String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
newFile(
[libPath, '_embedder.yaml'],
r'''
analyzer:
strong-mode: true
errors:
missing_return: false
linter:
rules:
- avoid_as
''');
// Setup .packages file
newFile(
[projPath, '.packages'],
r'''
test_pack:lib/''');
// Setup analysis options
newFile(
[projPath, optionsFileName],
r'''
analyzer:
language:
enableStrictCallChecks: true
errors:
unused_local_variable: false
linter:
rules:
- camel_case_types
''');
// Setup context.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
await pumpEventQueue();
// Verify options were set.
expect(analysisOptions.enableStrictCallChecks, isTrue);
expect(analysisOptions.strongMode, isTrue);
expect(errorProcessors, hasLength(2));
expect(lints, hasLength(2));
// Remove options.
deleteFile([projPath, optionsFileName]);
await pumpEventQueue();
// Verify defaults restored.
expect(analysisOptions.enableStrictCallChecks, isFalse);
expect(lints, hasLength(1));
expect(lints.first, new isInstanceOf<AvoidAs>());
expect(errorProcessors, hasLength(1));
expect(getProcessor(missing_return).severity, isNull);
}
test_analysis_options_include() async {
// Create files.
String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
newFile([libPath, 'main.dart']);
String sdkExtPath = newFolder([projPath, 'sdk_ext']);
newFile([sdkExtPath, 'entry.dart']);
String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
newFile([sdkExtSrcPath, 'part.dart']);
// Setup analysis options file which includes another options file.
newFile(
[projPath, optionsFileName],
r'''
include: other_options.yaml
''');
newFile(
[projPath, 'other_options.yaml'],
r'''
analyzer:
language:
enableStrictCallChecks: true
errors:
unused_local_variable: false
linter:
rules:
- camel_case_types
''');
// Setup context.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
await pumpEventQueue();
// Verify options were set.
expect(analysisOptions.enableStrictCallChecks, isTrue);
expect(errorProcessors, hasLength(1));
expect(lints, hasLength(1));
expect(lints[0].name, 'camel_case_types');
}
test_analysis_options_include_package() async {
// Create files.
String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
newFile([libPath, 'main.dart']);
String sdkExtPath = newFolder([projPath, 'sdk_ext']);
newFile([sdkExtPath, 'entry.dart']);
String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
newFile([sdkExtSrcPath, 'part.dart']);
// Setup package
String booLibPosixPath = '/my/pkg/boo/lib';
newFile(
[booLibPosixPath, 'other_options.yaml'],
r'''
analyzer:
language:
enableStrictCallChecks: true
errors:
unused_local_variable: false
linter:
rules:
- camel_case_types
''');
// Setup analysis options file which includes another options file.
newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME],
'boo:$booLibPosixPath\n');
newFile(
[projPath, optionsFileName],
r'''
include: package:boo/other_options.yaml
''');
// Setup context.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
await pumpEventQueue();
// Verify options were set.
expect(analysisOptions.enableStrictCallChecks, isTrue);
expect(errorProcessors, hasLength(1));
expect(lints, hasLength(1));
expect(lints[0].name, 'camel_case_types');
}
test_analysis_options_parse_failure() async {
// Create files.
String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
newFile([libPath, 'main.dart']);
String sdkExtPath = newFolder([projPath, 'sdk_ext']);
newFile([sdkExtPath, 'entry.dart']);
String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
newFile([sdkExtSrcPath, 'part.dart']);
// Setup analysis options file with ignore list.
newFile(
[projPath, optionsFileName],
r'''
;
''');
// Setup context.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// No error means success.
}
test_deleteRoot_hasAnalysisOptions() async {
newFile([projPath, optionsFileName], '');
// Add the root.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
await pumpEventQueue();
// Remove the root, with the analysis options file.
// No exceptions.
resourceProvider.deleteFolder(projPath);
await pumpEventQueue();
}
test_embedder_options() async {
// Create files.
String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
String sdkExtPath = newFolder([projPath, 'sdk_ext']);
newFile([projPath, 'test', 'test.dart']);
newFile([sdkExtPath, 'entry.dart']);
List<int> bytes = new SummaryBuilder([], null, true).build();
newFileFromBytes([projPath, 'sdk.ds'], bytes);
// Setup _embedder.yaml.
newFile(
[libPath, '_embedder.yaml'],
r'''
embedded_libs:
"dart:foobar": "../sdk_ext/entry.dart"
analyzer:
strong-mode: true
language:
enableSuperMixins: true
errors:
missing_return: false
linter:
rules:
- avoid_as
''');
// Setup .packages file
newFile(
[projPath, '.packages'],
r'''
test_pack:lib/''');
// Setup analysis options
newFile(
[projPath, optionsFileName],
r'''
analyzer:
exclude:
- 'test/**'
language:
enableStrictCallChecks: true
errors:
unused_local_variable: false
linter:
rules:
- camel_case_types
''');
// Setup context.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
await pumpEventQueue();
// Confirm that one context was created.
var contexts =
manager.contextsInAnalysisRoot(resourceProvider.newFolder(projPath));
expect(contexts, isNotNull);
expect(contexts, hasLength(1));
// Verify options.
// * from `_embedder.yaml`:
expect(analysisOptions.strongMode, isTrue);
expect(analysisOptions.enableSuperMixins, isTrue);
// * from analysis options:
expect(analysisOptions.enableStrictCallChecks, isTrue);
// * verify tests are excluded
expect(
callbacks.currentContextFilePaths[projPath].keys,
unorderedEquals(
['/my/proj/sdk_ext/entry.dart', '/my/proj/$optionsFileName']));
// Verify filter setup.
expect(errorProcessors, hasLength(2));
// * (embedder.)
expect(getProcessor(missing_return).severity, isNull);
// * (options.)
expect(getProcessor(unused_local_variable).severity, isNull);
// Verify lints.
var lintNames = lints.map((lint) => lint.name);
expect(
lintNames,
unorderedEquals(
['avoid_as' /* embedder */, 'camel_case_types' /* options */]));
// Sanity check embedder libs.
var source = sourceFactory.forUri('dart:foobar');
expect(source, isNotNull);
expect(source.fullName, '/my/proj/sdk_ext/entry.dart');
}
test_error_filter_analysis_option() async {
// Create files.
newFile(
[projPath, optionsFileName],
r'''
analyzer:
errors:
unused_local_variable: ignore
''');
// Setup context.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// Verify filter setup.
expect(errorProcessors, hasLength(1));
expect(getProcessor(unused_local_variable).severity, isNull);
}
test_error_filter_analysis_option_multiple_filters() async {
// Create files.
newFile(
[projPath, optionsFileName],
r'''
analyzer:
errors:
invalid_assignment: ignore
unused_local_variable: error
''');
// Setup context.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// Verify filter setup.
expect(errorProcessors, hasLength(2));
expect(getProcessor(invalid_assignment_error).severity, isNull);
expect(getProcessor(unused_local_variable).severity, ErrorSeverity.ERROR);
}
test_error_filter_analysis_option_synonyms() async {
// Create files.
newFile(
[projPath, optionsFileName],
r'''
analyzer:
errors:
unused_local_variable: ignore
ambiguous_import: false
''');
// Setup context.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// Verify filter setup.
expect(errorProcessors, isNotNull);
expect(errorProcessors, hasLength(2));
}
test_error_filter_analysis_option_unpsecified() async {
// Create files.
newFile(
[projPath, optionsFileName],
r'''
analyzer:
# errors:
# unused_local_variable: ignore
''');
// Setup context.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// Verify filter setup.
expect(errorProcessors, isEmpty);
}
test_optionsFile_update_strongMode() async {
var file = resourceProvider.newFile(
'$projPath/bin/test.dart',
r'''
main() {
var paths = <int>[];
var names = <String>[];
paths.addAll(names.map((s) => s.length));
}
''');
resourceProvider.newFile(
'$projPath/$optionsFileName',
r'''
analyzer:
strong-mode: false
''');
// Create the context.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
await pumpEventQueue();
if (enableAnalysisDriver) {
AnalysisResult result =
await callbacks.currentDriver.getResult(file.path);
// Not strong mode - both in the context and the SDK context.
AnalysisContext sdkContext = sourceFactory.dartSdk.context;
expect(analysisOptions.strongMode, isFalse);
expect(sdkContext.analysisOptions.strongMode, isFalse);
expect(result.errors, isEmpty);
} else {
AnalysisContext context = manager.getContextFor(projPath);
Source testSource = context.getSourcesWithFullName(file.path).single;
// Not strong mode - both in the context and the SDK context.
AnalysisContext sdkContext = sourceFactory.dartSdk.context;
expect(analysisOptions.strongMode, isFalse);
expect(sdkContext.analysisOptions.strongMode, isFalse);
expect(context.computeErrors(testSource), isEmpty);
}
// Update the options file - turn on 'strong-mode'.
resourceProvider.updateFile(
'$projPath/$optionsFileName',
r'''
analyzer:
strong-mode: true
''');
await pumpEventQueue();
// Strong mode - both in the context and the SDK context.
if (enableAnalysisDriver) {
AnalysisResult result =
await callbacks.currentDriver.getResult(file.path);
// Not strong mode - both in the context and the SDK context.
AnalysisContext sdkContext = sourceFactory.dartSdk.context;
expect(analysisOptions.strongMode, isTrue);
expect(sdkContext.analysisOptions.strongMode, isTrue);
// The code is strong-mode clean.
// Verify that TypeSystem was reset.
expect(result.errors, isEmpty);
} else {
AnalysisContext context = manager.getContextFor(projPath);
Source testSource = context.getSourcesWithFullName(file.path).single;
AnalysisContext sdkContext = sourceFactory.dartSdk.context;
expect(analysisOptions.strongMode, isTrue);
expect(sdkContext.analysisOptions.strongMode, isTrue);
// The code is strong-mode clean.
// Verify that TypeSystem was reset.
expect(context.computeErrors(testSource), isEmpty);
}
}
test_path_filter_analysis_option() async {
// Create files.
String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
newFile([libPath, 'main.dart']);
newFile([libPath, 'nope.dart']);
String sdkExtPath = newFolder([projPath, 'sdk_ext']);
newFile([sdkExtPath, 'entry.dart']);
String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
newFile([sdkExtSrcPath, 'part.dart']);
// Setup analysis options file with ignore list.
newFile(
[projPath, optionsFileName],
r'''
analyzer:
exclude:
- lib/nope.dart
- 'sdk_ext/**'
''');
// Setup context.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// Verify that analysis options was parsed and the ignore patterns applied.
Folder projectFolder = resourceProvider.newFolder(projPath);
if (enableAnalysisDriver) {
var drivers = manager.getDriversInAnalysisRoot(projectFolder);
expect(drivers, hasLength(1));
AnalysisDriver driver = drivers[0];
expect(
driver.addedFiles,
unorderedEquals(
['/my/proj/lib/main.dart', '/my/proj/$optionsFileName']));
} else {
Map<String, int> fileTimestamps =
callbacks.currentContextFilePaths[projPath];
expect(fileTimestamps, isNotEmpty);
List<String> files = fileTimestamps.keys.toList();
expect(
files,
unorderedEquals(
['/my/proj/lib/main.dart', '/my/proj/$optionsFileName']));
}
}
test_path_filter_child_contexts_option() async {
// Create files.
String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
newFile([libPath, 'main.dart']);
newFile(
[libPath, 'pubspec.yaml'],
r'''
name: foobar
''');
String otherLibPath = newFolder([projPath, 'other_lib']);
newFile([otherLibPath, 'entry.dart']);
newFile(
[otherLibPath, 'pubspec.yaml'],
r'''
name: other_lib
''');
// Setup analysis options file with ignore list that ignores the 'other_lib'
// directory by name.
newFile(
[projPath, optionsFileName],
r'''
analyzer:
exclude:
- 'other_lib'
''');
// Setup context.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// Verify that the context in other_lib wasn't created and that the
// context in lib was created.
Folder projectFolder = resourceProvider.newFolder(projPath);
if (enableAnalysisDriver) {
var drivers = manager.getDriversInAnalysisRoot(projectFolder);
expect(drivers, hasLength(2));
expect(drivers[0].name, equals('/my/proj'));
expect(drivers[1].name, equals('/my/proj/lib'));
} else {
var contexts =
manager.contextsInAnalysisRoot(resourceProvider.newFolder(projPath));
expect(contexts.length, 2);
expect(contexts[0].name, equals('/my/proj'));
expect(contexts[1].name, equals('/my/proj/lib'));
}
}
test_path_filter_recursive_wildcard_child_contexts_option() async {
// Create files.
String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
newFile([libPath, 'main.dart']);
newFile(
[libPath, 'pubspec.yaml'],
r'''
name: foobar
''');
String otherLibPath = newFolder([projPath, 'other_lib']);
newFile([otherLibPath, 'entry.dart']);
newFile(
[otherLibPath, 'pubspec.yaml'],
r'''
name: other_lib
''');
// Setup analysis options file with ignore list that ignores 'other_lib'
// and all descendants.
newFile(
[projPath, optionsFileName],
r'''
analyzer:
exclude:
- 'other_lib/**'
''');
// Setup context.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// Verify that the context in other_lib wasn't created and that the
// context in lib was created.
Folder projectFolder = resourceProvider.newFolder(projPath);
if (enableAnalysisDriver) {
var drivers = manager.getDriversInAnalysisRoot(projectFolder);
expect(drivers, hasLength(2));
expect(drivers[0].name, equals('/my/proj'));
expect(drivers[1].name, equals('/my/proj/lib'));
} else {
var contexts = manager.contextsInAnalysisRoot(projectFolder);
expect(contexts.length, 2);
expect(contexts[0].name, equals('/my/proj'));
expect(contexts[1].name, equals('/my/proj/lib'));
}
}
test_path_filter_wildcard_child_contexts_option() async {
// Create files.
String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
newFile([libPath, 'main.dart']);
newFile(
[libPath, 'pubspec.yaml'],
r'''
name: foobar
''');
String otherLibPath = newFolder([projPath, 'other_lib']);
newFile([otherLibPath, 'entry.dart']);
newFile(
[otherLibPath, 'pubspec.yaml'],
r'''
name: other_lib
''');
// Setup analysis options file with ignore list that ignores 'other_lib'
// and all immediate children.
newFile(
[projPath, optionsFileName],
r'''
analyzer:
exclude:
- 'other_lib/*'
''');
// Setup context / driver.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
Folder projectFolder = resourceProvider.newFolder(projPath);
if (enableAnalysisDriver) {
var drivers = manager.getDriversInAnalysisRoot(projectFolder);
expect(drivers, hasLength(2));
expect(drivers[0].name, equals('/my/proj'));
expect(drivers[1].name, equals('/my/proj/lib'));
} else {
// Verify that the context in other_lib wasn't created and that the
// context in lib was created.
var contexts = manager.contextsInAnalysisRoot(projectFolder);
expect(contexts, hasLength(2));
expect(contexts[0].name, equals('/my/proj'));
expect(contexts[1].name, equals('/my/proj/lib'));
}
}
void test_setRoots_nested_excludedByOuter() {
String project = '/project';
String projectPubspec = '$project/pubspec.yaml';
String example = '$project/example';
String examplePubspec = '$example/pubspec.yaml';
// create files
resourceProvider.newFile(projectPubspec, 'name: project');
resourceProvider.newFile(examplePubspec, 'name: example');
newFile(
[project, optionsFileName],
r'''
analyzer:
exclude:
- 'example'
''');
manager
.setRoots(<String>[project, example], <String>[], <String, String>{});
// verify
{
ContextInfo rootInfo = manager.rootInfo;
expect(rootInfo.children, hasLength(1));
{
ContextInfo projectInfo = rootInfo.children[0];
expect(projectInfo.folder.path, project);
expect(projectInfo.children, hasLength(1));
{
ContextInfo exampleInfo = projectInfo.children[0];
expect(exampleInfo.folder.path, example);
expect(exampleInfo.children, isEmpty);
}
}
}
expect(callbacks.currentContextRoots, hasLength(2));
expect(callbacks.currentContextRoots, unorderedEquals([project, example]));
}
void test_setRoots_nested_excludedByOuter_deep() {
String a = '/a';
String c = '$a/b/c';
String aPubspec = '$a/pubspec.yaml';
String cPubspec = '$c/pubspec.yaml';
// create files
resourceProvider.newFile(aPubspec, 'name: aaa');
resourceProvider.newFile(cPubspec, 'name: ccc');
newFile(
[a, optionsFileName],
r'''
analyzer:
exclude:
- 'b**'
''');
manager.setRoots(<String>[a, c], <String>[], <String, String>{});
// verify
{
ContextInfo rootInfo = manager.rootInfo;
expect(rootInfo.children, hasLength(1));
{
ContextInfo aInfo = rootInfo.children[0];
expect(aInfo.folder.path, a);
expect(aInfo.children, hasLength(1));
{
ContextInfo cInfo = aInfo.children[0];
expect(cInfo.folder.path, c);
expect(cInfo.children, isEmpty);
}
}
}
expect(callbacks.currentContextRoots, hasLength(2));
expect(callbacks.currentContextRoots, unorderedEquals([a, c]));
}
test_strong_mode_analysis_option() async {
// Create files.
newFile(
[projPath, optionsFileName],
r'''
analyzer:
strong-mode: true
''');
String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
newFile([libPath, 'main.dart']);
// Setup context.
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
// Verify that analysis options was parsed and strong-mode set.
expect(analysisOptions.strongMode, true);
}
}
class TestContextManagerCallbacks extends ContextManagerCallbacks {
/**
* Source of timestamps stored in [currentContextFilePaths].
*/
int now = 0;
/**
* The analysis context that was created.
*/
AnalysisContext currentContext;
/**
* The analysis driver that was created.
*/
AnalysisDriver currentDriver;
/**
* A table mapping paths to the analysis driver associated with that path.
*/
Map<String, AnalysisDriver> driverMap = <String, AnalysisDriver>{};
/**
* Map from context to the timestamp when the context was created.
*/
Map<String, int> currentContextTimestamps = <String, int>{};
/**
* Map from context to (map from file path to timestamp of last event).
*/
final Map<String, Map<String, int>> currentContextFilePaths =
<String, Map<String, int>>{};
/**
* A map from the paths of contexts to a set of the sources that should be
* explicitly analyzed in those contexts.
*/
final Map<String, Set<Source>> currentContextSources =
<String, Set<Source>>{};
/**
* Resource provider used for this test.
*/
final ResourceProvider resourceProvider;
/**
* The manager managing the SDKs.
*/
final DartSdkManager sdkManager;
/**
* The logger used by the scheduler and the driver.
*/
final PerformanceLog logger;
/**
* The scheduler used by the driver.
*/
final AnalysisDriverScheduler scheduler;
/**
* The list of `flushedFiles` in the last [removeContext] invocation.
*/
List<String> lastFlushedFiles;
TestContextManagerCallbacks(
this.resourceProvider, this.sdkManager, this.logger, this.scheduler);
/**
* Return the current set of analysis options.
*/
AnalysisOptions get analysisOptions => currentDriver == null
? currentContext.analysisOptions
: currentDriver.analysisOptions;
/**
* Return the paths to the context roots that currently exist.
*/
Iterable<String> get currentContextRoots {
return currentContextTimestamps.keys;
}
/**
* Return the paths to the files being analyzed in the current context root.
*/
Iterable<String> get currentFilePaths {
if (currentDriver == null) {
if (currentContext == null) {
return <String>[];
}
Map<String, int> fileMap = currentContextFilePaths[currentContext.name];
if (fileMap == null) {
return <String>[];
}
return fileMap.keys;
}
return currentDriver.addedFiles;
}
/**
* Return the current source factory.
*/
SourceFactory get sourceFactory => currentDriver == null
? currentContext.sourceFactory
: currentDriver.sourceFactory;
@override
AnalysisDriver addAnalysisDriver(
Folder folder, ContextRoot contextRoot, AnalysisOptions options) {
String path = folder.path;
expect(currentContextRoots, isNot(contains(path)));
expect(contextRoot, isNotNull);
expect(contextRoot.root, path);
currentContextTimestamps[path] = now;
ContextBuilder builder =
createContextBuilder(folder, options, useSummaries: true);
AnalysisContext context = builder.buildContext(folder.path);
SourceFactory sourceFactory = context.sourceFactory;
AnalysisOptions analysisOptions = context.analysisOptions;
context.dispose();
currentDriver = new AnalysisDriver(
scheduler,
logger,
resourceProvider,
new MemoryByteStore(),
new FileContentOverlay(),
contextRoot,
sourceFactory,
analysisOptions);
driverMap[path] = currentDriver;
currentDriver.exceptions.listen((ExceptionResult result) {
AnalysisEngine.instance.logger
.logError('Analysis failed: ${result.path}', result.exception);
});
return currentDriver;
}
@override
AnalysisContext addContext(Folder folder, AnalysisOptions options) {
String path = folder.path;
expect(currentContextRoots, isNot(contains(path)));
currentContextTimestamps[path] = now;
currentContextFilePaths[path] = <String, int>{};
currentContextSources[path] = new HashSet<Source>();
ContextBuilder builder = createContextBuilder(folder, options);
currentContext = builder.buildContext(path);
currentContext.name = path;
return currentContext;
}
@override
void applyChangesToContext(Folder contextFolder, ChangeSet changeSet) {
AnalysisDriver driver = driverMap[contextFolder.path];
if (driver != null) {
changeSet.addedSources.forEach((source) {
driver.addFile(source.fullName);
});
changeSet.changedSources.forEach((source) {
driver.changeFile(source.fullName);
});
changeSet.removedSources.forEach((source) {
driver.removeFile(source.fullName);
});
} else {
Map<String, int> filePaths = currentContextFilePaths[contextFolder.path];
Set<Source> sources = currentContextSources[contextFolder.path];
for (Source source in changeSet.addedSources) {
expect(filePaths, isNot(contains(source.fullName)));
filePaths[source.fullName] = now;
sources.add(source);
}
for (Source source in changeSet.removedSources) {
expect(filePaths, contains(source.fullName));
filePaths.remove(source.fullName);
sources.remove(source);
}
for (Source source in changeSet.changedSources) {
expect(filePaths, contains(source.fullName));
filePaths[source.fullName] = now;
}
currentContext.applyChanges(changeSet);
}
}
@override
void applyFileRemoved(AnalysisDriver driver, String file) {
driver.removeFile(file);
}
void assertContextFiles(String contextPath, List<String> expectedFiles) {
expect(getCurrentFilePaths(contextPath), unorderedEquals(expectedFiles));
}
void assertContextPaths(List<String> expected) {
expect(currentContextRoots, unorderedEquals(expected));
}
@override
void computingPackageMap(bool computing) {
// Do nothing.
}
@override
ContextBuilder createContextBuilder(Folder folder, AnalysisOptions options,
{bool useSummaries = false}) {
ContextBuilderOptions builderOptions = new ContextBuilderOptions();
builderOptions.defaultOptions = options;
ContextBuilder builder = new ContextBuilder(
resourceProvider, sdkManager, new ContentCache(),
options: builderOptions);
return builder;
}
/**
* Return the paths to the files being analyzed in the current context root.
*/
Iterable<Source> currentFileSources(String contextPath) {
if (currentDriver == null) {
if (currentContext == null) {
return <Source>[];
}
Set<Source> sources = currentContextSources[contextPath];
return sources ?? <Source>[];
}
AnalysisDriver driver = driverMap[contextPath];
SourceFactory sourceFactory = driver.sourceFactory;
return driver.addedFiles.map((String path) {
File file = resourceProvider.getFile(path);
Source source = file.createSource();
Uri uri = sourceFactory.restoreUri(source);
return file.createSource(uri);
});
}
/**
* Return the paths to the files being analyzed in the current context root.
*/
Iterable<String> getCurrentFilePaths(String contextPath) {
if (currentDriver == null) {
if (currentContext == null) {
return <String>[];
}
Map<String, int> fileMap = currentContextFilePaths[contextPath];
if (fileMap == null) {
return <String>[];
}
return fileMap.keys;
}
return driverMap[contextPath].addedFiles;
}
@override
void moveContext(Folder from, Folder to) {
String path = from.path;
String path2 = to.path;
expect(currentContextFilePaths, contains(path));
expect(currentContextTimestamps, contains(path));
expect(currentContextSources, contains(path));
expect(currentContextFilePaths, isNot(contains(path2)));
expect(currentContextTimestamps, isNot(contains(path2)));
expect(currentContextSources, isNot(contains(path2)));
currentContextFilePaths[path2] = currentContextFilePaths.remove(path);
currentContextTimestamps[path2] = currentContextTimestamps.remove(path);
currentContextSources[path2] = currentContextSources.remove(path);
}
@override
void removeContext(Folder folder, List<String> flushedFiles) {
String path = folder.path;
expect(currentContextRoots, contains(path));
currentContextTimestamps.remove(path);
currentContextFilePaths.remove(path);
currentContextSources.remove(path);
lastFlushedFiles = flushedFiles;
}
@override
void updateContextPackageUriResolver(AnalysisContext context) {
// Nothing to do.
}
}
/**
* A [Source] that knows it's [fullName].
*/
class TestSource implements Source {
TestSource();
@override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class TestUriResolver extends UriResolver {
Map<Uri, Source> uriMap;
TestUriResolver(this.uriMap);
@override
Source resolveAbsolute(Uri uri, [Uri actualUri]) {
return uriMap[uri];
}
}