blob: acc22cce95dc8fd6ed09f2f3c41f2797105ecdd4 [file] [log] [blame]
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/pub_summary.dart';
import 'package:analyzer/src/summary/summarize_elements.dart';
import 'package:path/path.dart' as pathos;
import 'package:unittest/unittest.dart' hide ERROR;
import '../../reflective_tests.dart';
import '../../utils.dart';
import '../context/abstract_context.dart';
main() {
initializeTestEnvironment();
runReflectiveTests(PubSummaryManagerTest);
}
@reflectiveTest
class PubSummaryManagerTest extends AbstractContextTest {
static const String CACHE = '/home/.pub-cache/hosted/pub.dartlang.org';
static Map<DartSdk, PackageBundle> sdkBundleMap = <DartSdk, PackageBundle>{};
PubSummaryManager manager;
void setUp() {
super.setUp();
manager = new PubSummaryManager(resourceProvider, '_.temp');
}
test_getLinkedBundles_noCycles() async {
resourceProvider.newFile(
'$CACHE/aaa/lib/a.dart',
'''
class A {}
int a;
''');
resourceProvider.newFile(
'$CACHE/bbb/lib/b.dart',
'''
import 'package:aaa/a.dart';
A b;
''');
// Configure packages resolution.
Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
context.sourceFactory = new SourceFactory(<UriResolver>[
sdkResolver,
resourceResolver,
new PackageMapUriResolver(resourceProvider, {
'aaa': [libFolderA],
'bbb': [libFolderB],
})
]);
// Ensure unlinked bundles.
manager.getUnlinkedBundles(context);
await manager.onUnlinkedComplete;
// Now we should be able to get linked bundles.
PackageBundle sdkBundle = getSdkBundle(sdk);
List<LinkedPubPackage> linkedPackages =
manager.getLinkedBundles(context, sdkBundle);
expect(linkedPackages, hasLength(2));
// package:aaa
{
LinkedPubPackage linkedPackage = linkedPackages
.singleWhere((linkedPackage) => linkedPackage.package.name == 'aaa');
PackageBundle unlinked = linkedPackage.unlinked;
PackageBundle linked = linkedPackage.linked;
expect(unlinked, isNotNull);
expect(linked, isNotNull);
expect(unlinked.unlinkedUnitUris, ['package:aaa/a.dart']);
expect(linked.linkedLibraryUris, ['package:aaa/a.dart']);
// Prepare linked `package:aaa/a.dart`.
UnlinkedUnit unlinkedUnitA = unlinked.unlinkedUnits[0];
LinkedLibrary linkedLibraryA = linked.linkedLibraries[0];
LinkedUnit linkedUnitA = linkedLibraryA.units[0];
// int a;
{
UnlinkedVariable a = unlinkedUnitA.variables[0];
expect(a.name, 'a');
_assertLinkedNameReference(unlinkedUnitA, linkedLibraryA, linkedUnitA,
a.type.reference, 'int', 'dart:core');
}
}
// package:bbb
{
LinkedPubPackage linkedPackage = linkedPackages
.singleWhere((linkedPackage) => linkedPackage.package.name == 'bbb');
PackageBundle unlinked = linkedPackage.unlinked;
PackageBundle linked = linkedPackage.linked;
expect(unlinked, isNotNull);
expect(linked, isNotNull);
expect(unlinked.unlinkedUnitUris, ['package:bbb/b.dart']);
expect(linked.linkedLibraryUris, ['package:bbb/b.dart']);
// Prepare linked `package:bbb/b.dart`.
UnlinkedUnit unlinkedUnit = unlinked.unlinkedUnits[0];
LinkedLibrary linkedLibrary = linked.linkedLibraries[0];
LinkedUnit linkedUnit = linkedLibrary.units[0];
// A b;
{
UnlinkedVariable b = unlinkedUnit.variables[0];
expect(b.name, 'b');
_assertLinkedNameReference(unlinkedUnit, linkedLibrary, linkedUnit,
b.type.reference, 'A', 'package:aaa/a.dart');
}
}
}
test_getUnlinkedBundles() async {
// Create package files.
resourceProvider.newFile(
'$CACHE/aaa/lib/a.dart',
'''
class A {}
''');
resourceProvider.newFile(
'$CACHE/aaa/lib/src/a2.dart',
'''
class A2 {}
''');
resourceProvider.newFile(
'$CACHE/bbb/lib/b.dart',
'''
class B {}
''');
// Configure packages resolution.
Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
context.sourceFactory = new SourceFactory(<UriResolver>[
sdkResolver,
resourceResolver,
new PackageMapUriResolver(resourceProvider, {
'aaa': [libFolderA],
'bbb': [libFolderB],
})
]);
// No unlinked bundles yet.
{
Map<PubPackage, PackageBundle> bundles =
manager.getUnlinkedBundles(context);
expect(bundles, isEmpty);
}
// The requested unlinked bundles must be available after the wait.
await manager.onUnlinkedComplete;
{
Map<PubPackage, PackageBundle> bundles =
manager.getUnlinkedBundles(context);
expect(bundles, hasLength(2));
{
PackageBundle bundle = _getBundleByPackageName(bundles, 'aaa');
expect(bundle.linkedLibraryUris, isEmpty);
expect(bundle.unlinkedUnitUris,
['package:aaa/a.dart', 'package:aaa/src/a2.dart']);
expect(bundle.unlinkedUnits, hasLength(2));
expect(bundle.unlinkedUnits[0].classes.map((c) => c.name), ['A']);
expect(bundle.unlinkedUnits[1].classes.map((c) => c.name), ['A2']);
}
{
PackageBundle bundle = _getBundleByPackageName(bundles, 'bbb');
expect(bundle.linkedLibraryUris, isEmpty);
expect(bundle.unlinkedUnitUris, ['package:bbb/b.dart']);
expect(bundle.unlinkedUnits, hasLength(1));
expect(bundle.unlinkedUnits[0].classes.map((c) => c.name), ['B']);
}
}
// The files must be created.
File fileA = libFolderA.parent.getChildAssumingFile('unlinked.ds');
File fileB = libFolderB.parent.getChildAssumingFile('unlinked.ds');
expect(fileA.exists, isTrue);
expect(fileB.exists, isTrue);
}
test_getUnlinkedBundles_nullPackageMap() async {
context.sourceFactory =
new SourceFactory(<UriResolver>[sdkResolver, resourceResolver]);
Map<PubPackage, PackageBundle> bundles =
manager.getUnlinkedBundles(context);
expect(bundles, isEmpty);
}
test_isPathInPubCache_posix() {
expect(
PubSummaryManager.isPathInPubCache(pathos.posix,
'/home/.pub-cache/hosted/pub.dartlang.org/foo/lib/bar.dart'),
isTrue);
expect(
PubSummaryManager.isPathInPubCache(
pathos.posix, '/home/.pub-cache/foo/lib/bar.dart'),
isTrue);
expect(
PubSummaryManager.isPathInPubCache(
pathos.posix, '/home/sources/dart/foo/lib/bar.dart'),
isFalse);
}
test_isPathInPubCache_windows() {
expect(
PubSummaryManager.isPathInPubCache(pathos.windows,
r'C:\Users\user\Setters\Pub\Cache\hosted\foo\lib\bar.dart'),
isTrue);
expect(
PubSummaryManager.isPathInPubCache(
pathos.windows, r'C:\Users\user\Sources\Dart\foo\lib\bar.dart'),
isFalse);
}
void _assertLinkedNameReference(
UnlinkedUnit unlinkedUnit,
LinkedLibrary linkedLibrary,
LinkedUnit linkedUnit,
int typeNameReference,
String expectedName,
String expectedDependencyUri) {
expect(unlinkedUnit.references[typeNameReference].name, expectedName);
int typeNameDependency =
linkedUnit.references[typeNameReference].dependency;
expect(linkedLibrary.dependencies[typeNameDependency].uri,
expectedDependencyUri);
}
/**
* Compute element based summary bundle for the given [sdk].
*/
static PackageBundle getSdkBundle(DartSdk sdk) {
return sdkBundleMap.putIfAbsent(sdk, () {
PackageBundleAssembler assembler = new PackageBundleAssembler();
for (SdkLibrary sdkLibrary in sdk.sdkLibraries) {
String uriStr = sdkLibrary.shortName;
Source source = sdk.mapDartUri(uriStr);
LibraryElement libraryElement =
sdk.context.computeLibraryElement(source);
assembler.serializeLibraryElement(libraryElement);
}
List<int> bytes = assembler.assemble().toBuffer();
return new PackageBundle.fromBuffer(bytes);
});
}
static PackageBundle _getBundleByPackageName(
Map<PubPackage, PackageBundle> bundles, String name) {
PubPackage package =
bundles.keys.singleWhere((package) => package.name == name);
return bundles[package];
}
}