Index: lib/src/runner/loader.dart |
diff --git a/lib/src/runner/loader.dart b/lib/src/runner/loader.dart |
index 79a2fbfd683cfa14e0eb729862f7704f6e5152a9..f9517124b06751d8a36881b03232187ffb0e192e 100644 |
--- a/lib/src/runner/loader.dart |
+++ b/lib/src/runner/loader.dart |
@@ -11,14 +11,23 @@ import 'dart:isolate'; |
import 'package:path/path.dart' as p; |
import '../backend/suite.dart'; |
+import '../runner/test_platform.dart'; |
import '../util/dart.dart'; |
import '../util/io.dart'; |
import '../util/remote_exception.dart'; |
-import 'vm/isolate_test.dart'; |
+import '../utils.dart'; |
+import 'browser/server.dart'; |
import 'load_exception.dart'; |
+import 'vm/isolate_test.dart'; |
/// A class for finding test files and loading them into a runnable form. |
class Loader { |
+ /// All platforms for which tests should be loaded. |
+ final List<TestPlatform> _platforms; |
+ |
+ /// Whether to enable colors for Dart compilation. |
+ final bool _color; |
+ |
/// The package root to use for loading tests, or `null` to use the automatic |
/// root. |
final String _packageRoot; |
@@ -26,35 +35,66 @@ class Loader { |
/// All isolates that have been spun up by the loader. |
final _isolates = new Set<Isolate>(); |
+ /// The server that serves browser test pages. |
+ /// |
+ /// This is lazily initialized the first time it's accessed. |
+ Future<BrowserServer> get _browserServer { |
+ if (_browserServerCompleter == null) { |
+ _browserServerCompleter = new Completer(); |
+ BrowserServer.start(packageRoot: _packageRoot, color: _color) |
+ .then(_browserServerCompleter.complete) |
+ .catchError(_browserServerCompleter.completeError); |
+ } |
+ return _browserServerCompleter.future; |
+ } |
+ Completer<BrowserServer> _browserServerCompleter; |
+ |
/// Creates a new loader. |
/// |
/// If [packageRoot] is passed, it's used as the package root for all loaded |
/// tests. Otherwise, the `packages/` directories next to the test entrypoints |
/// will be used. |
- Loader({String packageRoot}) |
- : _packageRoot = packageRoot; |
+ /// |
+ /// If [color] is true, console colors will be used when compiling Dart. |
+ Loader(Iterable<TestPlatform> platforms, {String packageRoot, |
+ bool color: false}) |
+ : _platforms = platforms.toList(), |
+ _packageRoot = packageRoot, |
+ _color = color; |
/// Loads all test suites in [dir]. |
/// |
/// This will load tests from files that end in "_test.dart". |
- Future<Set<Suite>> loadDir(String dir) { |
+ Future<List<Suite>> loadDir(String dir) { |
return Future.wait(new Directory(dir).listSync(recursive: true) |
.map((entry) { |
- if (entry is! File) return new Future.value(); |
- if (!entry.path.endsWith("_test.dart")) return new Future.value(); |
- if (p.split(entry.path).contains('packages')) return new Future.value(); |
+ if (entry is! File) return new Future.value([]); |
+ if (!entry.path.endsWith("_test.dart")) return new Future.value([]); |
+ if (p.split(entry.path).contains('packages')) return new Future.value([]); |
// TODO(nweiz): Provide a way for the caller to gracefully handle some |
- // isolates failing to load without stopping the rest. |
+ // suites failing to load without stopping the rest. |
return loadFile(entry.path); |
- })).then((suites) => suites.toSet()..remove(null)); |
+ })).then((suites) => flatten(suites)); |
} |
/// Loads a test suite from the file at [path]. |
/// |
/// This will throw a [LoadException] if the file fails to load. |
- Future<Suite> loadFile(String path) { |
- // TODO(nweiz): Support browser tests. |
+ Future<List<Suite>> loadFile(String path) { |
+ return Future.wait(_platforms.map((platform) { |
+ if (platform == TestPlatform.chrome) return _loadBrowserFile(path); |
+ assert(platform == TestPlatform.vm); |
+ return _loadVmFile(path); |
+ })); |
+ } |
+ |
+ /// Load the test suite at [path] in a browser. |
+ Future<Suite> _loadBrowserFile(String path) => |
+ _browserServer.then((browserServer) => browserServer.loadSuite(path)); |
+ |
+ /// Load the test suite at [path] in VM isolate. |
+ Future<Suite> _loadVmFile(String path) { |
var packageRoot = packageRootFor(path, _packageRoot); |
var receivePort = new ReceivePort(); |
return runInIsolate(''' |
@@ -85,9 +125,9 @@ void main(_, Map message) { |
asyncError.stackTrace); |
} |
- return new Suite(path, response["tests"].map((test) { |
+ return new Suite(response["tests"].map((test) { |
return new IsolateTest(test['name'], test['sendPort']); |
- })); |
+ }), path: path, platform: "VM"); |
}); |
} |
@@ -97,6 +137,8 @@ void main(_, Map message) { |
isolate.kill(); |
} |
_isolates.clear(); |
- return new Future.value(); |
+ |
+ if (_browserServerCompleter == null) return new Future.value(); |
+ return _browserServer.then((browserServer) => browserServer.close()); |
} |
} |