Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(500)

Side by Side Diff: lib/src/loader.dart

Issue 933083002: Add a test runner executable. (Closed) Base URL: git@github.com:dart-lang/unittest@master
Patch Set: fix loader_test? Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library unittest.loader; 5 library unittest.loader;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:io'; 8 import 'dart:io';
9 import 'dart:isolate'; 9 import 'dart:isolate';
10 10
11 import 'package:path/path.dart' as p; 11 import 'package:path/path.dart' as p;
12 12
13 import 'dart.dart'; 13 import 'dart.dart';
14 import 'isolate_test.dart'; 14 import 'isolate_test.dart';
15 import 'load_exception.dart';
16 import 'remote_exception.dart';
15 import 'suite.dart'; 17 import 'suite.dart';
16 18
17 /// A class for finding test files and loading them into a runnable form. 19 /// A class for finding test files and loading them into a runnable form.
18 class Loader { 20 class Loader {
19 /// The package root to use for loading tests, or `null` to use the automatic 21 /// The package root to use for loading tests, or `null` to use the automatic
20 /// root. 22 /// root.
21 final String _packageRoot; 23 final String _packageRoot;
22 24
23 /// All isolates that have been spun up by the loader. 25 /// All isolates that have been spun up by the loader.
24 final _isolates = new Set<Isolate>(); 26 final _isolates = new Set<Isolate>();
(...skipping 17 matching lines...) Expand all
42 if (p.split(entry.path).contains('packages')) return new Future.value(); 44 if (p.split(entry.path).contains('packages')) return new Future.value();
43 45
44 // TODO(nweiz): Provide a way for the caller to gracefully handle some 46 // TODO(nweiz): Provide a way for the caller to gracefully handle some
45 // isolates failing to load without stopping the rest. 47 // isolates failing to load without stopping the rest.
46 return loadFile(entry.path); 48 return loadFile(entry.path);
47 })).then((suites) => suites.toSet()..remove(null)); 49 })).then((suites) => suites.toSet()..remove(null));
48 } 50 }
49 51
50 /// Loads a test suite from the file at [path]. 52 /// Loads a test suite from the file at [path].
51 /// 53 ///
52 /// This wil throw a [FileSystemException] if there's no `packages/` directory 54 /// This will throw a [LoadException] if the file fails to load.
53 /// available for [path]. Any other load error will cause an
54 /// [IsolateSpawnException] or a [RemoteException].
55 Future<Suite> loadFile(String path) { 55 Future<Suite> loadFile(String path) {
56 // TODO(nweiz): Support browser tests. 56 // TODO(nweiz): Support browser tests.
57 var packageRoot = _packageRoot == null 57 var packageRoot = _packageRoot == null
58 ? p.join(p.dirname(path), 'packages') 58 ? p.join(p.dirname(path), 'packages')
59 : _packageRoot; 59 : _packageRoot;
60 60
61 if (!new Directory(packageRoot).existsSync()) { 61 if (!new Directory(packageRoot).existsSync()) {
62 throw new FileSystemException("Directory $packageRoot does not exist."); 62 throw new LoadException(path, "Directory $packageRoot does not exist.");
63 } 63 }
64 64
65 var receivePort = new ReceivePort(); 65 var receivePort = new ReceivePort();
66 return runInIsolate(''' 66 return runInIsolate('''
67 import "package:unittest/src/vm_listener.dart"; 67 import "package:unittest/src/vm_listener.dart";
68 68
69 import "${p.toUri(p.absolute(path))}" as test; 69 import "${p.toUri(p.absolute(path))}" as test;
70 70
71 void main(_, Map message) { 71 void main(_, Map message) {
72 var sendPort = message['reply']; 72 var sendPort = message['reply'];
73 VmListener.start(sendPort, test.main); 73 VmListener.start(sendPort, () => test.main);
74 } 74 }
75 ''', { 75 ''', {
76 'reply': receivePort.sendPort 76 'reply': receivePort.sendPort
77 }, packageRoot: packageRoot).then((isolate) { 77 }, packageRoot: packageRoot).catchError((error, stackTrace) {
78 receivePort.close();
79 return new Future.error(new LoadException(path, error), stackTrace);
80 }).then((isolate) {
78 _isolates.add(isolate); 81 _isolates.add(isolate);
79 return receivePort.first; 82 return receivePort.first;
80 }).then((tests) { 83 }).then((response) {
81 return new Suite(path, tests.map((test) { 84 if (response["type"] == "loadException") {
85 return new Future.error(new LoadException(path, response["message"]));
86 } else if (response["type"] == "error") {
87 var asyncError = RemoteException.deserialize(response["error"]);
88 return new Future.error(
89 new LoadException(path, asyncError.error),
90 asyncError.stackTrace);
91 }
92
93 return new Suite(path, response["tests"].map((test) {
82 return new IsolateTest(test['name'], test['sendPort']); 94 return new IsolateTest(test['name'], test['sendPort']);
83 })); 95 }));
84 }); 96 });
85 } 97 }
86 98
87 /// Closes the loader and releases all resources allocated by it. 99 /// Closes the loader and releases all resources allocated by it.
88 Future close() { 100 Future close() {
89 for (var isolate in _isolates) { 101 for (var isolate in _isolates) {
90 isolate.kill(); 102 isolate.kill();
91 } 103 }
92 _isolates.clear(); 104 _isolates.clear();
93 return new Future.value(); 105 return new Future.value();
94 } 106 }
95 } 107 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698