Allow spawnHybridUri() to take root-relative URLs (#708)
This makes it possible to use the same spawnHybridUri() call from
multiple test files that are in different places in the filesystem.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0f9a687..9478222 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 0.12.26
+
+* The `spawnHybridUri()` function now allows root-relative URLs, which are
+ interpreted as relative to the root of the package.
+
## 0.12.25
* Add a `override_platforms` configuration field which allows test platforms'
diff --git a/lib/src/frontend/spawn_hybrid.dart b/lib/src/frontend/spawn_hybrid.dart
index 2008935..001a00f 100644
--- a/lib/src/frontend/spawn_hybrid.dart
+++ b/lib/src/frontend/spawn_hybrid.dart
@@ -63,8 +63,11 @@
/// ```
///
/// If [uri] is relative, it will be interpreted relative to the `file:` URL for
-/// the test suite being executed. If it's a `package:` URL, it will be resolved
-/// using the current package's dependency constellation.
+/// the test suite being executed. If it's root-relative (that is, if it begins
+/// with `/`) it will be interpreted relative to the root of the package (the
+/// directory that contains `pubspec.yaml`, *not* the `test/` directory). If
+/// it's a `package:` URL, it will be resolved using the current package's
+/// dependency constellation.
///
/// Returns a [StreamChannel] that's connected to the channel passed to
/// `hybridMain()`. Only JSON-encodable objects may be sent through this
@@ -98,16 +101,35 @@
String absoluteUri;
if (parsedUrl.scheme.isEmpty) {
+ var isRootRelative = parsedUrl.path.startsWith("/");
+
// If we're running in a browser context, the working directory is already
// relative to the test file, whereas on the VM the working directory is the
// root of the package.
if (p.style == p.Style.url) {
- absoluteUri = p.absolute(parsedUrl.toString());
+ if (isRootRelative) {
+ // A root-relative URL is interpreted as relative to the package root,
+ // which means placing it beneath the URL secret.
+ var secret = Uri.encodeComponent(Uri.base.pathSegments[0]);
+ absoluteUri = p.absolute("/$secret$parsedUrl");
+ print("Uri.base: ${Uri.base}");
+ print("absoluteUri: ${absoluteUri}");
+ } else {
+ absoluteUri = p.absolute(parsedUrl.toString());
+ }
} else {
- var suitePath = Invoker.current.liveTest.suite.path;
- absoluteUri = p.url.join(
- p.url.dirname(p.toUri(p.absolute(suitePath)).toString()),
- parsedUrl.toString());
+ if (isRootRelative) {
+ // We assume that the current path is the package root. `pub run`
+ // enforces this currently, but at some point it would probably be good
+ // to pass in an explicit root.
+ absoluteUri = p.url
+ .join(p.toUri(p.current).toString(), parsedUrl.path.substring(1));
+ } else {
+ var suitePath = Invoker.current.liveTest.suite.path;
+ absoluteUri = p.url.join(
+ p.url.dirname(p.toUri(p.absolute(suitePath)).toString()),
+ parsedUrl.toString());
+ }
}
} else {
absoluteUri = uri.toString();
diff --git a/pubspec.yaml b/pubspec.yaml
index c94e820..2a8c344 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: test
-version: 0.12.25
+version: 0.12.26
author: Dart Team <misc@dartlang.org>
description: A library for writing dart unit tests.
homepage: https://github.com/dart-lang/test
diff --git a/test/runner/hybrid_test.dart b/test/runner/hybrid_test.dart
index cec8762..ec5d568 100644
--- a/test/runner/hybrid_test.dart
+++ b/test/runner/hybrid_test.dart
@@ -28,7 +28,11 @@
group("in the browser", () {
_spawnHybridUriTests(["-p", "chrome"]);
- }, tags: "browser");
+ }, tags: "chrome");
+
+ group("in Node.js", () {
+ _spawnHybridUriTests(["-p", "node"]);
+ }, tags: "node");
});
group("spawnHybridCode()", () {
@@ -454,6 +458,35 @@
await test.shouldExit(0);
});
+ test("resolves root-relative URIs relative to the package root", () async {
+ await d.dir("test/dir/subdir", [
+ d.file("test.dart", """
+ import "package:test/test.dart";
+
+ void main() {
+ test("hybrid emits numbers", () {
+ expect(
+ spawnHybridUri("/test/dir/subdir/hybrid.dart")
+ .stream.toList(),
+ completion(equals([1, 2, 3])));
+ });
+ }
+ """),
+ d.file("hybrid.dart", """
+ import "package:stream_channel/stream_channel.dart";
+
+ void hybridMain(StreamChannel channel) {
+ channel.sink..add(1)..add(2)..add(3)..close();
+ }
+ """),
+ ]).create();
+
+ var test = await runTest(["test/dir/subdir/test.dart"]..addAll(arguments));
+ expect(test.stdout,
+ containsInOrder(["+0: hybrid emits numbers", "+1: All tests passed!"]));
+ await test.shouldExit(0);
+ });
+
test("supports absolute file: URIs", () async {
var url = p.toUri(p.absolute(p.join(d.sandbox, 'hybrid.dart')));
await d.file("test.dart", """