Chromium Code Reviews| Index: tests/isolate/remote_unittest_helper.dart |
| diff --git a/tests/isolate/remote_unittest_helper.dart b/tests/isolate/remote_unittest_helper.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..68704ce78cd2cd348e241eceece886823b0a57a4 |
| --- /dev/null |
| +++ b/tests/isolate/remote_unittest_helper.dart |
| @@ -0,0 +1,125 @@ |
| +// Copyright (c) 2013, 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. |
| + |
| +// Helper functions and classes for running a set of unittests in a |
| +// remote isolate. |
| +// Used to test Isolate.spawn because dartium/drt does not allow it in the DOM |
| +// isolate. |
| + |
| +import "dart:isolate"; |
| +import "package:unittest/unittest.dart"; |
| +import "dart:mirrors"; |
| + |
| +/** |
| + * Use this function at the beginning of the main method: |
| + * |
| + * void main([args, port]) { |
| + * if (testRemote(main, port)) return; |
| + * // the usual test. |
| + * } |
| + */ |
|
siva
2013/11/14 17:21:08
I find this a little tricky, you probably did it t
Lasse Reichstein Nielsen
2013/11/15 14:57:45
Minimizing changes was a goal, yes :) Didn't succe
|
| +bool testRemote(Function main, SendPort port) { |
| + if (port == null) { |
| + return new LocalTests().run(main); |
| + } else { |
| + unittestConfiguration = new RemoteConfiguration(port); |
| + return false; |
| + } |
| +} |
| + |
| + |
| +class LocalTests { |
| + final ReceivePort _port = new ReceivePort(); |
| + final Map<String, Function> _testBody = new Map<String, Function>(); |
| + |
| + bool run(Function main) { |
| + ClosureMirror closure = reflect(main); |
| + LibraryMirror library = closure.function.owner; |
| + try { |
| + Isolate.spawnUri(library.uri, null, _port.sendPort); |
| + _port.listen(remoteAction); |
| + return true; |
| + } catch (e) { |
| + // spawnUri is only supported by dart2js if web workers are available. |
| + // If the spawnUri fails, run the tests locally instead, since we are |
| + // not in a browser anyway. |
| + return false; |
| + } |
| + } |
| + |
| + void remoteAction(message) { |
| + switch (message[0]) { |
| + case "testStart": |
| + String name = message[1]; |
| + test(name, () { |
| + _testBody[name] = expectAsync2((result, message) { |
| + if (result == FAIL) { |
| + fail(message); |
| + } else if (result == ERROR) { |
| + throw message; |
| + } |
| + _testBody.remove(name); |
| + }); |
| + }); |
| + break; |
| + case "testResult": |
| + String name = message[1]; |
| + Function completer = _testBody[name]; |
| + completer(message[2], message[3]); |
| + break; |
| + case "testResultChanged": |
| + throw new UnsupportedError("result change after the fact?"); |
| + case "logMessage": |
| + break; // Ignore. |
| + case "summary": |
| + throw message[1]; // Uncaught error. |
| + case "done": |
| + _port.close(); |
| + break; |
| + } |
| + } |
| +} |
| + |
| + |
| +class RemoteConfiguration implements Configuration { |
| + final SendPort _port; |
| + Duration timeout = const Duration(minutes: 2); |
| + |
| + RemoteConfiguration(this._port); |
| + |
| + bool get autoStart => true; |
| + |
| + void onInit() { } |
| + |
| + void onStart() { } |
| + |
| + void onTestStart(TestCase testCase) { |
| + _port.send(["testStart", testCase.description]); |
| + } |
| + |
| + void onTestResult(TestCase testCase) { |
| + _port.send(["testResult", testCase.description, |
| + testCase.result, testCase.message]); |
| + } |
| + |
| + void onTestResultChanged(TestCase testCase) { |
| + _port.send(["testResultChanged", testCase.description, |
| + testCase.result, testCase.message]); |
| + } |
| + |
| + void onLogMessage(TestCase testCase, String message) { |
| + _port.send(["logMessage", testCase.description, message]); |
| + } |
| + |
| + void onDone(bool success) { |
| + _port.send(["done", success]); |
| + } |
| + |
| + void onSummary(int passed, int failed, int errors, List<TestCase> results, |
| + String uncaughtError) { |
| + if (uncaughtError != null) { |
| + _port.send(["summary", uncaughtError]); |
| + } |
| + } |
| +} |