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

Side by Side Diff: tools/testing/dart/test_suite.dart

Issue 11817012: Migration of testing scripts in tools/ to libv2 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « tools/testing/dart/test_runner.dart ('k') | tools/version.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 /** 5 /**
6 * Classes and methods for enumerating and preparing tests. 6 * Classes and methods for enumerating and preparing tests.
7 * 7 *
8 * This library includes: 8 * This library includes:
9 * 9 *
10 * - Creating tests by listing all the Dart files in certain directories, 10 * - Creating tests by listing all the Dart files in certain directories,
11 * and creating [TestCase]s for those files that meet the relevant criteria. 11 * and creating [TestCase]s for those files that meet the relevant criteria.
12 * - Preparing tests, including copying files and frameworks to temporary 12 * - Preparing tests, including copying files and frameworks to temporary
13 * directories, and computing the command line and arguments to be run. 13 * directories, and computing the command line and arguments to be run.
14 */ 14 */
15 library test_suite; 15 library test_suite;
16 16
17 import "dart:async";
17 import "dart:io"; 18 import "dart:io";
18 import "dart:isolate"; 19 import "dart:isolate";
19 import "status_file_parser.dart"; 20 import "status_file_parser.dart";
20 import "test_runner.dart"; 21 import "test_runner.dart";
21 import "multitest.dart"; 22 import "multitest.dart";
22 import "drt_updater.dart"; 23 import "drt_updater.dart";
23 import "dart:uri"; 24 import "dart:uri";
24 25
25 part "browser_test.dart"; 26 part "browser_test.dart";
26 27
(...skipping 30 matching lines...) Expand all
57 } 58 }
58 59
59 /** A completer that waits until all added [Future]s complete. */ 60 /** A completer that waits until all added [Future]s complete. */
60 // TODO(rnystrom): Copied from web_components. Remove from here when it gets 61 // TODO(rnystrom): Copied from web_components. Remove from here when it gets
61 // added to dart:core. (See #6626.) 62 // added to dart:core. (See #6626.)
62 class FutureGroup { 63 class FutureGroup {
63 const _FINISHED = -1; 64 const _FINISHED = -1;
64 int _pending = 0; 65 int _pending = 0;
65 Completer<List> _completer = new Completer<List>(); 66 Completer<List> _completer = new Completer<List>();
66 final List<Future> futures = <Future>[]; 67 final List<Future> futures = <Future>[];
68 bool wasCompleted = false;
67 69
68 /** 70 /**
69 * Wait for [task] to complete (assuming this barrier has not already been 71 * Wait for [task] to complete (assuming this barrier has not already been
70 * marked as completed, otherwise you'll get an exception indicating that a 72 * marked as completed, otherwise you'll get an exception indicating that a
71 * future has already been completed). 73 * future has already been completed).
72 */ 74 */
73 void add(Future task) { 75 void add(Future task) {
74 if (_pending == _FINISHED) { 76 if (_pending == _FINISHED) {
75 throw new FutureAlreadyCompleteException(); 77 throw new Exception("FutureFutureAlreadyCompleteException");
76 } 78 }
77 _pending++; 79 _pending++;
78 futures.add(task); 80 var handledTaskFuture = task.catchError((e) {
Bill Hesse 2013/01/09 18:21:06 Couldn't you just put parentheses around all this,
kustermann 2013/01/09 18:27:40 I think it is a bit more readable this way.
79 task.handleException( 81 if (!wasCompleted) {
80 (e) => _completer.completeException(e, task.stackTrace)); 82 _completer.completeError(e.error, task.stackTrace);
81 task.then((_) { 83 wasCompleted = true;
84 }
85 }).then((_) {
82 _pending--; 86 _pending--;
83 if (_pending == 0) { 87 if (_pending == 0) {
84 _pending = _FINISHED; 88 _pending = _FINISHED;
85 _completer.complete(futures); 89 if (!wasCompleted) {
90 _completer.complete(futures);
91 wasCompleted = true;
92 }
86 } 93 }
87 }); 94 });
95 futures.add(handledTaskFuture);
88 } 96 }
89 97
90 Future<List> get future => _completer.future; 98 Future<List> get future => _completer.future;
91 } 99 }
92 100
93 /** 101 /**
94 * A TestSuite represents a collection of tests. It creates a [TestCase] 102 * A TestSuite represents a collection of tests. It creates a [TestCase]
95 * object for each test to be run, and passes the test cases to a callback. 103 * object for each test to be run, and passes the test cases to a callback.
96 * 104 *
97 * Most TestSuites represent a directory or directory tree containing tests, 105 * Most TestSuites represent a directory or directory tree containing tests,
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 p.onExit = (code) { 273 p.onExit = (code) {
266 if (code < 0) { 274 if (code < 0) {
267 print("Failed to list tests: $runnerPath --list"); 275 print("Failed to list tests: $runnerPath --list");
268 replyTo.send(""); 276 replyTo.send("");
269 } else { 277 } else {
270 processExited = true; 278 processExited = true;
271 checkDone(); 279 checkDone();
272 } 280 }
273 }; 281 };
274 port.close(); 282 port.close();
275 }); 283 }).catchError((e) {
276 processFuture.handleException((e) {
277 print("Failed to list tests: $runnerPath --list"); 284 print("Failed to list tests: $runnerPath --list");
278 replyTo.send(""); 285 replyTo.send("");
279 return true; 286 return true;
280 }); 287 });
281 }); 288 });
282 } 289 }
283 290
284 291
285 /** 292 /**
286 * A specialized [TestSuite] that runs tests written in C to unit test 293 * A specialized [TestSuite] that runs tests written in C to unit test
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 bool isTestFile(String filename) { 474 bool isTestFile(String filename) {
468 // Use the specified predicate, if provided. 475 // Use the specified predicate, if provided.
469 if (isTestFilePredicate != null) return isTestFilePredicate(filename); 476 if (isTestFilePredicate != null) return isTestFilePredicate(filename);
470 477
471 return filename.endsWith("Test.dart"); 478 return filename.endsWith("Test.dart");
472 } 479 }
473 480
474 List<String> additionalOptions(Path filePath) => []; 481 List<String> additionalOptions(Path filePath) => [];
475 482
476 void forEachTest(TestCaseEvent onTest, Map testCache, [VoidFunction onDone]) { 483 void forEachTest(TestCaseEvent onTest, Map testCache, [VoidFunction onDone]) {
477 updateDartium().chain((_) { 484 updateDartium().then((_) {
478 doTest = onTest; 485 doTest = onTest;
479 486
480 return readExpectations(); 487 return readExpectations();
481 }).chain((expectations) { 488 }).then((expectations) {
482 testExpectations = expectations; 489 testExpectations = expectations;
483 490
484 // Checked if we have already found and generated the tests for 491 // Checked if we have already found and generated the tests for
485 // this suite. 492 // this suite.
486 if (!testCache.containsKey(suiteName)) { 493 if (!testCache.containsKey(suiteName)) {
487 cachedTests = testCache[suiteName] = []; 494 cachedTests = testCache[suiteName] = [];
488 return enqueueTests(); 495 return enqueueTests();
489 } else { 496 } else {
490 // We rely on enqueueing completing asynchronously. 497 // We rely on enqueueing completing asynchronously.
491 return asynchronously(() { 498 return asynchronously(() {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 ReadTestExpectationsInto(expectations, 552 ReadTestExpectationsInto(expectations,
546 dartDir.append(statusFilePath).toNativePath(), 553 dartDir.append(statusFilePath).toNativePath(),
547 configuration, statusFileRead); 554 configuration, statusFileRead);
548 } 555 }
549 556
550 return completer.future; 557 return completer.future;
551 } 558 }
552 559
553 Future enqueueTests() { 560 Future enqueueTests() {
554 Directory dir = new Directory.fromPath(suiteDir); 561 Directory dir = new Directory.fromPath(suiteDir);
555 return dir.exists().chain((exists) { 562 return dir.exists().then((exists) {
556 if (!exists) { 563 if (!exists) {
557 print('Directory containing tests missing: ${suiteDir.toNativePath()}'); 564 print('Directory containing tests missing: ${suiteDir.toNativePath()}');
558 return new Future.immediate(null); 565 return new Future.immediate(null);
559 } else { 566 } else {
560 var group = new FutureGroup(); 567 var group = new FutureGroup();
561 enqueueDirectory(dir, group); 568 enqueueDirectory(dir, group);
562 return group.future; 569 return group.future;
563 } 570 }
564 }); 571 });
565 } 572 }
(...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after
1313 // Find the options in the file. 1320 // Find the options in the file.
1314 List<List> result = new List<List>(); 1321 List<List> result = new List<List>();
1315 List<String> dartOptions; 1322 List<String> dartOptions;
1316 String packageRoot; 1323 String packageRoot;
1317 bool hasCompileError = contents.contains("@compile-error"); 1324 bool hasCompileError = contents.contains("@compile-error");
1318 bool hasRuntimeError = contents.contains("@runtime-error"); 1325 bool hasRuntimeError = contents.contains("@runtime-error");
1319 bool isStaticClean = false; 1326 bool isStaticClean = false;
1320 1327
1321 Iterable<Match> matches = testOptionsRegExp.allMatches(contents); 1328 Iterable<Match> matches = testOptionsRegExp.allMatches(contents);
1322 for (var match in matches) { 1329 for (var match in matches) {
1323 result.add(match[1].split(' ').filter((e) => e != '')); 1330 result.add(match[1].split(' ').where((e) => e != '').toList());
1324 } 1331 }
1325 if (result.isEmpty) result.add([]); 1332 if (result.isEmpty) result.add([]);
1326 1333
1327 matches = dartOptionsRegExp.allMatches(contents); 1334 matches = dartOptionsRegExp.allMatches(contents);
1328 for (var match in matches) { 1335 for (var match in matches) {
1329 if (dartOptions != null) { 1336 if (dartOptions != null) {
1330 throw new Exception( 1337 throw new Exception(
1331 'More than one "// DartOptions=" line in test $filePath'); 1338 'More than one "// DartOptions=" line in test $filePath');
1332 } 1339 }
1333 dartOptions = match[1].split(' ').filter((e) => e != ''); 1340 dartOptions = match[1].split(' ').where((e) => e != '').toList();
1334 } 1341 }
1335 1342
1336 matches = packageRootRegExp.allMatches(contents); 1343 matches = packageRootRegExp.allMatches(contents);
1337 for (var match in matches) { 1344 for (var match in matches) {
1338 if (packageRoot != null) { 1345 if (packageRoot != null) {
1339 throw new Exception( 1346 throw new Exception(
1340 'More than one "// PackageRoot=" line in test $filePath'); 1347 'More than one "// PackageRoot=" line in test $filePath');
1341 } 1348 }
1342 packageRoot = match[1]; 1349 packageRoot = match[1];
1343 if (packageRoot != 'none') { 1350 if (packageRoot != 'none') {
1344 // PackageRoot=none means that no package-root option should be given. 1351 // PackageRoot=none means that no package-root option should be given.
1345 packageRoot = '${filePath.directoryPath.join(new Path(packageRoot))}'; 1352 packageRoot = '${filePath.directoryPath.join(new Path(packageRoot))}';
1346 } 1353 }
1347 } 1354 }
1348 1355
1349 matches = staticCleanRegExp.allMatches(contents); 1356 matches = staticCleanRegExp.allMatches(contents);
1350 for (var match in matches) { 1357 for (var match in matches) {
1351 if (isStaticClean) { 1358 if (isStaticClean) {
1352 throw new Exception( 1359 throw new Exception(
1353 'More than one "// @static-clean=" line in test $filePath'); 1360 'More than one "// @static-clean=" line in test $filePath');
1354 } 1361 }
1355 isStaticClean = true; 1362 isStaticClean = true;
1356 } 1363 }
1357 1364
1358 List<String> otherScripts = new List<String>(); 1365 List<String> otherScripts = new List<String>();
1359 matches = otherScriptsRegExp.allMatches(contents); 1366 matches = otherScriptsRegExp.allMatches(contents);
1360 for (var match in matches) { 1367 for (var match in matches) {
1361 otherScripts.addAll(match[1].split(' ').filter((e) => e != '')); 1368 otherScripts.addAll(match[1].split(' ').where((e) => e != '').toList());
1362 } 1369 }
1363 1370
1364 bool isMultitest = multiTestRegExp.hasMatch(contents); 1371 bool isMultitest = multiTestRegExp.hasMatch(contents);
1365 bool isMultiHtmlTest = multiHtmlTestRegExp.hasMatch(contents); 1372 bool isMultiHtmlTest = multiHtmlTestRegExp.hasMatch(contents);
1366 bool containsLeadingHash = leadingHashRegExp.hasMatch(contents); 1373 bool containsLeadingHash = leadingHashRegExp.hasMatch(contents);
1367 Match isolateMatch = isolateStubsRegExp.firstMatch(contents); 1374 Match isolateMatch = isolateStubsRegExp.firstMatch(contents);
1368 String isolateStubs = isolateMatch != null ? isolateMatch[1] : ''; 1375 String isolateStubs = isolateMatch != null ? isolateMatch[1] : '';
1369 bool containsDomImport = domImportRegExp.hasMatch(contents); 1376 bool containsDomImport = domImportRegExp.hasMatch(contents);
1370 bool isLibraryDefinition = libraryDefinitionRegExp.hasMatch(contents); 1377 bool isLibraryDefinition = libraryDefinitionRegExp.hasMatch(contents);
1371 bool containsSourceOrImport = sourceOrImportRegExp.hasMatch(contents); 1378 bool containsSourceOrImport = sourceOrImportRegExp.hasMatch(contents);
1372 int numStaticTypeAnnotations = 0; 1379 int numStaticTypeAnnotations = 0;
1373 for (var i in staticTypeRegExp.allMatches(contents)) { 1380 for (var i in staticTypeRegExp.allMatches(contents)) {
1374 numStaticTypeAnnotations++; 1381 numStaticTypeAnnotations++;
1375 } 1382 }
1376 int numCompileTimeAnnotations = 0; 1383 int numCompileTimeAnnotations = 0;
1377 for (var i in compileTimeRegExp.allMatches(contents)) { 1384 for (var i in compileTimeRegExp.allMatches(contents)) {
1378 numCompileTimeAnnotations++; 1385 numCompileTimeAnnotations++;
1379 } 1386 }
1380 1387
1381 // Note: This is brittle. It's the age-old problem of having a context free 1388 // Note: This is brittle. It's the age-old problem of having a context free
1382 // language but the means to easily identify the construct is a regular 1389 // language but the means to easily identify the construct is a regular
1383 // expression, aka impossible. Therefore we just make an approximation of 1390 // expression, aka impossible. Therefore we just make an approximation of
1384 // the number of top-level "group(...)" occurrences. This assumes you import 1391 // the number of top-level "group(...)" occurrences. This assumes you import
1385 // unittest with no prefix and always directly call "group(". It only uses 1392 // unittest with no prefix and always directly call "group(". It only uses
1386 // top-level "groups" so tests running nested groups will be no-ops. 1393 // top-level "groups" so tests running nested groups will be no-ops.
1387 RegExp numTests = new RegExp(r"\s*[^/]\s*group\('[^,']*"); 1394 RegExp numTests = new RegExp(r"\s*[^/]\s*group\('[^,']*");
1388 List<String> subtestNames = []; 1395 List<String> subtestNames = [];
1389 Iterator matchesIter = numTests.allMatches(contents).iterator(); 1396 Iterator matchesIter = numTests.allMatches(contents).iterator;
1390 while(matchesIter.hasNext && isMultiHtmlTest) { 1397 while(matchesIter.moveNext() && isMultiHtmlTest) {
1391 String fullMatch = matchesIter.next().group(0); 1398 String fullMatch = matchesIter.current.group(0);
1392 subtestNames.add(fullMatch.substring(fullMatch.indexOf("'") + 1)); 1399 subtestNames.add(fullMatch.substring(fullMatch.indexOf("'") + 1));
1393 } 1400 }
1394 1401
1395 return { "vmOptions": result, 1402 return { "vmOptions": result,
1396 "dartOptions": dartOptions, 1403 "dartOptions": dartOptions,
1397 "packageRoot": packageRoot, 1404 "packageRoot": packageRoot,
1398 "hasCompileError": hasCompileError, 1405 "hasCompileError": hasCompileError,
1399 "hasRuntimeError": hasRuntimeError, 1406 "hasRuntimeError": hasRuntimeError,
1400 "isStaticClean" : isStaticClean, 1407 "isStaticClean" : isStaticClean,
1401 "otherScripts": otherScripts, 1408 "otherScripts": otherScripts,
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
1806 * $pass tests are expected to pass 1813 * $pass tests are expected to pass
1807 * $failOk tests are expected to fail that we won't fix 1814 * $failOk tests are expected to fail that we won't fix
1808 * $fail tests are expected to fail that we should fix 1815 * $fail tests are expected to fail that we should fix
1809 * $crash tests are expected to crash that we should fix 1816 * $crash tests are expected to crash that we should fix
1810 * $timeout tests are allowed to timeout 1817 * $timeout tests are allowed to timeout
1811 * $compileErrorSkip tests are skipped on browsers due to compile-time error 1818 * $compileErrorSkip tests are skipped on browsers due to compile-time error
1812 """; 1819 """;
1813 print(report); 1820 print(report);
1814 } 1821 }
1815 } 1822 }
OLDNEW
« no previous file with comments | « tools/testing/dart/test_runner.dart ('k') | tools/version.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698