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

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

Powered by Google App Engine
This is Rietveld 408576698