blob: 235f493813b488e012e8cfcf25bf1c2043f52107 [file] [log] [blame]
// 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 "dart:io";
import "dart:convert";
import "package:test/test.dart";
import "package:package_config_2/src/packages_file.dart" as packages;
import "package:package_config_2/src/package_config_json.dart";
import "src/util.dart";
void main() {
group(".packages", () {
test("valid", () {
var packagesFile = "# Generated by pub yadda yadda\n"
"foo:file:///foo/lib/\n"
"bar:/bar/lib/\n"
"baz:lib/\n";
var result = packages.parse(
utf8.encode(packagesFile), Uri.parse("file:///tmp/file.dart"));
expect(result.version, 1);
expect({for (var p in result.packages) p.name}, {"foo", "bar", "baz"});
expect(result.resolve(pkg("foo", "foo.dart")),
Uri.parse("file:///foo/lib/foo.dart"));
expect(result.resolve(pkg("bar", "bar.dart")),
Uri.parse("file:///bar/lib/bar.dart"));
expect(result.resolve(pkg("baz", "baz.dart")),
Uri.parse("file:///tmp/lib/baz.dart"));
var foo = result["foo"];
expect(foo, isNotNull);
expect(foo.root, Uri.parse("file:///foo/lib/"));
expect(foo.packageUriRoot, Uri.parse("file:///foo/lib/"));
expect(foo.languageVersion, null);
});
test("valid empty", () {
var packagesFile = "# Generated by pub yadda yadda\n";
var result =
packages.parse(utf8.encode(packagesFile), Uri.file("/tmp/file.dart"));
expect(result.version, 1);
expect({for (var p in result.packages) p.name}, <String>{});
});
group("invalid", () {
var baseFile = Uri.file("/tmp/file.dart");
testThrows(String name, String content) {
test(name, () {
expect(() => packages.parse(utf8.encode(content), baseFile),
throwsA(TypeMatcher<FormatException>()));
});
}
testThrows("repeated package name", "foo:lib/\nfoo:lib\n");
testThrows("no colon", "foo\n");
testThrows("empty package name", ":lib/\n");
testThrows("dot only package name", ".:lib/\n");
testThrows("dot only package name", "..:lib/\n");
testThrows("invalid package name character", "f\\o:lib/\n");
testThrows("package URI", "foo:package:bar/lib/");
testThrows("location with query", "f\\o:lib/?\n");
testThrows("location with fragment", "f\\o:lib/#\n");
});
});
group("package_config.json", () {
test("valid", () {
var packageConfigFile = """
{
"configVersion": 2,
"packages": [
{
"name": "foo",
"rootUri": "file:///foo/",
"packageUri": "lib/",
"languageVersion": "2.5",
"nonstandard": true
},
{
"name": "bar",
"rootUri": "/bar/",
"packageUri": "lib/",
"languageVersion": "100.100"
},
{
"name": "baz",
"rootUri": "../",
"packageUri": "lib/"
}
],
"generator": "pub",
"other": [42]
}
""";
var config = parsePackageConfigBytes(utf8.encode(packageConfigFile),
Uri.parse("file:///tmp/.dart_tool/file.dart"));
expect(config.version, 2);
expect({for (var p in config.packages) p.name}, {"foo", "bar", "baz"});
expect(config.resolve(pkg("foo", "foo.dart")),
Uri.parse("file:///foo/lib/foo.dart"));
expect(config.resolve(pkg("bar", "bar.dart")),
Uri.parse("file:///bar/lib/bar.dart"));
expect(config.resolve(pkg("baz", "baz.dart")),
Uri.parse("file:///tmp/lib/baz.dart"));
var foo = config["foo"];
expect(foo, isNotNull);
expect(foo.root, Uri.parse("file:///foo/"));
expect(foo.packageUriRoot, Uri.parse("file:///foo/lib/"));
expect(foo.languageVersion, "2.5");
expect(foo.extraData, {"nonstandard": true});
var bar = config["bar"];
expect(bar, isNotNull);
expect(bar.root, Uri.parse("file:///bar/"));
expect(bar.packageUriRoot, Uri.parse("file:///bar/lib/"));
expect(bar.languageVersion, "100.100");
expect(bar.extraData, null);
var baz = config["baz"];
expect(baz, isNotNull);
expect(baz.root, Uri.parse("file:///tmp/"));
expect(baz.packageUriRoot, Uri.parse("file:///tmp/lib/"));
expect(baz.languageVersion, null);
expect(config.extraData, {
"generator": "pub",
"other": [42]
});
});
test("valid other order", () {
// The ordering in the file is not important.
var packageConfigFile = """
{
"generator": "pub",
"other": [42],
"packages": [
{
"languageVersion": "2.5",
"packageUri": "lib/",
"rootUri": "file:///foo/",
"name": "foo"
},
{
"packageUri": "lib/",
"languageVersion": "100.100",
"rootUri": "/bar/",
"name": "bar"
},
{
"packageUri": "lib/",
"name": "baz",
"rootUri": "../"
}
],
"configVersion": 2
}
""";
var config = parsePackageConfigBytes(utf8.encode(packageConfigFile),
Uri.parse("file:///tmp/.dart_tool/file.dart"));
expect(config.version, 2);
expect({for (var p in config.packages) p.name}, {"foo", "bar", "baz"});
expect(config.resolve(pkg("foo", "foo.dart")),
Uri.parse("file:///foo/lib/foo.dart"));
expect(config.resolve(pkg("bar", "bar.dart")),
Uri.parse("file:///bar/lib/bar.dart"));
expect(config.resolve(pkg("baz", "baz.dart")),
Uri.parse("file:///tmp/lib/baz.dart"));
expect(config.extraData, {
"generator": "pub",
"other": [42]
});
});
// Check that a few minimal configurations are valid.
// These form the basis of invalid tests below.
var cfg = '"configVersion":2';
var pkgs = '"packages":[]';
var name = '"name":"foo"';
var root = '"rootUri":"/foo/"';
test("minimal", () {
var config = parsePackageConfigBytes(utf8.encode("{$cfg,$pkgs}"),
Uri.parse("file:///tmp/.dart_tool/file.dart"));
expect(config.version, 2);
expect(config.packages, isEmpty);
});
test("minimal package", () {
// A package must have a name and a rootUri, the remaining properties
// are optional.
var config = parsePackageConfigBytes(
utf8.encode('{$cfg,"packages":[{$name,$root}]}'),
Uri.parse("file:///tmp/.dart_tool/file.dart"));
expect(config.version, 2);
expect(config.packages.first.name, "foo");
});
group("invalid", () {
testThrows(String name, String source) {
test(name, () {
expect(
() => parsePackageConfigBytes(utf8.encode(source),
Uri.parse("file:///tmp/.dart_tool/file.dart")),
throwsA(TypeMatcher<FormatException>()));
});
}
testThrows("comment", '# comment\n {$cfg,$pkgs}');
testThrows(".packages file", 'foo:/foo\n');
testThrows("no configVersion", '{$pkgs}');
testThrows("no packages", '{$cfg}');
group("config version:", () {
testThrows("null", '{"configVersion":null,$pkgs}');
testThrows("string", '{"configVersion":"2",$pkgs}');
testThrows("array", '{"configVersion":[2],$pkgs}');
});
group("packages:", () {
testThrows("null", '{$cfg,"packages":null}');
testThrows("string", '{$cfg,"packages":"foo"}');
testThrows("object", '{$cfg,"packages":{}}');
});
group("packages entry:", () {
testThrows("null", '{$cfg,"packages":[null]}');
testThrows("string", '{$cfg,"packages":["foo"]}');
testThrows("array", '{$cfg,"packages":[[]]}');
});
group("package", () {
testThrows("no name", '{$cfg,"packages":[{$root}]}');
group("name:", () {
testThrows("null", '{$cfg,"packages":[{"name":null,$root}]}');
testThrows("num", '{$cfg,"packages":[{"name":1,$root}]}');
testThrows("object", '{$cfg,"packages":[{"name":{},$root}]}');
testThrows("empty", '{$cfg,"packages":[{"name":"",$root}]}');
testThrows("one-dot", '{$cfg,"packages":[{"name":".",$root}]}');
testThrows("two-dot", '{$cfg,"packages":[{"name":"..",$root}]}');
testThrows(
"invalid char '\\'", '{$cfg,"packages":[{"name":"\\",$root}]}');
testThrows(
"invalid char ':'", '{$cfg,"packages":[{"name":":",$root}]}');
testThrows(
"invalid char ' '", '{$cfg,"packages":[{"name":" ",$root}]}');
});
testThrows("no root", '{$cfg,"packages":[{$name}]}');
group("root:", () {
testThrows("null", '{$cfg,"packages":[{$name,"rootUri":null}]}');
testThrows("num", '{$cfg,"packages":[{$name,"rootUri":1}]}');
testThrows("object", '{$cfg,"packages":[{$name,"rootUri":{}}]}');
testThrows("fragment", '{$cfg,"packages":[{$name,"rootUri":"x/#"}]}');
testThrows("query", '{$cfg,"packages":[{$name,"rootUri":"x/?"}]}');
testThrows("package-URI",
'{$cfg,"packages":[{$name,"rootUri":"package:x/x/"}]}');
});
group("package-URI root:", () {
testThrows(
"null", '{$cfg,"packages":[{$name,$root,"packageUri":null}]}');
testThrows("num", '{$cfg,"packages":[{$name,$root,"packageUri":1}]}');
testThrows(
"object", '{$cfg,"packages":[{$name,$root,"packageUri":{}}]}');
testThrows("fragment",
'{$cfg,"packages":[{$name,$root,"packageUri":"x/#"}]}');
testThrows(
"query", '{$cfg,"packages":[{$name,$root,"packageUri":"x/?"}]}');
testThrows("package: URI",
'{$cfg,"packages":[{$name,$root,"packageUri":"package:x/x/"}]}');
testThrows("not inside root",
'{$cfg,"packages":[{$name,$root,"packageUri":"../other/"}]}');
});
group("language version", () {
testThrows("null",
'{$cfg,"packages":[{$name,$root,"languageVersion":null}]}');
testThrows(
"num", '{$cfg,"packages":[{$name,$root,"languageVersion":1}]}');
testThrows("object",
'{$cfg,"packages":[{$name,$root,"languageVersion":{}}]}');
testThrows("empty",
'{$cfg,"packages":[{$name,$root,"languageVersion":""}]}');
testThrows("non number.number",
'{$cfg,"packages":[{$name,$root,"languageVersion":"x.1"}]}');
testThrows("number.non number",
'{$cfg,"packages":[{$name,$root,"languageVersion":"1.x"}]}');
testThrows("non number",
'{$cfg,"packages":[{$name,$root,"languageVersion":"x"}]}');
testThrows("one number",
'{$cfg,"packages":[{$name,$root,"languageVersion":"1"}]}');
testThrows("three numbers",
'{$cfg,"packages":[{$name,$root,"languageVersion":"1.2.3"}]}');
testThrows("leading zero first",
'{$cfg,"packages":[{$name,$root,"languageVersion":"01.1"}]}');
testThrows("leading zero second",
'{$cfg,"packages":[{$name,$root,"languageVersion":"1.01"}]}');
testThrows("trailing-",
'{$cfg,"packages":[{$name,$root,"languageVersion":"1.1-1"}]}');
testThrows("trailing+",
'{$cfg,"packages":[{$name,$root,"languageVersion":"1.1+1"}]}');
});
});
testThrows("duplicate package name",
'{$cfg,"packages":[{$name,$root},{$name,"rootUri":"/other/"}]}');
testThrows("same roots",
'{$cfg,"packages":[{$name,$root},{"name":"bar",$root}]}');
testThrows(
"overlapping roots",
'{$cfg,"packages":[{$name,$root},'
'{"name":"bar","rootUri":"/foo/sub/"}]}');
});
});
}