Chromium Code Reviews| Index: tests/standalone/packages_file_test.dart |
| diff --git a/tests/standalone/packages_file_test.dart b/tests/standalone/packages_file_test.dart |
| index 4d695eae5283ac4768547a75595358dcbbd799a0..c0c5d3980786f90eaa85afa1f7716a5d3036dc45 100644 |
| --- a/tests/standalone/packages_file_test.dart |
| +++ b/tests/standalone/packages_file_test.dart |
| @@ -11,197 +11,202 @@ import "package:async_helper/async_helper.dart"; |
| main() async { |
| asyncStart(); |
| - // The `test` function can generate file or http resources. |
| - // It replaces "%file/" with URI of the root directory of generated files and |
| - // "%http/" with the URI of the HTTP server's root in appropriate contexts |
| - // (all file contents and parameters). |
| - |
| - // With no specified resolutiuon and no implicit .packages or packages/ |
| - // available, nothing can be resolved and the package can't be imported. |
| - await test("file: no resolution", |
| - "%file/main.dart", |
| - file: {"main": testMain}, |
| - expect: {"foo.x": null}); |
| - |
| - // An HTTP script with no ".packages" file assumes a "packages" dir. |
| - // All packages are resolved relative to that dir, whether it exists or not. |
| - await test("http: no resolution", "%http/main.dart", |
| - http: {"main": testMain}, |
| - expect: { |
| - "iroot": "%http/packages/", |
| - // "foo": null, |
| - "foo/": "%http/packages/foo/", |
| - "foo/bar": "%http/packages/foo/bar", |
| - "foo.x": null, |
| - }); |
| + Future runTests(test) async { |
|
floitsch
2016/05/27 14:26:50
Move that function out. Should make the diff bette
|
| + // The `test` function can generate file or http resources. |
| + // It replaces "%file/" with URI of the root directory of generated files and |
|
floitsch
2016/05/27 14:26:50
Long line.
|
| + // "%http/" with the URI of the HTTP server's root in appropriate contexts |
| + // (all file contents and parameters). |
| + |
| + // With no specified resolutiuon and no implicit .packages or packages/ |
| + // available, nothing can be resolved and the package can't be imported. |
| + await test("file: no resolution", |
| + "%file/main.dart", |
| + file: {"main": testMain}, |
| + expect: {"foo.x": null}); |
| + |
| + // An HTTP script with no ".packages" file assumes a "packages" dir. |
| + // All packages are resolved relative to that dir, whether it exists or not. |
| + await test("http: no resolution", "%http/main.dart", |
| + http: {"main": testMain}, |
| + expect: { |
| + "iroot": "%http/packages/", |
| + // "foo": null, |
| + "foo/": "%http/packages/foo/", |
| + "foo/bar": "%http/packages/foo/bar", |
| + "foo.x": null, |
| + }); |
| - // A number of tests which behave similarly whether run as local files or |
| - // over HTTP. |
| - for (var scheme in ["file", "http"]) { |
| - |
| - /// Run a test in the current scheme. |
| - /// |
| - /// The files are served either through HTTP or in a local directory. |
| - /// Use "%$scheme/" to refer to the root of the served files. |
| - testScheme(name, main, {expect, files, args, root, config}) { |
| - return test("$scheme: $name", main, expect: expect, |
| - root: root, config: config, args: args, |
| - file: scheme == "file" ? files : null, |
| - http: scheme == "http" ? files : null); |
| - } |
| + // A number of tests which behave similarly whether run as local files or |
| + // over HTTP. |
| + for (var scheme in ["file", "http"]) { |
| + |
| + /// Run a test in the current scheme. |
| + /// |
| + /// The files are served either through HTTP or in a local directory. |
| + /// Use "%$scheme/" to refer to the root of the served files. |
| + testScheme(name, main, {expect, files, args, root, config}) { |
| + return test("$scheme: $name", main, expect: expect, |
| + root: root, config: config, args: args, |
| + file: scheme == "file" ? files : null, |
| + http: scheme == "http" ? files : null); |
| + } |
| - { |
| - var files = {"main": testMain, "packages": fooPackage}; |
| - // Expect implicitly detected package dir. |
| - await testScheme("implicit packages dir","%$scheme/main.dart", |
| - files: files, |
| - expect: { |
| - "iroot": "%$scheme/packages/", |
| - // "foo": null, |
| - "foo/": "%$scheme/packages/foo/", |
| - "foo/bar": "%$scheme/packages/foo/bar", |
| - }); |
| - } |
| + { |
| + var files = {"main": testMain, "packages": fooPackage}; |
| + // Expect implicitly detected package dir. |
| + await testScheme("implicit packages dir","%$scheme/main.dart", |
| + files: files, |
| + expect: { |
| + "iroot": "%$scheme/packages/", |
| + // "foo": null, |
| + "foo/": "%$scheme/packages/foo/", |
| + "foo/bar": "%$scheme/packages/foo/bar", |
| + }); |
| + } |
| - { |
| - var files = {"sub": {"main": testMain, "packages": fooPackage}, |
| - ".packages": ""}; |
| - // Expect implicitly detected package dir. |
| - // Should not detect the .packages file in parent directory. |
| - // That file is empty, so if it is used, the system cannot resolve "foo". |
| - await testScheme("implicit packages dir 2", "%$scheme/sub/main.dart", |
| - files: files, |
| - expect: { |
| - "iroot": "%$scheme/sub/packages/", |
| - // "foo": null, |
| - "foo/": "%$scheme/sub/packages/foo/", |
| - "foo/bar": "%$scheme/sub/packages/foo/bar", |
| - }); |
| - } |
| + { |
| + var files = {"sub": {"main": testMain, "packages": fooPackage}, |
| + ".packages": ""}; |
| + // Expect implicitly detected package dir. |
| + // Should not detect the .packages file in parent directory. |
| + // That file is empty, so if it is used, the system cannot resolve "foo". |
| + await testScheme("implicit packages dir 2", "%$scheme/sub/main.dart", |
| + files: files, |
| + expect: { |
| + "iroot": "%$scheme/sub/packages/", |
| + // "foo": null, |
| + "foo/": "%$scheme/sub/packages/foo/", |
| + "foo/bar": "%$scheme/sub/packages/foo/bar", |
| + }); |
| + } |
| - { |
| - var files = {"main": testMain, |
| - ".packages": "foo:pkgs/foo/", |
| - "pkgs": fooPackage}; |
| - await testScheme("implicit .packages file", "%$scheme/main.dart", |
| - files: files, |
| - expect: { |
| - "iconf": "%$scheme/.packages", |
| - // "foo": null, |
| - "foo/": "%$scheme/pkgs/foo/", |
| - "foo/bar": "%$scheme/pkgs/foo/bar", |
| - }); |
| - } |
| + { |
| + var files = {"main": testMain, |
| + ".packages": "foo:pkgs/foo/", |
| + "pkgs": fooPackage}; |
| + await testScheme("implicit .packages file", "%$scheme/main.dart", |
| + files: files, |
| + expect: { |
| + "iconf": "%$scheme/.packages", |
| + // "foo": null, |
| + "foo/": "%$scheme/pkgs/foo/", |
| + "foo/bar": "%$scheme/pkgs/foo/bar", |
| + }); |
| + } |
| - { |
| - var files = {"main": testMain, |
| - ".packages": "foo:packages/foo/", |
| - "packages": fooPackage, |
| - "pkgs": fooPackage}; |
| - await testScheme("explicit package root, no slash", "%$scheme/main.dart", |
| - files: files, |
| - root: "%$scheme/pkgs", |
| - expect: { |
| - "proot": "%$scheme/pkgs/", |
| - "iroot": "%$scheme/pkgs/", |
| - // "foo": null, |
| - "foo/": "%$scheme/pkgs/foo/", |
| - "foo/bar": "%$scheme/pkgs/foo/bar", |
| - }); |
| - } |
| + { |
| + var files = {"main": testMain, |
| + ".packages": "foo:packages/foo/", |
| + "packages": fooPackage, |
| + "pkgs": fooPackage}; |
| + await testScheme("explicit package root, no slash", "%$scheme/main.dart", |
| + files: files, |
| + root: "%$scheme/pkgs", |
| + expect: { |
| + "proot": "%$scheme/pkgs/", |
| + "iroot": "%$scheme/pkgs/", |
| + // "foo": null, |
| + "foo/": "%$scheme/pkgs/foo/", |
| + "foo/bar": "%$scheme/pkgs/foo/bar", |
| + }); |
| + } |
| - { |
| - var files = {"main": testMain, |
| - ".packages": "foo:packages/foo/", |
| - "packages": fooPackage, |
| - "pkgs": fooPackage}; |
| - await testScheme("explicit package root, slash", "%$scheme/main.dart", |
| - files: files, |
| - root: "%$scheme/pkgs", |
| - expect: { |
| - "proot": "%$scheme/pkgs/", |
| - "iroot": "%$scheme/pkgs/", |
| - // "foo": null, |
| - "foo/": "%$scheme/pkgs/foo/", |
| - "foo/bar": "%$scheme/pkgs/foo/bar", |
| - }); |
| + { |
| + var files = {"main": testMain, |
| + ".packages": "foo:packages/foo/", |
| + "packages": fooPackage, |
| + "pkgs": fooPackage}; |
| + await testScheme("explicit package root, slash", "%$scheme/main.dart", |
| + files: files, |
| + root: "%$scheme/pkgs", |
| + expect: { |
| + "proot": "%$scheme/pkgs/", |
| + "iroot": "%$scheme/pkgs/", |
| + // "foo": null, |
| + "foo/": "%$scheme/pkgs/foo/", |
| + "foo/bar": "%$scheme/pkgs/foo/bar", |
| + }); |
| + } |
| + |
| + { |
| + var files = {"main": testMain, |
| + ".packages": "foo:packages/foo/", |
| + "packages": fooPackage, |
| + ".pkgs": "foo:pkgs/foo/", |
| + "pkgs": fooPackage}; |
| + await testScheme("explicit package config file", "%$scheme/main.dart", |
| + files: files, |
| + config: "%$scheme/.pkgs", |
| + expect: { |
| + "pconf": "%$scheme/.pkgs", |
| + "iconf": "%$scheme/.pkgs", |
| + // "foo": null, |
| + "foo/": "%$scheme/pkgs/foo/", |
| + "foo/bar": "%$scheme/pkgs/foo/bar", |
| + }); |
| + } |
| + |
| + { |
| + /// The package config can be specified as a data: URI. |
| + /// (In that case, relative URI references in the config file won't work). |
| + var files = {"main": testMain, |
| + ".packages": "foo:packages/foo/", |
| + "packages": fooPackage, |
| + "pkgs": fooPackage}; |
| + var dataUri = "data:,foo:%$scheme/pkgs/foo/\n"; |
| + await testScheme("explicit data: config file", "%$scheme/main.dart", |
| + files: files, |
| + config: dataUri, |
| + expect: { |
| + "pconf": dataUri, |
| + "iconf": dataUri, |
| + // "foo": null, |
| + "foo/": "%$scheme/pkgs/foo/", |
| + "foo/bar": "%$scheme/pkgs/foo/bar", |
| + }); |
| + } |
| } |
| { |
| - var files = {"main": testMain, |
| - ".packages": "foo:packages/foo/", |
| - "packages": fooPackage, |
| - ".pkgs": "foo:pkgs/foo/", |
| + // With a file: URI, the lookup checks for a .packages file in superdirs |
| + // when it fails to find a ,packages file or packages/ directory next to |
| + // the entry point. |
| + var files = {"sub": { "main": testMain }, |
| + ".packages": "foo:pkgs/foo/", |
| "pkgs": fooPackage}; |
| - await testScheme("explicit package config file", "%$scheme/main.dart", |
| - files: files, |
| - config: "%$scheme/.pkgs", |
| + await test("file: implicit .packages file in ..", "%file/sub/main.dart", |
| + file: files, |
| expect: { |
| - "pconf": "%$scheme/.pkgs", |
| - "iconf": "%$scheme/.pkgs", |
| + "iconf": "%file/.packages", |
| // "foo": null, |
| - "foo/": "%$scheme/pkgs/foo/", |
| - "foo/bar": "%$scheme/pkgs/foo/bar", |
| + "foo/": "%file/pkgs/foo/", |
| + "foo/bar": "%file/pkgs/foo/bar", |
| }); |
| } |
| { |
| - /// The package config can be specified as a data: URI. |
| - /// (In that case, relative URI references in the config file won't work). |
| - var files = {"main": testMain, |
| - ".packages": "foo:packages/foo/", |
| - "packages": fooPackage, |
| + // With a non-file: URI, the lookup assumes a packges/ dir. |
| + // The absence of a .packages file next to the entry point means |
| + // that the resolution assumes a packages directory, whether it exists or |
| + // not. It should not find the .packages file in the parent directory. |
| + var files = {"sub": { "main": testMain }, |
| + ".packages": "foo:pkgs/foo/", |
| "pkgs": fooPackage}; |
| - var dataUri = "data:,foo:%$scheme/pkgs/foo/\n"; |
| - await testScheme("explicit data: config file", "%$scheme/main.dart", |
| - files: files, |
| - config: dataUri, |
| + await test("http: implicit packages dir", "%http/sub/main.dart", |
| + http: files, |
| expect: { |
| - "pconf": dataUri, |
| - "iconf": dataUri, |
| + "iroot": "%http/sub/packages/", |
| // "foo": null, |
| - "foo/": "%$scheme/pkgs/foo/", |
| - "foo/bar": "%$scheme/pkgs/foo/bar", |
| + "foo/": "%http/sub/packages/foo/", |
| + "foo/bar": "%http/sub/packages/foo/bar", |
| + "foo.x": null, |
| }); |
| } |
| } |
| - { |
| - // With a file: URI, the lookup checks for a .packages file in superdirs |
| - // when it fails to find a ,packages file or packages/ directory next to |
| - // the entry point. |
| - var files = {"sub": { "main": testMain }, |
| - ".packages": "foo:pkgs/foo/", |
| - "pkgs": fooPackage}; |
| - await test("file: implicit .packages file in ..", "%file/sub/main.dart", |
| - file: files, |
| - expect: { |
| - "iconf": "%file/.packages", |
| - // "foo": null, |
| - "foo/": "%file/pkgs/foo/", |
| - "foo/bar": "%file/pkgs/foo/bar", |
| - }); |
| - } |
| - |
| - { |
| - // With a non-file: URI, the lookup assumes a packges/ dir. |
| - // The absence of a .packages file next to the entry point means |
| - // that the resolution assumes a packages directory, whether it exists or |
| - // not. It should not find the .packages file in the parent directory. |
| - var files = {"sub": { "main": testMain }, |
| - ".packages": "foo:pkgs/foo/", |
| - "pkgs": fooPackage}; |
| - await test("http: implicit packages dir", "%http/sub/main.dart", |
| - http: files, |
| - expect: { |
| - "iroot": "%http/sub/packages/", |
| - // "foo": null, |
| - "foo/": "%http/sub/packages/foo/", |
| - "foo/bar": "%http/sub/packages/foo/bar", |
| - "foo.x": null, |
| - }); |
| - } |
| - |
| + await runTests(test); |
| + await runTests(testSpawn(test)); |
| + await runTests(testSpawn(testSpawn(test))); |
| if (failingTests.isNotEmpty) { |
| print("Errors found in tests:\n ${failingTests.join("\n ")}\n"); |
| @@ -217,6 +222,10 @@ var failingTests = new Set(); |
| var fileHttpRegexp = new RegExp(r"%(?:file|http)/"); |
| +typedef Future Test(String name, String main, |
| + {String root, String config, List<String> args, |
| + Map file, Map http, Map expect}); |
| + |
| Future test(String name, String main, |
| {String root, String config, List<String> args, |
| Map file, Map http, Map expect}) async { |
| @@ -285,6 +294,31 @@ Future test(String name, String main, |
| } |
| } |
| +Test testSpawn(Test test) => |
| + (String name, String main, |
| + {String root, String config, List<String> args, |
| + Map file, Map http, Map expect}) { |
| + // Add spawnMain file next to main file. |
| + var spawnMainName = "_spawnMain${tmpNameCounter++}"; |
| + var parts = main.split('/').toList(); |
| + var files; |
| + if (parts[0] == "%file") { |
| + files = file; |
| + } else { |
| + assert(parts[0] == "%http"); |
| + files = http; |
| + } |
| + for (var i = 1; i < parts.length - 1; i++) { |
| + files = files[parts[i]]; |
| + } |
| + files[spawnMainName] = spawnMain.replaceAll("%main", main); |
| + parts[parts.length - 1] = "$spawnMainName.dart"; |
| + |
| + return test("spawn: $name", parts.join("/"), |
| + root: root, config: config, args: args, |
| + file: file, http: http, expect: expect); |
| + }; |
| + |
| /// Test that the output of running testMain matches the expectations. |
| /// |
| @@ -359,23 +393,36 @@ main(args) async { |
| var isolate = await Isolate.spawnUri(target, restArgs, |
| packageRoot: root, packageConfig: conf, paused: true); |
| // Wait for isolate to exit before exiting the main isolate. |
| - var done = new RawReceivePort(); |
| - done.handler = (_) { done.close(); }; |
| - isolate.addExitHandler(done.sendPort); |
| + var port = new RawReceivePort(); |
| + port.handler = (res) async { |
| + port.close(); // Close on done or first error. |
| + if (res != null) { |
| + await new Future.error(res[0], new Stacktrace.fromString(res[1])); |
| + } |
| + }; |
| + isolate.addOnExitListener(port.sendPort); |
| + isolate.addErrorListener(port.sendPort); |
| isolate.resume(isolate.pauseCapability); |
| } |
| """; |
| /// Script that spawns a new Isolate using Isolate.spawn. |
| const String spawnMain = r""" |
| +import "dart:async"; |
| import "dart:isolate"; |
| -import "testmain.dart" as test; |
| -main() async { |
| +import "%main" as test; |
| +main([_]) async { |
| var isolate = await Isolate.spawn(test.main, [], paused: true); |
| // Wait for isolate to exit before exiting the main isolate. |
| - var done = new RawReceivePort(); |
| - done.handler = (_) { done.close(); }; |
| - isolate.addExitHandler(done.sendPort); |
| + var port = new RawReceivePort(); |
| + port.handler = (res) async { |
| + port.close(); // Close on port or first error. |
| + if (res != null) { |
| + await new Future.error(res[0], new Stacktrace.fromString(res[1])); |
| + } |
| + }; |
| + isolate.addOnExitListener(port.sendPort); |
| + isolate.addErrorListener(port.sendPort); |
| isolate.resume(isolate.pauseCapability); |
| } |
| """; |
| @@ -389,11 +436,14 @@ const Map fooPackage = const { "foo": const { "foo": "var x = 'qux';" }}; |
| Future<String> runDart(String script, |
| {String root, String config, |
| Iterable<String> scriptArgs}) async { |
| + var checked = false; |
| + assert((checked = true)); |
|
floitsch
2016/05/27 14:26:50
Add a comment.
|
| // TODO: Find a way to change CWD before running script. |
| var executable = Platform.executable; |
| var args = []; |
| - if (root != null) args..add("-p")..add(root); |
| - if (config != null) args..add("--packages=$config"); |
| + if (checked) args.add("--checked"); |
| + if (root != null) args.add("--package-root=$root"); |
| + if (config != null) args.add("--packages=$config"); |
| args.add(script); |
| if (scriptArgs != null) { |
| args.addAll(scriptArgs); |
| @@ -491,8 +541,8 @@ Future<HttpServer> startServer(Map files, String fixPaths(String text)) async { |
| // Counter used to avoid reusing temporary directory names. |
| // Some platforms are timer based, and creating two temp-dirs withing a short |
| // duration may cause a collision. |
| -int tmpDirCounter = 0; |
| +int tmpNameCounter = 0; |
| Directory createTempDir() { |
| - return Directory.systemTemp.createTempSync("pftest-${tmpDirCounter++}-"); |
| + return Directory.systemTemp.createTempSync("pftest-${tmpNameCounter++}-"); |
| } |