6fe8e2278b
If the package is know, we return the corresponding file, whether it exists or not. If the package is not know, there is no valid Source to resolve to, so we return null. We don't need all the features that existed. Internally we switched to BazelPackageUriResolver, which has its own logica for searching files in workspaces across multiple folders. All the places where we create PackageMapUriResolver in analyzer or analysis_server, we create it with exactly one folder. R=brianwilkerson@google.com BUG= Review-Url: https://codereview.chromium.org/2812093002 .
2909 lines
103 KiB
Dart
2909 lines
103 KiB
Dart
// 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];
|
|
}
|
|
}
|