cb4a19b5fc
Change-Id: I42a5c41394226f6ddc9c0608c6d688ae683ffdea Reviewed-on: https://dart-review.googlesource.com/62680 Commit-Queue: Kevin Moore <kevmoo@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
363 lines
13 KiB
Dart
363 lines
13 KiB
Dart
// Copyright (c) 2015, 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 'dart:convert';
|
|
|
|
import 'package:analyzer/file_system/file_system.dart';
|
|
import 'package:analyzer/file_system/memory_file_system.dart';
|
|
import 'package:analyzer/src/file_system/file_system.dart';
|
|
import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine, Logger;
|
|
import 'package:analyzer/src/generated/source.dart';
|
|
import 'package:analyzer/src/generated/source_io.dart';
|
|
import 'package:analyzer/src/generated/utilities_dart.dart' as utils;
|
|
import 'package:analyzer/src/source/package_map_resolver.dart';
|
|
import 'package:analyzer/src/source/source_resource.dart';
|
|
import 'package:package_config/packages.dart';
|
|
import 'package:package_config/packages_file.dart' as pkgfile show parse;
|
|
import 'package:package_config/src/packages_impl.dart';
|
|
import 'package:path/path.dart' as pathos;
|
|
import 'package:test/test.dart';
|
|
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
|
|
|
import 'test_support.dart';
|
|
|
|
main() {
|
|
runPackageMapTests();
|
|
defineReflectiveSuite(() {
|
|
defineReflectiveTests(SourceFactoryTest);
|
|
});
|
|
}
|
|
|
|
Source createSource({String path, String uri}) =>
|
|
//TODO(pquitslund): find some way to pass an actual URI into source creation
|
|
new MemoryResourceProvider()
|
|
.getFile(path)
|
|
.createSource(uri != null ? Uri.parse(uri) : null);
|
|
|
|
void runPackageMapTests() {
|
|
MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
|
|
final Uri baseUri = new Uri.file('test/base');
|
|
final List<UriResolver> testResolvers = [
|
|
new ResourceUriResolver(resourceProvider)
|
|
];
|
|
|
|
Packages createPackageMap(Uri base, String configFileContents) {
|
|
List<int> bytes = utf8.encode(configFileContents);
|
|
Map<String, Uri> map = pkgfile.parse(bytes, base);
|
|
return new MapPackages(map);
|
|
}
|
|
|
|
Map<String, List<Folder>> getPackageMap(String config) {
|
|
Packages packages = createPackageMap(baseUri, config);
|
|
SourceFactory factory = new SourceFactory(testResolvers, packages);
|
|
return factory.packageMap;
|
|
}
|
|
|
|
String resolvePackageUri(
|
|
{String uri,
|
|
String config,
|
|
Source containingSource,
|
|
UriResolver customResolver}) {
|
|
Packages packages = createPackageMap(baseUri, config);
|
|
List<UriResolver> resolvers = testResolvers.toList();
|
|
if (customResolver != null) {
|
|
resolvers.add(customResolver);
|
|
}
|
|
SourceFactory factory = new SourceFactory(resolvers, packages);
|
|
|
|
expect(AnalysisEngine.instance.logger, Logger.NULL);
|
|
var logger = new TestLogger();
|
|
AnalysisEngine.instance.logger = logger;
|
|
try {
|
|
Source source = factory.resolveUri(containingSource, uri);
|
|
expect(logger.log, []);
|
|
return source != null ? source.fullName : null;
|
|
} finally {
|
|
AnalysisEngine.instance.logger = Logger.NULL;
|
|
}
|
|
}
|
|
|
|
Uri restorePackageUri(
|
|
{Source source, String config, UriResolver customResolver}) {
|
|
Packages packages = createPackageMap(baseUri, config);
|
|
List<UriResolver> resolvers = testResolvers.toList();
|
|
if (customResolver != null) {
|
|
resolvers.add(customResolver);
|
|
}
|
|
SourceFactory factory = new SourceFactory(resolvers, packages);
|
|
return factory.restoreUri(source);
|
|
}
|
|
|
|
String _p(String path) => resourceProvider.convertPath(path);
|
|
|
|
Uri _u(String path) => resourceProvider.pathContext.toUri(_p(path));
|
|
|
|
group('SourceFactoryTest', () {
|
|
group('package mapping', () {
|
|
group('resolveUri', () {
|
|
test('URI in mapping', () {
|
|
String uri = resolvePackageUri(config: '''
|
|
unittest:${_u('/home/somebody/.pub/cache/unittest-0.9.9/lib/')}
|
|
async:${_u('/home/somebody/.pub/cache/async-1.1.0/lib/')}
|
|
quiver:${_u('/home/somebody/.pub/cache/quiver-1.2.1/lib')}
|
|
''', uri: 'package:unittest/unittest.dart');
|
|
expect(
|
|
uri,
|
|
equals(_p(
|
|
'/home/somebody/.pub/cache/unittest-0.9.9/lib/unittest.dart')));
|
|
});
|
|
test('URI not in mapping', () {
|
|
String uri = resolvePackageUri(config: '''
|
|
unittest:${_u('/home/somebody/.pub/cache/unittest-0.9.9/lib/')}
|
|
async:${_u('/home/somebody/.pub/cache/async-1.1.0/lib/')}
|
|
quiver:${_u('/home/somebody/.pub/cache/quiver-1.2.1/lib')}
|
|
''', uri: 'package:foo/foo.dart');
|
|
expect(uri, isNull);
|
|
});
|
|
test('Non-package URI', () {
|
|
var testResolver = new CustomUriResolver(uriPath: 'test_uri');
|
|
String uri = resolvePackageUri(config: '''
|
|
unittest:${_u('/home/somebody/.pub/cache/unittest-0.9.9/lib/')}
|
|
''', uri: 'custom:custom.dart', customResolver: testResolver);
|
|
expect(uri, testResolver.uriPath);
|
|
});
|
|
test('Bad package URI', () {
|
|
String uri = resolvePackageUri(config: '', uri: 'package:foo');
|
|
expect(uri, isNull);
|
|
});
|
|
test('Invalid URI', () {
|
|
// TODO(pquitslund): fix clients to handle errors appropriately
|
|
// CLI: print message 'invalid package file format'
|
|
// SERVER: best case tell user somehow and recover...
|
|
expect(
|
|
() => resolvePackageUri(
|
|
config: 'foo:<:&%>', uri: 'package:foo/bar.dart'),
|
|
throwsA(new TypeMatcher<FormatException>()));
|
|
});
|
|
test('Valid URI that cannot be further resolved', () {
|
|
String uri = resolvePackageUri(
|
|
config: 'foo:http://www.google.com', uri: 'package:foo/bar.dart');
|
|
expect(uri, isNull);
|
|
});
|
|
test('Relative URIs', () {
|
|
Source containingSource = createSource(
|
|
path: _p('/foo/bar/baz/foo.dart'), uri: 'package:foo/foo.dart');
|
|
String uri = resolvePackageUri(
|
|
config: 'foo:${_u('/foo/bar/baz')}',
|
|
uri: 'bar.dart',
|
|
containingSource: containingSource);
|
|
expect(uri, isNotNull);
|
|
expect(uri, equals(_p('/foo/bar/baz/bar.dart')));
|
|
});
|
|
});
|
|
group('restoreUri', () {
|
|
test('URI in mapping', () {
|
|
Uri uri = restorePackageUri(
|
|
config: '''
|
|
unittest:${_u('/home/somebody/.pub/cache/unittest-0.9.9/lib/')}
|
|
async:${_u('/home/somebody/.pub/cache/async-1.1.0/lib/')}
|
|
quiver:${_u('/home/somebody/.pub/cache/quiver-1.2.1/lib')}
|
|
''',
|
|
source: new FileSource(resourceProvider.getFile(
|
|
'/home/somebody/.pub/cache/unittest-0.9.9/lib/unittest.dart')));
|
|
expect(uri, isNotNull);
|
|
expect(uri.toString(), equals('package:unittest/unittest.dart'));
|
|
});
|
|
});
|
|
group('packageMap', () {
|
|
test('non-file URIs filtered', () {
|
|
Map<String, List<Folder>> map = getPackageMap('''
|
|
quiver:${_u('/home/somebody/.pub/cache/quiver-1.2.1/lib')}
|
|
foo:http://www.google.com
|
|
''');
|
|
expect(map.keys, unorderedEquals(['quiver']));
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
group('URI utils', () {
|
|
group('URI', () {
|
|
test('startsWith', () {
|
|
expect(utils.startsWith(Uri.parse('/foo/bar/'), Uri.parse('/foo/')),
|
|
isTrue);
|
|
expect(utils.startsWith(Uri.parse('/foo/bar/'), Uri.parse('/foo/bar/')),
|
|
isTrue);
|
|
expect(utils.startsWith(Uri.parse('/foo/bar'), Uri.parse('/foo/b')),
|
|
isFalse);
|
|
// Handle odd URIs (https://github.com/dart-lang/sdk/issues/24126)
|
|
expect(utils.startsWith(Uri.parse('/foo/bar'), Uri.parse('')), isFalse);
|
|
expect(utils.startsWith(Uri.parse(''), Uri.parse('/foo/bar')), isFalse);
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
class AbsoluteUriResolver extends UriResolver {
|
|
final MemoryResourceProvider resourceProvider;
|
|
|
|
AbsoluteUriResolver(this.resourceProvider);
|
|
|
|
@override
|
|
Source resolveAbsolute(Uri uri, [Uri actualUri]) {
|
|
return new FileSource(
|
|
resourceProvider.getFile(resourceProvider.pathContext.fromUri(uri)),
|
|
actualUri);
|
|
}
|
|
}
|
|
|
|
class CustomUriResolver extends UriResolver {
|
|
String uriPath;
|
|
CustomUriResolver({this.uriPath});
|
|
|
|
@override
|
|
Source resolveAbsolute(Uri uri, [Uri actualUri]) =>
|
|
createSource(path: uriPath);
|
|
}
|
|
|
|
@reflectiveTest
|
|
class SourceFactoryTest {
|
|
MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
|
|
|
|
void test_creation() {
|
|
expect(new SourceFactory([]), isNotNull);
|
|
}
|
|
|
|
void test_fromEncoding_invalidUri() {
|
|
SourceFactory factory = new SourceFactory([]);
|
|
expect(() => factory.fromEncoding("<:&%>"), throwsArgumentError);
|
|
}
|
|
|
|
void test_fromEncoding_noResolver() {
|
|
SourceFactory factory = new SourceFactory([]);
|
|
expect(() => factory.fromEncoding("foo:/does/not/exist.dart"),
|
|
throwsArgumentError);
|
|
}
|
|
|
|
void test_fromEncoding_valid() {
|
|
String encoding = "file:///does/not/exist.dart";
|
|
SourceFactory factory = new SourceFactory(
|
|
[new UriResolver_SourceFactoryTest_test_fromEncoding_valid(encoding)]);
|
|
expect(factory.fromEncoding(encoding), isNotNull);
|
|
}
|
|
|
|
void test_resolveUri_absolute() {
|
|
UriResolver_absolute resolver = new UriResolver_absolute();
|
|
SourceFactory factory = new SourceFactory([resolver]);
|
|
factory.resolveUri(null, "dart:core");
|
|
expect(resolver.invoked, isTrue);
|
|
}
|
|
|
|
void test_resolveUri_nonAbsolute_absolute() {
|
|
SourceFactory factory =
|
|
new SourceFactory([new AbsoluteUriResolver(resourceProvider)]);
|
|
String sourcePath = resourceProvider.convertPath('/does/not/exist.dart');
|
|
String targetRawPath = '/does/not/matter.dart';
|
|
String targetPath = resourceProvider.convertPath(targetRawPath);
|
|
String targetUri =
|
|
resourceProvider.pathContext.toUri(targetRawPath).toString();
|
|
Source sourceSource = new FileSource(resourceProvider.getFile(sourcePath));
|
|
Source result = factory.resolveUri(sourceSource, targetUri);
|
|
expect(result.fullName, targetPath);
|
|
}
|
|
|
|
void test_resolveUri_nonAbsolute_relative() {
|
|
SourceFactory factory =
|
|
new SourceFactory([new AbsoluteUriResolver(resourceProvider)]);
|
|
String path = _p('/does/not/have.dart');
|
|
Source containingSource = new FileSource(resourceProvider.getFile(path));
|
|
Source result = factory.resolveUri(containingSource, 'exist.dart');
|
|
expect(result.fullName, _p('/does/not/exist.dart'));
|
|
}
|
|
|
|
void test_resolveUri_nonAbsolute_relative_package() {
|
|
MemoryResourceProvider provider = new MemoryResourceProvider();
|
|
pathos.Context context = provider.pathContext;
|
|
String packagePath =
|
|
context.joinAll([context.separator, 'path', 'to', 'package']);
|
|
String libPath = context.joinAll([packagePath, 'lib']);
|
|
String dirPath = context.joinAll([libPath, 'dir']);
|
|
String firstPath = context.joinAll([dirPath, 'first.dart']);
|
|
String secondPath = context.joinAll([dirPath, 'second.dart']);
|
|
|
|
provider.newFolder(packagePath);
|
|
Folder libFolder = provider.newFolder(libPath);
|
|
provider.newFolder(dirPath);
|
|
File firstFile = provider.newFile(firstPath, '');
|
|
provider.newFile(secondPath, '');
|
|
|
|
PackageMapUriResolver resolver = new PackageMapUriResolver(provider, {
|
|
'package': [libFolder]
|
|
});
|
|
SourceFactory factory = new SourceFactory([resolver]);
|
|
Source librarySource =
|
|
firstFile.createSource(Uri.parse('package:package/dir/first.dart'));
|
|
|
|
Source result = factory.resolveUri(librarySource, 'second.dart');
|
|
expect(result, isNotNull);
|
|
expect(result.fullName, secondPath);
|
|
expect(result.uri.toString(), 'package:package/dir/second.dart');
|
|
}
|
|
|
|
void test_restoreUri() {
|
|
File file1 = resourceProvider.getFile("/some/file1.dart");
|
|
File file2 = resourceProvider.getFile("/some/file2.dart");
|
|
Source source1 = new FileSource(file1);
|
|
Source source2 = new FileSource(file2);
|
|
Uri expected1 = Uri.parse("file:///my_file.dart");
|
|
SourceFactory factory =
|
|
new SourceFactory([new UriResolver_restoreUri(source1, expected1)]);
|
|
expect(factory.restoreUri(source1), same(expected1));
|
|
expect(factory.restoreUri(source2), same(null));
|
|
}
|
|
|
|
/**
|
|
* Return the [resourceProvider] specific path for the given Posix [path].
|
|
*/
|
|
String _p(String path) => resourceProvider.convertPath(path);
|
|
}
|
|
|
|
class UriResolver_absolute extends UriResolver {
|
|
bool invoked = false;
|
|
|
|
UriResolver_absolute();
|
|
|
|
@override
|
|
Source resolveAbsolute(Uri uri, [Uri actualUri]) {
|
|
invoked = true;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
class UriResolver_restoreUri extends UriResolver {
|
|
Source source1;
|
|
Uri expected1;
|
|
UriResolver_restoreUri(this.source1, this.expected1);
|
|
|
|
@override
|
|
Source resolveAbsolute(Uri uri, [Uri actualUri]) => null;
|
|
|
|
@override
|
|
Uri restoreAbsolute(Source source) {
|
|
if (identical(source, source1)) {
|
|
return expected1;
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
class UriResolver_SourceFactoryTest_test_fromEncoding_valid
|
|
extends UriResolver {
|
|
String encoding;
|
|
UriResolver_SourceFactoryTest_test_fromEncoding_valid(this.encoding);
|
|
|
|
@override
|
|
Source resolveAbsolute(Uri uri, [Uri actualUri]) {
|
|
if (uri.toString() == encoding) {
|
|
return new TestSource();
|
|
}
|
|
return null;
|
|
}
|
|
}
|