blob: 16bdd267b19d9ebf51d01a6bc3f4bc7429cb8eba [file] [log] [blame]
// 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:async";
import "dart:io";
import "package:test/test.dart";
import "package:package_config/packages.dart";
import "package:package_config/discovery.dart";
import "package:path/path.dart" as path;
const packagesFile = """
# A comment
foo=file:///dart/packages/foo/
bar=http://example.com/dart/packages/bar/
baz=packages/baz/
""";
void validatePackagesFile(Packages resolver, Uri location) {
expect(resolver, isNotNull);
expect(resolver.resolve(pkg("foo", "bar/baz")),
equals(Uri.parse("file:///dart/packages/foo/bar/baz")));
expect(resolver.resolve(pkg("bar", "baz/qux")),
equals(Uri.parse("http://example.com/dart/packages/bar/baz/qux")));
expect(resolver.resolve(pkg("baz", "qux/foo")),
equals(location.resolve("packages/baz/qux/foo")));
expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"]));
}
void validatePackagesDir(Packages resolver, Uri location) {
// Expect three packages: foo, bar and baz
expect(resolver, isNotNull);
expect(resolver.resolve(pkg("foo", "bar/baz")),
equals(location.resolve("packages/foo/bar/baz")));
expect(resolver.resolve(pkg("bar", "baz/qux")),
equals(location.resolve("packages/bar/baz/qux")));
expect(resolver.resolve(pkg("baz", "qux/foo")),
equals(location.resolve("packages/baz/qux/foo")));
if (location.scheme == "file") {
expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"]));
} else {
expect(() => resolver.packages, throws);
}
}
Uri pkg(String packageName, String packagePath) {
var path;
if (packagePath.startsWith('/')) {
path = "$packageName$packagePath";
} else {
path = "$packageName/$packagePath";
}
return new Uri(scheme: "package", path: path);
}
main() {
generalTest(".packages",
{".packages": packagesFile,
"script.dart": "main(){}",
"packages": {"shouldNotBeFound": {}}},
(Uri location) async {
Packages resolver;
resolver = await findPackages(location);
validatePackagesFile(resolver, location);
resolver = await findPackages(location.resolve("script.dart"));
validatePackagesFile(resolver, location);
var specificDiscovery = (location.scheme == "file")
? findPackagesFromFile
: findPackagesFromNonFile;
resolver = await specificDiscovery(location);
validatePackagesFile(resolver, location);
resolver = await specificDiscovery(location.resolve("script.dart"));
validatePackagesFile(resolver, location);
});
generalTest("packages/",
{"packages": { "foo": {}, "bar": {}, "baz": {}},
"script.dart": "main(){}"},
(Uri location) async {
Packages resolver;
bool isFile = (location.scheme == "file");
resolver = await findPackages(location);
validatePackagesDir(resolver, location);
resolver = await findPackages(location.resolve("script.dart"));
validatePackagesDir(resolver, location);
var specificDiscovery = isFile
? findPackagesFromFile
: findPackagesFromNonFile;
resolver = await specificDiscovery(location);
validatePackagesDir(resolver, location);
resolver = await specificDiscovery(location.resolve("script.dart"));
validatePackagesDir(resolver, location);
});
fileTest(".packages recursive",
{".packages": packagesFile, "subdir": {"script.dart": "main(){}"}},
(Uri location) async {
Packages resolver;
resolver = await findPackages(location.resolve("subdir/"));
validatePackagesFile(resolver, location);
resolver = await findPackages(location.resolve("subdir/script.dart"));
validatePackagesFile(resolver, location);
resolver = await findPackagesFromFile(location.resolve("subdir/"));
validatePackagesFile(resolver, location);
resolver =
await findPackagesFromFile(location.resolve("subdir/script.dart"));
validatePackagesFile(resolver, location);
});
httpTest(".packages not recursive",
{".packages": packagesFile, "subdir": {"script.dart": "main(){}"}},
(Uri location) async {
Packages resolver;
var subdir = location.resolve("subdir/");
resolver = await findPackages(subdir);
validatePackagesDir(resolver, subdir);
resolver = await findPackages(subdir.resolve("script.dart"));
validatePackagesDir(resolver, subdir);
resolver = await findPackagesFromNonFile(subdir);
validatePackagesDir(resolver, subdir);
resolver = await findPackagesFromNonFile(subdir.resolve("script.dart"));
validatePackagesDir(resolver, subdir);
});
fileTest("no packages",
{"script.dart": "main(){}"},
(Uri location) async {
// A file: location with no .packages or packages returns
// Packages.noPackages.
Packages resolver;
resolver = await findPackages(location);
expect(resolver, same(Packages.noPackages));
resolver = await findPackages(location.resolve("script.dart"));
expect(resolver, same(Packages.noPackages));
resolver = findPackagesFromFile(location);
expect(resolver, same(Packages.noPackages));
resolver = findPackagesFromFile(location.resolve("script.dart"));
expect(resolver, same(Packages.noPackages));
});
httpTest("no packages",
{"script.dart": "main(){}"},
(Uri location) async {
// A non-file: location with no .packages or packages/:
// Assumes a packages dir exists, and resolves relative to that.
Packages resolver;
resolver = await findPackages(location);
validatePackagesDir(resolver, location);
resolver = await findPackages(location.resolve("script.dart"));
validatePackagesDir(resolver, location);
resolver = await findPackagesFromNonFile(location);
validatePackagesDir(resolver, location);
resolver = await findPackagesFromNonFile(location.resolve("script.dart"));
validatePackagesDir(resolver, location);
});
test(".packages w/ loader", () async {
Uri location = Uri.parse("krutch://example.com/path/");
Future loader(Uri file) async {
if (file.path.endsWith(".packages")) {
return packagesFile.codeUnits;
}
throw "not found";
}
// A non-file: location with no .packages or packages/:
// Assumes a packages dir exists, and resolves relative to that.
Packages resolver;
resolver = await findPackages(location, loader: loader);
validatePackagesFile(resolver, location);
resolver = await findPackages(location.resolve("script.dart"),
loader: loader);
validatePackagesFile(resolver, location);
resolver = await findPackagesFromNonFile(location, loader: loader);
validatePackagesFile(resolver, location);
resolver = await findPackagesFromNonFile(location.resolve("script.dart"),
loader: loader);
validatePackagesFile(resolver, location);
});
test("no packages w/ loader", () async {
Uri location = Uri.parse("krutch://example.com/path/");
Future loader(Uri file) async {
throw "not found";
}
// A non-file: location with no .packages or packages/:
// Assumes a packages dir exists, and resolves relative to that.
Packages resolver;
resolver = await findPackages(location, loader: loader);
validatePackagesDir(resolver, location);
resolver = await findPackages(location.resolve("script.dart"),
loader: loader);
validatePackagesDir(resolver, location);
resolver = await findPackagesFromNonFile(location, loader: loader);
validatePackagesDir(resolver, location);
resolver = await findPackagesFromNonFile(location.resolve("script.dart"),
loader:loader);
validatePackagesDir(resolver, location);
});
}
/// Create a directory structure from [description] and run [fileTest].
///
/// Description is a map, each key is a file entry. If the value is a map,
/// it's a sub-dir, otherwise it's a file and the value is the content
/// as a string.
void fileTest(String name,
Map description,
Future fileTest(Uri directory)) {
group("file-test", () {
Directory tempDir = Directory.systemTemp.createTempSync("file-test");
setUp(() {
_createFiles(tempDir, description);
});
tearDown(() {
tempDir.deleteSync(recursive: true);
});
test(name, () => fileTest(new Uri.file(path.join(tempDir.path, "."))));
});
}
/// HTTP-server the directory structure from [description] and run [htpTest].
///
/// Description is a map, each key is a file entry. If the value is a map,
/// it's a sub-dir, otherwise it's a file and the value is the content
/// as a string.
void httpTest(String name, Map description, Future httpTest(Uri directory)) {
group("http-test", () {
var serverSub;
var uri;
setUp(() {
return HttpServer
.bind(InternetAddress.LOOPBACK_IP_V4, 0)
.then((server) {
uri = new Uri(scheme: "http",
host: "127.0.0.1",
port: server.port,
path: "/");
serverSub = server.listen((HttpRequest request) {
// No error handling.
var path = request.uri.path;
if (path.startsWith('/')) path = path.substring(1);
if (path.endsWith('/')) path = path.substring(0, path.length - 1);
var parts = path.split('/');
var fileOrDir = description;
for (int i = 0; i < parts.length; i++) {
fileOrDir = fileOrDir[parts[i]];
if (fileOrDir == null) {
request.response.statusCode = 404;
request.response.close();
}
}
request.response.write(fileOrDir);
request.response.close();
});
});
});
tearDown(() => serverSub.cancel());
test(name, () => httpTest(uri));
});
}
void generalTest(String name, Map description, Future action(Uri location)) {
fileTest(name, description, action);
httpTest(name, description, action);
}
void _createFiles(Directory target, Map description) {
description.forEach((name, content) {
if (content is Map) {
Directory subDir = new Directory(path.join(target.path, name));
subDir.createSync();
_createFiles(subDir, content);
} else {
File file = new File(path.join(target.path, name));
file.writeAsStringSync(content, flush: true);
}
});
}