Add PubWorkspace, integrate it into ContextBuilder, and therefore fix sealed test
Also add a superclass to BasicWorkspace and PubWorkspace, since the bulk of their
implementation is shared; Only find() and findPackageFor() need to be separate;
the package mapping and resolving can be shared.
Change-Id: I13932d6947d6dc28fc7223594e5bd2526f12f573
Reviewed-on: https://dart-review.googlesource.com/c/89167
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart
index 5e2a359..960c862 100644
--- a/pkg/analyzer/lib/src/context/builder.dart
+++ b/pkg/analyzer/lib/src/context/builder.dart
@@ -40,6 +40,7 @@
import 'package:analyzer/src/workspace/bazel.dart';
import 'package:analyzer/src/workspace/gn.dart';
import 'package:analyzer/src/workspace/package_build.dart';
+import 'package:analyzer/src/workspace/pub.dart';
import 'package:analyzer/src/workspace/workspace.dart';
import 'package:args/args.dart';
import 'package:package_config/packages.dart';
@@ -672,16 +673,19 @@
static Workspace createWorkspace(ResourceProvider resourceProvider,
String rootPath, ContextBuilder contextBuilder) {
if (_hasPackageFileInPath(resourceProvider, rootPath)) {
- // Bazel workspaces that include package files are treated like normal
- // (non-Bazel) directories. But may still use package:build.
+ // A Bazel or Gn workspace that includes a '.packages' file is treated
+ // like a normal (non-Bazel/Gn) directory. But may still use
+ // package:build or Pub.
return PackageBuildWorkspace.find(
resourceProvider, rootPath, contextBuilder) ??
+ PubWorkspace.find(resourceProvider, rootPath, contextBuilder) ??
BasicWorkspace.find(resourceProvider, rootPath, contextBuilder);
}
Workspace workspace = BazelWorkspace.find(resourceProvider, rootPath);
workspace ??= GnWorkspace.find(resourceProvider, rootPath);
workspace ??=
PackageBuildWorkspace.find(resourceProvider, rootPath, contextBuilder);
+ workspace ??= PubWorkspace.find(resourceProvider, rootPath, contextBuilder);
return workspace ??
BasicWorkspace.find(resourceProvider, rootPath, contextBuilder);
}
diff --git a/pkg/analyzer/lib/src/workspace/basic.dart b/pkg/analyzer/lib/src/workspace/basic.dart
index e8784cc..89b270f 100644
--- a/pkg/analyzer/lib/src/workspace/basic.dart
+++ b/pkg/analyzer/lib/src/workspace/basic.dart
@@ -8,6 +8,7 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/workspace/simple.dart';
import 'package:analyzer/src/workspace/workspace.dart';
import 'package:package_config/packages.dart';
@@ -16,23 +17,7 @@
*
* A BasicWorkspace should only be used when no other workspace type is valid.
*/
-class BasicWorkspace extends Workspace {
- /**
- * The [ResourceProvider] by which paths are converted into [Resource]s.
- */
- final ResourceProvider provider;
-
- /**
- * The absolute workspace root path.
- */
- final String root;
-
- final ContextBuilder _builder;
-
- Map<String, List<Folder>> _packageMap;
-
- Packages _packages;
-
+class BasicWorkspace extends SimpleWorkspace {
/**
* The singular package in this workspace.
*
@@ -40,37 +25,9 @@
*/
BasicWorkspacePackage _theOnlyPackage;
- BasicWorkspace._(this.provider, this.root, this._builder);
-
- @override
- Map<String, List<Folder>> get packageMap {
- _packageMap ??= _builder.convertPackagesToMap(packages);
- return _packageMap;
- }
-
- Packages get packages {
- _packages ??= _builder.createPackageMap(root);
- return _packages;
- }
-
- @override
- UriResolver get packageUriResolver =>
- new PackageMapUriResolver(provider, packageMap);
-
- @override
- SourceFactory createSourceFactory(DartSdk sdk, SummaryDataStore summaryData) {
- if (summaryData != null) {
- throw new UnsupportedError(
- 'Summary files are not supported in a basic workspace.');
- }
- List<UriResolver> resolvers = <UriResolver>[];
- if (sdk != null) {
- resolvers.add(new DartUriResolver(sdk));
- }
- resolvers.add(packageUriResolver);
- resolvers.add(new ResourceUriResolver(provider));
- return new SourceFactory(resolvers, packages, provider);
- }
+ BasicWorkspace._(
+ ResourceProvider provider, String root, ContextBuilder builder)
+ : super(provider, root, builder);
@override
WorkspacePackage findPackageFor(String filePath) {
diff --git a/pkg/analyzer/lib/src/workspace/bazel.dart b/pkg/analyzer/lib/src/workspace/bazel.dart
index d4a83b9c..5e90c71 100644
--- a/pkg/analyzer/lib/src/workspace/bazel.dart
+++ b/pkg/analyzer/lib/src/workspace/bazel.dart
@@ -287,11 +287,12 @@
/**
* Find the Bazel workspace that contains the given [filePath].
*
- * Return `null` if a workspace markers, such as the `WORKSPACE` file, or
+ * Return `null` if a workspace marker, such as the `WORKSPACE` file, or
* the sibling `READONLY` folder cannot be found.
*
* Return `null` if the workspace does not have `bazel-genfiles` or
- * `blaze-genfiles` folders, so we don't know where to search generated files.
+ * `blaze-genfiles` folders, since we don't know where to search generated
+ * files.
*
* Return `null` if there is a folder 'foo' with the sibling `READONLY`
* folder, but there is corresponding folder 'foo' in `READONLY`, i.e. the
diff --git a/pkg/analyzer/lib/src/workspace/gn.dart b/pkg/analyzer/lib/src/workspace/gn.dart
index 77ef5e8..191c421 100644
--- a/pkg/analyzer/lib/src/workspace/gn.dart
+++ b/pkg/analyzer/lib/src/workspace/gn.dart
@@ -198,6 +198,10 @@
* file must be found in [filePath]'s output directory.
*/
static GnWorkspace find(ResourceProvider provider, String filePath) {
+ Resource resource = provider.getResource(filePath);
+ if (resource is File) {
+ filePath = resource.parent.path;
+ }
Folder folder = provider.getFolder(filePath);
while (true) {
Folder parent = folder.parent;
diff --git a/pkg/analyzer/lib/src/workspace/pub.dart b/pkg/analyzer/lib/src/workspace/pub.dart
new file mode 100644
index 0000000..f89937c
--- /dev/null
+++ b/pkg/analyzer/lib/src/workspace/pub.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/context/builder.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/workspace/simple.dart';
+import 'package:analyzer/src/workspace/workspace.dart';
+import 'package:package_config/packages.dart';
+
+/// Information about a Pub workspace.
+class PubWorkspace extends SimpleWorkspace {
+ /// The name of the file that identifies the root of the workspace.
+ static const String _pubspecName = 'pubspec.yaml';
+
+ /// The singular package in this workspace.
+ ///
+ /// Each Pub workspace is itself one package.
+ PubWorkspacePackage _theOnlyPackage;
+
+ PubWorkspace._(ResourceProvider provider, String root, ContextBuilder builder)
+ : super(provider, root, builder);
+
+ @override
+ WorkspacePackage findPackageFor(String filePath) {
+ final Folder folder = provider.getFolder(filePath);
+ if (provider.pathContext.isWithin(root, folder.path)) {
+ _theOnlyPackage ??= new PubWorkspacePackage(root, this);
+ return _theOnlyPackage;
+ } else {
+ return null;
+ }
+ }
+
+ /// Find the pub workspace that contains the given [path].
+ static PubWorkspace find(
+ ResourceProvider provider, String filePath, ContextBuilder builder) {
+ Resource resource = provider.getResource(filePath);
+ if (resource is File) {
+ filePath = resource.parent.path;
+ }
+ Folder folder = provider.getFolder(filePath);
+ while (true) {
+ Folder parent = folder.parent;
+ if (parent == null) {
+ return null;
+ }
+
+ if (folder.getChildAssumingFile(_pubspecName).exists) {
+ // Found the pubspec.yaml file; this is our root.
+ String root = folder.path;
+ return new PubWorkspace._(provider, root, builder);
+ }
+
+ // Go up a folder.
+ folder = parent;
+ }
+ }
+}
+
+/// Information about a package defined in a [PubWorkspace].
+///
+/// Separate from [Packages] or package maps, this class is designed to simply
+/// understand whether arbitrary file paths represent libraries declared within
+/// a given package in a [PubWorkspace].
+class PubWorkspacePackage extends WorkspacePackage {
+ final String root;
+
+ final PubWorkspace workspace;
+
+ PubWorkspacePackage(this.root, this.workspace);
+
+ @override
+ bool contains(String path) {
+ // There is a 1-1 relationship between [PubWorkspace]s and
+ // [PubWorkspacePackage]s. If a file is in a package's workspace, then it
+ // is in the package as well.
+ return workspace.provider.pathContext.isWithin(root, path);
+ }
+}
diff --git a/pkg/analyzer/lib/src/workspace/simple.dart b/pkg/analyzer/lib/src/workspace/simple.dart
new file mode 100644
index 0000000..c2d0d8e
--- /dev/null
+++ b/pkg/analyzer/lib/src/workspace/simple.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/context/builder.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/workspace/workspace.dart';
+import 'package:package_config/packages.dart';
+
+/// An abstract class for simple workspaces which do not feature any build
+/// artifacts or generated files.
+///
+/// The [packageMap] and [packageUrlResolver] are simple derivations from the
+/// [ContextBuilder] and [ResourceProvider] required for the class.
+abstract class SimpleWorkspace extends Workspace {
+ /// The [ResourceProvider] by which paths are converted into [Resource]s.
+ final ResourceProvider provider;
+
+ /// The absolute workspace root path.
+ final String root;
+
+ final ContextBuilder _builder;
+
+ Map<String, List<Folder>> _packageMap;
+
+ Packages _packages;
+
+ SimpleWorkspace(this.provider, this.root, this._builder);
+
+ @override
+ Map<String, List<Folder>> get packageMap {
+ _packageMap ??= _builder.convertPackagesToMap(packages);
+ return _packageMap;
+ }
+
+ Packages get packages {
+ _packages ??= _builder.createPackageMap(root);
+ return _packages;
+ }
+
+ @override
+ UriResolver get packageUriResolver =>
+ new PackageMapUriResolver(provider, packageMap);
+
+ @override
+ SourceFactory createSourceFactory(DartSdk sdk, SummaryDataStore summaryData) {
+ if (summaryData != null) {
+ throw new UnsupportedError(
+ 'Summary files are not supported in a Pub workspace.');
+ }
+ List<UriResolver> resolvers = <UriResolver>[];
+ if (sdk != null) {
+ resolvers.add(new DartUriResolver(sdk));
+ }
+ resolvers.add(packageUriResolver);
+ resolvers.add(new ResourceUriResolver(provider));
+ return new SourceFactory(resolvers, packages, provider);
+ }
+}
diff --git a/pkg/analyzer/test/generated/hint_code_test.dart b/pkg/analyzer/test/generated/hint_code_test.dart
index 47bdb3a..e33ea7d 100644
--- a/pkg/analyzer/test/generated/hint_code_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_test.dart
@@ -68,11 +68,8 @@
@reflectiveTest
class CrossPackageHintCodeTest extends ResolverTestCase {
- /// Write a pubspec file at [root], so that BestPracticesVerifier can see that
- /// [root] is the root of a BasicWorkspace, and a BasicWorkspacePackage.
- void newBasicPackage(String root) {
- newFile('$root/pubspec.yaml');
- }
+ @override
+ bool get enableNewAnalysisDriver => true;
test_subtypeOfSealedClass_extending() async {
super.resetWith(packages: [
@@ -86,7 +83,7 @@
]
]);
- newBasicPackage('/pkg1');
+ _newPubPackageRoot('/pkg1');
Source source = addNamedSource('/pkg1/lib/lib1.dart', r'''
import 'package:foo/foo.dart';
class Bar extends Foo {}
@@ -108,7 +105,7 @@
]
]);
- newBasicPackage('/pkg1');
+ _newPubPackageRoot('/pkg1');
Source source = addNamedSource('/pkg1/lib/lib1.dart', r'''
import 'package:foo/foo.dart';
class Bar implements Foo {}
@@ -130,7 +127,7 @@
]
]);
- newBasicPackage('/pkg1');
+ _newPubPackageRoot('/pkg1');
Source source = addNamedSource('/pkg1/lib/lib1.dart', r'''
import 'package:foo/foo.dart';
class Bar1 {}
@@ -153,7 +150,7 @@
]
]);
- newBasicPackage('/pkg1');
+ _newPubPackageRoot('/pkg1');
Source source = addNamedSource('/pkg1/lib/lib1.dart', r'''
import 'package:foo/foo.dart';
mixin Bar implements Foo {}
@@ -175,7 +172,7 @@
]
]);
- newBasicPackage('/pkg1');
+ _newPubPackageRoot('/pkg1');
Source source = addNamedSource('/pkg1/lib/lib1.dart', r'''
import 'package:foo/foo.dart';
mixin Bar on Foo {}
@@ -197,7 +194,7 @@
]
]);
- newBasicPackage('/pkg1');
+ _newPubPackageRoot('/pkg1');
Source source = addNamedSource('/pkg1/lib/lib1.dart', r'''
import 'package:foo/foo.dart';
class Bar extends Object with Foo {}
@@ -212,7 +209,7 @@
['meta', metaLibraryStub],
]);
- newBasicPackage('/pkg1');
+ _newPubPackageRoot('/pkg1');
Source source = addNamedSource('/pkg1/lib/lib1.dart', r'''
import 'package:meta/meta.dart';
@sealed class Foo {}
@@ -233,12 +230,13 @@
['meta', metaLibraryStub],
]);
- newBasicPackage('/pkg1');
+ _newPubPackageRoot('/pkg1');
Source source1 = addNamedSource('/pkg1/lib/lib1.dart', r'''
import 'package:meta/meta.dart';
@sealed class Foo {}
''');
- addNamedSource('/pkg1/lib/src/lib2.dart', r'''
+ Source source2 = addNamedSource('/pkg1/lib/src/lib2.dart', r'''
+ import '../lib1.dart';
class Bar1 extends Foo {}
class Bar2 implements Foo {}
class Bar4 = Bar1 with Foo;
@@ -246,8 +244,10 @@
mixin Bar6 implements Foo {}
''');
await computeAnalysisResult(source1);
+ await computeAnalysisResult(source2);
assertNoErrors(source1);
- verify([source1]);
+ assertNoErrors(source2);
+ verify([source1, source2]);
}
test_subtypeOfSealedClass_withinPackageTestDirectory_OK() async {
@@ -255,12 +255,15 @@
['meta', metaLibraryStub],
]);
- newBasicPackage('/pkg1');
+ newFolder('/pkg1');
+ _newPubPackageRoot('/pkg1');
+
Source source1 = addNamedSource('/pkg1/lib/lib1.dart', r'''
import 'package:meta/meta.dart';
@sealed class Foo {}
''');
- addNamedSource('/pkg1/test/test.dart', r'''
+ Source source2 = addNamedSource('/pkg1/test/test.dart', r'''
+ import '../lib/lib1.dart';
class Bar1 extends Foo {}
class Bar2 implements Foo {}
class Bar4 = Bar1 with Foo;
@@ -268,8 +271,10 @@
mixin Bar6 implements Foo {}
''');
await computeAnalysisResult(source1);
+ await computeAnalysisResult(source2);
assertNoErrors(source1);
- verify([source1]);
+ assertNoErrors(source2);
+ verify([source1, source2]);
}
test_subtypeOfSealedClass_withinPart_OK() async {
@@ -277,7 +282,7 @@
['meta', metaLibraryStub],
]);
- newBasicPackage('/pkg1');
+ _newPubPackageRoot('/pkg1');
Source source1 = addNamedSource('/pkg1/lib/lib1.dart', r'''
import 'package:meta/meta.dart';
part 'part1.dart';
@@ -308,7 +313,7 @@
]
]);
- newBasicPackage('/pkg1');
+ _newPubPackageRoot('/pkg1');
Source source = addNamedSource('/pkg1/lib/lib1.dart', r'''
import 'package:foo/foo.dart';
class Bar1 {}
@@ -331,7 +336,7 @@
]
]);
- newBasicPackage('/pkg1');
+ _newPubPackageRoot('/pkg1');
Source source = addNamedSource('/pkg1/lib/lib1.dart', r'''
import 'package:foo/foo.dart';
class Bar extends Object with Foo {}
@@ -340,6 +345,12 @@
assertErrors(source, [HintCode.SUBTYPE_OF_SEALED_CLASS]);
verify([source]);
}
+
+ /// Write a pubspec file at [root], so that BestPracticesVerifier can see
+ /// that [root] is the root of a PubWorkspace, and a PubWorkspacePackage.
+ void _newPubPackageRoot(String root) {
+ newFile('$root/pubspec.yaml');
+ }
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index 3594512..23e564e 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -17,7 +17,12 @@
import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:analyzer/src/workspace/basic.dart';
import 'package:analyzer/src/workspace/bazel.dart';
+import 'package:analyzer/src/workspace/gn.dart';
+import 'package:analyzer/src/workspace/package_build.dart';
+import 'package:analyzer/src/workspace/pub.dart';
+import 'package:analyzer/src/workspace/workspace.dart';
import 'package:args/args.dart';
import 'package:package_config/packages.dart';
import 'package:package_config/src/packages_impl.dart';
@@ -872,6 +877,68 @@
expect(result.path, filePath);
}
+ void test_createWorkspace_hasPackagesFile_hasDartToolAndPubspec() {
+ newFile('/workspace/.packages');
+ newFolder('/workspace/.dart_tool/build/generated/project/lib');
+ newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
+ Workspace workspace = ContextBuilder.createWorkspace(
+ resourceProvider, '/workspace/project/lib/lib.dart', builder);
+ expect(workspace, TypeMatcher<PackageBuildWorkspace>());
+ }
+
+ void test_createWorkspace_hasPackagesFile_hasPubspec() {
+ newFile('/workspace/.packages');
+ newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
+ Workspace workspace = ContextBuilder.createWorkspace(
+ resourceProvider, '/workspace/project/lib/lib.dart', builder);
+ expect(workspace, TypeMatcher<PubWorkspace>());
+ }
+
+ void test_createWorkspace_hasPackagesFile_noMarkerFiles() {
+ newFile('/workspace/.packages');
+ Workspace workspace = ContextBuilder.createWorkspace(
+ resourceProvider, '/workspace/project/lib/lib.dart', builder);
+ expect(workspace, TypeMatcher<BasicWorkspace>());
+ }
+
+ void test_createWorkspace_noPackagesFile_hasDartToolAndPubspec() {
+ newFolder('/workspace/.dart_tool/build/generated/project/lib');
+ newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
+ Workspace workspace = ContextBuilder.createWorkspace(
+ resourceProvider, '/workspace/project/lib/lib.dart', builder);
+ expect(workspace, TypeMatcher<PackageBuildWorkspace>());
+ }
+
+ void test_createWorkspace_noPackagesFile_hasPubspec() {
+ newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
+ Workspace workspace = ContextBuilder.createWorkspace(
+ resourceProvider, '/workspace/project/lib/lib.dart', builder);
+ expect(workspace, TypeMatcher<PubWorkspace>());
+ }
+
+ void test_createWorkspace_noPackagesFile_noMarkerFiles() {
+ Workspace workspace = ContextBuilder.createWorkspace(
+ resourceProvider, '/workspace/project/lib/lib.dart', builder);
+ expect(workspace, TypeMatcher<BasicWorkspace>());
+ }
+
+ void test_createWorkspace_noPackagesFile_hasGnMarkerFiles() {
+ newFolder('/workspace/.jiri_root');
+ newFile(
+ '/workspace/out/debug-x87_128/dartlang/gen/project/lib/lib.packages');
+ Workspace workspace = ContextBuilder.createWorkspace(
+ resourceProvider, '/workspace/project/lib/lib.dart', builder);
+ expect(workspace, TypeMatcher<GnWorkspace>());
+ }
+
+ void test_createWorkspace_noPackagesFile_hasBazelMarkerFiles() {
+ newFile('/workspace/WORKSPACE');
+ newFolder('/workspace/bazel-genfiles');
+ Workspace workspace = ContextBuilder.createWorkspace(
+ resourceProvider, '/workspace/project/lib/lib.dart', builder);
+ expect(workspace, TypeMatcher<BazelWorkspace>());
+ }
+
_defineMockLintRules() {
_mockLintRule = new _MockLintRule('mock_lint_rule');
Registry.ruleRegistry.registerDefault(_mockLintRule);
diff --git a/pkg/analyzer/test/src/workspace/gn_test.dart b/pkg/analyzer/test/src/workspace/gn_test.dart
index bc75f28..8cd0a5b 100644
--- a/pkg/analyzer/test/src/workspace/gn_test.dart
+++ b/pkg/analyzer/test/src/workspace/gn_test.dart
@@ -182,6 +182,7 @@
newFile('/ws/.config',
content: 'FOO=foo\n' + 'FUCHSIA_BUILD_DIR="$buildDir"\n' + 'BAR=bar\n');
newFile('/ws/out/debug-x87_128/dartlang/gen/some/code/foo.packages');
+ newFolder('/ws/some/code');
return GnWorkspace.find(resourceProvider, convertPath('/ws/some/code'));
}
diff --git a/pkg/analyzer/test/src/workspace/pub_test.dart b/pkg/analyzer/test/src/workspace/pub_test.dart
new file mode 100644
index 0000000..48d88d6
--- /dev/null
+++ b/pkg/analyzer/test/src/workspace/pub_test.dart
@@ -0,0 +1,119 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/context/builder.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:analyzer/src/workspace/pub.dart';
+import 'package:package_config/packages.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(PubWorkspacePackageTest);
+ defineReflectiveTests(PubWorkspaceTest);
+ });
+}
+
+class MockContextBuilder implements ContextBuilder {
+ Map<String, Packages> packagesMapMap = <String, Packages>{};
+ Map<Packages, Map<String, List<Folder>>> packagesToMapMap =
+ <Packages, Map<String, List<Folder>>>{};
+
+ Map<String, List<Folder>> convertPackagesToMap(Packages packages) =>
+ packagesToMapMap[packages];
+
+ Packages createPackageMap(String rootDirectoryPath) =>
+ packagesMapMap[rootDirectoryPath];
+
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+class MockPackages implements Packages {
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+@reflectiveTest
+class PubWorkspacePackageTest with ResourceProviderMixin {
+ PubWorkspace workspace;
+
+ setUp() {
+ final contextBuilder = new MockContextBuilder();
+ final packages = new MockPackages();
+ final packageMap = <String, List<Folder>>{'project': []};
+ contextBuilder.packagesMapMap[convertPath('/workspace')] = packages;
+ contextBuilder.packagesToMapMap[packages] = packageMap;
+
+ newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
+ workspace = PubWorkspace.find(
+ resourceProvider, convertPath('/workspace'), contextBuilder);
+ }
+
+ void test_findPackageFor_unrelatedFile() {
+ newFile('/workspace/project/lib/file.dart');
+
+ var package = workspace
+ .findPackageFor(convertPath('/workspace2/project/lib/file.dart'));
+ expect(package, isNull);
+ }
+
+ void test_findPackageFor_includedFile() {
+ newFile('/workspace/project/lib/file.dart');
+
+ var package = workspace
+ .findPackageFor(convertPath('/workspace/project/lib/file.dart'));
+ expect(package, isNotNull);
+ expect(package.root, convertPath('/workspace'));
+ expect(package.workspace, equals(workspace));
+ }
+
+ void test_contains_differentWorkspace() {
+ newFile('/workspace2/project/lib/file.dart');
+
+ var package = workspace
+ .findPackageFor(convertPath('/workspace/project/lib/code.dart'));
+ expect(package.contains('/workspace2/project/lib/file.dart'), isFalse);
+ }
+
+ void test_contains_sameWorkspace() {
+ newFile('/workspace/project/lib/file2.dart');
+
+ var package = workspace
+ .findPackageFor(convertPath('/workspace/project/lib/code.dart'));
+ expect(package.contains('/workspace/project/lib/file2.dart'), isTrue);
+ expect(package.contains('/workspace/project/bin/bin.dart'), isTrue);
+ expect(package.contains('/workspace/project/test/test.dart'), isTrue);
+ }
+}
+
+@reflectiveTest
+class PubWorkspaceTest with ResourceProviderMixin {
+ void test_find_fail_notAbsolute() {
+ expect(
+ () => PubWorkspace.find(resourceProvider, convertPath('not_absolute'),
+ new MockContextBuilder()),
+ throwsA(TypeMatcher<ArgumentError>()));
+ }
+
+ void test_find_missingPubspec() {
+ PubWorkspace workspace = PubWorkspace.find(resourceProvider,
+ convertPath('/workspace/lib/lib1.dart'), new MockContextBuilder());
+ expect(workspace, isNull);
+ }
+
+ void test_find_directory() {
+ newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
+ PubWorkspace workspace = PubWorkspace.find(
+ resourceProvider, convertPath('/workspace'), new MockContextBuilder());
+ expect(workspace.root, convertPath('/workspace'));
+ }
+
+ void test_find_file() {
+ newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
+ PubWorkspace workspace = PubWorkspace.find(resourceProvider,
+ convertPath('/workspace/lib/lib1.dart'), new MockContextBuilder());
+ expect(workspace.root, convertPath('/workspace'));
+ }
+}