Skip to content

Commit

Permalink
Fix spawnHybridUri() in the browser (#689)
Browse files Browse the repository at this point in the history
  • Loading branch information
nex3 authored Sep 28, 2017
1 parent f80261e commit c07f13b
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 162 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.12.24+8

* `spawnHybridUri()` now interprets relative URIs correctly in browser tests.

## 0.12.24+7

* Declare support for `async` 2.0.0.
Expand Down
15 changes: 11 additions & 4 deletions lib/src/frontend/spawn_hybrid.dart
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,17 @@ StreamChannel spawnHybridUri(uri, {Object message, bool stayAlive: false}) {

String absoluteUri;
if (parsedUrl.scheme.isEmpty) {
var suitePath = Invoker.current.liveTest.suite.path;
absoluteUri = p.url.join(
p.url.dirname(p.toUri(p.absolute(suitePath)).toString()),
parsedUrl.toString());
// 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());
} 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();
}
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: test
version: 0.12.24+7
version: 0.12.24+8
author: Dart Team <misc@dartlang.org>
description: A library for writing dart unit tests.
homepage: https://github.com/dart-lang/test
Expand Down
322 changes: 165 additions & 157 deletions test/runner/hybrid_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,165 +22,13 @@ void main() {
});

group("spawnHybridUri():", () {
test("loads a file in a separate isolate connected via StreamChannel",
() async {
await d.file("test.dart", """
import "package:test/test.dart";
void main() {
test("hybrid emits numbers", () {
expect(spawnHybridUri("hybrid.dart").stream.toList(),
completion(equals([1, 2, 3])));
});
}
""").create();

await 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.dart"]);
expect(
test.stdout,
containsInOrder(
["+0: hybrid emits numbers", "+1: All tests passed!"]));
await test.shouldExit(0);
});

test("resolves URIs relative to the test file", () async {
await d.dir("test/dir/subdir", [
d.file("test.dart", """
import "package:test/test.dart";
void main() {
test("hybrid emits numbers", () {
expect(spawnHybridUri("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"]);
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", """
import "package:test/test.dart";
void main() {
test("hybrid emits numbers", () {
expect(spawnHybridUri("$url").stream.toList(),
completion(equals([1, 2, 3])));
});
}
""").create();

await 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.dart"]);
expect(
test.stdout,
containsInOrder(
["+0: hybrid emits numbers", "+1: All tests passed!"]));
await test.shouldExit(0);
});

test("supports Uri objects", () async {
await d.file("test.dart", """
import "package:test/test.dart";
void main() {
test("hybrid emits numbers", () {
expect(spawnHybridUri(Uri.parse("hybrid.dart")).stream.toList(),
completion(equals([1, 2, 3])));
});
}
""").create();

await 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.dart"]);
expect(
test.stdout,
containsInOrder(
["+0: hybrid emits numbers", "+1: All tests passed!"]));
await test.shouldExit(0);
});

test("rejects non-String, non-Uri objects", () {
expect(() => spawnHybridUri(123), throwsArgumentError);
group("in the VM", () {
_spawnHybridUriTests();
});

test("passes a message to the hybrid isolate", () async {
await d.file("test.dart", """
import "package:test/test.dart";
void main() {
test("hybrid echoes message", () {
expect(
spawnHybridUri(Uri.parse("hybrid.dart"), message: 123)
.stream.first,
completion(equals(123)));
expect(
spawnHybridUri(Uri.parse("hybrid.dart"), message: "wow")
.stream.first,
completion(equals("wow")));
});
}
""").create();

await d.file("hybrid.dart", """
import "package:stream_channel/stream_channel.dart";
void hybridMain(StreamChannel channel, Object message) {
channel.sink..add(message)..close();
}
""").create();

var test = await runTest(["test.dart"]);
expect(
test.stdout,
containsInOrder(
["+0: hybrid echoes message", "+1: All tests passed!"]));
await test.shouldExit(0);
});

test("emits an error from the stream channel if the isolate fails to load",
() {
expect(spawnHybridUri("non existent file").stream.first,
throwsA(new isInstanceOf<IsolateSpawnException>()));
});
group("in the browser", () {
_spawnHybridUriTests(["-p", "chrome"]);
}, tags: "browser");
});

group("spawnHybridCode()", () {
Expand Down Expand Up @@ -544,3 +392,163 @@ void main() {
});
});
}

/// Defines tests for `spawnHybridUri()`.
///
/// If [arguments] is given, it's passed on to the invocation of the test
/// runner.
void _spawnHybridUriTests([Iterable<String> arguments]) {
arguments ??= [];

test("loads a file in a separate isolate connected via StreamChannel",
() async {
await d.file("test.dart", """
import "package:test/test.dart";
void main() {
test("hybrid emits numbers", () {
expect(spawnHybridUri("hybrid.dart").stream.toList(),
completion(equals([1, 2, 3])));
});
}
""").create();

await 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.dart"]..addAll(arguments));
expect(test.stdout,
containsInOrder(["+0: hybrid emits numbers", "+1: All tests passed!"]));
await test.shouldExit(0);
});

test("resolves URIs relative to the test file", () async {
await d.dir("test/dir/subdir", [
d.file("test.dart", """
import "package:test/test.dart";
void main() {
test("hybrid emits numbers", () {
expect(spawnHybridUri("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", """
import "package:test/test.dart";
void main() {
test("hybrid emits numbers", () {
expect(spawnHybridUri("$url").stream.toList(),
completion(equals([1, 2, 3])));
});
}
""").create();

await 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.dart"]..addAll(arguments));
expect(test.stdout,
containsInOrder(["+0: hybrid emits numbers", "+1: All tests passed!"]));
await test.shouldExit(0);
});

test("supports Uri objects", () async {
await d.file("test.dart", """
import "package:test/test.dart";
void main() {
test("hybrid emits numbers", () {
expect(spawnHybridUri(Uri.parse("hybrid.dart")).stream.toList(),
completion(equals([1, 2, 3])));
});
}
""").create();

await 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.dart"]..addAll(arguments));
expect(test.stdout,
containsInOrder(["+0: hybrid emits numbers", "+1: All tests passed!"]));
await test.shouldExit(0);
});

test("rejects non-String, non-Uri objects", () {
expect(() => spawnHybridUri(123), throwsArgumentError);
});

test("passes a message to the hybrid isolate", () async {
await d.file("test.dart", """
import "package:test/test.dart";
void main() {
test("hybrid echoes message", () {
expect(
spawnHybridUri(Uri.parse("hybrid.dart"), message: 123)
.stream.first,
completion(equals(123)));
expect(
spawnHybridUri(Uri.parse("hybrid.dart"), message: "wow")
.stream.first,
completion(equals("wow")));
});
}
""").create();

await d.file("hybrid.dart", """
import "package:stream_channel/stream_channel.dart";
void hybridMain(StreamChannel channel, Object message) {
channel.sink..add(message)..close();
}
""").create();

var test = await runTest(["test.dart"]..addAll(arguments));
expect(
test.stdout,
containsInOrder(
["+0: hybrid echoes message", "+1: All tests passed!"]));
await test.shouldExit(0);
});

test("emits an error from the stream channel if the isolate fails to load",
() {
expect(spawnHybridUri("non existent file").stream.first,
throwsA(new isInstanceOf<IsolateSpawnException>()));
});
}

0 comments on commit c07f13b

Please sign in to comment.