From 472805265165e7c66bb6eca810f00f7832aa82ea Mon Sep 17 00:00:00 2001 From: Natalie Weizenbaum <nweiz@google.com> Date: Wed, 22 Jul 2015 11:38:12 -0700 Subject: [PATCH] Convert a bunch of tests to use scheduled_test's infrastructure. This makes the tests cleaner and more concise, as well as providing more information for debugging. This gets rid of the "does not preserve state" browser tests, because it turns out that they weren't actually doing anything anyway (otherwise IE would have failed, since it *does* preserve state). It also adds tests for every browser being able to run successful and failing tests. R=kevmoo@google.com Review URL: https://codereview.chromium.org//1243293002 . --- pubspec.yaml | 6 +- test/io.dart | 187 +++--- test/runner/browser/chrome_test.dart | 167 ++---- test/runner/browser/code_server.dart | 87 +++ .../runner/browser/compact_reporter_test.dart | 49 +- test/runner/browser/content_shell_test.dart | 168 ++---- test/runner/browser/dartium_test.dart | 166 +----- .../browser/expanded_reporter_test.dart | 49 +- test/runner/browser/firefox_test.dart | 177 +----- .../browser/internet_explorer_test.dart | 122 ++-- test/runner/browser/phantom_js_test.dart | 167 +----- test/runner/browser/runner_test.dart | 527 ++++++++--------- test/runner/browser/safari_test.dart | 158 ++--- test/runner/compact_reporter_test.dart | 64 +- test/runner/expanded_reporter_test.dart | 58 +- test/runner/pub_serve_test.dart | 348 +++++------ test/runner/runner_test.dart | 550 +++++++++--------- test/runner/signal_test.dart | 201 +++---- test/runner/test_on_test.dart | 122 ++-- 19 files changed, 1371 insertions(+), 2002 deletions(-) create mode 100644 test/runner/browser/code_server.dart diff --git a/pubspec.yaml b/pubspec.yaml index 55f3dfc9..d6d264b6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,8 @@ name: test -version: 0.12.3+8 + +# This version should really be 0.12.4-dev, but scheduled_test depends on +# test <0.12.4, so we're using + instead. +version: 0.12.3+dev author: Dart Team <misc@dartlang.org> description: A library for writing dart unit tests. homepage: https://github.com/dart-lang/test @@ -33,3 +36,4 @@ dependencies: matcher: '>=0.12.0 <0.12.1' dev_dependencies: fake_async: '^0.1.2' + scheduled_test: '^0.12.2' diff --git a/test/io.dart b/test/io.dart index 7bb87336..93f5c583 100644 --- a/test/io.dart +++ b/test/io.dart @@ -8,8 +8,11 @@ import 'dart:async'; import 'dart:io'; import 'package:path/path.dart' as p; +import 'package:scheduled_test/descriptor.dart' as d; +import 'package:scheduled_test/scheduled_process.dart'; +import 'package:scheduled_test/scheduled_stream.dart'; +import 'package:scheduled_test/scheduled_test.dart'; import 'package:test/src/util/io.dart'; -import 'package:test/src/utils.dart'; /// The path to the root directory of the `test` package. final String packageDir = p.dirname(p.dirname(libraryPath(#test.test.io))); @@ -28,25 +31,93 @@ final String noSuchFileMessage = Platform.isWindows final _servingRegExp = new RegExp(r'^Serving myapp [a-z]+ on http://localhost:(\d+)$'); +/// A future that will return the port of a pub serve instance run via +/// [runPubServe]. +/// +/// This should only be called after [runPubServe]. +Future<int> get pubServePort => _pubServePortCompleter.future; +Completer<int> _pubServePortCompleter; + +/// The path to the sandbox directory. +/// +/// This is only set in tests for which [useSandbox] is active. +String get sandbox => _sandbox; +String _sandbox; + +/// Declares a [setUp] function that creates a sandbox diretory and sets it as +/// the default for scheduled_test's directory descriptors. +/// +/// This should be called outside of any tests. If [additionalSetup] is passed, +/// it's run after the sandbox creation has been scheduled. +void useSandbox([void additionalSetup()]) { + setUp(() { + _sandbox = createTempDir(); + d.defaultRoot = _sandbox; + + currentSchedule.onComplete.schedule(() { + try { + new Directory(_sandbox).deleteSync(recursive: true); + } on IOException catch (_) { + // Silently swallow exceptions on Windows. If the test failed, there may + // still be lingering processes that have files in the sandbox open, + // which will cause this to fail on Windows. + if (!Platform.isWindows) rethrow; + } + }, 'deleting the sandbox directory'); + + if (additionalSetup != null) additionalSetup(); + }); +} + +/// Expects that the entire stdout stream of [test] equals [expected]. +void expectStdoutEquals(ScheduledProcess test, String expected) => + _expectStreamEquals(test.stdoutStream(), expected); + +/// Expects that the entire stderr stream of [test] equals [expected]. +void expectStderrEquals(ScheduledProcess test, String expected) => + _expectStreamEquals(test.stderrStream(), expected); + +/// Expects that the entirety of the line stream [stream] equals [expected]. +void _expectStreamEquals(Stream<String> stream, String expected) { + expect((() async { + var lines = await stream.toList(); + expect(lines.join("\n").trim(), equals(expected.trim())); + })(), completes); +} + +/// Returns a [StreamMatcher] that asserts that the stream emits strings +/// containing each string in [strings] in order. +/// +/// This expects each string in [strings] to match a different string in the +/// stream. +StreamMatcher containsInOrder(Iterable<String> strings) => + inOrder(strings.map((string) => consumeThrough(contains(string)))); + /// Runs the test executable with the package root set properly. -ProcessResult runTest(List<String> args, {String workingDirectory, - Map<String, String> environment}) { +ScheduledProcess runTest(List args, {bool compact: false, + int concurrency, Map<String, String> environment}) { + if (concurrency == null) concurrency = 1; + var allArgs = [ p.absolute(p.join(packageDir, 'bin/test.dart')), - "--package-root=${p.join(packageDir, 'packages')}" - ]..addAll(args); + "--package-root=${p.join(packageDir, 'packages')}", + "--concurrency=$concurrency" + ]; + + if (!compact) allArgs.addAll(["-r", "expanded"]); + allArgs.addAll(args); if (environment == null) environment = {}; environment.putIfAbsent("_UNITTEST_USE_COLOR", () => "false"); - // TODO(nweiz): Use ScheduledProcess once it's compatible. - return runDart(allArgs, workingDirectory: workingDirectory, - environment: environment); + return runDart(allArgs, + environment: environment, + description: "dart bin/test.dart"); } /// Runs Dart. -ProcessResult runDart(List<String> args, {String workingDirectory, - Map<String, String> environment}) { +ScheduledProcess runDart(List args, {Map<String, String> environment, + String description}) { var allArgs = Platform.executableArguments.map((arg) { // The package root might be relative, so we need to make it absolute if // we're going to run in a different working directory. @@ -55,88 +126,44 @@ ProcessResult runDart(List<String> args, {String workingDirectory, p.absolute(p.fromUri(arg.substring("--package-root=".length))); }).toList()..addAll(args); - // TODO(nweiz): Use ScheduledProcess once it's compatible. - return new _NormalizedProcessResult(Process.runSync( + return new ScheduledProcess.start( p.absolute(Platform.executable), allArgs, - workingDirectory: workingDirectory, environment: environment)); + workingDirectory: _sandbox, + environment: environment, + description: description); } /// Runs Pub. -ProcessResult runPub(List<String> args, {String workingDirectory, - Map<String, String> environment}) { - // TODO(nweiz): Use ScheduledProcess once it's compatible. - return new _NormalizedProcessResult(Process.runSync( +ScheduledProcess runPub(List args, {Map<String, String> environment}) { + return new ScheduledProcess.start( _pubPath, args, - workingDirectory: workingDirectory, environment: environment)); + workingDirectory: _sandbox, + environment: environment, + description: "pub ${args.first}"); } -/// Starts the test executable with the package root set properly. -Future<Process> startTest(List<String> args, {String workingDirectory, - Map<String, String> environment}) { - var allArgs = [ - p.absolute(p.join(packageDir, 'bin/test.dart')), - "--package-root=${p.join(packageDir, 'packages')}" - ]..addAll(args); - - if (environment == null) environment = {}; - environment.putIfAbsent("_UNITTEST_USE_COLOR", () => "false"); - - return startDart(allArgs, workingDirectory: workingDirectory, - environment: environment); -} - -/// Starts Dart. -Future<Process> startDart(List<String> args, {String workingDirectory, - Map<String, String> environment}) { - var allArgs = Platform.executableArguments.toList()..addAll(args); - - // TODO(nweiz): Use ScheduledProcess once it's compatible. - return Process.start(Platform.executable, allArgs, - workingDirectory: workingDirectory, environment: environment); -} - -/// Starts Pub. -Future<Process> startPub(List<String> args, {String workingDirectory, +/// Runs "pub serve". +/// +/// This returns assigns [_pubServePort] to a future that will complete to the +/// port of the "pub serve" instance. +ScheduledProcess runPubServe({List args, String workingDirectory, Map<String, String> environment}) { - // TODO(nweiz): Use ScheduledProcess once it's compatible. - return Process.start(_pubPath, args, - workingDirectory: workingDirectory, environment: environment); -} + _pubServePortCompleter = new Completer(); + currentSchedule.onComplete.schedule(() => _pubServePortCompleter = null); -/// Starts "pub serve". -/// -/// This returns a pair of the pub serve process and the port it's serving on. -Future<Pair<Process, int>> startPubServe({List<String> args, - String workingDirectory, Map<String, String> environment}) async { var allArgs = ['serve', '--port', '0']; if (args != null) allArgs.addAll(args); - var process = await startPub(allArgs, - workingDirectory: workingDirectory, environment: environment); - var line = await lineSplitter.bind(process.stdout) - .firstWhere(_servingRegExp.hasMatch); - var match = _servingRegExp.firstMatch(line); + var pub = runPub(allArgs, environment: environment); - return new Pair(process, int.parse(match[1])); -} + schedule(() async { + var match; + while (match == null) { + var line = await pub.stdout.next(); + match = _servingRegExp.firstMatch(line); + } + _pubServePortCompleter.complete(int.parse(match[1])); + }, "waiting for pub serve to emit its port number"); -/// A wrapper around [ProcessResult] that normalizes the newline format across -/// operating systems. -class _NormalizedProcessResult implements ProcessResult { - final ProcessResult _inner; - - int get exitCode => _inner.exitCode; - int get pid => _inner.pid; - - final String stdout; - final String stderr; - - _NormalizedProcessResult(ProcessResult inner) - : _inner = inner, - stdout = Platform.isWindows - ? inner.stdout.replaceAll("\r\n", "\n") - : inner.stdout, - stderr = Platform.isWindows - ? inner.stderr.replaceAll("\r\n", "\n") - : inner.stderr; + return pub; } diff --git a/test/runner/browser/chrome_test.dart b/test/runner/browser/chrome_test.dart index deb80a12..3011670f 100644 --- a/test/runner/browser/chrome_test.dart +++ b/test/runner/browser/chrome_test.dart @@ -4,141 +4,50 @@ @TestOn("vm") -import 'dart:async'; - -import 'package:test/test.dart'; +import 'package:scheduled_test/descriptor.dart' as d; +import 'package:scheduled_test/scheduled_stream.dart'; +import 'package:scheduled_test/scheduled_test.dart'; import 'package:test/src/runner/browser/chrome.dart'; -import 'package:test/src/util/io.dart'; -import 'package:shelf/shelf.dart' as shelf; -import 'package:shelf/shelf_io.dart' as shelf_io; -import 'package:shelf_web_socket/shelf_web_socket.dart'; import '../../io.dart'; import '../../utils.dart'; +import 'code_server.dart'; void main() { - group("running JavaScript", () { - // The JavaScript to serve in the server. We use actual JavaScript here to - // avoid the pain of compiling to JS in a test - var javaScript; - - var servePage = (request) { - var path = request.url.path; - - // We support both shelf 0.5.x and 0.6.x. The former has a leading "/" - // here, the latter does not. - if (path.startsWith("/")) path = path.substring(1); - - if (path.isEmpty) { - return new shelf.Response.ok(""" -<!doctype html> -<html> -<head> - <script src="index.js"></script> -</head> -</html> -""", headers: {'content-type': 'text/html'}); - } else if (path == "index.js") { - return new shelf.Response.ok(javaScript, - headers: {'content-type': 'application/javascript'}); - } else { - return new shelf.Response.notFound(null); - } - }; - - var server; - var webSockets; - setUp(() async { - var webSocketsController = new StreamController(); - webSockets = webSocketsController.stream; - - server = await shelf_io.serve( - new shelf.Cascade() - .add(webSocketHandler(webSocketsController.add)) - .add(servePage).handler, - 'localhost', 0); - }); + useSandbox(); - tearDown(() { - if (server != null) server.close(); + test("starts Chrome with the given URL", () { + var server = new CodeServer(); - javaScript = null; - server = null; - webSockets = null; + schedule(() async { + var chrome = new Chrome(await server.url); + currentSchedule.onComplete.schedule(() async => (await chrome).close()); }); - test("starts Chrome with the given URL", () async { - javaScript = ''' + server.handleJavaScript(''' var webSocket = new WebSocket(window.location.href.replace("http://", "ws://")); webSocket.addEventListener("open", function() { webSocket.send("loaded!"); }); -'''; - var chrome = new Chrome(baseUrlForAddress(server.address, server.port)); - - try { - var message = await (await webSockets.first).first; - expect(message, equals("loaded!")); - } finally { - chrome.close(); - } - }, - // It's not clear why, but this test in particular seems to time out - // when run in parallel with many other tests. - timeout: new Timeout.factor(2)); - - test("doesn't preserve state across runs", () { - javaScript = ''' -localStorage.setItem("data", "value"); +'''); -var webSocket = new WebSocket(window.location.href.replace("http://", "ws://")); -webSocket.addEventListener("open", function() { - webSocket.send("done"); -}); -'''; - var chrome = new Chrome(baseUrlForAddress(server.address, server.port)); - - var first = true; - webSockets.listen(expectAsync((webSocket) { - if (first) { - // The first request will set local storage data. We can't kill the - // old chrome and start a new one until we're sure that that has - // finished. - webSocket.first.then((_) { - chrome.close(); - - javaScript = ''' -var webSocket = new WebSocket(window.location.href.replace("http://", "ws://")); -webSocket.addEventListener("open", function() { - webSocket.send(localStorage.getItem("data")); -}); -'''; - chrome = new Chrome(baseUrlForAddress(server.address, server.port)); - first = false; - }); - } else { - // The second request will return the local storage data. This should - // be null, indicating that no data was saved between runs. - expect( - webSocket.first - .then((message) => expect(message, equals('null'))) - .whenComplete(chrome.close), - completes); - } - }, count: 2)); + var webSocket = server.handleWebSocket(); + + schedule(() async { + expect(await (await webSocket).first, equals("loaded!")); }); - }); + }, + // It's not clear why, but this test in particular seems to time out + // when run in parallel with many other tests. + timeout: new Timeout.factor(2)); test("a process can be killed synchronously after it's started", () async { - var server = await shelf_io.serve( - expectAsync((_) {}, count: 0), 'localhost', 0); + var server = new CodeServer(); - try { - var chrome = new Chrome(baseUrlForAddress(server.address, server.port)); + schedule(() async { + var chrome = new Chrome(await server.url); await chrome.close(); - } finally { - server.close(); - } + }); }); test("reports an error in onExit", () { @@ -147,4 +56,32 @@ webSocket.addEventListener("open", function() { expect(chrome.onExit, throwsA(isApplicationException(startsWith( "Failed to run Chrome: $noSuchFileMessage")))); }); + + test("can run successful tests", () { + d.file("test.dart", """ +import 'package:test/test.dart'; + +void main() { + test("success", () {}); +} +""").create(); + + var test = runTest(["-p", "chrome", "test.dart"]); + test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); + test.shouldExit(0); + }); + + test("can run failing tests", () { + d.file("test.dart", """ +import 'package:test/test.dart'; + +void main() { + test("failure", () => throw new TestFailure("oh no")); +} +""").create(); + + var test = runTest(["-p", "chrome", "test.dart"]); + test.stdout.expect(consumeThrough(contains("-1: Some tests failed."))); + test.shouldExit(1); + }); } diff --git a/test/runner/browser/code_server.dart b/test/runner/browser/code_server.dart new file mode 100644 index 00000000..9b114cd9 --- /dev/null +++ b/test/runner/browser/code_server.dart @@ -0,0 +1,87 @@ +// 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:shelf/shelf.dart' as shelf; +import 'package:shelf_web_socket/shelf_web_socket.dart'; +import 'package:scheduled_test/scheduled_server.dart'; + +/// A class that schedules a server to serve Dart and/or JS code and receive +/// WebSocket connections. +/// +/// This uses [ScheduledServer] under the hood, and has similar semantics: its +/// `handle*` methods all schedule a handler that must be hit before the +/// schedule will continue. +class CodeServer { + /// The underlying server. + final ScheduledServer _server; + + /// The URL of the server (including the port), once it's actually + /// instantiated. + Future<Uri> get url => _server.url; + + /// The port of the server, once it's actually instantiated. + Future<int> get port => _server.port; + + CodeServer() + : _server = new ScheduledServer("code server") { + _server.handleUnscheduled("GET", "/favicon.ico", + (_) => new shelf.Response.notFound(null)); + } + + /// Sets up a handler for the root of the server, "/", that serves a basic + /// HTML page with a script tag that will run [dart]. + void handleDart(String dart) { + _server.handle("GET", "/", (_) { + return new shelf.Response.ok(""" +<!doctype html> +<html> +<head> + <script type="application/dart" src="index.dart"></script> +</head> +</html> +""", headers: {'content-type': 'text/html'}); + }); + + _server.handle("GET", "/index.dart", (_) { + return new shelf.Response.ok(''' +import "dart:html"; + +main() async { + $dart +} +''', headers: {'content-type': 'application/dart'}); + }); + } + + /// Sets up a handler for the root of the server, "/", that serves a basic + /// HTML page with a script tag that will run [javaScript]. + void handleJavaScript(String javaScript) { + _server.handle("GET", "/", (_) { + return new shelf.Response.ok(""" +<!doctype html> +<html> +<head> + <script src="index.js"></script> +</head> +</html> +""", headers: {'content-type': 'text/html'}); + }); + + _server.handle("GET", "/index.js", (_) { + return new shelf.Response.ok(javaScript, + headers: {'content-type': 'application/javascript'}); + }); + } + + /// Handles a WebSocket connection to the root of the server, and returns a + /// future that will complete to the WebSocket. + Future<WebSocket> handleWebSocket() { + var completer = new Completer(); + _server.handle("GET", "/", webSocketHandler(completer.complete)); + return completer.future; + } +} diff --git a/test/runner/browser/compact_reporter_test.dart b/test/runner/browser/compact_reporter_test.dart index 529f308d..30d402be 100644 --- a/test/runner/browser/compact_reporter_test.dart +++ b/test/runner/browser/compact_reporter_test.dart @@ -4,27 +4,16 @@ @TestOn("vm") -import 'dart:io'; - -import 'package:path/path.dart' as p; -import 'package:test/src/util/io.dart'; -import 'package:test/test.dart'; +import 'package:scheduled_test/descriptor.dart' as d; +import 'package:scheduled_test/scheduled_test.dart'; import '../../io.dart'; -String _sandbox; - void main() { - setUp(() { - _sandbox = createTempDir(); - }); - - tearDown(() { - new Directory(_sandbox).deleteSync(recursive: true); - }); + useSandbox(); test("prints the platform name when running on multiple platforms", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + d.file("test.dart", """ import 'dart:async'; import 'package:path/path.dart' as p; @@ -33,24 +22,18 @@ import 'package:test/test.dart'; void main() { test("success", () {}); } -"""); - - var result = _runTest([ - "-r", - "compact", - "-p", - "content-shell", - "-p", - "vm", - "-j", - "1", +""").create(); + + var test = runTest([ + "-r", "compact", + "-p", "content-shell", + "-p", "vm", + "-j", "1", "test.dart" - ]); - expect(result.stdout, contains("[VM]")); - expect(result.stdout, contains("[Dartium Content Shell]")); - expect(result.exitCode, equals(0)); + ], compact: true); + + test.stdout.expect(containsInOrder(["[VM]", "[Dartium Content Shell]"])); + + test.shouldExit(0); }); } - -ProcessResult _runTest(List<String> args) => - runTest(args, workingDirectory: _sandbox); diff --git a/test/runner/browser/content_shell_test.dart b/test/runner/browser/content_shell_test.dart index e466a753..afe64150 100644 --- a/test/runner/browser/content_shell_test.dart +++ b/test/runner/browser/content_shell_test.dart @@ -4,146 +4,48 @@ @TestOn("vm") -import 'dart:async'; - -import 'package:shelf/shelf.dart' as shelf; -import 'package:shelf/shelf_io.dart' as shelf_io; -import 'package:shelf_web_socket/shelf_web_socket.dart'; +import 'package:scheduled_test/descriptor.dart' as d; +import 'package:scheduled_test/scheduled_stream.dart'; +import 'package:scheduled_test/scheduled_test.dart'; import 'package:test/src/runner/browser/content_shell.dart'; -import 'package:test/src/util/io.dart'; -import 'package:test/src/utils.dart'; -import 'package:test/test.dart'; import '../../io.dart'; import '../../utils.dart'; +import 'code_server.dart'; void main() { - group("running Dart", () { - // The Dart to serve in the server. - var dart; - - var servePage = (request) { - var path = shelfUrl(request).path; - - if (path.isEmpty) { - return new shelf.Response.ok(""" -<!doctype html> -<html> -<head> - <script type="application/dart" src="index.dart"></script> -</head> -</html> -""", headers: {'content-type': 'text/html'}); - } else if (path == "index.dart") { - return new shelf.Response.ok(''' -import "dart:js" as js; -import "dart:html"; - -main() async { - js.context['testRunner'].callMethod('waitUntilDone', []); - - $dart -} -''', headers: {'content-type': 'application/dart'}); - } else { - return new shelf.Response.notFound(null); - } - }; - - var server; - var webSockets; - setUp(() async { - var webSocketsController = new StreamController(); - webSockets = webSocketsController.stream; - - server = await shelf_io.serve( - new shelf.Cascade() - .add(webSocketHandler(webSocketsController.add)) - .add(servePage).handler, - 'localhost', 0); - }); + useSandbox(); - tearDown(() { - if (server != null) server.close(); + test("starts content shell with the given URL", () { + var server = new CodeServer(); - dart = null; - server = null; - webSockets = null; + schedule(() async { + var contentShell = new ContentShell(await server.url); + currentSchedule.onComplete.schedule( + () async => (await contentShell).close()); }); - test("starts content shell with the given URL", () async { - dart = ''' + server.handleDart(''' var webSocket = new WebSocket( window.location.href.replaceFirst("http://", "ws://")); await webSocket.onOpen.first; webSocket.send("loaded!"); -'''; - var contentShell = new ContentShell( - baseUrlForAddress(server.address, server.port)); - - try { - var message = await (await webSockets.first).first; - expect(message, equals("loaded!")); - } finally { - contentShell.close(); - } - }); +'''); - test("doesn't preserve state across runs", () { - dart = ''' -window.localStorage["data"] = "value"; + var webSocket = server.handleWebSocket(); -var webSocket = new WebSocket( - window.location.href.replaceFirst("http://", "ws://")); -await webSocket.onOpen.first; -webSocket.send("done"); -'''; - var contentShell = new ContentShell( - baseUrlForAddress(server.address, server.port)); - - var first = true; - webSockets.listen(expectAsync((webSocket) { - if (first) { - // The first request will set local storage data. We can't kill the - // old content shell and start a new one until we're sure that that - // has finished. - webSocket.first.then((_) { - contentShell.close(); - - dart = ''' -var webSocket = new WebSocket( - window.location.href.replaceFirst("http://", "ws://")); -await webSocket.onOpen.first; -webSocket.send(window.localStorage["data"].toString()); -'''; - contentShell = new ContentShell( - baseUrlForAddress(server.address, server.port)); - first = false; - }); - } else { - // The second request will return the local storage data. This should - // be null, indicating that no data was saved between runs. - expect( - webSocket.first - .then((message) => expect(message, equals('null'))) - .whenComplete(contentShell.close), - completes); - } - }, count: 2)); + schedule(() async { + expect(await (await webSocket).first, equals("loaded!")); }); - }); + }, skip: "Failing with mysterious WebSocket issues."); test("a process can be killed synchronously after it's started", () async { - var server = await shelf_io.serve( - expectAsync((_) {}, count: 0), 'localhost', 0); + var server = new CodeServer(); - try { - var contentShell = - new ContentShell(baseUrlForAddress(server.address, server.port)); + schedule(() async { + var contentShell = new ContentShell(await server.url); await contentShell.close(); - } finally { - server.close(); - } + }); }); test("reports an error in onExit", () { @@ -152,4 +54,32 @@ webSocket.send(window.localStorage["data"].toString()); expect(contentShell.onExit, throwsA(isApplicationException(startsWith( "Failed to run Content Shell: $noSuchFileMessage")))); }); + + test("can run successful tests", () { + d.file("test.dart", """ +import 'package:test/test.dart'; + +void main() { + test("success", () {}); +} +""").create(); + + var test = runTest(["-p", "content-shell", "test.dart"]); + test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); + test.shouldExit(0); + }); + + test("can run failing tests", () { + d.file("test.dart", """ +import 'package:test/test.dart'; + +void main() { + test("failure", () => throw new TestFailure("oh no")); +} +""").create(); + + var test = runTest(["-p", "content-shell", "test.dart"]); + test.stdout.expect(consumeThrough(contains("-1: Some tests failed."))); + test.shouldExit(1); + }); } diff --git a/test/runner/browser/dartium_test.dart b/test/runner/browser/dartium_test.dart index 6968b5dd..cb51c39a 100644 --- a/test/runner/browser/dartium_test.dart +++ b/test/runner/browser/dartium_test.dart @@ -4,152 +4,47 @@ @TestOn("vm") -import 'dart:async'; -import 'dart:io'; - -import 'package:path/path.dart' as p; -import 'package:shelf/shelf.dart' as shelf; -import 'package:shelf/shelf_io.dart' as shelf_io; -import 'package:shelf_web_socket/shelf_web_socket.dart'; +import 'package:scheduled_test/descriptor.dart' as d; +import 'package:scheduled_test/scheduled_stream.dart'; +import 'package:scheduled_test/scheduled_test.dart'; import 'package:test/src/runner/browser/dartium.dart'; -import 'package:test/src/util/io.dart'; -import 'package:test/src/utils.dart'; -import 'package:test/test.dart'; import '../../io.dart'; import '../../utils.dart'; - -String _sandbox; +import 'code_server.dart'; void main() { - setUp(() { - _sandbox = createTempDir(); - }); - - tearDown(() { - new Directory(_sandbox).deleteSync(recursive: true); - }); - - group("running Dart", () { - // The Dart to serve in the server. - var dart; - - var servePage = (request) { - var path = shelfUrl(request).path; - - if (path.isEmpty) { - return new shelf.Response.ok(""" -<!doctype html> -<html> -<head> - <script type="application/dart" src="index.dart"></script> -</head> -</html> -""", headers: {'content-type': 'text/html'}); - } else if (path == "index.dart") { - return new shelf.Response.ok(''' -import "dart:html"; - -main() async { - $dart -} -''', headers: {'content-type': 'application/dart'}); - } else { - return new shelf.Response.notFound(null); - } - }; - - var server; - var webSockets; - setUp(() async { - var webSocketsController = new StreamController(); - webSockets = webSocketsController.stream; - - server = await shelf_io.serve( - new shelf.Cascade() - .add(webSocketHandler(webSocketsController.add)) - .add(servePage).handler, - 'localhost', 0); - }); + useSandbox(); - tearDown(() { - if (server != null) server.close(); + test("starts Dartium with the given URL", () { + var server = new CodeServer(); - dart = null; - server = null; - webSockets = null; + schedule(() async { + var dartium = new Dartium(await server.url); + currentSchedule.onComplete.schedule(() async => (await dartium).close()); }); - test("starts Dartium with the given URL", () async { - dart = ''' + server.handleDart(''' var webSocket = new WebSocket( window.location.href.replaceFirst("http://", "ws://")); await webSocket.onOpen.first; webSocket.send("loaded!"); -'''; - var dartium = new Dartium(baseUrlForAddress(server.address, server.port)); - - try { - var message = await (await webSockets.first).first; - expect(message, equals("loaded!")); - } finally { - dartium.close(); - } - }); +'''); - test("doesn't preserve state across runs", () { - dart = ''' -window.localStorage["data"] = "value"; + var webSocket = server.handleWebSocket(); -var webSocket = new WebSocket( - window.location.href.replaceFirst("http://", "ws://")); -await webSocket.onOpen.first; -webSocket.send("done"); -'''; - var dartium = new Dartium(baseUrlForAddress(server.address, server.port)); - - var first = true; - webSockets.listen(expectAsync((webSocket) { - if (first) { - // The first request will set local storage data. We can't kill the - // old Dartium and start a new one until we're sure that that has - // finished. - webSocket.first.then((_) { - dartium.close(); - - dart = ''' -var webSocket = new WebSocket( - window.location.href.replaceFirst("http://", "ws://")); -await webSocket.onOpen.first; -webSocket.send(window.localStorage["data"].toString()); -'''; - dartium = new Dartium( - baseUrlForAddress(server.address, server.port)); - first = false; - }); - } else { - // The second request will return the local storage data. This should - // be null, indicating that no data was saved between runs. - expect( - webSocket.first - .then((message) => expect(message, equals('null'))) - .whenComplete(dartium.close), - completes); - } - }, count: 2)); + schedule(() async { + expect(await (await webSocket).first, equals("loaded!")); }); }); test("a process can be killed synchronously after it's started", () async { - var server = await shelf_io.serve( - expectAsync((_) {}, count: 0), 'localhost', 0); + var server = new CodeServer(); - try { - var dartium = new Dartium(baseUrlForAddress(server.address, server.port)); + schedule(() async { + var dartium = new Dartium(await server.url); await dartium.close(); - } finally { - server.close(); - } + }); }); test("reports an error in onExit", () { @@ -160,32 +55,31 @@ webSocket.send(window.localStorage["data"].toString()); }); test("can run successful tests", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + d.file("test.dart", """ import 'package:test/test.dart'; void main() { test("success", () {}); } -"""); +""").create(); - var result = _runTest(["-p", "dartium", "test.dart"]); - expect(result.stdout, isNot(contains("Compiling"))); - expect(result.exitCode, equals(0)); + var test = runTest(["-p", "dartium", "test.dart"]); + test.stdout.fork().expect(never(contains("Compiling"))); + test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); + test.shouldExit(0); }); test("can run failing tests", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + d.file("test.dart", """ import 'package:test/test.dart'; void main() { test("failure", () => throw new TestFailure("oh no")); } -"""); +""").create(); - var result = _runTest(["-p", "dartium", "test.dart"]); - expect(result.exitCode, equals(1)); + var test = runTest(["-p", "dartium", "test.dart"]); + test.stdout.expect(consumeThrough(contains("-1: Some tests failed."))); + test.shouldExit(1); }); } - -ProcessResult _runTest(List<String> args) => - runTest(args, workingDirectory: _sandbox); diff --git a/test/runner/browser/expanded_reporter_test.dart b/test/runner/browser/expanded_reporter_test.dart index a75eeced..06ca5473 100644 --- a/test/runner/browser/expanded_reporter_test.dart +++ b/test/runner/browser/expanded_reporter_test.dart @@ -4,53 +4,36 @@ @TestOn("vm") -import 'dart:io'; - -import 'package:path/path.dart' as p; -import 'package:test/src/util/io.dart'; -import 'package:test/test.dart'; +import 'package:scheduled_test/descriptor.dart' as d; +import 'package:scheduled_test/scheduled_stream.dart'; +import 'package:scheduled_test/scheduled_test.dart'; import '../../io.dart'; -String _sandbox; - void main() { - setUp(() { - _sandbox = createTempDir(); - }); - - tearDown(() { - new Directory(_sandbox).deleteSync(recursive: true); - }); + useSandbox(); test("prints the platform name when running on multiple platforms", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + d.file("test.dart", """ import 'dart:async'; -import 'package:path/path.dart' as p; import 'package:test/test.dart'; void main() { test("success", () {}); } -"""); - - var result = _runTest([ - "-r", - "expanded", - "-p", - "content-shell", - "-p", - "vm", - "-j", - "1", +""").create(); + + var test = runTest([ + "-r", "expanded", + "-p", "content-shell", + "-p", "vm", + "-j", "1", "test.dart" ]); - expect(result.stdout, contains("[VM]")); - expect(result.stdout, contains("[Dartium Content Shell]")); - expect(result.exitCode, equals(0)); + + test.stdout.fork().expect(consumeThrough(contains("[VM]"))); + test.stdout.expect(consumeThrough(contains("[Dartium Content Shell]"))); + test.shouldExit(0); }); } - -ProcessResult _runTest(List<String> args) => - runTest(args, workingDirectory: _sandbox); diff --git a/test/runner/browser/firefox_test.dart b/test/runner/browser/firefox_test.dart index 4539641d..f123679b 100644 --- a/test/runner/browser/firefox_test.dart +++ b/test/runner/browser/firefox_test.dart @@ -4,150 +4,47 @@ @TestOn("vm") -import 'dart:async'; -import 'dart:io'; - -import 'package:path/path.dart' as p; -import 'package:test/test.dart'; +import 'package:scheduled_test/descriptor.dart' as d; +import 'package:scheduled_test/scheduled_stream.dart'; +import 'package:scheduled_test/scheduled_test.dart'; import 'package:test/src/runner/browser/firefox.dart'; -import 'package:test/src/util/io.dart'; -import 'package:shelf/shelf.dart' as shelf; -import 'package:shelf/shelf_io.dart' as shelf_io; -import 'package:shelf_web_socket/shelf_web_socket.dart'; import '../../io.dart'; import '../../utils.dart'; - -String _sandbox; +import 'code_server.dart'; void main() { - setUp(() { - _sandbox = createTempDir(); - }); + useSandbox(); - tearDown(() { - new Directory(_sandbox).deleteSync(recursive: true); - }); + test("starts Firefox with the given URL", () { + var server = new CodeServer(); - group("running JavaScript", () { - // The JavaScript to serve in the server. We use actual JavaScript here to - // avoid the pain of compiling to JS in a test - var javaScript; - - var servePage = (request) { - var path = request.url.path; - - // We support both shelf 0.5.x and 0.6.x. The former has a leading "/" - // here, the latter does not. - if (path.startsWith("/")) path = path.substring(1); - - if (path.isEmpty) { - return new shelf.Response.ok(""" -<!doctype html> -<html> -<head> - <script src="index.js"></script> -</head> -</html> -""", headers: {'content-type': 'text/html'}); - } else if (path == "index.js") { - return new shelf.Response.ok(javaScript, - headers: {'content-type': 'application/javascript'}); - } else { - return new shelf.Response.notFound(null); - } - }; - - var server; - var webSockets; - setUp(() async { - var webSocketsController = new StreamController(); - webSockets = webSocketsController.stream; - - server = await shelf_io.serve( - new shelf.Cascade() - .add(webSocketHandler(webSocketsController.add)) - .add(servePage).handler, - 'localhost', 0); + schedule(() async { + var firefox = new Firefox(await server.url); + currentSchedule.onComplete.schedule(() async => (await firefox).close()); }); - tearDown(() { - if (server != null) server.close(); - - javaScript = null; - server = null; - webSockets = null; - }); - - test("starts Firefox with the given URL", () async { - javaScript = ''' + server.handleJavaScript(''' var webSocket = new WebSocket(window.location.href.replace("http://", "ws://")); webSocket.addEventListener("open", function() { webSocket.send("loaded!"); }); -'''; - var firefox = new Firefox(baseUrlForAddress(server.address, server.port)); - - try { - var message = await (await webSockets.first).first; - expect(message, equals("loaded!")); - } finally { - firefox.close(); - } - }); +'''); - test("doesn't preserve state across runs", () { - javaScript = ''' -localStorage.setItem("data", "value"); + var webSocket = server.handleWebSocket(); -var webSocket = new WebSocket(window.location.href.replace("http://", "ws://")); -webSocket.addEventListener("open", function() { - webSocket.send("done"); -}); -'''; - var firefox = new Firefox(baseUrlForAddress(server.address, server.port)); - - var first = true; - webSockets.listen(expectAsync((webSocket) { - if (first) { - // The first request will set local storage data. We can't kill the - // old firefox and start a new one until we're sure that that has - // finished. - webSocket.first.then((_) { - firefox.close(); - - javaScript = ''' -var webSocket = new WebSocket(window.location.href.replace("http://", "ws://")); -webSocket.addEventListener("open", function() { - webSocket.send(localStorage.getItem("data")); -}); -'''; - firefox = new Firefox(baseUrlForAddress(server.address, server.port)); - first = false; - }); - } else { - // The second request will return the local storage data. This should - // be null, indicating that no data was saved between runs. - expect( - webSocket.first - .then((message) => expect(message, equals('null'))) - .whenComplete(firefox.close), - completes); - } - }, count: 2)); + schedule(() async { + expect(await (await webSocket).first, equals("loaded!")); }); }); test("a process can be killed synchronously after it's started", () async { - var server = await shelf_io.serve( - expectAsync((_) {}, count: 0), 'localhost', 0); + var server = new CodeServer(); - try { - var firefox = new Firefox(baseUrlForAddress(server.address, server.port)); + schedule(() async { + var firefox = new Firefox(await server.url); await firefox.close(); - } finally { - server.close(); - } + }); }); test("reports an error in onExit", () { @@ -157,45 +54,31 @@ webSocket.addEventListener("open", function() { "Failed to run Firefox: $noSuchFileMessage")))); }); - group("can run successful tests", () { - setUp(() { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + test("can run successful tests", () { + d.file("test.dart", """ import 'package:test/test.dart'; void main() { test("success", () {}); } -"""); - }); +""").create(); - test("itself", () { - var result = _runTest(["-p", "firefox", "test.dart"]); - expect(result.exitCode, equals(0)); - }); - - test("alongside another browser", () { - var result = _runTest(["-p", "firefox", "-p", "chrome", "test.dart"]); - - // Only one browser should compile the code. - expect(result.stdout.contains("[Chrome] compiling"), - isNot(result.stdout.contains("[Firefox] compiling"))); - expect(result.exitCode, equals(0)); - }); + var test = runTest(["-p", "firefox", "test.dart"]); + test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); + test.shouldExit(0); }); test("can run failing tests", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + d.file("test.dart", """ import 'package:test/test.dart'; void main() { test("failure", () => throw new TestFailure("oh no")); } -"""); +""").create(); - var result = _runTest(["-p", "firefox", "test.dart"]); - expect(result.exitCode, equals(1)); + var test = runTest(["-p", "firefox", "test.dart"]); + test.stdout.expect(consumeThrough(contains("-1: Some tests failed."))); + test.shouldExit(1); }); } - -ProcessResult _runTest(List<String> args) => - runTest(args, workingDirectory: _sandbox); diff --git a/test/runner/browser/internet_explorer_test.dart b/test/runner/browser/internet_explorer_test.dart index 02469918..f363f443 100644 --- a/test/runner/browser/internet_explorer_test.dart +++ b/test/runner/browser/internet_explorer_test.dart @@ -4,99 +4,47 @@ @TestOn("vm && windows") -import 'dart:async'; - -import 'package:test/test.dart'; +import 'package:scheduled_test/descriptor.dart' as d; +import 'package:scheduled_test/scheduled_stream.dart'; +import 'package:scheduled_test/scheduled_test.dart'; import 'package:test/src/runner/browser/internet_explorer.dart'; -import 'package:test/src/util/io.dart'; -import 'package:shelf/shelf.dart' as shelf; -import 'package:shelf/shelf_io.dart' as shelf_io; -import 'package:shelf_web_socket/shelf_web_socket.dart'; import '../../io.dart'; import '../../utils.dart'; +import 'code_server.dart'; void main() { - group("running JavaScript", () { - // The JavaScript to serve in the server. We use actual JavaScript here to - // avoid the pain of compiling to JS in a test - var javaScript; - - var servePage = (request) { - var path = request.url.path; - - // We support both shelf 0.5.x and 0.6.x. The former has a leading "/" - // here, the latter does not. - if (path.startsWith("/")) path = path.substring(1); - - if (path.isEmpty) { - return new shelf.Response.ok(""" -<!doctype html> -<html> -<head> - <script src="index.js"></script> -</head> -</html> -""", headers: {'content-type': 'text/html'}); - } else if (path == "index.js") { - return new shelf.Response.ok(javaScript, - headers: {'content-type': 'application/javascript'}); - } else { - return new shelf.Response.notFound(null); - } - }; - - var server; - var webSockets; - setUp(() async { - var webSocketsController = new StreamController(); - webSockets = webSocketsController.stream; - - server = await shelf_io.serve( - new shelf.Cascade() - .add(webSocketHandler(webSocketsController.add)) - .add(servePage).handler, - 'localhost', 0); - }); + useSandbox(); - tearDown(() { - if (server != null) server.close(); + test("starts IE with the given URL", () async { + var server = new CodeServer(); - javaScript = null; - server = null; - webSockets = null; + schedule(() async { + var ie = new InternetExplorer(await server.url); + currentSchedule.onComplete.schedule(() async => (await ie).close()); }); - test("starts IE with the given URL", () async { - javaScript = ''' + server.handleJavaScript(''' var webSocket = new WebSocket(window.location.href.replace("http://", "ws://")); webSocket.addEventListener("open", function() { webSocket.send("loaded!"); }); -'''; - var ie = new InternetExplorer( - baseUrlForAddress(server.address, server.port)); - - try { - var message = await (await webSockets.first).first; - expect(message, equals("loaded!")); - } finally { - ie.close(); - } +'''); + + var webSocket = server.handleWebSocket(); + + schedule(() async { + expect(await (await webSocket).first, equals("loaded!")); }); }); test("a process can be killed synchronously after it's started", () async { - var server = await shelf_io.serve( - expectAsync((_) {}, count: 0), 'localhost', 0); + var server = new CodeServer(); - try { - var ie = new InternetExplorer( - baseUrlForAddress(server.address, server.port)); + schedule(() async { + var ie = new InternetExplorer(await server.url); await ie.close(); - } finally { - server.close(); - } + }); }); test("reports an error in onExit", () { @@ -105,4 +53,32 @@ webSocket.addEventListener("open", function() { expect(ie.onExit, throwsA(isApplicationException(startsWith( "Failed to run Internet Explorer: $noSuchFileMessage")))); }); + + test("can run successful tests", () { + d.file("test.dart", """ +import 'package:test/test.dart'; + +void main() { + test("success", () {}); +} +""").create(); + + var test = runTest(["-p", "ie", "test.dart"]); + test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); + test.shouldExit(0); + }); + + test("can run failing tests", () { + d.file("test.dart", """ +import 'package:test/test.dart'; + +void main() { + test("failure", () => throw new TestFailure("oh no")); +} +""").create(); + + var test = runTest(["-p", "ie", "test.dart"]); + test.stdout.expect(consumeThrough(contains("-1: Some tests failed."))); + test.shouldExit(1); + }); } diff --git a/test/runner/browser/phantom_js_test.dart b/test/runner/browser/phantom_js_test.dart index bd34adaa..1e915a39 100644 --- a/test/runner/browser/phantom_js_test.dart +++ b/test/runner/browser/phantom_js_test.dart @@ -4,154 +4,48 @@ @TestOn("vm") -import 'dart:async'; -import 'dart:io'; - -import 'package:path/path.dart' as p; -import 'package:test/test.dart'; +import 'package:scheduled_test/descriptor.dart' as d; +import 'package:scheduled_test/scheduled_stream.dart'; +import 'package:scheduled_test/scheduled_test.dart'; import 'package:test/src/runner/browser/phantom_js.dart'; -import 'package:test/src/util/io.dart'; -import 'package:shelf/shelf.dart' as shelf; -import 'package:shelf/shelf_io.dart' as shelf_io; -import 'package:shelf_web_socket/shelf_web_socket.dart'; import '../../io.dart'; import '../../utils.dart'; - -String _sandbox; +import 'code_server.dart'; void main() { - setUp(() { - _sandbox = createTempDir(); - }); + useSandbox(); - tearDown(() { - new Directory(_sandbox).deleteSync(recursive: true); - }); + test("starts PhantomJS with the given URL", () { + var server = new CodeServer(); - group("running JavaScript", () { - // The JavaScript to serve in the server. We use actual JavaScript here to - // avoid the pain of compiling to JS in a test - var javaScript; - - var servePage = (request) { - var path = request.url.path; - - // We support both shelf 0.5.x and 0.6.x. The former has a leading "/" - // here, the latter does not. - if (path.startsWith("/")) path = path.substring(1); - - if (path.isEmpty) { - return new shelf.Response.ok(""" -<!doctype html> -<html> -<head> - <script src="index.js"></script> -</head> -</html> -""", headers: {'content-type': 'text/html'}); - } else if (path == "index.js") { - return new shelf.Response.ok(javaScript, - headers: {'content-type': 'application/javascript'}); - } else { - return new shelf.Response.notFound(null); - } - }; - - var server; - var webSockets; - setUp(() async { - var webSocketsController = new StreamController(); - webSockets = webSocketsController.stream; - - server = await shelf_io.serve( - new shelf.Cascade() - .add(webSocketHandler(webSocketsController.add)) - .add(servePage).handler, - 'localhost', 0); + schedule(() async { + var phantomJS = new PhantomJS(await server.url); + currentSchedule.onComplete.schedule( + () async => (await phantomJS).close()); }); - tearDown(() { - if (server != null) server.close(); - - javaScript = null; - server = null; - webSockets = null; - }); - - test("starts PhantomJs with the given URL", () async { - javaScript = ''' + server.handleJavaScript(''' var webSocket = new WebSocket(window.location.href.replace("http://", "ws://")); webSocket.addEventListener("open", function() { webSocket.send("loaded!"); }); -'''; - var phantomJS = new PhantomJS( - baseUrlForAddress(server.address, server.port)); - - try { - var message = await (await webSockets.first).first; - expect(message, equals("loaded!")); - } finally { - phantomJS.close(); - } - }); +'''); - test("doesn't preserve state across runs", () { - javaScript = ''' -localStorage.setItem("data", "value"); + var webSocket = server.handleWebSocket(); -var webSocket = new WebSocket(window.location.href.replace("http://", "ws://")); -webSocket.addEventListener("open", function() { - webSocket.send("done"); -}); -'''; - var phantomJS = new PhantomJS( - baseUrlForAddress(server.address, server.port)); - - var first = true; - webSockets.listen(expectAsync((webSocket) { - if (first) { - // The first request will set local storage data. We can't kill the - // old PhantomJS and start a new one until we're sure that that has - // finished. - webSocket.first.then((_) { - phantomJS.close(); - - javaScript = ''' -var webSocket = new WebSocket(window.location.href.replace("http://", "ws://")); -webSocket.addEventListener("open", function() { - webSocket.send(localStorage.getItem("data")); -}); -'''; - phantomJS = new PhantomJS( - baseUrlForAddress(server.address, server.port)); - first = false; - }); - } else { - // The second request will return the local storage data. This should - // be null, indicating that no data was saved between runs. - expect( - webSocket.first - .then((message) => expect(message, equals('null'))) - .whenComplete(phantomJS.close), - completes); - } - }, count: 2)); + schedule(() async { + expect(await (await webSocket).first, equals("loaded!")); }); }); test("a process can be killed synchronously after it's started", () async { - var server = await shelf_io.serve( - expectAsync((_) {}, count: 0), 'localhost', 0); + var server = new CodeServer(); - try { - var phantomJS = new PhantomJS( - baseUrlForAddress(server.address, server.port)); + schedule(() async { + var phantomJS = new PhantomJS(await server.url); await phantomJS.close(); - } finally { - server.close(); - } + }); }); test("reports an error in onExit", () { @@ -162,31 +56,30 @@ webSocket.addEventListener("open", function() { }); test("can run successful tests", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + d.file("test.dart", """ import 'package:test/test.dart'; void main() { test("success", () {}); } -"""); +""").create(); - var result = _runTest(["-p", "phantomjs", "test.dart"]); - expect(result.exitCode, equals(0)); + var test = runTest(["-p", "phantomjs", "test.dart"]); + test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); + test.shouldExit(0); }); test("can run failing tests", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + d.file("test.dart", """ import 'package:test/test.dart'; void main() { test("failure", () => throw new TestFailure("oh no")); } -"""); +""").create(); - var result = _runTest(["-p", "phantomjs", "test.dart"]); - expect(result.exitCode, equals(1)); + var test = runTest(["-p", "phantomjs", "test.dart"]); + test.stdout.expect(consumeThrough(contains("-1: Some tests failed."))); + test.shouldExit(1); }); } - -ProcessResult _runTest(List<String> args) => - runTest(args, workingDirectory: _sandbox); diff --git a/test/runner/browser/runner_test.dart b/test/runner/browser/runner_test.dart index ec17e038..14ad58da 100644 --- a/test/runner/browser/runner_test.dart +++ b/test/runner/browser/runner_test.dart @@ -4,16 +4,12 @@ @TestOn("vm") -import 'dart:io'; - -import 'package:path/path.dart' as p; -import 'package:test/src/util/io.dart'; -import 'package:test/test.dart'; +import 'package:scheduled_test/descriptor.dart' as d; +import 'package:scheduled_test/scheduled_stream.dart'; +import 'package:scheduled_test/scheduled_test.dart'; import '../../io.dart'; -String _sandbox; - final _success = """ import 'package:test/test.dart'; @@ -31,137 +27,109 @@ void main() { """; void main() { - setUp(() { - _sandbox = createTempDir(); - }); - - tearDown(() { - new Directory(_sandbox).deleteSync(recursive: true); - }); + useSandbox(); group("fails gracefully if", () { test("a test file fails to compile", () { - var testPath = p.join(_sandbox, "test.dart"); - new File(testPath).writeAsStringSync("invalid Dart file"); - var result = _runTest(["-p", "chrome", "test.dart"]); - - var relativePath = p.relative(testPath, from: _sandbox); - expect(result.stdout, allOf([ - contains("Expected a declaration, but got 'invalid'"), - contains('-1: compiling $relativePath'), - contains('Failed to load "$relativePath": dart2js failed.') + d.file("test.dart", "invalid Dart file").create(); + var test = runTest(["-p", "chrome", "test.dart"]); + + test.stdout.expect(containsInOrder([ + "Expected a declaration, but got 'invalid'", + '-1: compiling test.dart', + 'Failed to load "test.dart": dart2js failed.' ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); test("a test file throws", () { - var testPath = p.join(_sandbox, "test.dart"); - new File(testPath).writeAsStringSync("void main() => throw 'oh no';"); - - var relativePath = p.relative(testPath, from: _sandbox); - var result = _runTest(["-p", "chrome", "test.dart"]); - expect(result.stdout, allOf([ - contains('-1: compiling $relativePath'), - contains('Failed to load "$relativePath": oh no') + d.file("test.dart", "void main() => throw 'oh no';").create(); + + var test = runTest(["-p", "chrome", "test.dart"]); + test.stdout.expect(containsInOrder([ + '-1: compiling test.dart', + 'Failed to load "test.dart": oh no' ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); test("a test file doesn't have a main defined", () { - var testPath = p.join(_sandbox, "test.dart"); - new File(testPath).writeAsStringSync("void foo() {}"); - - var relativePath = p.relative(testPath, from: _sandbox); - var result = _runTest(["-p", "chrome", "test.dart"]); - expect(result.stdout, allOf([ - contains('-1: compiling $relativePath'), - contains('Failed to load "$relativePath": No top-level main() function ' - 'defined.') + d.file("test.dart", "void foo() {}").create(); + + var test = runTest(["-p", "chrome", "test.dart"]); + test.stdout.expect(containsInOrder([ + '-1: compiling test.dart', + 'Failed to load "test.dart": No top-level main() function defined.' ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); test("a test file has a non-function main", () { - var testPath = p.join(_sandbox, "test.dart"); - new File(testPath).writeAsStringSync("int main;"); - - var relativePath = p.relative(testPath, from: _sandbox); - var result = _runTest(["-p", "chrome", "test.dart"]); - expect(result.stdout, allOf([ - contains('-1: compiling $relativePath'), - contains('Failed to load "$relativePath": Top-level main getter is not ' - 'a function.\n') + d.file("test.dart", "int main;").create(); + + var test = runTest(["-p", "chrome", "test.dart"]); + test.stdout.expect(containsInOrder([ + '-1: compiling test.dart', + 'Failed to load "test.dart": Top-level main getter is not a function.' ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); test("a test file has a main with arguments", () { - var testPath = p.join(_sandbox, "test.dart"); - new File(testPath).writeAsStringSync("void main(arg) {}"); - - var relativePath = p.relative(testPath, from: _sandbox); - var result = _runTest(["-p", "chrome", "test.dart"]); - expect(result.stdout, allOf([ - contains('-1: compiling $relativePath'), - contains('Failed to load "$relativePath": Top-level main() function ' - 'takes arguments.\n') + d.file("test.dart", "void main(arg) {}").create(); + + var test = runTest(["-p", "chrome", "test.dart"]); + test.stdout.expect(containsInOrder([ + '-1: compiling test.dart', + 'Failed to load "test.dart": Top-level main() function takes arguments.' ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); test("a custom HTML file has no script tag", () { - var testPath = p.join(_sandbox, "test.dart"); - new File(testPath).writeAsStringSync("void main(arg) {}"); + d.file("test.dart", "void main() {}").create(); - new File(p.join(_sandbox, "test.html")).writeAsStringSync(""" + d.file("test.html", """ <html> <head> <link rel="x-dart-test" href="test.dart"> </head> </html> -"""); - - var relativePath = p.relative(testPath, from: _sandbox); - var result = _runTest(["-p", "content-shell", "test.dart"]); - expect(result.stdout, allOf([ - contains('-1: loading $relativePath'), - contains( - 'Failed to load "$relativePath": ' - '"${p.withoutExtension(relativePath)}.html" must contain ' - '<script src="packages/test/dart.js"></script>.\n') +""").create(); + + var test = runTest(["-p", "content-shell", "test.dart"]); + test.stdout.expect(containsInOrder([ + '-1: loading test.dart', + 'Failed to load "test.dart": "test.html" must contain ' + '<script src="packages/test/dart.js"></script>.' ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); test("a custom HTML file has no link", () { - var testPath = p.join(_sandbox, "test.dart"); - new File(testPath).writeAsStringSync("void main(arg) {}"); + d.file("test.dart", "void main() {}").create(); - new File(p.join(_sandbox, "test.html")).writeAsStringSync(""" + d.file("test.html", """ <html> <head> <script src="packages/test/dart.js"></script> </head> </html> -"""); - - var relativePath = p.relative(testPath, from: _sandbox); - var result = _runTest(["-p", "content-shell", "test.dart"]); - expect(result.stdout, allOf([ - contains('-1: loading $relativePath'), - contains( - 'Failed to load "$relativePath": ' - 'Expected exactly 1 <link rel="x-dart-test"> in test.html, ' - 'found 0.\n') +""").create(); + + var test = runTest(["-p", "content-shell", "test.dart"]); + test.stdout.expect(containsInOrder([ + '-1: loading test.dart', + 'Failed to load "test.dart": Expected exactly 1 ' + '<link rel="x-dart-test"> in test.html, found 0.' ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); test("a custom HTML file has too many links", () { - var testPath = p.join(_sandbox, "test.dart"); - new File(testPath).writeAsStringSync("void main(arg) {}"); + d.file("test.dart", "void main() {}").create(); - new File(p.join(_sandbox, "test.html")).writeAsStringSync(""" + d.file("test.html", """ <html> <head> <link rel='x-dart-test' href='test.dart'> @@ -169,67 +137,56 @@ void main() { <script src="packages/test/dart.js"></script> </head> </html> -"""); - - var relativePath = p.relative(testPath, from: _sandbox); - var result = _runTest(["-p", "content-shell", "test.dart"]); - expect(result.stdout, allOf([ - contains('-1: loading $relativePath'), - contains( - 'Failed to load "$relativePath": ' - 'Expected exactly 1 <link rel="x-dart-test"> in test.html, ' - 'found 2.\n') +""").create(); + + var test = runTest(["-p", "content-shell", "test.dart"]); + test.stdout.expect(containsInOrder([ + '-1: loading test.dart', + 'Failed to load "test.dart": Expected exactly 1 ' + '<link rel="x-dart-test"> in test.html, found 2.' ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); test("a custom HTML file has no href in the link", () { - var testPath = p.join(_sandbox, "test.dart"); - new File(testPath).writeAsStringSync("void main(arg) {}"); + d.file("test.dart", "void main() {}").create(); - new File(p.join(_sandbox, "test.html")).writeAsStringSync(""" + d.file("test.html", """ <html> <head> <link rel='x-dart-test'> <script src="packages/test/dart.js"></script> </head> </html> -"""); - - var relativePath = p.relative(testPath, from: _sandbox); - var result = _runTest(["-p", "content-shell", "test.dart"]); - expect(result.stdout, allOf([ - contains('-1: loading $relativePath'), - contains( - 'Failed to load "$relativePath": ' - 'Expected <link rel="x-dart-test"> in test.html to have an ' - '"href" attribute.\n') +""").create(); + + var test = runTest(["-p", "content-shell", "test.dart"]); + test.stdout.expect(containsInOrder([ + '-1: loading test.dart', + 'Failed to load "test.dart": Expected <link rel="x-dart-test"> in ' + 'test.html to have an "href" attribute.' ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); test("a custom HTML file has an invalid test URL", () { - var testPath = p.join(_sandbox, "test.dart"); - new File(testPath).writeAsStringSync("void main(arg) {}"); + d.file("test.dart", "void main() {}").create(); - new File(p.join(_sandbox, "test.html")).writeAsStringSync(""" + d.file("test.html", """ <html> <head> <link rel='x-dart-test' href='wrong.dart'> <script src="packages/test/dart.js"></script> </head> </html> -"""); - - var relativePath = p.relative(testPath, from: _sandbox); - var result = _runTest(["-p", "content-shell", "test.dart"]); - expect(result.stdout, allOf([ - contains('-1: loading $relativePath'), - contains( - 'Failed to load "$relativePath": ' - 'Failed to load script at ') +""").create(); + + var test = runTest(["-p", "content-shell", "test.dart"]); + test.stdout.expect(containsInOrder([ + '-1: loading test.dart', + 'Failed to load "test.dart": Failed to load script at ' ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); // TODO(nweiz): test what happens when a test file is unreadable once issue @@ -237,53 +194,35 @@ void main() { }); group("runs successful tests", () { - test("on Chrome", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(_success); - var result = _runTest(["-p", "chrome", "test.dart"]); - expect(result.exitCode, equals(0)); - }); - - test("on Safari", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(_success); - var result = _runTest(["-p", "safari", "test.dart"]); - expect(result.exitCode, equals(0)); - }, testOn: "mac-os"); - - test("on content shell", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(_success); - var result = _runTest(["-p", "content-shell", "test.dart"]); - expect(result.stdout, isNot(contains("Compiling"))); - expect(result.exitCode, equals(0)); - }); - test("on a JS and non-JS browser", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(_success); - var result = _runTest( - ["-p", "content-shell", "-p", "chrome", "test.dart"]); - expect(result.stdout, contains("[Chrome] compiling")); - expect(result.stdout, - isNot(contains("[Dartium Content Shell] compiling"))); - expect(result.exitCode, equals(0)); + d.file("test.dart", _success).create(); + var test = runTest(["-p", "content-shell", "-p", "chrome", "test.dart"]); + + test.stdout.fork().expect(consumeThrough(contains("[Chrome] compiling"))); + test.stdout.expect(never(contains("[Dartium Content Shell] compiling"))); + test.shouldExit(0); }); test("on a browser and the VM", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(_success); - var result = _runTest(["-p", "content-shell", "-p", "vm", "test.dart"]); - expect(result.exitCode, equals(0)); + d.file("test.dart", _success).create(); + var test = runTest(["-p", "content-shell", "-p", "vm", "test.dart"]); + + test.stdout.expect(consumeThrough(contains("+2: All tests passed!"))); + test.shouldExit(0); }); // Regression test; this broke in 0.12.0-beta.9. test("on a file in a subdirectory", () { - new Directory(p.join(_sandbox, "dir")).createSync(); - new File(p.join(_sandbox, "dir", "test.dart")) - .writeAsStringSync(_success); - var result = _runTest(["-p", "chrome", "dir/test.dart"]); - expect(result.exitCode, equals(0)); + d.dir("dir", [d.file("test.dart", _success)]).create(); + + var test = runTest(["-p", "chrome", "dir/test.dart"]); + test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); + test.shouldExit(0); }); group("with a custom HTML file", () { setUp(() { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + d.file("test.dart", """ import 'dart:html'; import 'package:test/test.dart'; @@ -293,9 +232,9 @@ void main() { expect(document.query('#foo'), isNotNull); }); } -"""); +""").create(); - new File(p.join(_sandbox, "test.html")).writeAsStringSync(""" + d.file("test.html", """ <html> <head> <link rel='x-dart-test' href='test.dart'> @@ -305,22 +244,24 @@ void main() { <div id="foo"></div> </body> </html> -"""); +""").create(); }); test("on content shell", () { - var result = _runTest(["-p", "content-shell", "test.dart"]); - expect(result.exitCode, equals(0)); + var test = runTest(["-p", "content-shell", "test.dart"]); + test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); + test.shouldExit(0); }); test("on Chrome", () { - var result = _runTest(["-p", "chrome", "test.dart"]); - expect(result.exitCode, equals(0)); + var test = runTest(["-p", "chrome", "test.dart"]); + test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); + test.shouldExit(0); }); // Regression test for https://github.com/dart-lang/test/issues/82. test("ignores irrelevant link tags", () { - new File(p.join(_sandbox, "test.html")).writeAsStringSync(""" + d.file("test.html", """ <html> <head> <link rel='x-dart-test-not'> @@ -332,35 +273,18 @@ void main() { <div id="foo"></div> </body> </html> -"""); +""").create(); - var result = _runTest(["-p", "content-shell", "test.dart"]); - expect(result.exitCode, equals(0)); + var test = runTest(["-p", "content-shell", "test.dart"]); + test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); + test.shouldExit(0); }); }); }); group("runs failing tests", () { - test("on Chrome", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(_failure); - var result = _runTest(["-p", "chrome", "test.dart"]); - expect(result.exitCode, equals(1)); - }); - - test("on Safari", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(_failure); - var result = _runTest(["-p", "safari", "test.dart"]); - expect(result.exitCode, equals(1)); - }, testOn: "mac-os"); - - test("on content-shell", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(_failure); - var result = _runTest(["-p", "content-shell", "test.dart"]); - expect(result.exitCode, equals(1)); - }); - test("that fail only on the browser", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + d.file("test.dart", """ import 'dart:async'; import 'package:path/path.dart' as p; @@ -371,13 +295,15 @@ void main() { if (p.style == p.Style.url) throw new TestFailure("oh no"); }); } -"""); - var result = _runTest(["-p", "content-shell", "-p", "vm", "test.dart"]); - expect(result.exitCode, equals(1)); +""").create(); + + var test = runTest(["-p", "content-shell", "-p", "vm", "test.dart"]); + test.stdout.expect(consumeThrough(contains("+1 -1: Some tests failed."))); + test.shouldExit(1); }); test("that fail only on the VM", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + d.file("test.dart", """ import 'dart:async'; import 'package:path/path.dart' as p; @@ -388,15 +314,16 @@ void main() { if (p.style != p.Style.url) throw new TestFailure("oh no"); }); } -"""); - var result = _runTest(["-p", "content-shell", "-p", "vm", "test.dart"]); - expect(result.exitCode, equals(1)); - }); +""").create(); + var test = runTest(["-p", "content-shell", "-p", "vm", "test.dart"]); + test.stdout.expect(consumeThrough(contains("+1 -1: Some tests failed."))); + test.shouldExit(1); + }); group("with a custom HTML file", () { setUp(() { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + d.file("test.dart", """ import 'dart:html'; import 'package:test/test.dart'; @@ -406,9 +333,9 @@ void main() { expect(document.query('#foo'), isNull); }); } -"""); +""").create(); - new File(p.join(_sandbox, "test.html")).writeAsStringSync(""" + d.file("test.html", """ <html> <head> <link rel='x-dart-test' href='test.dart'> @@ -418,32 +345,33 @@ void main() { <div id="foo"></div> </body> </html> -"""); +""").create(); }); test("on content shell", () { - var result = _runTest(["-p", "content-shell", "test.dart"]); - expect(result.exitCode, equals(1)); + var test = runTest(["-p", "content-shell", "test.dart"]); + test.stdout.expect(consumeThrough(contains("-1: Some tests failed."))); + test.shouldExit(1); }); test("on Chrome", () { - var result = _runTest(["-p", "chrome", "test.dart"]); - expect(result.exitCode, equals(1)); + var test = runTest(["-p", "chrome", "test.dart"]); + test.stdout.expect(consumeThrough(contains("-1: Some tests failed."))); + test.shouldExit(1); }); }); }); test("the compiler uses colors if the test runner uses colors", () { - var testPath = p.join(_sandbox, "test.dart"); - new File(testPath).writeAsStringSync("String main() => 12;\n"); + d.file("test.dart", "String main() => 12;\n").create(); - var result = _runTest(["--color", "-p", "chrome", "test.dart"]); - expect(result.stdout, contains('\u001b[35m')); - expect(result.exitCode, equals(1)); + var test = runTest(["--color", "-p", "chrome", "test.dart"]); + test.stdout.expect(consumeThrough(contains('\u001b[35m'))); + test.shouldExit(1); }); test("forwards prints from the browser test", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + d.file("test.dart", """ import 'dart:async'; import 'package:test/test.dart'; @@ -454,34 +382,42 @@ void main() { return new Future(() => print("world!")); }); } -"""); - - var result = _runTest(["-p", "content-shell", "test.dart"]); - expect(result.stdout, contains("Hello,\nworld!\n")); - expect(result.exitCode, equals(0)); +""").create(); + + var test = runTest(["-p", "content-shell", "test.dart"]); + test.stdout.expect(inOrder([ + consumeThrough("Hello,"), + "world!" + ])); + test.shouldExit(0); }); test("dartifies stack traces for JS-compiled tests by default", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(_failure); - var result = _runTest(["-p", "chrome", "--verbose-trace", "test.dart"]); - expect(result.stdout, contains(" main.<fn>\n")); - expect(result.stdout, contains("package:test")); - expect(result.stdout, contains("dart:async/zone.dart")); - expect(result.exitCode, equals(1)); + d.file("test.dart", _failure).create(); + + var test = runTest(["-p", "chrome", "--verbose-trace", "test.dart"]); + test.stdout.expect(containsInOrder([ + " main.<fn>", + "package:test", + "dart:async/zone.dart" + ])); + test.shouldExit(1); }); test("doesn't dartify stack traces for JS-compiled tests with --js-trace", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(_failure); - var result = _runTest( + d.file("test.dart", _failure).create(); + + var test = runTest( ["-p", "chrome", "--verbose-trace", "--js-trace", "test.dart"]); - expect(result.stdout, isNot(contains(" main.<fn>\n"))); - expect(result.stdout, isNot(contains("package:test"))); - expect(result.stdout, isNot(contains("dart:async/zone.dart"))); - expect(result.exitCode, equals(1)); + test.stdout.fork().expect(never(endsWith(" main.<fn>"))); + test.stdout.fork().expect(never(contains("package:test"))); + test.stdout.fork().expect(never(contains("dart:async/zone.dart"))); + test.stdout.expect(consumeThrough(contains("-1: Some tests failed."))); + test.shouldExit(1); }); test("respects top-level @Timeout declarations", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(''' + d.file("test.dart", ''' @Timeout(const Duration(seconds: 0)) import 'dart:async'; @@ -491,16 +427,19 @@ import 'package:test/test.dart'; void main() { test("timeout", () {}); } -'''); - - var result = _runTest(["-p", "content-shell", "test.dart"]); - expect(result.stdout, contains("Test timed out after 0 seconds.")); - expect(result.stdout, contains("-1: Some tests failed.")); +''').create(); + + var test = runTest(["-p", "content-shell", "test.dart"]); + test.stdout.expect(containsInOrder([ + "Test timed out after 0 seconds.", + "-1: Some tests failed." + ])); + test.shouldExit(1); }); group("with onPlatform", () { test("respects matching Skips", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(''' + d.file("test.dart", ''' import 'dart:async'; import 'package:test/test.dart'; @@ -508,14 +447,15 @@ import 'package:test/test.dart'; void main() { test("fail", () => throw 'oh no', onPlatform: {"browser": new Skip()}); } -'''); +''').create(); - var result = _runTest(["-p", "content-shell", "test.dart"]); - expect(result.stdout, contains("+0 ~1: All tests skipped.")); + var test = runTest(["-p", "content-shell", "test.dart"]); + test.stdout.expect(consumeThrough(contains("+0 ~1: All tests skipped."))); + test.shouldExit(0); }); test("ignores non-matching Skips", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(''' + d.file("test.dart", ''' import 'dart:async'; import 'package:test/test.dart'; @@ -523,14 +463,15 @@ import 'package:test/test.dart'; void main() { test("success", () {}, onPlatform: {"vm": new Skip()}); } -'''); +''').create(); - var result = _runTest(["-p", "content-shell", "test.dart"]); - expect(result.stdout, contains("+1: All tests passed!")); + var test = runTest(["-p", "content-shell", "test.dart"]); + test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); + test.shouldExit(0); }); test("respects matching Timeouts", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(''' + d.file("test.dart", ''' import 'dart:async'; import 'package:test/test.dart'; @@ -540,15 +481,18 @@ void main() { "browser": new Timeout(new Duration(seconds: 0)) }); } -'''); +''').create(); - var result = _runTest(["-p", "content-shell", "test.dart"]); - expect(result.stdout, contains("Test timed out after 0 seconds.")); - expect(result.stdout, contains("-1: Some tests failed.")); + var test = runTest(["-p", "content-shell", "test.dart"]); + test.stdout.expect(containsInOrder([ + "Test timed out after 0 seconds.", + "-1: Some tests failed." + ])); + test.shouldExit(1); }); test("ignores non-matching Timeouts", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(''' + d.file("test.dart", ''' import 'dart:async'; import 'package:test/test.dart'; @@ -558,14 +502,15 @@ void main() { "vm": new Timeout(new Duration(seconds: 0)) }); } -'''); +''').create(); - var result = _runTest(["-p", "content-shell", "test.dart"]); - expect(result.stdout, contains("+1: All tests passed!")); + var test = runTest(["-p", "content-shell", "test.dart"]); + test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); + test.shouldExit(0); }); test("applies matching platforms in order", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(''' + d.file("test.dart", ''' import 'dart:async'; import 'package:test/test.dart'; @@ -579,22 +524,21 @@ void main() { "browser || android": new Skip("fifth") }); } -'''); - - var result = _runTest(["-p", "content-shell", "test.dart"]); - expect(result.stdout, contains("Skip: fifth")); - expect(result.stdout, isNot(anyOf([ - contains("Skip: first"), - contains("Skip: second"), - contains("Skip: third"), - contains("Skip: fourth") - ]))); +''').create(); + + var test = runTest(["-p", "content-shell", "test.dart"]); + test.stdout.fork().expect(never(contains("Skip: first"))); + test.stdout.fork().expect(never(contains("Skip: second"))); + test.stdout.fork().expect(never(contains("Skip: third"))); + test.stdout.fork().expect(never(contains("Skip: fourth"))); + test.stdout.expect(consumeThrough(contains("Skip: fifth"))); + test.shouldExit(0); }); }); group("with an @OnPlatform annotation", () { test("respects matching Skips", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(''' + d.file("test.dart", ''' @OnPlatform(const {"browser": const Skip()}) import 'dart:async'; @@ -604,14 +548,15 @@ import 'package:test/test.dart'; void main() { test("fail", () => throw 'oh no'); } -'''); +''').create(); - var result = _runTest(["-p", "content-shell", "test.dart"]); - expect(result.stdout, contains("+0 ~1: All tests skipped.")); + var test = runTest(["-p", "content-shell", "test.dart"]); + test.stdout.expect(consumeThrough(contains("~1: All tests skipped."))); + test.shouldExit(0); }); test("ignores non-matching Skips", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(''' + d.file("test.dart", ''' @OnPlatform(const {"vm": const Skip()}) import 'dart:async'; @@ -621,14 +566,15 @@ import 'package:test/test.dart'; void main() { test("success", () {}); } -'''); +''').create(); - var result = _runTest(["-p", "content-shell", "test.dart"]); - expect(result.stdout, contains("+1: All tests passed!")); + var test = runTest(["-p", "content-shell", "test.dart"]); + test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); + test.shouldExit(0); }); test("respects matching Timeouts", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(''' + d.file("test.dart", ''' @OnPlatform(const { "browser": const Timeout(const Duration(seconds: 0)) }) @@ -640,15 +586,18 @@ import 'package:test/test.dart'; void main() { test("fail", () => throw 'oh no'); } -'''); +''').create(); - var result = _runTest(["-p", "content-shell", "test.dart"]); - expect(result.stdout, contains("Test timed out after 0 seconds.")); - expect(result.stdout, contains("-1: Some tests failed.")); + var test = runTest(["-p", "content-shell", "test.dart"]); + test.stdout.expect(containsInOrder([ + "Test timed out after 0 seconds.", + "-1: Some tests failed." + ])); + test.shouldExit(1); }); test("ignores non-matching Timeouts", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(''' + d.file("test.dart", ''' @OnPlatform(const { "vm": const Timeout(const Duration(seconds: 0)) }) @@ -660,13 +609,11 @@ import 'package:test/test.dart'; void main() { test("success", () {}); } -'''); +''').create(); - var result = _runTest(["-p", "content-shell", "test.dart"]); - expect(result.stdout, contains("+1: All tests passed!")); + var test = runTest(["-p", "content-shell", "test.dart"]); + test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); + test.shouldExit(0); }); }); } - -ProcessResult _runTest(List<String> args) => - runTest(args, workingDirectory: _sandbox); diff --git a/test/runner/browser/safari_test.dart b/test/runner/browser/safari_test.dart index 254a0fc8..85d4f56f 100644 --- a/test/runner/browser/safari_test.dart +++ b/test/runner/browser/safari_test.dart @@ -4,138 +4,48 @@ @TestOn("vm && mac-os") -import 'dart:async'; - -import 'package:test/test.dart'; +import 'package:scheduled_test/descriptor.dart' as d; +import 'package:scheduled_test/scheduled_stream.dart'; +import 'package:scheduled_test/scheduled_test.dart'; import 'package:test/src/runner/browser/safari.dart'; -import 'package:test/src/util/io.dart'; -import 'package:shelf/shelf.dart' as shelf; -import 'package:shelf/shelf_io.dart' as shelf_io; -import 'package:shelf_web_socket/shelf_web_socket.dart'; import '../../io.dart'; import '../../utils.dart'; +import 'code_server.dart'; void main() { - group("running JavaScript", () { - // The JavaScript to serve in the server. We use actual JavaScript here to - // avoid the pain of compiling to JS in a test - var javaScript; - - var servePage = (request) { - var path = request.url.path; - - // We support both shelf 0.5.x and 0.6.x. The former has a leading "/" - // here, the latter does not. - if (path.startsWith("/")) path = path.substring(1); - - if (path.isEmpty) { - return new shelf.Response.ok(""" -<!doctype html> -<html> -<head> - <script src="index.js"></script> -</head> -</html> -""", headers: {'content-type': 'text/html'}); - } else if (path == "index.js") { - return new shelf.Response.ok(javaScript, - headers: {'content-type': 'application/javascript'}); - } else { - return new shelf.Response.notFound(null); - } - }; - - var server; - var webSockets; - setUp(() async { - var webSocketsController = new StreamController(); - webSockets = webSocketsController.stream; - - server = await shelf_io.serve( - new shelf.Cascade() - .add(webSocketHandler(webSocketsController.add)) - .add(servePage).handler, - 'localhost', 0); - }); + useSandbox(); - tearDown(() { - if (server != null) server.close(); + test("starts Safari with the given URL", () { + var server = new CodeServer(); - javaScript = null; - server = null; - webSockets = null; + schedule(() async { + var safari = new Safari(await server.url); + currentSchedule.onComplete.schedule( + () async => (await safari).close()); }); - test("starts Safari with the given URL", () async { - javaScript = ''' + server.handleJavaScript(''' var webSocket = new WebSocket(window.location.href.replace("http://", "ws://")); webSocket.addEventListener("open", function() { webSocket.send("loaded!"); }); -'''; - var safari = new Safari(baseUrlForAddress(server.address, server.port)); - - try { - var message = await (await webSockets.first).first; - expect(message, equals("loaded!")); - } finally { - safari.close(); - } - }); +'''); - test("doesn't preserve state across runs", () { - javaScript = ''' -localStorage.setItem("data", "value"); + var webSocket = server.handleWebSocket(); -var webSocket = new WebSocket(window.location.href.replace("http://", "ws://")); -webSocket.addEventListener("open", function() { - webSocket.send("done"); -}); -'''; - var safari = new Safari(baseUrlForAddress(server.address, server.port)); - - var first = true; - webSockets.listen(expectAsync((webSocket) { - if (first) { - // The first request will set local storage data. We can't kill the - // old safari and start a new one until we're sure that that has - // finished. - webSocket.first.then((_) { - safari.close(); - - javaScript = ''' -var webSocket = new WebSocket(window.location.href.replace("http://", "ws://")); -webSocket.addEventListener("open", function() { - webSocket.send(localStorage.getItem("data")); -}); -'''; - safari = new Safari(baseUrlForAddress(server.address, server.port)); - first = false; - }); - } else { - // The second request will return the local storage data. This should - // be null, indicating that no data was saved between runs. - expect( - webSocket.first - .then((message) => expect(message, equals('null'))) - .whenComplete(safari.close), - completes); - } - }, count: 2)); + schedule(() async { + expect(await (await webSocket).first, equals("loaded!")); }); }); test("a process can be killed synchronously after it's started", () async { - var server = await shelf_io.serve( - expectAsync((_) {}, count: 0), 'localhost', 0); + var server = new CodeServer(); - try { - var safari = new Safari(baseUrlForAddress(server.address, server.port)); + schedule(() async { + var safari = new Safari(await server.url); await safari.close(); - } finally { - server.close(); - } + }); }); test("reports an error in onExit", () { @@ -144,4 +54,32 @@ webSocket.addEventListener("open", function() { expect(safari.onExit, throwsA(isApplicationException(startsWith( "Failed to run Safari: $noSuchFileMessage")))); }); + + test("can run successful tests", () { + d.file("test.dart", """ +import 'package:test/test.dart'; + +void main() { + test("success", () {}); +} +""").create(); + + var test = runTest(["-p", "safari", "test.dart"]); + test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); + test.shouldExit(0); + }); + + test("can run failing tests", () { + d.file("test.dart", """ +import 'package:test/test.dart'; + +void main() { + test("failure", () => throw new TestFailure("oh no")); +} +""").create(); + + var test = runTest(["-p", "safari", "test.dart"]); + test.stdout.expect(consumeThrough(contains("-1: Some tests failed."))); + test.shouldExit(1); + }); } diff --git a/test/runner/compact_reporter_test.dart b/test/runner/compact_reporter_test.dart index 5a4b6561..967021f2 100644 --- a/test/runner/compact_reporter_test.dart +++ b/test/runner/compact_reporter_test.dart @@ -4,22 +4,21 @@ @TestOn("vm") -import 'dart:io'; - -import 'package:path/path.dart' as p; -import 'package:test/src/util/io.dart'; -import 'package:test/test.dart'; +import 'package:scheduled_test/descriptor.dart' as d; +import 'package:scheduled_test/scheduled_stream.dart'; +import 'package:scheduled_test/scheduled_test.dart'; import '../io.dart'; void main() { + useSandbox(); + test("reports when no tests are run", () { - return withTempDir((path) { - new File(p.join(path, "test.dart")).writeAsStringSync("void main() {}"); - var result = runTest(["-r", "compact", "test.dart"], - workingDirectory: path); - expect(result.stdout, contains("No tests ran.")); - }); + d.file("test.dart", "void main() {}").create(); + + var test = runTest(["test.dart"], compact: true); + test.stdout.expect(consumeThrough(contains("No tests ran."))); + test.shouldExit(0); }); test("runs several successful tests and reports when each completes", () { @@ -67,8 +66,7 @@ void main() { }); test("includes the full stack trace with --verbose-trace", () { - return withTempDir((path) { - new File(p.join(path, "test.dart")).writeAsStringSync(""" + d.file("test.dart", """ import 'dart:async'; import 'package:test/test.dart'; @@ -76,11 +74,11 @@ import 'package:test/test.dart'; void main() { test("failure", () => throw "oh no"); } -"""); - var result = runTest(["-r", "compact", "--verbose-trace", "test.dart"], - workingDirectory: path); - expect(result.stdout, contains("dart:isolate-patch")); - }); +""").create(); + + var test = runTest(["--verbose-trace", "test.dart"], compact: true); + test.stdout.expect(consumeThrough(contains("dart:isolate-patch"))); + test.shouldExit(1); }); test("runs failing tests along with successful tests", () { @@ -378,10 +376,7 @@ void main() { }); } -void _expectReport(String tests, String expected, {List<String> args, - int concurrency}) { - if (concurrency == null) concurrency = 1; - +void _expectReport(String tests, String expected) { var dart = """ import 'dart:async'; @@ -392,19 +387,18 @@ $tests } """; - expect(withTempDir((path) { - new File(p.join(path, "test.dart")).writeAsStringSync(dart); - if (args == null) args = []; - args = args.toList() - ..add("test.dart") - ..add("--concurrency=$concurrency") - ..add("--reporter=compact"); - var result = runTest(args, workingDirectory: path); - - // Convert CRs into newlines, remove excess trailing whitespace, and trim - // off timestamps. + d.file("test.dart", dart).create(); + + var test = runTest(["test.dart"], compact: true); + test.shouldExit(); + + schedule(() async { + var stdoutLines = await test.stdoutStream().toList(); + + // Skip the first CR, remove excess trailing whitespace, and trim off + // timestamps. var lastLine; - var actual = result.stdout.trim().split(new RegExp(r"[\r\n]")).map((line) { + var actual = stdoutLines.skip(1).map((line) { if (line.startsWith(" ") || line.isEmpty) return line.trimRight(); var trimmed = line.trim() @@ -425,5 +419,5 @@ $tests }).join("\n"); expect(actual, equals(expected)); - }), completes); + }); } diff --git a/test/runner/expanded_reporter_test.dart b/test/runner/expanded_reporter_test.dart index d22ad8d3..a35f5692 100644 --- a/test/runner/expanded_reporter_test.dart +++ b/test/runner/expanded_reporter_test.dart @@ -4,22 +4,21 @@ @TestOn("vm") -import 'dart:io'; - -import 'package:path/path.dart' as p; -import 'package:test/src/util/io.dart'; -import 'package:test/test.dart'; +import 'package:scheduled_test/descriptor.dart' as d; +import 'package:scheduled_test/scheduled_stream.dart'; +import 'package:scheduled_test/scheduled_test.dart'; import '../io.dart'; void main() { + useSandbox(); + test("reports when no tests are run", () { - return withTempDir((path) { - new File(p.join(path, "test.dart")).writeAsStringSync("void main() {}"); - var result = runTest(["-r", "expanded", "test.dart"], - workingDirectory: path); - expect(result.stdout, contains("No tests ran.")); - }); + d.file("test.dart", "void main() {}").create(); + + var test = runTest(["test.dart"], compact: true); + test.stdout.expect(consumeThrough(contains("No tests ran."))); + test.shouldExit(0); }); test("runs several successful tests and reports when each completes", () { @@ -59,8 +58,7 @@ void main() { }); test("includes the full stack trace with --verbose-trace", () { - return withTempDir((path) { - new File(p.join(path, "test.dart")).writeAsStringSync(""" + d.file("test.dart", """ import 'dart:async'; import 'package:test/test.dart'; @@ -68,11 +66,11 @@ import 'package:test/test.dart'; void main() { test("failure", () => throw "oh no"); } -"""); - var result = runTest(["-r", "compact", "--verbose-trace", "test.dart"], - workingDirectory: path); - expect(result.stdout, contains("dart:isolate-patch")); - }); +""").create(); + + var test = runTest(["--verbose-trace", "test.dart"], compact: true); + test.stdout.expect(consumeThrough(contains("dart:isolate-patch"))); + test.shouldExit(1); }); test("runs failing tests along with successful tests", () { @@ -309,10 +307,7 @@ void main() { }); } -void _expectReport(String tests, String expected, {List<String> args, - int concurrency}) { - if (concurrency == null) concurrency = 1; - +void _expectReport(String tests, String expected) { var dart = """ import 'dart:async'; @@ -323,17 +318,16 @@ $tests } """; - expect(withTempDir((path) { - new File(p.join(path, "test.dart")).writeAsStringSync(dart); - if (args == null) args = []; - args = args.toList() - ..add("test.dart") - ..add("--concurrency=$concurrency") - ..add("--reporter=expanded"); - var result = runTest(args, workingDirectory: path); + d.file("test.dart", dart).create(); + + var test = runTest(["test.dart"]); + test.shouldExit(); + + schedule(() async { + var stdoutLines = await test.stdoutStream().toList(); // Remove excess trailing whitespace and trim off timestamps. - var actual = result.stdout.trim().split("\n").map((line) { + var actual = stdoutLines.map((line) { if (line.startsWith(" ") || line.isEmpty) return line.trimRight(); return line.trim().replaceFirst(new RegExp("^[0-9]{2}:[0-9]{2} "), ""); }).join("\n"); @@ -346,5 +340,5 @@ $tests }).join("\n"); expect(actual, equals(expected)); - }), completes); + }); } diff --git a/test/runner/pub_serve_test.dart b/test/runner/pub_serve_test.dart index 7841a546..505c04b1 100644 --- a/test/runner/pub_serve_test.dart +++ b/test/runner/pub_serve_test.dart @@ -4,21 +4,24 @@ @TestOn("vm") +import 'dart:async'; import 'dart:io'; import 'package:path/path.dart' as p; +import 'package:scheduled_test/descriptor.dart' as d; +import 'package:scheduled_test/scheduled_stream.dart'; +import 'package:scheduled_test/scheduled_test.dart'; import 'package:test/src/util/exit_codes.dart' as exit_codes; -import 'package:test/test.dart'; import '../io.dart'; -String _sandbox; +/// The `--pub-serve` argument for the test process, based on [pubServePort]. +Future<String> get _pubServeArg => + pubServePort.then((port) => '--pub-serve=$port'); void main() { - setUp(() { - _sandbox = Directory.systemTemp.createTempSync('test_').path; - - new File(p.join(_sandbox, "pubspec.yaml")).writeAsStringSync(""" + useSandbox(() { + d.file("pubspec.yaml", """ name: myapp dependencies: barback: any @@ -30,21 +33,20 @@ transformers: \$include: test/**_test.dart dependency_overrides: matcher: '0.12.0-alpha.0' -"""); - - new Directory(p.join(_sandbox, "test")).createSync(); +""").create(); - new File(p.join(_sandbox, "test", "my_test.dart")).writeAsStringSync(""" + d.dir("test", [ + d.file("my_test.dart", """ import 'package:test/test.dart'; void main() { test("test", () => expect(true, isTrue)); } -"""); +""") + ]).create(); - new Directory(p.join(_sandbox, "lib")).createSync(); - - new File(p.join(_sandbox, "lib", "myapp.dart")).writeAsStringSync(""" + d.dir("lib", [ + d.file("myapp.dart", """ import 'package:barback/barback.dart'; class MyTransformer extends Transformer { @@ -59,143 +61,111 @@ class MyTransformer extends Transformer { contents.replaceAll("isFalse", "isTrue"))); } } -"""); - - var pubGetResult = runPub(['get'], workingDirectory: _sandbox); - expect(pubGetResult.exitCode, equals(0)); - }); +""") + ]).create(); - tearDown(() { - // On Windows, there's no way to shut down the actual "pub serve" process. - // Killing the process we start will just kill the batch file wrapper (issue - // 23304), not the underlying "pub serve" process. Since that process has - // locks on files in the sandbox, we can't delete the sandbox on Windows - // without errors. - if (Platform.isWindows) return; - - new Directory(_sandbox).deleteSync(recursive: true); + runPub(['get']).shouldExit(0); }); group("with transformed tests", () { setUp(() { // Give the test a failing assertion that the transformer will convert to // a passing assertion. - new File(p.join(_sandbox, "test", "my_test.dart")).writeAsStringSync(""" + d.file("test/my_test.dart", """ import 'package:test/test.dart'; void main() { test("test", () => expect(true, isFalse)); } -"""); +""").create(); }); - test("runs those tests in the VM", () async { - var pair = await startPubServe(workingDirectory: _sandbox); - try { - var result = runTest(['--pub-serve=${pair.last}'], - workingDirectory: _sandbox); - expect(result.exitCode, equals(0)); - expect(result.stdout, contains('+1: All tests passed!')); - } finally { - pair.first.kill(); - } + test("runs those tests in the VM", () { + var pub = runPubServe(); + var test = runTest([_pubServeArg]); + test.stdout.expect(consumeThrough(contains('+1: All tests passed!'))); + test.shouldExit(0); + pub.kill(); }); - test("runs those tests on Chrome", () async { - var pair = await startPubServe(workingDirectory: _sandbox); - try { - var result = runTest(['--pub-serve=${pair.last}', '-p', 'chrome'], - workingDirectory: _sandbox); - expect(result.exitCode, equals(0)); - expect(result.stdout, contains('+1: All tests passed!')); - } finally { - pair.first.kill(); - } + test("runs those tests on Chrome", () { + var pub = runPubServe(); + var test = runTest([_pubServeArg, '-p', 'chrome']); + test.stdout.expect(consumeThrough(contains('+1: All tests passed!'))); + test.shouldExit(0); + pub.kill(); }); - test("runs those tests on content shell", () async { - var pair = await startPubServe(workingDirectory: _sandbox); - try { - var result = runTest( - ['--pub-serve=${pair.last}', '-p', 'content-shell'], - workingDirectory: _sandbox); - expect(result.exitCode, equals(0)); - expect(result.stdout, contains('+1: All tests passed!')); - } finally { - pair.first.kill(); - } + test("runs those tests on content shell", () { + var pub = runPubServe(); + var test = runTest([_pubServeArg, '-p', 'content-shell']); + test.stdout.expect(consumeThrough(contains('+1: All tests passed!'))); + test.shouldExit(0); + pub.kill(); }); test("gracefully handles pub serve running on the wrong directory for " - "VM tests", () async { - new Directory(p.join(_sandbox, "web")).createSync(); - - var pair = await startPubServe(args: ['web'], workingDirectory: _sandbox); - try { - var result = runTest(['--pub-serve=${pair.last}'], - workingDirectory: _sandbox); - expect(result.stdout, allOf([ - contains('-1: loading ${p.join("test", "my_test.dart")}'), - contains('Failed to load "${p.join("test", "my_test.dart")}":'), - contains('404 Not Found'), - contains('Make sure "pub serve" is serving the test/ directory.') - ])); - expect(result.exitCode, equals(1)); - } finally { - pair.first.kill(); - } + "VM tests", () { + d.dir("web").create(); + + var pub = runPubServe(args: ['web']); + var test = runTest([_pubServeArg]); + test.stdout.expect(containsInOrder([ + '-1: loading ${p.join("test", "my_test.dart")}', + 'Failed to load "${p.join("test", "my_test.dart")}":', + '404 Not Found', + 'Make sure "pub serve" is serving the test/ directory.' + ])); + test.shouldExit(1); + + pub.kill(); }); test("gracefully handles pub serve running on the wrong directory for " - "browser tests", () async { - new Directory(p.join(_sandbox, "web")).createSync(); - - var pair = await startPubServe(args: ['web'], workingDirectory: _sandbox); - try { - var result = runTest(['--pub-serve=${pair.last}', '-p', 'chrome'], - workingDirectory: _sandbox); - expect(result.stdout, allOf([ - contains('-1: compiling ${p.join("test", "my_test.dart")}'), - contains('Failed to load "${p.join("test", "my_test.dart")}":'), - contains('404 Not Found'), - contains('Make sure "pub serve" is serving the test/ directory.') - ])); - expect(result.exitCode, equals(1)); - } finally { - pair.first.kill(); - } + "browser tests", () { + d.dir("web").create(); + + var pub = runPubServe(args: ['web']); + var test = runTest([_pubServeArg, '-p', 'chrome']); + test.stdout.expect(containsInOrder([ + '-1: compiling ${p.join("test", "my_test.dart")}', + 'Failed to load "${p.join("test", "my_test.dart")}":', + '404 Not Found', + 'Make sure "pub serve" is serving the test/ directory.' + ])); + test.shouldExit(1); + + pub.kill(); }); - test("gracefully handles unconfigured transformers", () async { - new File(p.join(_sandbox, "pubspec.yaml")).writeAsStringSync(""" + test("gracefully handles unconfigured transformers", () { + d.file("pubspec.yaml", """ name: myapp dependencies: barback: any test: {path: ${p.current}} -"""); - - var pair = await startPubServe(workingDirectory: _sandbox); - try { - var result = runTest(['--pub-serve=${pair.last}'], - workingDirectory: _sandbox); - expect(result.exitCode, equals(exit_codes.data)); - expect(result.stderr, equals(''' +""").create(); + + var pub = runPubServe(); + var test = runTest([_pubServeArg]); + expectStderrEquals(test, ''' When using --pub-serve, you must include the "test/pub_serve" transformer in your pubspec: transformers: - test/pub_serve: \$include: test/**_test.dart -''')); - } finally { - pair.first.kill(); - } +'''); + test.shouldExit(exit_codes.data); + + pub.kill(); }); }); group("uses a custom HTML file", () { setUp(() { - new File(p.join(_sandbox, "test", "test.dart")).writeAsStringSync(""" + d.dir("test", [ + d.file("test.dart", """ import 'dart:html'; import 'package:test/test.dart'; @@ -205,9 +175,9 @@ void main() { expect(document.query('#foo'), isNull); }); } -"""); +"""), - new File(p.join(_sandbox, "test", "test.html")).writeAsStringSync(""" + d.file("test.html", """ <html> <head> <link rel='x-dart-test' href='test.dart'> @@ -216,39 +186,30 @@ void main() { <body> <div id="foo"></div> </body> -"""); +""") + ]).create(); }); - test("on Chrome", () async { - var pair = await startPubServe(workingDirectory: _sandbox); - try { - var result = runTest(['--pub-serve=${pair.last}', '-p', 'chrome'], - workingDirectory: _sandbox); - expect(result.exitCode, equals(0)); - expect(result.stdout, contains('+1: All tests passed!')); - } finally { - pair.first.kill(); - } + test("on Chrome", () { + var pub = runPubServe(); + var test = runTest([_pubServeArg, '-p', 'chrome']); + test.stdout.expect(consumeThrough(contains('+1: All tests passed!'))); + test.shouldExit(0); + pub.kill(); }); - test("on content shell", () async { - var pair = await startPubServe(workingDirectory: _sandbox); - try { - var result = runTest( - ['--pub-serve=${pair.last}', '-p', 'content-shell'], - workingDirectory: _sandbox); - expect(result.exitCode, equals(0)); - expect(result.stdout, contains('+1: All tests passed!')); - } finally { - pair.first.kill(); - } + test("on content shell", () { + var pub = runPubServe(); + var test = runTest([_pubServeArg, '-p', 'content-shell']); + test.stdout.expect(consumeThrough(contains('+1: All tests passed!'))); + test.shouldExit(0); + pub.kill(); }); }); - group("with a failing test", () { setUp(() { - new File(p.join(_sandbox, "test", "my_test.dart")).writeAsStringSync(""" + d.file("test/my_test.dart", """ import 'dart:html'; import 'package:test/test.dart'; @@ -256,88 +217,81 @@ import 'package:test/test.dart'; void main() { test("failure", () => throw 'oh no'); } -"""); +""").create(); }); - test("dartifies stack traces for JS-compiled tests by default", () async { - var pair = await startPubServe(workingDirectory: _sandbox); - try { - var result = runTest([ - '--pub-serve=${pair.last}', - '-p', 'chrome', - '--verbose-trace' - ], workingDirectory: _sandbox); - expect(result.stdout, contains(" main.<fn>\n")); - expect(result.stdout, contains("package:test")); - expect(result.stdout, contains("dart:async/zone.dart")); - expect(result.exitCode, equals(1)); - } finally { - pair.first.kill(); - } + test("dartifies stack traces for JS-compiled tests by default", () { + var pub = runPubServe(); + var test = runTest([_pubServeArg, '-p', 'chrome', '--verbose-trace']); + test.stdout.expect(containsInOrder([ + " main.<fn>", + "package:test", + "dart:async/zone.dart" + ])); + test.shouldExit(1); + pub.kill(); }); test("doesn't dartify stack traces for JS-compiled tests with --js-trace", - () async { - var pair = await startPubServe(workingDirectory: _sandbox); - try { - var result = runTest([ - '--pub-serve=${pair.last}', - '-p', 'chrome', - '--js-trace', - '--verbose-trace' - ], workingDirectory: _sandbox); - expect(result.stdout, isNot(contains(" main.<fn>\n"))); - expect(result.stdout, isNot(contains("package:test"))); - expect(result.stdout, isNot(contains("dart:async/zone.dart"))); - expect(result.exitCode, equals(1)); - } finally { - pair.first.kill(); - } + () { + var pub = runPubServe(); + var test = runTest([ + _pubServeArg, + '-p', 'chrome', + '--js-trace', + '--verbose-trace' + ]); + + test.stdout.fork().expect(never(endsWith(" main.<fn>"))); + test.stdout.fork().expect(never(contains("package:test"))); + test.stdout.fork().expect(never(contains("dart:async/zone.dart"))); + test.stdout.expect(consumeThrough(contains("-1: Some tests failed."))); + test.shouldExit(1); + + pub.kill(); }); }); test("gracefully handles pub serve not running for VM tests", () { - var result = runTest(['--pub-serve=54321'], - workingDirectory: _sandbox); - expect(result.stdout, allOf([ - contains('-1: loading ${p.join("test", "my_test.dart")}'), - contains(''' - Failed to load "${p.join("test", "my_test.dart")}": - Error getting http://localhost:54321/my_test.dart.vm_test.dart: Connection refused - Make sure "pub serve" is running.''') + var test = runTest(['--pub-serve=54321']); + test.stdout.expect(containsInOrder([ + '-1: loading ${p.join("test", "my_test.dart")}', + 'Failed to load "${p.join("test", "my_test.dart")}":', + 'Error getting http://localhost:54321/my_test.dart.vm_test.dart: ' + 'Connection refused', + 'Make sure "pub serve" is running.' ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); test("gracefully handles pub serve not running for browser tests", () { - var result = runTest(['--pub-serve=54321', '-p', 'chrome'], - workingDirectory: _sandbox); + var test = runTest(['--pub-serve=54321', '-p', 'chrome']); var message = Platform.isWindows ? 'The remote computer refused the network connection.' : 'Connection refused (errno '; - expect(result.stdout, allOf([ - contains('-1: compiling ${p.join("test", "my_test.dart")}'), - contains('Failed to load "${p.join("test", "my_test.dart")}":'), - contains('Error getting http://localhost:54321/my_test.dart.browser_test' - '.dart.js.map: $message'), - contains('Make sure "pub serve" is running.') + test.stdout.expect(containsInOrder([ + '-1: compiling ${p.join("test", "my_test.dart")}', + 'Failed to load "${p.join("test", "my_test.dart")}":', + 'Error getting http://localhost:54321/my_test.dart.browser_test.dart.js' + '.map: $message', + 'Make sure "pub serve" is running.' ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); test("gracefully handles a test file not being in test/", () { - new File(p.join(_sandbox, 'test/my_test.dart')) - .copySync(p.join(_sandbox, 'my_test.dart')); - - var result = runTest(['--pub-serve=54321', 'my_test.dart'], - workingDirectory: _sandbox); - expect(result.stdout, allOf([ - contains('-1: loading my_test.dart'), - contains( - 'Failed to load "my_test.dart": When using "pub serve", all test ' - 'files must be in test/.\n') + schedule(() { + new File(p.join(sandbox, 'test/my_test.dart')) + .copySync(p.join(sandbox, 'my_test.dart')); + }); + + var test = runTest(['--pub-serve=54321', 'my_test.dart']); + test.stdout.expect(containsInOrder([ + '-1: loading my_test.dart', + 'Failed to load "my_test.dart": When using "pub serve", all test files ' + 'must be in test/.' ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); } diff --git a/test/runner/runner_test.dart b/test/runner/runner_test.dart index 7b578d12..389c9718 100644 --- a/test/runner/runner_test.dart +++ b/test/runner/runner_test.dart @@ -8,14 +8,13 @@ import 'dart:io'; import 'dart:math' as math; import 'package:path/path.dart' as p; +import 'package:scheduled_test/descriptor.dart' as d; +import 'package:scheduled_test/scheduled_stream.dart'; +import 'package:scheduled_test/scheduled_test.dart'; import 'package:test/src/util/exit_codes.dart' as exit_codes; -import 'package:test/src/util/io.dart'; -import 'package:test/test.dart'; import '../io.dart'; -String _sandbox; - final _success = """ import 'dart:async'; @@ -71,205 +70,177 @@ Usage: pub run test:test [files or directories...] """; void main() { - setUp(() { - _sandbox = createTempDir(); - }); - - tearDown(() { - new Directory(_sandbox).deleteSync(recursive: true); - }); + useSandbox(); test("prints help information", () { - var result = _runTest(["--help"]); - expect(result.stdout, equals(""" + var test = runTest(["--help"]); + expectStdoutEquals(test, """ Runs tests in this package. -$_usage""")); - expect(result.exitCode, equals(exit_codes.success)); +$_usage"""); + test.shouldExit(0); }); group("fails gracefully if", () { test("an invalid option is passed", () { - var result = _runTest(["--asdf"]); - expect(result.stderr, equals(""" + var test = runTest(["--asdf"]); + expectStderrEquals(test, """ Could not find an option named "asdf". -$_usage""")); - expect(result.exitCode, equals(exit_codes.usage)); +$_usage"""); + test.shouldExit(exit_codes.usage); }); test("a non-existent file is passed", () { - var result = _runTest(["file"]); - expect(result.stdout, allOf([ - contains('-1: loading file'), - contains('Failed to load "file": Does not exist.') + var test = runTest(["file"]); + test.stdout.expect(containsInOrder([ + '-1: loading file', + 'Failed to load "file": Does not exist.' ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); test("the default directory doesn't exist", () { - var result = _runTest([]); - expect(result.stderr, equals(""" + var test = runTest([]); + expectStderrEquals(test, """ No test files were passed and the default "test/" directory doesn't exist. -$_usage""")); - expect(result.exitCode, equals(exit_codes.data)); +$_usage"""); + test.shouldExit(exit_codes.data); }); test("a test file fails to load", () { - var testPath = p.join(_sandbox, "test.dart"); - new File(testPath).writeAsStringSync("invalid Dart file"); - var result = _runTest(["test.dart"]); - - expect(result.stdout, allOf([ - contains('-1: loading test.dart'), - contains( - ' Failed to load "${p.relative(testPath, from: _sandbox)}":\n' - " line 1 pos 1: unexpected token 'invalid'\n" - " invalid Dart file\n" - " ^\n") + d.file("test.dart", "invalid Dart file").create(); + var test = runTest(["test.dart"]); + + test.stdout.expect(containsInOrder([ + '-1: loading test.dart', + 'Failed to load "test.dart":', + "line 1 pos 1: unexpected token 'invalid'", + "invalid Dart file", + "^" ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); // This syntax error is detected lazily, and so requires some extra // machinery to support. test("a test file fails to parse due to a missing semicolon", () { - var testPath = p.join(_sandbox, "test.dart"); - new File(testPath).writeAsStringSync("void main() {foo}"); - var result = _runTest(["test.dart"]); - - expect(result.stdout, allOf([ - contains('-1: loading test.dart'), - contains( - ' Failed to load "${p.relative(testPath, from: _sandbox)}":\n' - " line 1 pos 17: semicolon expected\n" - " void main() {foo}\n" - " ^\n") + d.file("test.dart", "void main() {foo}").create(); + var test = runTest(["test.dart"]); + + test.stdout.expect(containsInOrder([ + '-1: loading test.dart', + 'Failed to load "test.dart":', + 'line 1 pos 17: semicolon expected', + 'void main() {foo}', + ' ^' ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); // This is slightly different from the above test because it's an error // that's caught first by the analyzer when it's used to parse the file. test("a test file fails to parse", () { - var testPath = p.join(_sandbox, "test.dart"); - new File(testPath).writeAsStringSync("@TestOn)"); - var result = _runTest(["test.dart"]); - - expect(result.stdout, allOf([ - contains('-1: loading test.dart'), - contains( - ' Failed to load "${p.relative(testPath, from: _sandbox)}":\n' - " line 1 pos 8: unexpected token ')'\n" - " @TestOn)\n" - " ^\n") + d.file("test.dart", "@TestOn)").create(); + var test = runTest(["test.dart"]); + + test.stdout.expect(containsInOrder([ + '-1: loading test.dart', + 'Failed to load "test.dart":', + "line 1 pos 8: unexpected token ')'", + "@TestOn)", + " ^" ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); test("an annotation's structure is invalid", () { - var testPath = p.join(_sandbox, "test.dart"); - new File(testPath).writeAsStringSync("@TestOn()\nlibrary foo;"); - var result = _runTest(["test.dart"]); - - expect(result.stdout, allOf([ - contains('-1: loading test.dart'), - contains( - ' Failed to load "${p.relative(testPath, from: _sandbox)}":\n' - " Error on line 1, column 8: TestOn takes 1 argument.\n" - " @TestOn()\n" - " ^^\n") + d.file("test.dart", "@TestOn()\nlibrary foo;").create(); + var test = runTest(["test.dart"]); + + test.stdout.expect(containsInOrder([ + '-1: loading test.dart', + 'Failed to load "test.dart":', + "Error on line 1, column 8: TestOn takes 1 argument.", + "@TestOn()", + " ^^" ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); test("an annotation's contents are invalid", () { - var testPath = p.join(_sandbox, "test.dart"); - new File(testPath).writeAsStringSync("@TestOn('zim')\nlibrary foo;"); - var result = _runTest(["test.dart"]); - - expect(result.stdout, allOf([ - contains('-1: loading test.dart'), - contains( - ' Failed to load "${p.relative(testPath, from: _sandbox)}":\n' - " Error on line 1, column 10: Undefined variable.\n" - " @TestOn('zim')\n" - " ^^^\n") + d.file("test.dart", "@TestOn('zim')\nlibrary foo;").create(); + var test = runTest(["test.dart"]); + + test.stdout.expect(containsInOrder([ + '-1: loading test.dart', + 'Failed to load "test.dart":', + "Error on line 1, column 10: Undefined variable.", + "@TestOn('zim')", + " ^^^" ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); test("a test file throws", () { - var testPath = p.join(_sandbox, "test.dart"); - new File(testPath).writeAsStringSync("void main() => throw 'oh no';"); - - var result = _runTest(["test.dart"]); - expect(result.stdout, allOf([ - contains('-1: loading test.dart'), - contains( - 'Failed to load "${p.relative(testPath, from: _sandbox)}": oh no') + d.file("test.dart", "void main() => throw 'oh no';").create(); + var test = runTest(["test.dart"]); + + test.stdout.expect(containsInOrder([ + '-1: loading test.dart', + 'Failed to load "test.dart": oh no' ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); test("a test file doesn't have a main defined", () { - var testPath = p.join(_sandbox, "test.dart"); - new File(testPath).writeAsStringSync("void foo() {}"); - - var result = _runTest(["test.dart"]); - expect(result.stdout, allOf([ - contains('-1: loading test.dart'), - contains( - 'Failed to load "${p.relative(testPath, from: _sandbox)}": No ' - 'top-level main() function defined.') + d.file("test.dart", "void foo() {}").create(); + var test = runTest(["test.dart"]); + + test.stdout.expect(containsInOrder([ + '-1: loading test.dart', + 'Failed to load "test.dart": No top-level main() function defined.' ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); test("a test file has a non-function main", () { - var testPath = p.join(_sandbox, "test.dart"); - new File(testPath).writeAsStringSync("int main;"); - - var result = _runTest(["test.dart"]); - expect(result.stdout, allOf([ - contains('-1: loading test.dart'), - contains( - 'Failed to load "${p.relative(testPath, from: _sandbox)}": ' - 'Top-level main getter is not a function.') + d.file("test.dart", "int main;").create(); + var test = runTest(["test.dart"]); + + test.stdout.expect(containsInOrder([ + '-1: loading test.dart', + 'Failed to load "test.dart": Top-level main getter is not a function.' ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); test("a test file has a main with arguments", () { - var testPath = p.join(_sandbox, "test.dart"); - new File(testPath).writeAsStringSync("void main(arg) {}"); - - var result = _runTest(["test.dart"]); - expect(result.stdout, allOf([ - contains('-1: loading test.dart'), - contains( - 'Failed to load "${p.relative(testPath, from: _sandbox)}": ' - 'Top-level main() function takes arguments.') + d.file("test.dart", "void main(arg) {}").create(); + var test = runTest(["test.dart"]); + + test.stdout.expect(containsInOrder([ + '-1: loading test.dart', + 'Failed to load "test.dart": Top-level main() function takes arguments.' ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); test("multiple load errors occur", () { - var testPath = p.join(_sandbox, "test.dart"); - new File(testPath).writeAsStringSync("invalid Dart file"); - var result = _runTest(["test.dart", "nonexistent.dart"]); - - expect(result.stdout, allOf([ - contains('loading test.dart'), - contains( - ' Failed to load "test.dart":\n' - " line 1 pos 1: unexpected token 'invalid'\n" - " invalid Dart file\n" - " ^\n"), - contains('loading nonexistent.dart'), - contains('Failed to load "nonexistent.dart": Does not exist.') + d.file("test.dart", "invalid Dart file").create(); + var test = runTest(["test.dart", "nonexistent.dart"]); + + test.stdout.expect(containsInOrder([ + 'loading nonexistent.dart', + 'Failed to load "nonexistent.dart": Does not exist.', + 'loading test.dart', + 'Failed to load "test.dart":', + "line 1 pos 1: unexpected token 'invalid'", + "invalid Dart file", + "^" ])); + test.shouldExit(1); }); // TODO(nweiz): test what happens when a test file is unreadable once issue @@ -278,100 +249,103 @@ $_usage""")); group("runs successful tests", () { test("defined in a single file", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(_success); - var result = _runTest(["test.dart"]); - expect(result.exitCode, equals(0)); + d.file("test.dart", _success).create(); + var test = runTest(["test.dart"]); + test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); + test.shouldExit(0); }); test("defined in a directory", () { for (var i = 0; i < 3; i++) { - new File(p.join(_sandbox, "${i}_test.dart")) - .writeAsStringSync(_success); + d.file("${i}_test.dart", _success).create(); } - var result = _runTest(["."]); - expect(result.exitCode, equals(0)); + var test = runTest(["."]); + test.stdout.expect(consumeThrough(contains("+3: All tests passed!"))); + test.shouldExit(0); }); test("defaulting to the test directory", () { - new Directory(p.join(_sandbox, "test")).createSync(); - for (var i = 0; i < 3; i++) { - new File(p.join(_sandbox, "test", "${i}_test.dart")) - .writeAsStringSync(_success); - } + d.dir("test", new Iterable.generate(3, (i) { + return d.file("${i}_test.dart", _success); + })).create(); - var result = _runTest([]); - expect(result.exitCode, equals(0)); + var test = runTest([]); + test.stdout.expect(consumeThrough(contains("+3: All tests passed!"))); + test.shouldExit(0); }); test("directly", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(_success); - var result = _runDart([ + d.file("test.dart", _success).create(); + var test = runDart([ "--package-root=${p.join(packageDir, 'packages')}", "test.dart" ]); - expect(result.stdout, contains("All tests passed!")); - expect(result.exitCode, equals(0)); + + test.stdout.expect(consumeThrough(contains("All tests passed!"))); + test.shouldExit(0); }); // Regression test; this broke in 0.12.0-beta.9. test("on a file in a subdirectory", () { - new Directory(p.join(_sandbox, "dir")).createSync(); - new File(p.join(_sandbox, "dir", "test.dart")) - .writeAsStringSync(_success); - var result = _runTest(["dir/test.dart"]); - expect(result.exitCode, equals(0)); + d.dir("dir", [d.file("test.dart", _success)]).create(); + + var test = runTest(["dir/test.dart"]); + test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); + test.shouldExit(0); }); }); group("runs failing tests", () { test("defined in a single file", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(_failure); - var result = _runTest(["test.dart"]); - expect(result.exitCode, equals(1)); + d.file("test.dart", _failure).create(); + + var test = runTest(["test.dart"]); + test.stdout.expect(consumeThrough(contains("-1: Some tests failed."))); + test.shouldExit(1); }); test("defined in a directory", () { for (var i = 0; i < 3; i++) { - new File(p.join(_sandbox, "${i}_test.dart")) - .writeAsStringSync(_failure); + d.file("${i}_test.dart", _failure).create(); } - var result = _runTest(["."]); - expect(result.exitCode, equals(1)); + var test = runTest(["."]); + test.stdout.expect(consumeThrough(contains("-3: Some tests failed."))); + test.shouldExit(1); }); test("defaulting to the test directory", () { - new Directory(p.join(_sandbox, "test")).createSync(); - for (var i = 0; i < 3; i++) { - new File(p.join(_sandbox, "test", "${i}_test.dart")) - .writeAsStringSync(_failure); - } + d.dir("test", new Iterable.generate(3, (i) { + return d.file("${i}_test.dart", _failure); + })).create(); - var result = _runTest([]); - expect(result.exitCode, equals(1)); + var test = runTest([]); + test.stdout.expect(consumeThrough(contains("-3: Some tests failed."))); + test.shouldExit(1); }); test("directly", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(_failure); - var result = _runDart([ + d.file("test.dart", _failure).create(); + var test = runDart([ "--package-root=${p.join(packageDir, 'packages')}", "test.dart" ]); - expect(result.stdout, contains("Some tests failed.")); - expect(result.exitCode, isNot(equals(0))); + test.stdout.expect(consumeThrough(contains("Some tests failed."))); + test.shouldExit(255); }); }); test("runs tests even when a file fails to load", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(_success); - var result = _runTest(["test.dart", "nonexistent.dart"]); - expect(result.stdout, contains("+1 -1: Some tests failed.")); - expect(result.exitCode, equals(1)); + d.file("test.dart", _success).create(); + + var test = runTest(["test.dart", "nonexistent.dart"]); + test.stdout.expect(consumeThrough(contains("+1 -1: Some tests failed."))); + test.shouldExit(1); }); test("respects top-level @Timeout declarations", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(''' + d.file("test.dart", ''' @Timeout(const Duration(seconds: 0)) import 'dart:async'; @@ -381,15 +355,18 @@ import 'package:test/test.dart'; void main() { test("timeout", () {}); } -'''); - - var result = _runTest(["test.dart"]); - expect(result.stdout, contains("Test timed out after 0 seconds.")); - expect(result.stdout, contains("-1: Some tests failed.")); +''').create(); + + var test = runTest(["test.dart"]); + test.stdout.expect(containsInOrder([ + "Test timed out after 0 seconds.", + "-1: Some tests failed." + ])); + test.shouldExit(1); }); test("respects top-level @Skip declarations", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(''' + d.file("test.dart", ''' @Skip() import 'dart:async'; @@ -399,15 +376,16 @@ import 'package:test/test.dart'; void main() { test("fail", () => throw 'oh no'); } -'''); +''').create(); - var result = _runTest(["test.dart"]); - expect(result.stdout, contains("+0 ~1: All tests skipped.")); + var test = runTest(["test.dart"]); + test.stdout.expect(consumeThrough(contains("+0 ~1: All tests skipped."))); + test.shouldExit(0); }); group("with onPlatform", () { test("respects matching Skips", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(''' + d.file("test.dart", ''' import 'dart:async'; import 'package:test/test.dart'; @@ -415,14 +393,15 @@ import 'package:test/test.dart'; void main() { test("fail", () => throw 'oh no', onPlatform: {"vm": new Skip()}); } -'''); +''').create(); - var result = _runTest(["test.dart"]); - expect(result.stdout, contains("+0 ~1: All tests skipped.")); + var test = runTest(["test.dart"]); + test.stdout.expect(consumeThrough(contains("+0 ~1: All tests skipped."))); + test.shouldExit(0); }); test("ignores non-matching Skips", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(''' + d.file("test.dart", ''' import 'dart:async'; import 'package:test/test.dart'; @@ -430,14 +409,15 @@ import 'package:test/test.dart'; void main() { test("success", () {}, onPlatform: {"chrome": new Skip()}); } -'''); +''').create(); - var result = _runTest(["test.dart"]); - expect(result.stdout, contains("+1: All tests passed!")); + var test = runTest(["test.dart"]); + test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); + test.shouldExit(0); }); test("respects matching Timeouts", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(''' + d.file("test.dart", ''' import 'dart:async'; import 'package:test/test.dart'; @@ -447,15 +427,18 @@ void main() { "vm": new Timeout(new Duration(seconds: 0)) }); } -'''); +''').create(); - var result = _runTest(["test.dart"]); - expect(result.stdout, contains("Test timed out after 0 seconds.")); - expect(result.stdout, contains("-1: Some tests failed.")); + var test = runTest(["test.dart"]); + test.stdout.expect(containsInOrder([ + "Test timed out after 0 seconds.", + "-1: Some tests failed." + ])); + test.shouldExit(1); }); test("ignores non-matching Timeouts", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(''' + d.file("test.dart", ''' import 'dart:async'; import 'package:test/test.dart'; @@ -465,14 +448,15 @@ void main() { "chrome": new Timeout(new Duration(seconds: 0)) }); } -'''); +''').create(); - var result = _runTest(["test.dart"]); - expect(result.stdout, contains("+1: All tests passed!")); + var test = runTest(["test.dart"]); + test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); + test.shouldExit(0); }); test("applies matching platforms in order", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(''' + d.file("test.dart", ''' import 'dart:async'; import 'package:test/test.dart'; @@ -486,22 +470,21 @@ void main() { "vm || android": new Skip("fifth") }); } -'''); +''').create(); - var result = _runTest(["test.dart"]); - expect(result.stdout, contains("Skip: fifth")); - expect(result.stdout, isNot(anyOf([ - contains("Skip: first"), - contains("Skip: second"), - contains("Skip: third"), - contains("Skip: fourth") - ]))); + var test = runTest(["test.dart"]); + test.stdout.fork().expect(never(contains("Skip: first"))); + test.stdout.fork().expect(never(contains("Skip: second"))); + test.stdout.fork().expect(never(contains("Skip: third"))); + test.stdout.fork().expect(never(contains("Skip: fourth"))); + test.stdout.expect(consumeThrough(contains("Skip: fifth"))); + test.shouldExit(0); }); }); group("with an @OnPlatform annotation", () { test("respects matching Skips", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(''' + d.file("test.dart", ''' @OnPlatform(const {"vm": const Skip()}) import 'dart:async'; @@ -511,14 +494,15 @@ import 'package:test/test.dart'; void main() { test("fail", () => throw 'oh no'); } -'''); +''').create(); - var result = _runTest(["test.dart"]); - expect(result.stdout, contains("+0 ~1: All tests skipped.")); + var test = runTest(["test.dart"]); + test.stdout.expect(consumeThrough(contains("+0 ~1: All tests skipped."))); + test.shouldExit(0); }); test("ignores non-matching Skips", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(''' + d.file("test.dart", ''' @OnPlatform(const {"chrome": const Skip()}) import 'dart:async'; @@ -528,14 +512,15 @@ import 'package:test/test.dart'; void main() { test("success", () {}); } -'''); +''').create(); - var result = _runTest(["test.dart"]); - expect(result.stdout, contains("+1: All tests passed!")); + var test = runTest(["test.dart"]); + test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); + test.shouldExit(0); }); test("respects matching Timeouts", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(''' + d.file("test.dart", ''' @OnPlatform(const { "vm": const Timeout(const Duration(seconds: 0)) }) @@ -547,15 +532,18 @@ import 'package:test/test.dart'; void main() { test("fail", () => throw 'oh no'); } -'''); +''').create(); - var result = _runTest(["test.dart"]); - expect(result.stdout, contains("Test timed out after 0 seconds.")); - expect(result.stdout, contains("-1: Some tests failed.")); + var test = runTest(["test.dart"]); + test.stdout.expect(containsInOrder([ + "Test timed out after 0 seconds.", + "-1: Some tests failed." + ])); + test.shouldExit(1); }); test("ignores non-matching Timeouts", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(''' + d.file("test.dart", ''' @OnPlatform(const { "chrome": const Timeout(const Duration(seconds: 0)) }) @@ -567,24 +555,26 @@ import 'package:test/test.dart'; void main() { test("success", () {}); } -'''); +''').create(); - var result = _runTest(["test.dart"]); - expect(result.stdout, contains("+1: All tests passed!")); + var test = runTest(["test.dart"]); + test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); + test.shouldExit(0); }); }); group("flags:", () { test("with the --color flag, uses colors", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(_failure); - var result = _runTest(["--color", "test.dart"]); + d.file("test.dart", _failure).create(); + var test = runTest(["--color", "test.dart"]); // This is the color code for red. - expect(result.stdout, contains("\u001b[31m")); + test.stdout.expect(consumeThrough(contains("\u001b[31m"))); + test.shouldExit(); }); group("with the --name flag,", () { test("selects tests with matching names", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + d.file("test.dart", """ import 'dart:async'; import 'package:test/test.dart'; @@ -594,15 +584,15 @@ void main() { test("nope", () => throw new TestFailure("oh no")); test("selected 2", () {}); } -"""); +""").create(); - var result = _runTest(["--name", "selected", "test.dart"]); - expect(result.stdout, contains("+2: All tests passed!")); - expect(result.exitCode, equals(0)); + var test = runTest(["--name", "selected", "test.dart"]); + test.stdout.expect(consumeThrough(contains("+2: All tests passed!"))); + test.shouldExit(0); }); test("supports RegExp syntax", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + d.file("test.dart", """ import 'dart:async'; import 'package:test/test.dart'; @@ -612,35 +602,35 @@ void main() { test("test 2", () => throw new TestFailure("oh no")); test("test 3", () {}); } -"""); +""").create(); - var result = _runTest(["--name", "test [13]", "test.dart"]); - expect(result.stdout, contains("+2: All tests passed!")); - expect(result.exitCode, equals(0)); + var test = runTest(["--name", "test [13]", "test.dart"]); + test.stdout.expect(consumeThrough(contains("+2: All tests passed!"))); + test.shouldExit(0); }); test("produces an error when no tests match", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(_success); + d.file("test.dart", _success).create(); - var result = _runTest(["--name", "no match", "test.dart"]); - expect(result.stderr, - contains('No tests match regular expression "no match".')); - expect(result.exitCode, equals(exit_codes.data)); + var test = runTest(["--name", "no match", "test.dart"]); + test.stderr.expect(consumeThrough( + contains('No tests match regular expression "no match".'))); + test.shouldExit(exit_codes.data); }); test("doesn't filter out load exceptions", () { - var result = _runTest(["--name", "name", "file"]); - expect(result.stdout, allOf([ - contains('-1: loading file'), - contains('Failed to load "file": Does not exist.') + var test = runTest(["--name", "name", "file"]); + test.stdout.expect(containsInOrder([ + '-1: loading file', + ' Failed to load "file": Does not exist.' ])); - expect(result.exitCode, equals(1)); + test.shouldExit(1); }); }); group("with the --plain-name flag,", () { test("selects tests with matching names", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + d.file("test.dart", """ import 'dart:async'; import 'package:test/test.dart'; @@ -650,15 +640,15 @@ void main() { test("nope", () => throw new TestFailure("oh no")); test("selected 2", () {}); } -"""); +""").create(); - var result = _runTest(["--plain-name", "selected", "test.dart"]); - expect(result.stdout, contains("+2: All tests passed!")); - expect(result.exitCode, equals(0)); + var test = runTest(["--plain-name", "selected", "test.dart"]); + test.stdout.expect(consumeThrough(contains("+2: All tests passed!"))); + test.shouldExit(0); }); test("doesn't support RegExp syntax", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + d.file("test.dart", """ import 'dart:async'; import 'package:test/test.dart'; @@ -668,27 +658,21 @@ void main() { test("test 2", () => throw new TestFailure("oh no")); test("test [12]", () {}); } -"""); +""").create(); - var result = _runTest(["--plain-name", "test [12]", "test.dart"]); - expect(result.stdout, contains("+1: All tests passed!")); - expect(result.exitCode, equals(0)); + var test = runTest(["--plain-name", "test [12]", "test.dart"]); + test.stdout.expect(consumeThrough(contains("+1: All tests passed!"))); + test.shouldExit(0); }); test("produces an error when no tests match", () { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(_success); + d.file("test.dart", _success).create(); - var result = _runTest(["--plain-name", "no match", "test.dart"]); - expect(result.stderr, - contains('No tests match "no match".')); - expect(result.exitCode, equals(exit_codes.data)); + var test = runTest(["--plain-name", "no match", "test.dart"]); + test.stderr.expect( + consumeThrough(contains('No tests match "no match".'))); + test.shouldExit(exit_codes.data); }); }); }); } - -ProcessResult _runTest(List<String> args) => - runTest(args, workingDirectory: _sandbox); - -ProcessResult _runDart(List<String> args) => - runDart(args, workingDirectory: _sandbox); diff --git a/test/runner/signal_test.dart b/test/runner/signal_test.dart index 155b24ee..5397d076 100644 --- a/test/runner/signal_test.dart +++ b/test/runner/signal_test.dart @@ -9,89 +9,73 @@ import 'dart:async'; import 'dart:io'; import 'package:path/path.dart' as p; -import 'package:test/src/util/io.dart'; -import 'package:test/src/utils.dart'; -import 'package:test/test.dart'; +import 'package:scheduled_test/descriptor.dart' as d; +import 'package:scheduled_test/scheduled_process.dart'; +import 'package:scheduled_test/scheduled_stream.dart'; +import 'package:scheduled_test/scheduled_test.dart'; import '../io.dart'; -String _sandbox; - -String get _tempDir => p.join(_sandbox, "tmp"); +String get _tempDir => p.join(sandbox, "tmp"); // This test is inherently prone to race conditions. If it fails, it will likely // do so flakily, but if it succeeds, it will succeed consistently. The tests // represent a best effort to kill the test runner at certain times during its // execution. void main() { - setUp(() { - _sandbox = createTempDir(); - }); - - tearDown(() { - new Directory(_sandbox).deleteSync(recursive: true); - }); + useSandbox(() => d.dir("tmp").create()); group("during loading,", () { - test("cleans up if killed while loading a VM test", () async { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + test("cleans up if killed while loading a VM test", () { + d.file("test.dart", """ void main() { print("in test.dart"); // Spin for a long time so the test is probably killed while still loading. for (var i = 0; i < 100000000; i++) {} } -"""); +""").create(); - var process = await _startTest(["-r", "expanded", "test.dart"]); + var test = _runTest(["test.dart"]); + test.stdout.expect(consumeThrough("in test.dart")); + signalAndQuit(test); - // Skip a progress line. - var line = await lineSplitter.bind(process.stdout).skip(1).first; - expect(line, equals("in test.dart")); - process.kill(); - await process.exitCode; - expect(new Directory(_tempDir).listSync(), isEmpty); + expectTempDirEmpty(); }); - test("cleans up if killed while loading a browser test", () async { - new File(p.join(_sandbox, "test.dart")) - .writeAsStringSync("void main() {}"); - - var process = await _startTest( - ["-r", "expanded", "-p", "chrome", "test.dart"]); - var line = await lineSplitter.bind(process.stdout).first; - expect(line, endsWith("compiling test.dart")); - process.kill(); - await process.exitCode; - expect(new Directory(_tempDir).listSync(), isEmpty); + test("cleans up if killed while loading a browser test", () { + d.file("test.dart", "void main() {}").create(); + + var test = _runTest(["-p", "chrome", "test.dart"]); + test.stdout.expect(consumeThrough(endsWith("compiling test.dart"))); + signalAndQuit(test); + + expectTempDirEmpty(); }); - test("exits immediately if ^C is sent twice", () async { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + test("exits immediately if ^C is sent twice", () { + d.file("test.dart", """ void main() { print("in test.dart"); while (true) {} } -"""); +""").create(); - var process = await _startTest(["-r", "expanded", "test.dart"]); - - // Skip a progress line. - var line = await lineSplitter.bind(process.stdout).skip(1).first; - expect(line, equals("in test.dart")); - process.kill(); + var test = _runTest(["test.dart"]); + test.stdout.expect(consumeThrough("in test.dart")); + test.signal(ProcessSignal.SIGTERM); // TODO(nweiz): Sending two signals in close succession can cause the // second one to be ignored, so we wait a bit before the second // one. Remove this hack when issue 23047 is fixed. - await new Future.delayed(new Duration(seconds: 1)); - process.kill(); - await process.exitCode; + schedule(() => new Future.delayed(new Duration(seconds: 1))); + + signalAndQuit(test); }); }); group("during test running", () { - test("waits for a VM test to finish running", () async { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + test("waits for a VM test to finish running", () { + d.file("test.dart", """ import 'dart:async'; import 'dart:io'; @@ -105,22 +89,18 @@ void main() { return new Future.delayed(new Duration(seconds: 1)); }); } -"""); - - var process = await _startTest(["-r", "expanded", "test.dart"]); - - // Skip a progress line. - var line = await lineSplitter.bind(process.stdout).skip(1).first; - expect(line, equals("running test")); - process.kill(); - await process.exitCode; - expect(new File(p.join(_sandbox, "output")).readAsStringSync(), - equals("ran teardown")); - expect(new Directory(_tempDir).listSync(), isEmpty); +""").create(); + + var test = _runTest(["test.dart"]); + test.stdout.expect(consumeThrough("running test")); + signalAndQuit(test); + + d.file("output", "ran teardown").validate(); + expectTempDirEmpty(); }); - test("kills a browser test immediately", () async { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + test("kills a browser test immediately", () { + d.file("test.dart", """ import 'dart:async'; import 'package:test/test.dart'; @@ -137,21 +117,17 @@ void main() { }); }); } -"""); +""").create(); - var process = await _startTest( - ["-r", "expanded", "-p", "content-shell", "test.dart"]); + var test = _runTest(["-p", "content-shell", "test.dart"]); + test.stdout.expect(consumeThrough("running test")); + signalAndQuit(test); - // Skip a progress line.. - var line = await lineSplitter.bind(process.stdout).skip(1).first; - expect(line, equals("running test")); - process.kill(); - await process.exitCode; - expect(new Directory(_tempDir).listSync(), isEmpty); + expectTempDirEmpty(); }); - test("kills a VM test immediately if ^C is sent twice", () async { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + test("kills a VM test immediately if ^C is sent twice", () { + d.file("test.dart", """ import 'package:test/test.dart'; void main() { @@ -160,25 +136,21 @@ void main() { while (true) {} }); } -"""); - - var process = await _startTest(["-r", "expanded", "test.dart"]); +""").create(); - // Skip a progress line. - var line = await lineSplitter.bind(process.stdout).skip(1).first; - expect(line, equals("running test")); - process.kill(); + var test = _runTest(["test.dart"]); + test.stdout.expect(consumeThrough("running test")); + test.signal(ProcessSignal.SIGTERM); // TODO(nweiz): Sending two signals in close succession can cause the // second one to be ignored, so we wait a bit before the second // one. Remove this hack when issue 23047 is fixed. - await new Future.delayed(new Duration(seconds: 1)); - process.kill(); - await process.exitCode; + schedule(() => new Future.delayed(new Duration(seconds: 1))); + signalAndQuit(test); }); - test("causes expect() to always throw an error immediately", () async { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + test("causes expect() to always throw an error immediately", () { + d.file("test.dart", """ import 'dart:async'; import 'dart:io'; @@ -202,22 +174,18 @@ void main() { } }); } -"""); - - var process = await _startTest(["-r", "expanded", "test.dart"]); - - // Skip a progress line. - var line = await lineSplitter.bind(process.stdout).skip(1).first; - expect(line, equals("running test")); - process.kill(); - await process.exitCode; - expect(new File(p.join(_sandbox, "output")).readAsStringSync(), - equals("true")); - expect(new Directory(_tempDir).listSync(), isEmpty); +""").create(); + + var test = _runTest(["test.dart"]); + test.stdout.expect(consumeThrough("running test")); + signalAndQuit(test); + + d.file("output", "true").validate(); + expectTempDirEmpty(); }); - test("causes expectAsync() to always throw an error immediately", () async { - new File(p.join(_sandbox, "test.dart")).writeAsStringSync(""" + test("causes expectAsync() to always throw an error immediately", () { + d.file("test.dart", """ import 'dart:async'; import 'dart:io'; @@ -241,24 +209,27 @@ void main() { } }); } -"""); - - var process = await _startTest(["-r", "expanded", "test.dart"]); - - // Skip a progress line. - var line = await lineSplitter.bind(process.stdout).skip(1).first; - expect(line, equals("running test")); - process.kill(); - await process.exitCode; - expect(new File(p.join(_sandbox, "output")).readAsStringSync(), - equals("true")); - expect(new Directory(_tempDir).listSync(), isEmpty); +""").create(); + + var test = _runTest(["test.dart"]); + test.stdout.expect(consumeThrough("running test")); + signalAndQuit(test); + + d.file("output", "true").validate(); + expectTempDirEmpty(); }); }); } -Future<Process> _startTest(List<String> args) { - new Directory(_tempDir).create(); - return startTest(args, workingDirectory: _sandbox, - environment: {"_UNITTEST_TEMP_DIR": _tempDir}); +ScheduledProcess _runTest(List<String> args) => + runTest(args, environment: {"_UNITTEST_TEMP_DIR": _tempDir}); + +void signalAndQuit(ScheduledProcess test) { + test.signal(ProcessSignal.SIGTERM); + test.shouldExit(); + test.stderr.expect(isDone); +} + +void expectTempDirEmpty() { + schedule(() => expect(new Directory(_tempDir).listSync(), isEmpty)); } diff --git a/test/runner/test_on_test.dart b/test/runner/test_on_test.dart index 1c299af1..8c34a102 100644 --- a/test/runner/test_on_test.dart +++ b/test/runner/test_on_test.dart @@ -6,57 +6,50 @@ import 'dart:io'; -import 'package:path/path.dart' as p; +import 'package:scheduled_test/descriptor.dart' as d; +import 'package:scheduled_test/scheduled_stream.dart'; +import 'package:scheduled_test/scheduled_test.dart'; import 'package:test/src/util/io.dart'; -import 'package:test/test.dart'; import '../io.dart'; -String _sandbox; - final _otherOS = Platform.isWindows ? "mac-os" : "windows"; void main() { - setUp(() { - _sandbox = createTempDir(); - }); - - tearDown(() { - new Directory(_sandbox).deleteSync(recursive: true); - }); + useSandbox(); group("for suite", () { test("runs a test suite on a matching platform", () { _writeTestFile("vm_test.dart", suiteTestOn: "vm"); - var result = _runTest(["vm_test.dart"]); - expect(result.stdout, contains("All tests passed!")); - expect(result.exitCode, equals(0)); + var test = runTest(["vm_test.dart"]); + test.stdout.expect(consumeThrough(contains("All tests passed!"))); + test.shouldExit(0); }); test("doesn't run a test suite on a non-matching platform", () { _writeTestFile("vm_test.dart", suiteTestOn: "vm"); - var result = _runTest(["--platform", "content-shell", "vm_test.dart"]); - expect(result.stdout, contains("No tests ran.")); - expect(result.exitCode, equals(0)); + var test = runTest(["--platform", "content-shell", "vm_test.dart"]); + test.stdout.expect(consumeThrough(contains("No tests ran."))); + test.shouldExit(0); }); test("runs a test suite on a matching operating system", () { _writeTestFile("os_test.dart", suiteTestOn: currentOS.name); - var result = _runTest(["os_test.dart"]); - expect(result.stdout, contains("All tests passed!")); - expect(result.exitCode, equals(0)); + var test = runTest(["os_test.dart"]); + test.stdout.expect(consumeThrough(contains("All tests passed!"))); + test.shouldExit(0); }); test("doesn't run a test suite on a non-matching operating system", () { _writeTestFile("os_test.dart", suiteTestOn: _otherOS, loadable: false); - var result = _runTest(["os_test.dart"]); - expect(result.stdout, contains("No tests ran.")); - expect(result.exitCode, equals(0)); + var test = runTest(["os_test.dart"]); + test.stdout.expect(consumeThrough(contains("No tests ran."))); + test.shouldExit(0); }); test("only loads matching files when loading as a group", () { @@ -67,9 +60,9 @@ void main() { _writeTestFile("other_os_test.dart", suiteTestOn: _otherOS, loadable: false); - var result = _runTest(["."]); - expect(result.stdout, contains("+2: All tests passed!")); - expect(result.exitCode, equals(0)); + var test = runTest(["."]); + test.stdout.expect(consumeThrough(contains("+2: All tests passed!"))); + test.shouldExit(0); }); }); @@ -77,34 +70,34 @@ void main() { test("runs a VM group on the VM", () { _writeTestFile("vm_test.dart", groupTestOn: "vm"); - var result = _runTest(["vm_test.dart"]); - expect(result.stdout, contains("All tests passed!")); - expect(result.exitCode, equals(0)); + var test = runTest(["vm_test.dart"]); + test.stdout.expect(consumeThrough(contains("All tests passed!"))); + test.shouldExit(0); }); test("doesn't run a Browser group on the VM", () { _writeTestFile("browser_test.dart", groupTestOn: "browser"); - var result = _runTest(["browser_test.dart"]); - expect(result.stdout, contains("No tests ran.")); - expect(result.exitCode, equals(0)); + var test = runTest(["browser_test.dart"]); + test.stdout.expect(consumeThrough(contains("No tests ran."))); + test.shouldExit(0); }); test("runs a browser group on a browser", () { _writeTestFile("browser_test.dart", groupTestOn: "browser"); - var result = _runTest( + var test = runTest( ["--platform", "content-shell", "browser_test.dart"]); - expect(result.stdout, contains("All tests passed!")); - expect(result.exitCode, equals(0)); + test.stdout.expect(consumeThrough(contains("All tests passed!"))); + test.shouldExit(0); }); test("doesn't run a VM group on a browser", () { _writeTestFile("vm_test.dart", groupTestOn: "vm"); - var result = _runTest(["--platform", "content-shell", "vm_test.dart"]); - expect(result.stdout, contains("No tests ran.")); - expect(result.exitCode, equals(0)); + var test = runTest(["--platform", "content-shell", "vm_test.dart"]); + test.stdout.expect(consumeThrough(contains("No tests ran."))); + test.shouldExit(0); }); }); @@ -112,34 +105,34 @@ void main() { test("runs a VM test on the VM", () { _writeTestFile("vm_test.dart", testTestOn: "vm"); - var result = _runTest(["vm_test.dart"]); - expect(result.stdout, contains("All tests passed!")); - expect(result.exitCode, equals(0)); + var test = runTest(["vm_test.dart"]); + test.stdout.expect(consumeThrough(contains("All tests passed!"))); + test.shouldExit(0); }); test("doesn't run a browser test on the VM", () { _writeTestFile("browser_test.dart", testTestOn: "browser"); - var result = _runTest(["browser_test.dart"]); - expect(result.stdout, contains("No tests ran.")); - expect(result.exitCode, equals(0)); + var test = runTest(["browser_test.dart"]); + test.stdout.expect(consumeThrough(contains("No tests ran."))); + test.shouldExit(0); }); test("runs a browser test on a browser", () { _writeTestFile("browser_test.dart", testTestOn: "browser"); - var result = _runTest( + var test = runTest( ["--platform", "content-shell", "browser_test.dart"]); - expect(result.stdout, contains("All tests passed!")); - expect(result.exitCode, equals(0)); + test.stdout.expect(consumeThrough(contains("All tests passed!"))); + test.shouldExit(0); }); test("doesn't run a VM test on a browser", () { _writeTestFile("vm_test.dart", testTestOn: "vm"); - var result = _runTest(["--platform", "content-shell", "vm_test.dart"]); - expect(result.stdout, contains("No tests ran.")); - expect(result.exitCode, equals(0)); + var test = runTest(["--platform", "content-shell", "vm_test.dart"]); + test.stdout.expect(consumeThrough(contains("No tests ran."))); + test.shouldExit(0); }); }); @@ -148,36 +141,36 @@ void main() { _writeTestFile("vm_test.dart", suiteTestOn: "!browser", groupTestOn: "!js", testTestOn: "vm"); - var result = _runTest(["vm_test.dart"]); - expect(result.stdout, contains("All tests passed!")); - expect(result.exitCode, equals(0)); + var test = runTest(["vm_test.dart"]); + test.stdout.expect(consumeThrough(contains("All tests passed!"))); + test.shouldExit(0); }); test("doesn't runs the test if the suite doesn't match", () { _writeTestFile("vm_test.dart", suiteTestOn: "browser", groupTestOn: "!js", testTestOn: "vm"); - var result = _runTest(["vm_test.dart"]); - expect(result.stdout, contains("No tests ran.")); - expect(result.exitCode, equals(0)); + var test = runTest(["vm_test.dart"]); + test.stdout.expect(consumeThrough(contains("No tests ran."))); + test.shouldExit(0); }); test("doesn't runs the test if the group doesn't match", () { _writeTestFile("vm_test.dart", suiteTestOn: "!browser", groupTestOn: "browser", testTestOn: "vm"); - var result = _runTest(["vm_test.dart"]); - expect(result.stdout, contains("No tests ran.")); - expect(result.exitCode, equals(0)); + var test = runTest(["vm_test.dart"]); + test.stdout.expect(consumeThrough(contains("No tests ran."))); + test.shouldExit(0); }); test("doesn't runs the test if the test doesn't match", () { _writeTestFile("vm_test.dart", suiteTestOn: "!browser", groupTestOn: "!js", testTestOn: "browser"); - var result = _runTest(["vm_test.dart"]); - expect(result.stdout, contains("No tests ran.")); - expect(result.exitCode, equals(0)); + var test = runTest(["vm_test.dart"]); + test.stdout.expect(consumeThrough(contains("No tests ran."))); + test.shouldExit(0); }); }); } @@ -212,8 +205,5 @@ void _writeTestFile(String filename, {String suiteTestOn, String groupTestOn, buffer.writeln("}"); - new File(p.join(_sandbox, filename)).writeAsStringSync(buffer.toString()); + d.file(filename, buffer.toString()).create(); } - -ProcessResult _runTest(List<String> args) => - runTest(args, workingDirectory: _sandbox); -- GitLab