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

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

Issue 10584014: Change test scripts to use Path library in most places, instead of strings. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address my own comments. Created 8 years, 5 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
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,
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 Function doTest; 104 Function doTest;
105 Function doDone; 105 Function doDone;
106 ReceivePort receiveTestName; 106 ReceivePort receiveTestName;
107 TestExpectations testExpectations; 107 TestExpectations testExpectations;
108 108
109 CCTestSuite(Map this.configuration, 109 CCTestSuite(Map this.configuration,
110 String this.suiteName, 110 String this.suiteName,
111 String runnerName, 111 String runnerName,
112 List<String> this.statusFilePaths, 112 List<String> this.statusFilePaths,
113 [this.testPrefix = '']) 113 [this.testPrefix = ''])
114 : dartDir = TestUtils.dartDir() { 114 : dartDir = TestUtils.dartDir().toNativePath() {
Anton Muhin 2012/06/26 13:22:18 should dartDir be a String?
Bill Hesse 2012/06/27 09:35:03 I'm not changing the class CCTestSuite, except to
115 runnerPath = '${TestUtils.buildDir(configuration)}/$runnerName'; 115 runnerPath = '${TestUtils.buildDir(configuration)}/$runnerName';
116 } 116 }
117 117
118 void testNameHandler(String testName, ignore) { 118 void testNameHandler(String testName, ignore) {
119 if (testName == "") { 119 if (testName == "") {
120 receiveTestName.close(); 120 receiveTestName.close();
121 doDone(true); 121 doDone(true);
122 } else { 122 } else {
123 // Only run the tests that match the pattern. Use the name 123 // Only run the tests that match the pattern. Use the name
124 // "suiteName/testName" for cc tests. 124 // "suiteName/testName" for cc tests.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 statusFileRead); 172 statusFileRead);
173 } 173 }
174 } 174 }
175 175
176 void completeHandler(TestCase testCase) { 176 void completeHandler(TestCase testCase) {
177 } 177 }
178 } 178 }
179 179
180 180
181 class TestInformation { 181 class TestInformation {
182 String filename; 182 Path filePath;
183 Map optionsFromFile; 183 Map optionsFromFile;
184 bool isNegative; 184 bool isNegative;
185 bool isNegativeIfChecked; 185 bool isNegativeIfChecked;
186 bool hasFatalTypeErrors; 186 bool hasFatalTypeErrors;
187 bool hasRuntimeErrors; 187 bool hasRuntimeErrors;
188 Set<String> multitestOutcome; 188 Set<String> multitestOutcome;
189 189
190 TestInformation(this.filename, this.optionsFromFile, this.isNegative, 190 TestInformation(this.filePath, this.optionsFromFile, this.isNegative,
191 this.isNegativeIfChecked, this.hasFatalTypeErrors, 191 this.isNegativeIfChecked, this.hasFatalTypeErrors,
192 this.hasRuntimeErrors, this.multitestOutcome); 192 this.hasRuntimeErrors, this.multitestOutcome) {
193 Expect.isTrue(filePath.isAbsolute);
194 }
195
196 // String get filename() => '$filePath';
Anton Muhin 2012/06/26 13:22:18 commented out code
Bill Hesse 2012/06/27 09:35:03 Done.
193 } 197 }
194 198
195 199
196 /** 200 /**
197 * A standard [TestSuite] implementation that searches for tests in a 201 * A standard [TestSuite] implementation that searches for tests in a
198 * directory, and creates [TestCase]s that compile and/or run them. 202 * directory, and creates [TestCase]s that compile and/or run them.
199 */ 203 */
200 class StandardTestSuite implements TestSuite { 204 class StandardTestSuite implements TestSuite {
201 Map configuration; 205 Map configuration;
202 String suiteName; 206 String suiteName;
203 String directoryPath; 207 Path suiteDir;
204 List<String> statusFilePaths; 208 List<String> statusFilePaths;
205 Function doTest; 209 Function doTest;
206 Function doDone; 210 Function doDone;
207 int activeTestGenerators = 0; 211 int activeTestGenerators = 0;
208 bool listingDone = false; 212 bool listingDone = false;
209 TestExpectations testExpectations; 213 TestExpectations testExpectations;
210 List<TestInformation> cachedTests; 214 List<TestInformation> cachedTests;
211 final String dartDir; 215 final Path dartDir;
212 Predicate<String> isTestFilePredicate; 216 Predicate<String> isTestFilePredicate;
213 bool _listRecursive; 217 bool _listRecursive;
214 218
215 StandardTestSuite(Map this.configuration, 219 StandardTestSuite(this.configuration,
216 String this.suiteName, 220 this.suiteName,
217 String this.directoryPath, 221 Path suiteDirectory,
218 List<String> this.statusFilePaths, 222 this.statusFilePaths,
219 [Predicate<String> this.isTestFilePredicate, 223 [this.isTestFilePredicate,
220 bool recursive = false]) 224 bool recursive = false])
221 : dartDir = TestUtils.dartDir(), _listRecursive = recursive; 225 : dartDir = TestUtils.dartDir(), _listRecursive = recursive,
226 suiteDir = TestUtils.dartDir().join(suiteDirectory);
222 227
223 /** 228 /**
224 * Creates a test suite whose file organization matches an expected structure. 229 * Creates a test suite whose file organization matches an expected structure.
225 * To use this, your suite should look like: 230 * To use this, your suite should look like:
226 * 231 *
227 * dart/ 232 * dart/
228 * path/ 233 * path/
229 * to/ 234 * to/
230 * mytestsuite/ 235 * mytestsuite/
231 * mytestsuite.status 236 * mytestsuite.status
232 * example1_test.dart 237 * example1_test.dart
233 * example2_test.dart 238 * example2_test.dart
234 * example3_test.dart 239 * example3_test.dart
235 * 240 *
236 * The important parts: 241 * The important parts:
237 * 242 *
238 * * The leaf directory name is the name of your test suite. 243 * * The leaf directory name is the name of your test suite.
239 * * The status file uses the same name. 244 * * The status file uses the same name.
240 * * Test files are directly in that directory and end in "_test.dart". 245 * * Test files are directly in that directory and end in "_test.dart".
241 * 246 *
242 * If you follow that convention, then you can construct one of these like: 247 * If you follow that convention, then you can construct one of these like:
243 * 248 *
244 * new StandardTestSuite.forDirectory(configuration, 'path/to/mytestsuite'); 249 * new StandardTestSuite.forDirectory(configuration, 'path/to/mytestsuite');
245 * 250 *
246 * instead of having to create a custom [StandardTestSuite] subclass. In 251 * instead of having to create a custom [StandardTestSuite] subclass. In
247 * particular, if you add 'path/to/mytestsuite' to [TEST_SUITE_DIRECTORIES] 252 * particular, if you add 'path/to/mytestsuite' to [TEST_SUITE_DIRECTORIES]
248 * in test.dart, this will all be set up for you. 253 * in test.dart, this will all be set up for you.
249 */ 254 */
250 factory StandardTestSuite.forDirectory( 255 factory StandardTestSuite.forDirectory(
251 Map configuration, String directory) { 256 Map configuration, Path directory) {
252 final name = directory.substring(directory.lastIndexOf('/') + 1); 257 final name = directory.filename;
253 258
254 return new StandardTestSuite(configuration, 259 return new StandardTestSuite(configuration,
255 name, directory, 260 name, directory,
256 ['$directory/$name.status', '$directory/${name}_dart2js.status'], 261 ['$directory/$name.status', '$directory/${name}_dart2js.status'],
257 (filename) => filename.endsWith('_test.dart'), 262 (filename) => filename.endsWith('_test.dart'),
258 recursive: true); 263 recursive: true);
259 } 264 }
260 265
261 /** 266 /**
262 * The default implementation assumes a file is a test if 267 * The default implementation assumes a file is a test if
263 * it ends in "Test.dart". 268 * it ends in "Test.dart".
264 */ 269 */
265 bool isTestFile(String filename) { 270 bool isTestFile(String filename) {
266 // Use the specified predicate, if provided. 271 // Use the specified predicate, if provided.
267 if (isTestFilePredicate != null) return isTestFilePredicate(filename); 272 if (isTestFilePredicate != null) return isTestFilePredicate(filename);
268 273
269 return filename.endsWith("Test.dart"); 274 return filename.endsWith("Test.dart");
270 } 275 }
271 276
272 bool listRecursively() => _listRecursive; 277 bool listRecursively() => _listRecursive;
273 278
274 String shellPath() => TestUtils.dartShellFileName(configuration); 279 String shellPath() => TestUtils.dartShellFileName(configuration);
275 280
276 List<String> additionalOptions(String filename) => []; 281 List<String> additionalOptions(Path filePath) => [];
277 282
278 void forEachTest(Function onTest, Map testCache, [Function onDone = null]) { 283 void forEachTest(Function onTest, Map testCache, [Function onDone = null]) {
279 // If DumpRenderTree/Dartium is required, and not yet updated, 284 // If DumpRenderTree/Dartium is required, and not yet updated,
280 // wait for update. 285 // wait for update.
281 var updater = runtimeUpdater(configuration); 286 var updater = runtimeUpdater(configuration);
282 if (updater !== null && !updater.updated) { 287 if (updater !== null && !updater.updated) {
283 Expect.isTrue(updater.isActive); 288 Expect.isTrue(updater.isActive);
284 updater.onUpdated.add(() { 289 updater.onUpdated.add(() {
285 forEachTest(onTest, testCache, onDone); 290 forEachTest(onTest, testCache, onDone);
286 }); 291 });
(...skipping 25 matching lines...) Expand all
312 } 317 }
313 } 318 }
314 } 319 }
315 320
316 // Read test expectations from status files. 321 // Read test expectations from status files.
317 testExpectations = new TestExpectations(); 322 testExpectations = new TestExpectations();
318 for (var statusFilePath in statusFilePaths) { 323 for (var statusFilePath in statusFilePaths) {
319 // [forDirectory] adds name_dart2js.status for all tests suites, use it if 324 // [forDirectory] adds name_dart2js.status for all tests suites, use it if
320 // it exists, but otherwise skip it and don't fail. 325 // it exists, but otherwise skip it and don't fail.
321 if (statusFilePath.endsWith('_dart2js.status')) { 326 if (statusFilePath.endsWith('_dart2js.status')) {
322 File file = new File('$dartDir/$statusFilePath'); 327 File file = new File.fromPath(dartDir.append(statusFilePath));
323 if (!file.existsSync()) { 328 if (!file.existsSync()) {
324 filesRead++; 329 filesRead++;
325 continue; 330 continue;
326 } 331 }
327 } 332 }
328 ReadTestExpectationsInto(testExpectations, 333 ReadTestExpectationsInto(testExpectations,
329 '$dartDir/$statusFilePath', 334 '${dartDir.toNativePath()}/$statusFilePath',
Anton Muhin 2012/06/26 13:22:18 join?
Bill Hesse 2012/06/27 09:35:03 Actually, append, since statusFilePaths is a list
330 configuration, 335 configuration,
331 statusFileRead); 336 statusFileRead);
332 } 337 }
333 } 338 }
334 339
335 void processDirectory() { 340 void processDirectory() {
336 directoryPath = '$dartDir/$directoryPath'; 341 Directory dir = new Directory.fromPath(suiteDir);
337 Directory dir = new Directory(directoryPath);
338 dir.exists().then((exists) { 342 dir.exists().then((exists) {
339 if (!exists) { 343 if (!exists) {
340 print('Directory containing tests not found: $directoryPath'); 344 print('Directory containing tests not found: $suiteDir');
341 directoryListingDone(false); 345 directoryListingDone(false);
342 } else { 346 } else {
343 var lister = dir.list(recursive: listRecursively()); 347 var lister = dir.list(recursive: listRecursively());
344 lister.onFile = processFile; 348 lister.onFile = processFile;
345 lister.onDone = directoryListingDone; 349 lister.onDone = directoryListingDone;
346 } 350 }
347 }); 351 });
348 } 352 }
349 353
350 void enqueueTestCaseFromTestInformation(TestInformation info) { 354 void enqueueTestCaseFromTestInformation(TestInformation info) {
351 var filename = info.filename; 355 var filePath = info.filePath;
352 var optionsFromFile = info.optionsFromFile; 356 var optionsFromFile = info.optionsFromFile;
353 var isNegative = info.isNegative; 357 var isNegative = info.isNegative;
354 358
355 // Look up expectations in status files using a modified file path. 359 // Look up expectations in status files using a test name generated
360 // from the test file's path.
356 String testName; 361 String testName;
357 filename = filename.replaceAll('\\', '/');
358 362
359 // See if there's a 'src' directory inside the 'tests' one. 363 if (optionsFromFile['isMultitest']) {
360 int testsStart = filename.lastIndexOf('tests/'); 364 // Multitests do not run on browsers.
361 int start = filename.lastIndexOf('src/'); 365 if (TestUtils.isBrowserRuntime(configuration['runtime'])) return;
362 if (start > testsStart) { 366 // Multitests are in [build directory]/generated_tests/... .
363 // Old-style test suites with tests in a 'src' subdirectory. 367 // The test name will be '[test filename (no extension)]/[multitest key].
364 // TODO(sigmund): delete this branch once all tests stop using the src/ 368 String name = filePath.filenameWithoutExtension;
365 // directory 369 int middle = name.lastIndexOf('_');
366 testName = filename.substring(start + 4, filename.length - 5); 370 testName = '${name.substring(0, middle)}/${name.substring(middle + 1)}';
367 } else if (optionsFromFile['isMultitest']) {
368 start = filename.lastIndexOf('/');
369 int middle = filename.lastIndexOf('_');
370 var multitestBase = filename.substring(start + 1, middle);
371 var multitestKey = filename.substring(middle + 1, filename.length - 5);
372 testName = '$multitestBase/$multitestKey';
373 } else { 371 } else {
374 // New-style test suites created by StandardTestSuite.forDirectory(). 372 // The test name is the relative path from the test suite directory to
375 start = filename.indexOf(directoryPath); 373 // the test, with the .dart extension removed.
376 if (start != -1) { 374 Expect.isTrue(filePath.toNativePath().startsWith(
377 testName = filename.substring(start + directoryPath.length + 1); 375 suiteDir.toNativePath()));
378 } else { 376 var testNamePath =
379 testName = filename; 377 filePath.relativeTo(suiteDir);
380 } 378 Expect.isTrue(testNamePath.extension == 'dart');
381 if (testName.endsWith('.dart')) { 379 if (testNamePath.extension == 'dart') {
382 testName = testName.substring(0, testName.length - 5); 380 testName = testNamePath.directoryPath.append(
381 testNamePath.filenameWithoutExtension).toString();
383 } 382 }
384 } 383 }
385 int shards = configuration['shards']; 384 int shards = configuration['shards'];
386 if (shards > 1) { 385 if (shards > 1) {
387 int shard = configuration['shard']; 386 int shard = configuration['shard'];
388 if (testName.hashCode() % shards != shard - 1) { 387 if (testName.hashCode() % shards != shard - 1) {
389 return; 388 return;
390 } 389 }
391 } 390 }
392 391
393 Set<String> expectations = testExpectations.expectations(testName); 392 Set<String> expectations = testExpectations.expectations(testName);
394 if (configuration['report']) { 393 if (configuration['report']) {
395 // Tests with multiple VMOptions are counted more than once. 394 // Tests with multiple VMOptions are counted more than once.
396 for (var dummy in getVmOptions(optionsFromFile)) { 395 for (var dummy in getVmOptions(optionsFromFile)) {
397 if (TestUtils.isBrowserRuntime(configuration['runtime']) &&
398 optionsFromFile['isMultitest']) {
399 break; // Browser tests skip multitests.
400 }
401 SummaryReport.add(expectations); 396 SummaryReport.add(expectations);
402 } 397 }
403 } 398 }
404 if (expectations.contains(SKIP)) return; 399 if (expectations.contains(SKIP)) return;
405 400
406 if (TestUtils.isBrowserRuntime(configuration['runtime'])) { 401 if (TestUtils.isBrowserRuntime(configuration['runtime'])) {
407 enqueueBrowserTest(info, testName, expectations); 402 enqueueBrowserTest(info, testName, expectations);
408 } else { 403 } else {
409 enqueueStandardTest(info, testName, expectations); 404 enqueueStandardTest(info, testName, expectations);
410 } 405 }
411 } 406 }
412 407
413 void enqueueStandardTest(TestInformation info, 408 void enqueueStandardTest(TestInformation info,
414 String testName, 409 String testName,
415 Set<String> expectations) { 410 Set<String> expectations) {
416 bool isNegative = info.isNegative || 411 bool isNegative = info.isNegative ||
417 (configuration['checked'] && info.isNegativeIfChecked); 412 (configuration['checked'] && info.isNegativeIfChecked);
418 413
419 if (configuration['compiler'] == 'dartc') { 414 if (configuration['compiler'] == 'dartc') {
420 // dartc can detect static type warnings by the 415 // dartc can detect static type warnings by the
421 // format of the error line 416 // format of the error line
422 if (info.hasFatalTypeErrors) { 417 if (info.hasFatalTypeErrors) {
423 isNegative = true; 418 isNegative = true;
424 } else if (info.hasRuntimeErrors) { 419 } else if (info.hasRuntimeErrors) {
425 isNegative = false; 420 isNegative = false;
426 } 421 }
427 } 422 }
428 423
429 var argumentLists = argumentListsFromFile(info.filename, 424 var argumentLists = argumentListsFromFile(info.filePath,
430 info.optionsFromFile); 425 info.optionsFromFile);
431 426
432 for (var args in argumentLists) { 427 for (var args in argumentLists) {
433 doTest(new TestCase('$suiteName/$testName', 428 doTest(new TestCase('$suiteName/$testName',
434 makeCommands(info, args), 429 makeCommands(info, args),
435 configuration, 430 configuration,
436 completeHandler, 431 completeHandler,
437 expectations, 432 expectations,
438 isNegative, 433 isNegative,
439 info)); 434 info));
440 } 435 }
441 } 436 }
442 437
443 List<Command> makeCommands(TestInformation info, var args) { 438 List<Command> makeCommands(TestInformation info, var args) {
444 if (configuration['compiler'] == 'dart2js') { 439 if (configuration['compiler'] == 'dart2js') {
445 args = new List.from(args); 440 args = new List.from(args);
446 String testPath = 441 String tempDir = createOutputDirectory(info.filePath, '');
447 new File(info.filename).fullPathSync().replaceAll('\\', '/');
448 String tempDir = createOutputDirectory(testPath, '');
449 args.add('--out=$tempDir/out.js'); 442 args.add('--out=$tempDir/out.js');
450 List<Command> commands = <Command>[new Command(shellPath(), args)]; 443 List<Command> commands = <Command>[new Command(shellPath(), args)];
451 if (configuration['runtime'] == 'd8') { 444 if (configuration['runtime'] == 'd8') {
452 var d8 = TestUtils.d8FileName(configuration); 445 var d8 = TestUtils.d8FileName(configuration);
453 commands.add(new Command(d8, ['$tempDir/out.js'])); 446 commands.add(new Command(d8, ['$tempDir/out.js']));
454 } 447 }
455 return commands; 448 return commands;
456 } else { 449 } else {
457 return <Command>[new Command(shellPath(), args)]; 450 return <Command>[new Command(shellPath(), args)];
458 } 451 }
459 } 452 }
460 453
461 Function makeTestCaseCreator(Map optionsFromFile) { 454 Function makeTestCaseCreator(Map optionsFromFile) {
462 return (String filename, 455 return (Path filePath,
463 bool isNegative, 456 bool isNegative,
464 [bool isNegativeIfChecked = false, 457 [bool isNegativeIfChecked = false,
465 bool hasFatalTypeErrors = false, 458 bool hasFatalTypeErrors = false,
466 bool hasRuntimeErrors = false, 459 bool hasRuntimeErrors = false,
467 Set<String> multitestOutcome = null]) { 460 Set<String> multitestOutcome = null]) {
468 // Cache the test information for each test case. 461 // Cache the test information for each test case.
469 var info = new TestInformation(filename, 462 var info = new TestInformation(filePath,
470 optionsFromFile, 463 optionsFromFile,
471 isNegative, 464 isNegative,
472 isNegativeIfChecked, 465 isNegativeIfChecked,
473 hasFatalTypeErrors, 466 hasFatalTypeErrors,
474 hasRuntimeErrors, 467 hasRuntimeErrors,
475 multitestOutcome); 468 multitestOutcome);
476 cachedTests.add(info); 469 cachedTests.add(info);
477 enqueueTestCaseFromTestInformation(info); 470 enqueueTestCaseFromTestInformation(info);
478 }; 471 };
479 } 472 }
480 473
481 void processFile(String filename) { 474 void processFile(String filename) {
482 if (!isTestFile(filename)) return; 475 if (!isTestFile(filename)) return;
476 Path filePath = new Path.fromNative(filename);
483 477
484 // Only run the tests that match the pattern. 478 // Only run the tests that match the pattern.
485 RegExp pattern = configuration['selectors'][suiteName]; 479 RegExp pattern = configuration['selectors'][suiteName];
486 if (!pattern.hasMatch(filename)) return; 480 if (!pattern.hasMatch('$filePath')) return;
487 if (filename.endsWith('test_config.dart')) return; 481 if (filePath.filename.endsWith('test_config.dart')) return;
488 482
489 var optionsFromFile = readOptionsFromFile(filename); 483 var optionsFromFile = readOptionsFromFile(filePath);
490 Function createTestCase = makeTestCaseCreator(optionsFromFile); 484 Function createTestCase = makeTestCaseCreator(optionsFromFile);
491 485
492 if (optionsFromFile['isMultitest']) { 486 if (optionsFromFile['isMultitest']) {
493 testGeneratorStarted(); 487 testGeneratorStarted();
494 DoMultitest(filename, 488 DoMultitest(filePath,
495 TestUtils.buildDir(configuration), 489 TestUtils.buildDir(configuration),
496 directoryPath, 490 suiteDir,
497 createTestCase, 491 createTestCase,
498 testGeneratorDone); 492 testGeneratorDone);
499 } else { 493 } else {
500 createTestCase(filename, optionsFromFile['isNegative']); 494 createTestCase(filePath, optionsFromFile['isNegative']);
501 } 495 }
502 } 496 }
503 497
504 /** 498 /**
505 * The [StandardTestSuite] has support for tests that 499 * The [StandardTestSuite] has support for tests that
506 * compile a test from Dart to Javascript, and then run the resulting 500 * compile a test from Dart to Javascript, and then run the resulting
507 * Javascript. This function creates a working directory to hold the 501 * Javascript. This function creates a working directory to hold the
508 * Javascript version of the test, and copies the appropriate framework 502 * Javascript version of the test, and copies the appropriate framework
509 * files to that directory. It creates a [BrowserTestCase], which has 503 * files to that directory. It creates a [BrowserTestCase], which has
510 * two sequential steps to be run by the [ProcessQueue when] the test is 504 * two sequential steps to be run by the [ProcessQueue when] the test is
511 * executed: a compilation 505 * executed: a compilation
512 * step and an execution step, both with the appropriate executable and 506 * step and an execution step, both with the appropriate executable and
513 * arguments. 507 * arguments.
514 */ 508 */
515 void enqueueBrowserTest(TestInformation info, 509 void enqueueBrowserTest(TestInformation info,
516 String testName, 510 String testName,
517 Set<String> expectations) { 511 Set<String> expectations) {
518 Map optionsFromFile = info.optionsFromFile; 512 Map optionsFromFile = info.optionsFromFile;
519 String filename = info.filename; 513 Path filePath = info.filePath;
520 if (optionsFromFile['isMultitest']) return; 514 String filename = info.filename; // filePath.toString, an absolute path.
521 bool isWebTest = optionsFromFile['containsDomImport']; 515 bool isWebTest = optionsFromFile['containsDomImport'];
522 bool isLibraryDefinition = optionsFromFile['isLibraryDefinition']; 516 bool isLibraryDefinition = optionsFromFile['isLibraryDefinition'];
523 if (!isLibraryDefinition && optionsFromFile['containsSourceOrImport']) { 517 if (!isLibraryDefinition && optionsFromFile['containsSourceOrImport']) {
524 print('Warning for $filename: Browser tests require #library ' 518 print('Warning for $filename: Browser tests require #library '
525 'in any file that uses #import, #source, or #resource'); 519 'in any file that uses #import, #source, or #resource');
526 } 520 }
527 521
528 final String compiler = configuration['compiler']; 522 final String compiler = configuration['compiler'];
529 final String runtime = configuration['runtime']; 523 final String runtime = configuration['runtime'];
530 final String testPath =
531 new File(filename).fullPathSync().replaceAll('\\', '/');
532 524
533 for (var vmOptions in getVmOptions(optionsFromFile)) { 525 for (var vmOptions in getVmOptions(optionsFromFile)) {
534 // Create a unique temporary directory for each set of vmOptions. 526 // Create a unique temporary directory for each set of vmOptions.
535 // TODO(dart:429): Replace separate replaceAlls with a RegExp when 527 // TODO(dart:429): Replace separate replaceAlls with a RegExp when
536 // replaceAll(RegExp, String) is implemented. 528 // replaceAll(RegExp, String) is implemented.
537 String optionsName = ''; 529 String optionsName = '';
538 if (getVmOptions(optionsFromFile).length > 1) { 530 if (getVmOptions(optionsFromFile).length > 1) {
539 optionsName = Strings.join(vmOptions, '-').replaceAll('-','') 531 optionsName = Strings.join(vmOptions, '-').replaceAll('-','')
540 .replaceAll('=','') 532 .replaceAll('=','')
541 .replaceAll('/',''); 533 .replaceAll('/','');
542 } 534 }
543 final String tempDir = createOutputDirectory(testPath, optionsName); 535 final String tempDir = createOutputDirectory(info.filePath, optionsName);
544 536
545 String dartWrapperFilename = '$tempDir/test.dart'; 537 String dartWrapperFilename = '$tempDir/test.dart';
546 String compiledDartWrapperFilename = '$tempDir/test.js'; 538 String compiledDartWrapperFilename = '$tempDir/test.js';
547 539
548 String htmlPath = '$tempDir/test.html'; 540 String htmlPath = '$tempDir/test.html';
549 if (!isWebTest) { 541 if (!isWebTest) {
550 // test.dart will import the dart test directly, if it is a library, 542 // test.dart will import the dart test directly, if it is a library,
551 // or indirectly through test_as_library.dart, if it is not. 543 // or indirectly through test_as_library.dart, if it is not.
552 String dartLibraryFilename; 544 Path dartLibraryFilename = filePath;
553 if (isLibraryDefinition) { 545 if (!isLibraryDefinition) {
554 dartLibraryFilename = testPath; 546 dartLibraryFilename = new Path('test_as_library.dart');
555 } else {
556 dartLibraryFilename = 'test_as_library.dart';
557 File file = new File('$tempDir/$dartLibraryFilename'); 547 File file = new File('$tempDir/$dartLibraryFilename');
558 RandomAccessFile dartLibrary = file.openSync(FileMode.WRITE); 548 RandomAccessFile dartLibrary = file.openSync(FileMode.WRITE);
559 dartLibrary.writeStringSync(WrapDartTestInLibrary(testPath)); 549 dartLibrary.writeStringSync(WrapDartTestInLibrary(filePath));
560 dartLibrary.closeSync(); 550 dartLibrary.closeSync();
561 } 551 }
562 552
563 File file = new File(dartWrapperFilename); 553 File file = new File(dartWrapperFilename);
564 RandomAccessFile dartWrapper = file.openSync(FileMode.WRITE); 554 RandomAccessFile dartWrapper = file.openSync(FileMode.WRITE);
565 dartWrapper.writeStringSync( 555 dartWrapper.writeStringSync(
566 DartTestWrapper(dartDir, dartLibraryFilename)); 556 DartTestWrapper(dartDir, dartLibraryFilename));
567 dartWrapper.closeSync(); 557 dartWrapper.closeSync();
568 } else { 558 } else {
569 dartWrapperFilename = testPath; 559 dartWrapperFilename = filename;
570 // TODO(whesse): Once test.py is retired, adjust the relative path in 560 // TODO(whesse): Once test.py is retired, adjust the relative path in
571 // the client/samples/dartcombat test to its css file, remove the 561 // the client/samples/dartcombat test to its css file, remove the
572 // "../../" from this path, and move this out of the isWebTest guard. 562 // "../../" from this path, and move this out of the isWebTest guard.
573 // Also remove getHtmlName, and just use test.html. 563 // Also remove getHtmlName, and just use test.html.
574 // TODO(efortuna): this shortening of htmlFilename is a band-aid until 564 // TODO(efortuna): this shortening of htmlFilename is a band-aid until
575 // the above TODO gets fixed. Windows cannot have paths that are longer 565 // the above TODO gets fixed. Windows cannot have paths that are longer
576 // than 260 characters, and without this hack, we were running past the 566 // than 260 characters, and without this hack, we were running past the
577 // the limit. 567 // the limit.
578 String htmlFilename = getHtmlName(filename); 568 String htmlFilename = getHtmlName(filename);
579 while ('$tempDir/../$htmlFilename'.length >= 260) { 569 while ('$tempDir/../$htmlFilename'.length >= 260) {
580 htmlFilename = htmlFilename.substring(htmlFilename.length~/2); 570 htmlFilename = htmlFilename.substring(htmlFilename.length~/2);
581 } 571 }
582 htmlPath = '$tempDir/../$htmlFilename'; 572 htmlPath = '$tempDir/../$htmlFilename';
583 } 573 }
584 final String scriptPath = (compiler == 'none') ? 574 final String scriptPath = (compiler == 'none') ?
585 dartWrapperFilename : compiledDartWrapperFilename; 575 dartWrapperFilename : compiledDartWrapperFilename;
586 // Create the HTML file for the test. 576 // Create the HTML file for the test.
587 RandomAccessFile htmlTest = new File(htmlPath).openSync(FileMode.WRITE); 577 RandomAccessFile htmlTest = new File(htmlPath).openSync(FileMode.WRITE);
588 String filePrefix = ''; 578 String filePrefix = '';
589 if (Platform.operatingSystem == 'windows') { 579 if (Platform.operatingSystem == 'windows') {
590 // Firefox on Windows does not like absolute file path names that start 580 // Firefox on Windows does not like absolute file path names that start
591 // with 'C:' adding 'file:///' solves the problem. 581 // with 'C:' adding 'file:///' solves the problem.
592 filePrefix = 'file:///'; 582 filePrefix = 'file:///';
593 } 583 }
594 htmlTest.writeStringSync(GetHtmlContents( 584 htmlTest.writeStringSync(GetHtmlContents(
595 filename, 585 filename,
596 '$filePrefix$dartDir/lib/unittest/test_controller.js', 586 '$filePrefix${dartDir.append("lib/unittest/test_controller.js")}',
597 scriptType, 587 scriptType,
598 '$filePrefix$scriptPath')); 588 '$filePrefix$scriptPath'));
599 htmlTest.closeSync(); 589 htmlTest.closeSync();
600 590
601 // Construct the command(s) that compile all the inputs needed by the 591 // Construct the command(s) that compile all the inputs needed by the
602 // browser test. For running Dart in DRT, this will be noop commands. 592 // browser test. For running Dart in DRT, this will be noop commands.
603 List<Command> commands = []; 593 List<Command> commands = [];
604 if (compiler != 'none') { 594 if (compiler != 'none') {
605 commands.add(_compileCommand( 595 commands.add(_compileCommand(
606 dartWrapperFilename, compiledDartWrapperFilename, 596 dartWrapperFilename, compiledDartWrapperFilename,
607 compiler, tempDir, vmOptions)); 597 compiler, tempDir, vmOptions));
608 598
609 // some tests require compiling multiple input scripts. 599 // some tests require compiling multiple input scripts.
610 List<String> otherScripts = optionsFromFile['otherScripts']; 600 List<String> otherScripts = optionsFromFile['otherScripts'];
611 for (String name in otherScripts) { 601 for (String name in otherScripts) {
612 int end = filename.lastIndexOf('/'); 602 Path namePath = new Path(name);
613 if (end == -1) { 603 Expect.equals(namePath.extension, 'dart');
614 print('Warning: error processing "OtherScripts" of $filename.'); 604 String compiledName = namePath.filenameWithoutExtension;
615 print('Skipping test ($testName).'); 605 Path fromPath = filePath.directoryPath.join(namePath);
616 return;
617 }
618 String dir = filename.substring(0, end);
619 end = name.lastIndexOf('.dart');
620 if (end == -1) {
621 print('Warning: error processing "OtherScripts" in $filename.');
622 print('Skipping test ($testName).');
623 return;
624 }
625 String compiledName = '${name.substring(0, end)}.js';
626 commands.add(_compileCommand( 606 commands.add(_compileCommand(
627 '$dir/$name', '$tempDir/$compiledName', 607 fromPath.toNativePath(), '$tempDir/$compiledName',
628 compiler, tempDir, vmOptions)); 608 compiler, tempDir, vmOptions));
629 } 609 }
630 } 610 }
631 611
632 // Construct the command that executes the browser test 612 // Construct the command that executes the browser test
633 List<String> args; 613 List<String> args;
634 if (runtime == 'ie' || runtime == 'ff' || runtime == 'chrome' || 614 if (runtime == 'ie' || runtime == 'ff' || runtime == 'chrome' ||
635 runtime == 'safari' || runtime == 'opera' || runtime == 'dartium') { 615 runtime == 'safari' || runtime == 'opera' || runtime == 'dartium') {
636 args = ['$dartDir/tools/testing/run_selenium.py', 616 args = [dartDir.append('tools/testing/run_selenium.py').toNativePath(),
637 '--browser=$runtime', 617 '--browser=$runtime',
638 '--timeout=${configuration["timeout"] - 2}', 618 '--timeout=${configuration["timeout"] - 2}',
639 '--out=$htmlPath']; 619 '--out=$htmlPath'];
640 if (runtime == 'dartium') { 620 if (runtime == 'dartium') {
641 args.add('--executable=$dartiumFilename'); 621 args.add('--executable=$dartiumFilename');
642 } 622 }
643 } else { 623 } else {
644 args = [ 624 args = [
645 '$dartDir/tools/testing/drt-trampoline.py', 625 dartDir.append('tools/testing/drt-trampoline.py').toNativePath(),
646 dumpRenderTreeFilename, 626 dumpRenderTreeFilename,
647 '--no-timeout' 627 '--no-timeout'
648 ]; 628 ];
649 if (runtime == 'drt' && compiler == 'none') { 629 if (runtime == 'drt' && compiler == 'none') {
650 var dartFlags = ['--ignore-unrecognized-flags']; 630 var dartFlags = ['--ignore-unrecognized-flags'];
651 if (configuration["checked"]) { 631 if (configuration["checked"]) {
652 dartFlags.add('--enable_asserts'); 632 dartFlags.add('--enable_asserts');
653 dartFlags.add("--enable_type_checks"); 633 dartFlags.add("--enable_type_checks");
654 } 634 }
655 dartFlags.addAll(vmOptions); 635 dartFlags.addAll(vmOptions);
(...skipping 13 matching lines...) Expand all
669 649
670 /** Helper to create a compilation command for a single input file. */ 650 /** Helper to create a compilation command for a single input file. */
671 Command _compileCommand(String inputFile, String outputFile, 651 Command _compileCommand(String inputFile, String outputFile,
672 String compiler, String dir, var vmOptions) { 652 String compiler, String dir, var vmOptions) {
673 String executable = TestUtils.compilerPath(configuration); 653 String executable = TestUtils.compilerPath(configuration);
674 List<String> args = TestUtils.standardOptions(configuration); 654 List<String> args = TestUtils.standardOptions(configuration);
675 switch (compiler) { 655 switch (compiler) {
676 case 'frog': 656 case 'frog':
677 String libdir = configuration['froglib']; 657 String libdir = configuration['froglib'];
678 if (libdir == '') { 658 if (libdir == '') {
679 libdir = '$dartDir/frog/lib'; 659 libdir = dartDir.append('frog/lib').toNativePath();
680 } 660 }
681 args.addAll(['--libdir=$libdir', 661 args.addAll(['--libdir=$libdir',
682 '--compile-only', 662 '--compile-only',
683 '--out=$outputFile']); 663 '--out=$outputFile']);
684 args.addAll(vmOptions); 664 args.addAll(vmOptions);
685 args.add(inputFile); 665 args.add(inputFile);
686 break; 666 break;
687 case 'dart2js': 667 case 'dart2js':
688 args.add('--out=$outputFile'); 668 args.add('--out=$outputFile');
689 args.add(inputFile); 669 args.add(inputFile);
(...skipping 15 matching lines...) Expand all
705 * an HTML page, with a testing framework based on scripting and DOM events. 685 * an HTML page, with a testing framework based on scripting and DOM events.
706 * These scripts and pages are written to a generated_test directory 686 * These scripts and pages are written to a generated_test directory
707 * inside the build directory of the checkout. 687 * inside the build directory of the checkout.
708 * 688 *
709 * Those tests which are already HTML web applications (web tests), with 689 * Those tests which are already HTML web applications (web tests), with
710 * resources including CSS files and HTML files, need to be compiled into 690 * resources including CSS files and HTML files, need to be compiled into
711 * a work directory where the relative URLS to the resources work. 691 * a work directory where the relative URLS to the resources work.
712 * We use a subdirectory of the build directory that is the same number 692 * We use a subdirectory of the build directory that is the same number
713 * of levels down in the checkout as the original path of the web test. 693 * of levels down in the checkout as the original path of the web test.
714 */ 694 */
715 String createOutputDirectory(String testPath, String optionsName) { 695 String createOutputDirectory(Path testPath, String optionsName) {
716 String testUniqueName = 696 Path testUniqueNamePath = testPath.relativeTo(TestUtils.dartDir());
717 testPath.substring(dartDir.length + 1, testPath.length - 5); 697 String testUniqueName = testUniqueNamePath.toString();
698 testUniqueName = testUniqueName.substring(0, testUniqueName.length - 5);
718 testUniqueName = testUniqueName.replaceAll('/', '_'); 699 testUniqueName = testUniqueName.replaceAll('/', '_');
719 if (!optionsName.isEmpty()) { 700 if (!optionsName.isEmpty()) {
720 testUniqueName = '$testUniqueName-$optionsName'; 701 testUniqueName = '$testUniqueName-$optionsName';
721 } 702 }
722 703
723 // Create '[build dir]/generated_tests/$compiler-$runtime/$testUniqueName', 704 // Create '[build dir]/generated_tests/$compiler-$runtime/$testUniqueName',
724 // including any intermediate directories that don't exist. 705 // including any intermediate directories that don't exist.
725 var generatedTestPath = Strings.join( 706 var generatedTestPath = Strings.join(
726 [TestUtils.buildDir(configuration), 707 [TestUtils.buildDir(configuration),
727 'generated_tests', 708 'generated_tests',
728 "${configuration['compiler']}-${configuration['runtime']}", 709 "${configuration['compiler']}-${configuration['runtime']}",
729 testUniqueName], '/'); 710 testUniqueName], '/');
730 711
731 TestUtils.mkdirRecursive('.', generatedTestPath); 712 TestUtils.mkdirRecursive(new Path('.'), new Path(generatedTestPath));
732 return new File(generatedTestPath).fullPathSync().replaceAll('\\', '/'); 713 return new File(generatedTestPath).fullPathSync().replaceAll('\\', '/');
733 } 714 }
734 715
735 String get scriptType() { 716 String get scriptType() {
736 switch (configuration['compiler']) { 717 switch (configuration['compiler']) {
737 case 'none': 718 case 'none':
738 return 'application/dart'; 719 return 'application/dart';
739 case 'frog': 720 case 'frog':
740 case 'dart2js': 721 case 'dart2js':
741 case 'dartc': 722 case 'dartc':
(...skipping 23 matching lines...) Expand all
765 746
766 return "$cleanFilename" 747 return "$cleanFilename"
767 "${configuration['compiler']}-${configuration['runtime']}.html"; 748 "${configuration['compiler']}-${configuration['runtime']}.html";
768 } 749 }
769 750
770 String get dumpRenderTreeFilename() { 751 String get dumpRenderTreeFilename() {
771 if (configuration['drt'] != '') { 752 if (configuration['drt'] != '') {
772 return configuration['drt']; 753 return configuration['drt'];
773 } 754 }
774 if (Platform.operatingSystem == 'macos') { 755 if (Platform.operatingSystem == 'macos') {
775 return '$dartDir/client/tests/drt/DumpRenderTree.app/Contents/' 756 return dartDir.append('/client/tests/drt/DumpRenderTree.app/Contents/'
776 'MacOS/DumpRenderTree'; 757 'MacOS/DumpRenderTree').toNativePath();
777 } 758 }
778 return '$dartDir/client/tests/drt/DumpRenderTree'; 759 return dartDir.append('client/tests/drt/DumpRenderTree').toNativePath();
779 } 760 }
780 761
781 String get dartiumFilename() { 762 String get dartiumFilename() {
782 if (configuration['dartium'] != '') { 763 if (configuration['dartium'] != '') {
783 return configuration['dartium']; 764 return configuration['dartium'];
784 } 765 }
785 if (Platform.operatingSystem == 'macos') { 766 if (Platform.operatingSystem == 'macos') {
786 return '$dartDir/client/tests/dartium/Chromium.app/Contents/' 767 return dartDir.append('client/tests/dartium/Chromium.app/Contents/'
787 'MacOS/Chromium'; 768 'MacOS/Chromium').toNativePath();
788 } 769 }
789 return '$dartDir/client/tests/dartium/chrome'; 770 return dartDir.append('client/tests/dartium/chrome').toNativePath();
790 } 771 }
791 772
792 void testGeneratorStarted() { 773 void testGeneratorStarted() {
793 ++activeTestGenerators; 774 ++activeTestGenerators;
794 } 775 }
795 776
796 void testGeneratorDone() { 777 void testGeneratorDone() {
797 --activeTestGenerators; 778 --activeTestGenerators;
798 if (activeTestGenerators == 0 && listingDone) { 779 if (activeTestGenerators == 0 && listingDone) {
799 doDone(); 780 doDone();
800 } 781 }
801 } 782 }
802 783
803 void directoryListingDone(ignore) { 784 void directoryListingDone(ignore) {
804 listingDone = true; 785 listingDone = true;
805 if (activeTestGenerators == 0) { 786 if (activeTestGenerators == 0) {
806 doDone(); 787 doDone();
807 } 788 }
808 } 789 }
809 790
810 void completeHandler(TestCase testCase) { 791 void completeHandler(TestCase testCase) {
811 } 792 }
812 793
813 List<List<String>> argumentListsFromFile(String filename, 794 List<List<String>> argumentListsFromFile(Path filePath,
814 Map optionsFromFile) { 795 Map optionsFromFile) {
815 List args = TestUtils.standardOptions(configuration); 796 List args = TestUtils.standardOptions(configuration);
816 args.addAll(additionalOptions(filename)); 797 args.addAll(additionalOptions(filePath));
817 if (configuration['compiler'] == 'dartc') { 798 if (configuration['compiler'] == 'dartc') {
818 args.add('--error_format'); 799 args.add('--error_format');
819 args.add('machine'); 800 args.add('machine');
820 } 801 }
821 if ((configuration['compiler'] == 'frog') 802 if ((configuration['compiler'] == 'frog')
822 && (configuration['runtime'] == 'none')) { 803 && (configuration['runtime'] == 'none')) {
823 args.add('--compile-only'); 804 args.add('--compile-only');
824 } 805 }
825 806
826 bool isMultitest = optionsFromFile["isMultitest"]; 807 bool isMultitest = optionsFromFile["isMultitest"];
827 List<String> dartOptions = optionsFromFile["dartOptions"]; 808 List<String> dartOptions = optionsFromFile["dartOptions"];
828 List<List<String>> vmOptionsList = getVmOptions(optionsFromFile); 809 List<List<String>> vmOptionsList = getVmOptions(optionsFromFile);
829 Expect.isTrue(!isMultitest || dartOptions == null); 810 Expect.isTrue(!isMultitest || dartOptions == null);
830 if (dartOptions == null) { 811 if (dartOptions == null) {
831 args.add(filename); 812 args.add('$filePath');
832 } else { 813 } else {
833 var executable_name = dartOptions[0]; 814 var executable_name = dartOptions[0];
834 // TODO(ager): Get rid of this hack when the runtime checkout goes away. 815 // TODO(ager): Get rid of this hack when the runtime checkout goes away.
835 var file = new File(executable_name); 816 var file = new File(executable_name);
836 if (!file.existsSync()) { 817 if (!file.existsSync()) {
837 executable_name = '../$executable_name'; 818 executable_name = '../$executable_name';
838 Expect.isTrue(new File(executable_name).existsSync()); 819 Expect.isTrue(new File(executable_name).existsSync());
839 dartOptions[0] = executable_name; 820 dartOptions[0] = executable_name;
840 } 821 }
841 args.addAll(dartOptions); 822 args.addAll(dartOptions);
842 } 823 }
843 824
844 var result = new List<List<String>>(); 825 var result = new List<List<String>>();
845 Expect.isFalse(vmOptionsList.isEmpty(), "empty vmOptionsList"); 826 Expect.isFalse(vmOptionsList.isEmpty(), "empty vmOptionsList");
846 for (var vmOptions in vmOptionsList) { 827 for (var vmOptions in vmOptionsList) {
847 var options = new List<String>.from(vmOptions); 828 var options = new List<String>.from(vmOptions);
848 options.addAll(args); 829 options.addAll(args);
849 result.add(options); 830 result.add(options);
850 } 831 }
851 832
852 return result; 833 return result;
853 } 834 }
854 835
855 Map readOptionsFromFile(String filename) { 836 Map readOptionsFromFile(Path filePath) {
856 RegExp testOptionsRegExp = const RegExp(@"// VMOptions=(.*)"); 837 RegExp testOptionsRegExp = const RegExp(@"// VMOptions=(.*)");
857 RegExp dartOptionsRegExp = const RegExp(@"// DartOptions=(.*)"); 838 RegExp dartOptionsRegExp = const RegExp(@"// DartOptions=(.*)");
858 RegExp otherScriptsRegExp = const RegExp(@"// OtherScripts=(.*)"); 839 RegExp otherScriptsRegExp = const RegExp(@"// OtherScripts=(.*)");
859 RegExp multiTestRegExp = const RegExp(@"/// [0-9][0-9]:(.*)"); 840 RegExp multiTestRegExp = const RegExp(@"/// [0-9][0-9]:(.*)");
860 RegExp staticTypeRegExp = 841 RegExp staticTypeRegExp =
861 const RegExp(@"/// ([0-9][0-9]:){0,1}\s*static type warning"); 842 const RegExp(@"/// ([0-9][0-9]:){0,1}\s*static type warning");
862 RegExp compileTimeRegExp = 843 RegExp compileTimeRegExp =
863 const RegExp(@"/// ([0-9][0-9]:){0,1}\s*compile-time error"); 844 const RegExp(@"/// ([0-9][0-9]:){0,1}\s*compile-time error");
864 RegExp staticCleanRegExp = const RegExp(@"// @static-clean"); 845 RegExp staticCleanRegExp = const RegExp(@"// @static-clean");
865 RegExp leadingHashRegExp = const RegExp(@"^#", multiLine: true); 846 RegExp leadingHashRegExp = const RegExp(@"^#", multiLine: true);
866 RegExp isolateStubsRegExp = const RegExp(@"// IsolateStubs=(.*)"); 847 RegExp isolateStubsRegExp = const RegExp(@"// IsolateStubs=(.*)");
867 RegExp domImportRegExp = 848 RegExp domImportRegExp =
868 const RegExp(@"^#import.*(dart:(dom|html)|html\.dart).*\)", 849 const RegExp(@"^#import.*(dart:(dom|html)|html\.dart).*\)",
869 multiLine: true); 850 multiLine: true);
870 RegExp libraryDefinitionRegExp = 851 RegExp libraryDefinitionRegExp =
871 const RegExp(@"^#library\(", multiLine: true); 852 const RegExp(@"^#library\(", multiLine: true);
872 RegExp sourceOrImportRegExp = 853 RegExp sourceOrImportRegExp =
873 const RegExp(@"^#(source|import|resource)\(", multiLine: true); 854 const RegExp(@"^#(source|import|resource)\(", multiLine: true);
874 855
875 // Read the entire file into a byte buffer and transform it to a 856 // Read the entire file into a byte buffer and transform it to a
876 // String. This will treat the file as ascii but the only parts 857 // String. This will treat the file as ascii but the only parts
877 // we are interested in will be ascii in any case. 858 // we are interested in will be ascii in any case.
878 RandomAccessFile file = new File(filename).openSync(FileMode.READ); 859 RandomAccessFile file = new File.fromPath(filePath).openSync(FileMode.READ);
879 List chars = new List(file.lengthSync()); 860 List chars = new List(file.lengthSync());
880 var offset = 0; 861 var offset = 0;
881 while (offset != chars.length) { 862 while (offset != chars.length) {
882 offset += file.readListSync(chars, offset, chars.length - offset); 863 offset += file.readListSync(chars, offset, chars.length - offset);
883 } 864 }
884 file.closeSync(); 865 file.closeSync();
885 String contents = new String.fromCharCodes(chars); 866 String contents = new String.fromCharCodes(chars);
886 chars = null; 867 chars = null;
887 868
888 // Find the options in the file. 869 // Find the options in the file.
889 List<List> result = new List<List>(); 870 List<List> result = new List<List>();
890 List<String> dartOptions; 871 List<String> dartOptions;
891 bool isNegative = false; 872 bool isNegative = false;
892 bool isStaticClean = false; 873 bool isStaticClean = false;
893 874
894 Iterable<Match> matches = testOptionsRegExp.allMatches(contents); 875 Iterable<Match> matches = testOptionsRegExp.allMatches(contents);
895 for (var match in matches) { 876 for (var match in matches) {
896 result.add(match[1].split(' ').filter((e) => e != '')); 877 result.add(match[1].split(' ').filter((e) => e != ''));
897 } 878 }
898 if (result.isEmpty()) result.add([]); 879 if (result.isEmpty()) result.add([]);
899 880
900 matches = dartOptionsRegExp.allMatches(contents); 881 matches = dartOptionsRegExp.allMatches(contents);
901 for (var match in matches) { 882 for (var match in matches) {
902 if (dartOptions != null) { 883 if (dartOptions != null) {
903 throw new Exception( 884 throw new Exception(
904 'More than one "// DartOptions=" line in test $filename'); 885 'More than one "// DartOptions=" line in test $filePath');
905 } 886 }
906 dartOptions = match[1].split(' ').filter((e) => e != ''); 887 dartOptions = match[1].split(' ').filter((e) => e != '');
907 } 888 }
908 889
909 matches = staticCleanRegExp.allMatches(contents); 890 matches = staticCleanRegExp.allMatches(contents);
910 for (var match in matches) { 891 for (var match in matches) {
911 if (isStaticClean) { 892 if (isStaticClean) {
912 throw new Exception( 893 throw new Exception(
913 'More than one "// @static-clean=" line in test $filename'); 894 'More than one "// @static-clean=" line in test $filePath');
914 } 895 }
915 isStaticClean = true; 896 isStaticClean = true;
916 } 897 }
917 898
918 List<String> otherScripts = new List<String>(); 899 List<String> otherScripts = new List<String>();
919 matches = otherScriptsRegExp.allMatches(contents); 900 matches = otherScriptsRegExp.allMatches(contents);
920 for (var match in matches) { 901 for (var match in matches) {
921 otherScripts.addAll(match[1].split(' ').filter((e) => e != '')); 902 otherScripts.addAll(match[1].split(' ').filter((e) => e != ''));
922 } 903 }
923 904
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
974 List<String> _testDirs; 955 List<String> _testDirs;
975 int activityCount = 0; 956 int activityCount = 0;
976 957
977 DartcCompilationTestSuite(Map configuration, 958 DartcCompilationTestSuite(Map configuration,
978 String suiteName, 959 String suiteName,
979 String directoryPath, 960 String directoryPath,
980 List<String> this._testDirs, 961 List<String> this._testDirs,
981 List<String> expectations) 962 List<String> expectations)
982 : super(configuration, 963 : super(configuration,
983 suiteName, 964 suiteName,
984 directoryPath, 965 new Path.fromNative(directoryPath),
985 expectations); 966 expectations);
986 967
987 void activityStarted() { ++activityCount; } 968 void activityStarted() { ++activityCount; }
988 969
989 void activityCompleted() { 970 void activityCompleted() {
990 if (--activityCount == 0) { 971 if (--activityCount == 0) {
991 directoryListingDone(true); 972 directoryListingDone(true);
992 } 973 }
993 } 974 }
994 975
995 String shellPath() => TestUtils.compilerPath(configuration); 976 String shellPath() => TestUtils.compilerPath(configuration);
996 977
997 List<String> additionalOptions(String filename) { 978 List<String> additionalOptions(Path filePath) {
998 return ['--fatal-warnings', '--fatal-type-errors']; 979 return ['--fatal-warnings', '--fatal-type-errors'];
999 } 980 }
1000 981
1001 void processDirectory() { 982 void processDirectory() {
1002 directoryPath = '$dartDir/$directoryPath';
1003 // Enqueueing the directory listers is an activity. 983 // Enqueueing the directory listers is an activity.
1004 activityStarted(); 984 activityStarted();
1005 for (String testDir in _testDirs) { 985 for (String testDir in _testDirs) {
1006 Directory dir = new Directory("$directoryPath/$testDir"); 986 Directory dir = new Directory.fromPath(suiteDir.append(testDir));
1007 if (dir.existsSync()) { 987 if (dir.existsSync()) {
1008 activityStarted(); 988 activityStarted();
1009 var lister = dir.list(recursive: listRecursively()); 989 var lister = dir.list(recursive: listRecursively());
1010 lister.onFile = processFile; 990 lister.onFile = processFile;
1011 lister.onDone = (ignore) => activityCompleted(); 991 lister.onDone = (ignore) => activityCompleted();
1012 } 992 }
1013 } 993 }
1014 // Completed the enqueueing of listers. 994 // Completed the enqueueing of listers.
1015 activityCompleted(); 995 activityCompleted();
1016 } 996 }
(...skipping 10 matching lines...) Expand all
1027 String classPath; 1007 String classPath;
1028 List<String> testClasses; 1008 List<String> testClasses;
1029 Function doTest; 1009 Function doTest;
1030 Function doDone; 1010 Function doDone;
1031 TestExpectations testExpectations; 1011 TestExpectations testExpectations;
1032 1012
1033 JUnitTestSuite(Map this.configuration, 1013 JUnitTestSuite(Map this.configuration,
1034 String this.suiteName, 1014 String this.suiteName,
1035 String this.directoryPath, 1015 String this.directoryPath,
1036 String this.statusFilePath) 1016 String this.statusFilePath)
1037 : dartDir = TestUtils.dartDir(); 1017 : dartDir = TestUtils.dartDir().toNativePath();
1038 1018
1039 bool isTestFile(String filename) => filename.endsWith("Tests.java") && 1019 bool isTestFile(String filename) => filename.endsWith("Tests.java") &&
1040 !filename.contains('com/google/dart/compiler/vm') && 1020 !filename.contains('com/google/dart/compiler/vm') &&
1041 !filename.contains('com/google/dart/corelib/SharedTests.java'); 1021 !filename.contains('com/google/dart/corelib/SharedTests.java');
1042 1022
1043 void forEachTest(Function onTest, 1023 void forEachTest(Function onTest,
1044 Map testCacheIgnored, 1024 Map testCacheIgnored,
1045 [Function onDone = null]) { 1025 [Function onDone = null]) {
1046 doTest = onTest; 1026 doTest = onTest;
1047 doDone = (onDone != null) ? onDone : (() => null); 1027 doDone = (onDone != null) ? onDone : (() => null);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1131 ':'); // Path separator. 1111 ':'); // Path separator.
1132 } 1112 }
1133 } 1113 }
1134 1114
1135 1115
1136 class TestUtils { 1116 class TestUtils {
1137 /** 1117 /**
1138 * Creates a directory using a [relativePath] to an existing 1118 * Creates a directory using a [relativePath] to an existing
1139 * [base] directory if that [relativePath] does not already exist. 1119 * [base] directory if that [relativePath] does not already exist.
1140 */ 1120 */
1141 static Directory mkdirRecursive(String base, String relativePath) { 1121 static Directory mkdirRecursive(Path base, Path relativePath) {
1142 Directory baseDir = new Directory(base); 1122 Directory dir = new Directory.fromPath(base);
1143 Expect.isTrue(baseDir.existsSync(), 1123 Expect.isTrue(dir.existsSync(),
1144 "Expected ${base} to already exist"); 1124 "Expected ${dir} to already exist");
1145 var tempDir = new Directory(base); 1125 var segments = relativePath.segments();
1146 for (String dir in relativePath.split('/')) { 1126 for (String segment in segments) {
1147 base = "$base/$dir"; 1127 base = base.append(segment);
1148 tempDir = new Directory(base); 1128 dir = new Directory.fromPath(base);
1149 if (!tempDir.existsSync()) { 1129 if (!dir.existsSync()) {
1150 tempDir.createSync(); 1130 dir.createSync();
1151 } 1131 }
1152 Expect.isTrue(tempDir.existsSync(), "Failed to create ${tempDir.path}"); 1132 Expect.isTrue(dir.existsSync(), "Failed to create ${dir.path}");
1153 } 1133 }
1154 return tempDir; 1134 return dir;
1155 } 1135 }
1156 1136
1157 /** 1137 /**
1158 * Copy a [source] file to a new place. 1138 * Copy a [source] file to a new place.
1159 * Assumes that the directory for [dest] already exists. 1139 * Assumes that the directory for [dest] already exists.
1160 */ 1140 */
1161 static void copyFile(File source, File dest) { 1141 static Future copyFile(Path source, Path dest) {
1162 List contents = source.readAsBytesSync(); 1142 var output = new File.fromPath(dest).openOutputStream();
1163 RandomAccessFile handle = dest.openSync(FileMode.WRITE); 1143 new File.fromPath(source).openInputStream().pipe(output);
1164 handle.writeListSync(contents, 0, contents.length); 1144 var completer = new Completer();
1165 handle.closeSync(); 1145 output.onClosed = (){ completer.complete(null); };
1146 return completer.future;
1166 } 1147 }
1167 1148
1168 static String executableSuffix(String executable) { 1149 static String executableSuffix(String executable) {
1169 if (Platform.operatingSystem == 'windows') { 1150 if (Platform.operatingSystem == 'windows') {
1170 if (executable == 'd8' || executable == 'vm' || executable == 'none') { 1151 if (executable == 'd8' || executable == 'vm' || executable == 'none') {
1171 return '.exe'; 1152 return '.exe';
1172 } else { 1153 } else {
1173 return '.bat'; 1154 return '.bat';
1174 } 1155 }
1175 } 1156 }
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1260 } 1241 }
1261 return result; 1242 return result;
1262 } 1243 }
1263 1244
1264 static String buildDir(Map configuration) { 1245 static String buildDir(Map configuration) {
1265 String mode = (configuration['mode'] == 'debug') ? 'Debug' : 'Release'; 1246 String mode = (configuration['mode'] == 'debug') ? 'Debug' : 'Release';
1266 String arch = configuration['arch'].toUpperCase(); 1247 String arch = configuration['arch'].toUpperCase();
1267 return "${outputDir(configuration)}$mode$arch"; 1248 return "${outputDir(configuration)}$mode$arch";
1268 } 1249 }
1269 1250
1270 static String dartDir() { 1251 static Path dartDir() {
1271 String scriptPath = new Options().script.replaceAll('\\', '/'); 1252 File scriptF = new File(new Options().script);
1272 String toolsDir = scriptPath.substring(0, scriptPath.lastIndexOf('/')); 1253 Path scriptP = new Path.fromNative(scriptF.fullPathSync());
1273 return new File('$toolsDir/..').fullPathSync().replaceAll('\\', '/'); 1254 return scriptP.directoryPath.directoryPath;
1274 } 1255 }
1275 1256
1276 static List<String> standardOptions(Map configuration) { 1257 static List<String> standardOptions(Map configuration) {
1277 List args = ["--ignore-unrecognized-flags"]; 1258 List args = ["--ignore-unrecognized-flags"];
1278 if (configuration["checked"]) { 1259 if (configuration["checked"]) {
1279 args.add('--enable_asserts'); 1260 args.add('--enable_asserts');
1280 args.add("--enable_type_checks"); 1261 args.add("--enable_type_checks");
1281 } 1262 }
1282 if (configuration["compiler"] == "dart2js") { 1263 if (configuration["compiler"] == "dart2js") {
1283 args = []; 1264 args = [];
1284 if (configuration["checked"]) { 1265 if (configuration["checked"]) {
1285 args.add('--enable-checked-mode'); 1266 args.add('--enable-checked-mode');
1286 } 1267 }
1287 args.add("--verbose"); 1268 args.add("--verbose");
1288 if (!isBrowserRuntime(configuration['runtime'])) { 1269 if (!isBrowserRuntime(configuration['runtime'])) {
1289 args.add("--allow-mock-compilation"); 1270 args.add("--allow-mock-compilation");
1290 } 1271 }
1291 } 1272 }
1292 return args; 1273 return args;
1293 } 1274 }
1294 1275
1295 static bool isBrowserRuntime(String runtime) => 1276 static bool isBrowserRuntime(String runtime) =>
1296 const <String>['drt', 1277 const {'drt': 1,
1297 'dartium', 1278 'dartium': 1,
1298 'ie', 1279 'ie': 1,
1299 'safari', 1280 'safari': 1,
1300 'opera', 1281 'opera': 1,
1301 'chrome', 1282 'chrome': 1,
1302 'ff'].some((x) => x == runtime); 1283 'ff': 1}.containsKey(runtime);
1303 } 1284 }
1304 1285
1305 class SummaryReport { 1286 class SummaryReport {
1306 static int total = 0; 1287 static int total = 0;
1307 static int skipped = 0; 1288 static int skipped = 0;
1308 static int noCrash = 0; 1289 static int noCrash = 0;
1309 static int pass = 0; 1290 static int pass = 0;
1310 static int failOk = 0; 1291 static int failOk = 0;
1311 static int fail = 0; 1292 static int fail = 0;
1312 static int crash = 0; 1293 static int crash = 0;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1346 * $noCrash tests are expected to be flaky but not crash 1327 * $noCrash tests are expected to be flaky but not crash
1347 * $pass tests are expected to pass 1328 * $pass tests are expected to pass
1348 * $failOk tests are expected to fail that we won't fix 1329 * $failOk tests are expected to fail that we won't fix
1349 * $fail tests are expected to fail that we should fix 1330 * $fail tests are expected to fail that we should fix
1350 * $crash tests are expected to crash that we should fix 1331 * $crash tests are expected to crash that we should fix
1351 * $timeout tests are allowed to timeout 1332 * $timeout tests are allowed to timeout
1352 """; 1333 """;
1353 print(report); 1334 print(report);
1354 } 1335 }
1355 } 1336 }
OLDNEW
« tools/testing/dart/multitest.dart ('K') | « tools/testing/dart/test_runner.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698