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

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: Fix bugs 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() {
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(
Emily Fortuna 2012/06/26 18:26:24 Just FYI: Isn't we planning on removing Expect as
Bill Hesse 2012/06/27 09:35:03 Yes, but it fits such a need here, in a script tha
377 testName = filename.substring(start + directoryPath.length + 1); 373 suiteDir.toNativePath()));
378 } else { 374 var testNamePath =
379 testName = filename; 375 filePath.relativeTo(suiteDir);
Anton Muhin 2012/06/27 13:11:24 nit: won't it fit a single line?
Bill Hesse 2012/06/28 15:31:22 Done.
380 } 376 Expect.isTrue(testNamePath.extension == 'dart');
381 if (testName.endsWith('.dart')) { 377 if (testNamePath.extension == 'dart') {
382 testName = testName.substring(0, testName.length - 5); 378 testName = testNamePath.directoryPath.append(
379 testNamePath.filenameWithoutExtension).toString();
383 } 380 }
384 } 381 }
385 int shards = configuration['shards']; 382 int shards = configuration['shards'];
386 if (shards > 1) { 383 if (shards > 1) {
387 int shard = configuration['shard']; 384 int shard = configuration['shard'];
388 if (testName.hashCode() % shards != shard - 1) { 385 if (testName.hashCode() % shards != shard - 1) {
389 return; 386 return;
390 } 387 }
391 } 388 }
392 389
393 Set<String> expectations = testExpectations.expectations(testName); 390 Set<String> expectations = testExpectations.expectations(testName);
394 if (configuration['report']) { 391 if (configuration['report']) {
395 // Tests with multiple VMOptions are counted more than once. 392 // Tests with multiple VMOptions are counted more than once.
396 for (var dummy in getVmOptions(optionsFromFile)) { 393 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); 394 SummaryReport.add(expectations);
402 } 395 }
403 } 396 }
404 if (expectations.contains(SKIP)) return; 397 if (expectations.contains(SKIP)) return;
405 398
406 if (TestUtils.isBrowserRuntime(configuration['runtime'])) { 399 if (TestUtils.isBrowserRuntime(configuration['runtime'])) {
407 enqueueBrowserTest(info, testName, expectations); 400 enqueueBrowserTest(info, testName, expectations);
408 } else { 401 } else {
409 enqueueStandardTest(info, testName, expectations); 402 enqueueStandardTest(info, testName, expectations);
410 } 403 }
411 } 404 }
412 405
413 void enqueueStandardTest(TestInformation info, 406 void enqueueStandardTest(TestInformation info,
414 String testName, 407 String testName,
415 Set<String> expectations) { 408 Set<String> expectations) {
416 bool isNegative = info.isNegative || 409 bool isNegative = info.isNegative ||
417 (configuration['checked'] && info.isNegativeIfChecked); 410 (configuration['checked'] && info.isNegativeIfChecked);
418 411
419 if (configuration['compiler'] == 'dartc') { 412 if (configuration['compiler'] == 'dartc') {
420 // dartc can detect static type warnings by the 413 // dartc can detect static type warnings by the
421 // format of the error line 414 // format of the error line
422 if (info.hasFatalTypeErrors) { 415 if (info.hasFatalTypeErrors) {
423 isNegative = true; 416 isNegative = true;
424 } else if (info.hasRuntimeErrors) { 417 } else if (info.hasRuntimeErrors) {
425 isNegative = false; 418 isNegative = false;
426 } 419 }
427 } 420 }
428 421
429 var argumentLists = argumentListsFromFile(info.filename, 422 var argumentLists = argumentListsFromFile(info.filePath,
430 info.optionsFromFile); 423 info.optionsFromFile);
431 424
432 for (var args in argumentLists) { 425 for (var args in argumentLists) {
433 doTest(new TestCase('$suiteName/$testName', 426 doTest(new TestCase('$suiteName/$testName',
434 makeCommands(info, args), 427 makeCommands(info, args),
435 configuration, 428 configuration,
436 completeHandler, 429 completeHandler,
437 expectations, 430 expectations,
438 isNegative, 431 isNegative,
439 info)); 432 info));
440 } 433 }
441 } 434 }
442 435
443 List<Command> makeCommands(TestInformation info, var args) { 436 List<Command> makeCommands(TestInformation info, var args) {
444 if (configuration['compiler'] == 'dart2js') { 437 if (configuration['compiler'] == 'dart2js') {
445 args = new List.from(args); 438 args = new List.from(args);
446 String testPath = 439 String tempDir = createOutputDirectory(info.filePath, '');
447 new File(info.filename).fullPathSync().replaceAll('\\', '/');
448 String tempDir = createOutputDirectory(testPath, '');
449 args.add('--out=$tempDir/out.js'); 440 args.add('--out=$tempDir/out.js');
450 List<Command> commands = <Command>[new Command(shellPath(), args)]; 441 List<Command> commands = <Command>[new Command(shellPath(), args)];
451 if (configuration['runtime'] == 'd8') { 442 if (configuration['runtime'] == 'd8') {
452 var d8 = TestUtils.d8FileName(configuration); 443 var d8 = TestUtils.d8FileName(configuration);
453 commands.add(new Command(d8, ['$tempDir/out.js'])); 444 commands.add(new Command(d8, ['$tempDir/out.js']));
454 } 445 }
455 return commands; 446 return commands;
456 } else { 447 } else {
457 return <Command>[new Command(shellPath(), args)]; 448 return <Command>[new Command(shellPath(), args)];
458 } 449 }
459 } 450 }
460 451
461 Function makeTestCaseCreator(Map optionsFromFile) { 452 Function makeTestCaseCreator(Map optionsFromFile) {
462 return (String filename, 453 return (Path filePath,
463 bool isNegative, 454 bool isNegative,
464 [bool isNegativeIfChecked = false, 455 [bool isNegativeIfChecked = false,
465 bool hasFatalTypeErrors = false, 456 bool hasFatalTypeErrors = false,
466 bool hasRuntimeErrors = false, 457 bool hasRuntimeErrors = false,
467 Set<String> multitestOutcome = null]) { 458 Set<String> multitestOutcome = null]) {
468 // Cache the test information for each test case. 459 // Cache the test information for each test case.
469 var info = new TestInformation(filename, 460 var info = new TestInformation(filePath,
470 optionsFromFile, 461 optionsFromFile,
471 isNegative, 462 isNegative,
472 isNegativeIfChecked, 463 isNegativeIfChecked,
473 hasFatalTypeErrors, 464 hasFatalTypeErrors,
474 hasRuntimeErrors, 465 hasRuntimeErrors,
475 multitestOutcome); 466 multitestOutcome);
476 cachedTests.add(info); 467 cachedTests.add(info);
477 enqueueTestCaseFromTestInformation(info); 468 enqueueTestCaseFromTestInformation(info);
478 }; 469 };
479 } 470 }
480 471
481 void processFile(String filename) { 472 void processFile(String filename) {
482 if (!isTestFile(filename)) return; 473 if (!isTestFile(filename)) return;
474 Path filePath = new Path.fromNative(filename);
483 475
484 // Only run the tests that match the pattern. 476 // Only run the tests that match the pattern.
485 RegExp pattern = configuration['selectors'][suiteName]; 477 RegExp pattern = configuration['selectors'][suiteName];
486 if (!pattern.hasMatch(filename)) return; 478 if (!pattern.hasMatch('$filePath')) return;
487 if (filename.endsWith('test_config.dart')) return; 479 if (filePath.filename.endsWith('test_config.dart')) return;
488 480
489 var optionsFromFile = readOptionsFromFile(filename); 481 var optionsFromFile = readOptionsFromFile(filePath);
490 Function createTestCase = makeTestCaseCreator(optionsFromFile); 482 Function createTestCase = makeTestCaseCreator(optionsFromFile);
491 483
492 if (optionsFromFile['isMultitest']) { 484 if (optionsFromFile['isMultitest']) {
493 testGeneratorStarted(); 485 testGeneratorStarted();
494 DoMultitest(filename, 486 DoMultitest(filePath,
495 TestUtils.buildDir(configuration), 487 TestUtils.buildDir(configuration),
496 directoryPath, 488 suiteDir,
497 createTestCase, 489 createTestCase,
498 testGeneratorDone); 490 testGeneratorDone);
499 } else { 491 } else {
500 createTestCase(filename, optionsFromFile['isNegative']); 492 createTestCase(filePath, optionsFromFile['isNegative']);
501 } 493 }
502 } 494 }
503 495
504 /** 496 /**
505 * The [StandardTestSuite] has support for tests that 497 * The [StandardTestSuite] has support for tests that
506 * compile a test from Dart to Javascript, and then run the resulting 498 * compile a test from Dart to Javascript, and then run the resulting
507 * Javascript. This function creates a working directory to hold the 499 * Javascript. This function creates a working directory to hold the
508 * Javascript version of the test, and copies the appropriate framework 500 * Javascript version of the test, and copies the appropriate framework
509 * files to that directory. It creates a [BrowserTestCase], which has 501 * files to that directory. It creates a [BrowserTestCase], which has
510 * two sequential steps to be run by the [ProcessQueue when] the test is 502 * two sequential steps to be run by the [ProcessQueue when] the test is
511 * executed: a compilation 503 * executed: a compilation
512 * step and an execution step, both with the appropriate executable and 504 * step and an execution step, both with the appropriate executable and
513 * arguments. 505 * arguments.
514 */ 506 */
515 void enqueueBrowserTest(TestInformation info, 507 void enqueueBrowserTest(TestInformation info,
516 String testName, 508 String testName,
517 Set<String> expectations) { 509 Set<String> expectations) {
518 Map optionsFromFile = info.optionsFromFile; 510 Map optionsFromFile = info.optionsFromFile;
519 String filename = info.filename; 511 Path filePath = info.filePath;
520 if (optionsFromFile['isMultitest']) return; 512 String filename = filePath.toString();
521 bool isWebTest = optionsFromFile['containsDomImport']; 513 bool isWebTest = optionsFromFile['containsDomImport'];
522 bool isLibraryDefinition = optionsFromFile['isLibraryDefinition']; 514 bool isLibraryDefinition = optionsFromFile['isLibraryDefinition'];
523 if (!isLibraryDefinition && optionsFromFile['containsSourceOrImport']) { 515 if (!isLibraryDefinition && optionsFromFile['containsSourceOrImport']) {
524 print('Warning for $filename: Browser tests require #library ' 516 print('Warning for $filename: Browser tests require #library '
525 'in any file that uses #import, #source, or #resource'); 517 'in any file that uses #import, #source, or #resource');
526 } 518 }
527 519
528 final String compiler = configuration['compiler']; 520 final String compiler = configuration['compiler'];
529 final String runtime = configuration['runtime']; 521 final String runtime = configuration['runtime'];
530 final String testPath =
531 new File(filename).fullPathSync().replaceAll('\\', '/');
532 522
533 for (var vmOptions in getVmOptions(optionsFromFile)) { 523 for (var vmOptions in getVmOptions(optionsFromFile)) {
534 // Create a unique temporary directory for each set of vmOptions. 524 // Create a unique temporary directory for each set of vmOptions.
535 // TODO(dart:429): Replace separate replaceAlls with a RegExp when 525 // TODO(dart:429): Replace separate replaceAlls with a RegExp when
536 // replaceAll(RegExp, String) is implemented. 526 // replaceAll(RegExp, String) is implemented.
537 String optionsName = ''; 527 String optionsName = '';
538 if (getVmOptions(optionsFromFile).length > 1) { 528 if (getVmOptions(optionsFromFile).length > 1) {
539 optionsName = Strings.join(vmOptions, '-').replaceAll('-','') 529 optionsName = Strings.join(vmOptions, '-').replaceAll('-','')
540 .replaceAll('=','') 530 .replaceAll('=','')
541 .replaceAll('/',''); 531 .replaceAll('/','');
542 } 532 }
543 final String tempDir = createOutputDirectory(testPath, optionsName); 533 final String tempDir = createOutputDirectory(info.filePath, optionsName);
544 534
545 String dartWrapperFilename = '$tempDir/test.dart'; 535 String dartWrapperFilename = '$tempDir/test.dart';
546 String compiledDartWrapperFilename = '$tempDir/test.js'; 536 String compiledDartWrapperFilename = '$tempDir/test.js';
547 537
548 String htmlPath = '$tempDir/test.html'; 538 String htmlPath = '$tempDir/test.html';
549 if (!isWebTest) { 539 if (!isWebTest) {
550 // test.dart will import the dart test directly, if it is a library, 540 // 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. 541 // or indirectly through test_as_library.dart, if it is not.
552 String dartLibraryFilename; 542 Path dartLibraryFilename = filePath;
553 if (isLibraryDefinition) { 543 if (!isLibraryDefinition) {
554 dartLibraryFilename = testPath; 544 dartLibraryFilename = new Path('test_as_library.dart');
555 } else {
556 dartLibraryFilename = 'test_as_library.dart';
557 File file = new File('$tempDir/$dartLibraryFilename'); 545 File file = new File('$tempDir/$dartLibraryFilename');
558 RandomAccessFile dartLibrary = file.openSync(FileMode.WRITE); 546 RandomAccessFile dartLibrary = file.openSync(FileMode.WRITE);
559 dartLibrary.writeStringSync(WrapDartTestInLibrary(testPath)); 547 dartLibrary.writeStringSync(WrapDartTestInLibrary(filePath));
560 dartLibrary.closeSync(); 548 dartLibrary.closeSync();
561 } 549 }
562 550
563 File file = new File(dartWrapperFilename); 551 File file = new File(dartWrapperFilename);
564 RandomAccessFile dartWrapper = file.openSync(FileMode.WRITE); 552 RandomAccessFile dartWrapper = file.openSync(FileMode.WRITE);
565 dartWrapper.writeStringSync( 553 dartWrapper.writeStringSync(
566 DartTestWrapper(dartDir, dartLibraryFilename)); 554 DartTestWrapper(dartDir, dartLibraryFilename));
567 dartWrapper.closeSync(); 555 dartWrapper.closeSync();
568 } else { 556 } else {
569 dartWrapperFilename = testPath; 557 dartWrapperFilename = filename;
570 // TODO(whesse): Once test.py is retired, adjust the relative path in 558 // TODO(whesse): Once test.py is retired, adjust the relative path in
571 // the client/samples/dartcombat test to its css file, remove the 559 // the client/samples/dartcombat test to its css file, remove the
572 // "../../" from this path, and move this out of the isWebTest guard. 560 // "../../" from this path, and move this out of the isWebTest guard.
573 // Also remove getHtmlName, and just use test.html. 561 // Also remove getHtmlName, and just use test.html.
574 // TODO(efortuna): this shortening of htmlFilename is a band-aid until 562 // TODO(efortuna): this shortening of htmlFilename is a band-aid until
575 // the above TODO gets fixed. Windows cannot have paths that are longer 563 // 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 564 // than 260 characters, and without this hack, we were running past the
577 // the limit. 565 // the limit.
578 String htmlFilename = getHtmlName(filename); 566 String htmlFilename = getHtmlName(filename);
579 while ('$tempDir/../$htmlFilename'.length >= 260) { 567 while ('$tempDir/../$htmlFilename'.length >= 260) {
580 htmlFilename = htmlFilename.substring(htmlFilename.length~/2); 568 htmlFilename = htmlFilename.substring(htmlFilename.length~/2);
581 } 569 }
582 htmlPath = '$tempDir/../$htmlFilename'; 570 htmlPath = '$tempDir/../$htmlFilename';
583 } 571 }
584 final String scriptPath = (compiler == 'none') ? 572 final String scriptPath = (compiler == 'none') ?
585 dartWrapperFilename : compiledDartWrapperFilename; 573 dartWrapperFilename : compiledDartWrapperFilename;
586 // Create the HTML file for the test. 574 // Create the HTML file for the test.
587 RandomAccessFile htmlTest = new File(htmlPath).openSync(FileMode.WRITE); 575 RandomAccessFile htmlTest = new File(htmlPath).openSync(FileMode.WRITE);
588 String filePrefix = ''; 576 String filePrefix = '';
589 if (Platform.operatingSystem == 'windows') { 577 if (Platform.operatingSystem == 'windows') {
590 // Firefox on Windows does not like absolute file path names that start 578 // Firefox on Windows does not like absolute file path names that start
591 // with 'C:' adding 'file:///' solves the problem. 579 // with 'C:' adding 'file:///' solves the problem.
592 filePrefix = 'file:///'; 580 filePrefix = 'file:///';
593 } 581 }
594 htmlTest.writeStringSync(GetHtmlContents( 582 htmlTest.writeStringSync(GetHtmlContents(
595 filename, 583 filename,
596 '$filePrefix$dartDir/lib/unittest/test_controller.js', 584 '$filePrefix${dartDir.append("lib/unittest/test_controller.js")}',
597 scriptType, 585 scriptType,
598 '$filePrefix$scriptPath')); 586 '$filePrefix$scriptPath'));
599 htmlTest.closeSync(); 587 htmlTest.closeSync();
600 588
601 // Construct the command(s) that compile all the inputs needed by the 589 // 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. 590 // browser test. For running Dart in DRT, this will be noop commands.
603 List<Command> commands = []; 591 List<Command> commands = [];
604 if (compiler != 'none') { 592 if (compiler != 'none') {
605 commands.add(_compileCommand( 593 commands.add(_compileCommand(
606 dartWrapperFilename, compiledDartWrapperFilename, 594 dartWrapperFilename, compiledDartWrapperFilename,
607 compiler, tempDir, vmOptions)); 595 compiler, tempDir, vmOptions));
608 596
609 // some tests require compiling multiple input scripts. 597 // some tests require compiling multiple input scripts.
610 List<String> otherScripts = optionsFromFile['otherScripts']; 598 List<String> otherScripts = optionsFromFile['otherScripts'];
611 for (String name in otherScripts) { 599 for (String name in otherScripts) {
612 int end = filename.lastIndexOf('/'); 600 Path namePath = new Path(name);
613 if (end == -1) { 601 Expect.equals(namePath.extension, 'dart');
614 print('Warning: error processing "OtherScripts" of $filename.'); 602 String compiledName = namePath.filenameWithoutExtension;
Siggi Cherem (dart-lang) 2012/06/27 17:19:03 missing .js extension: => '${namePath.filenameWith
Bill Hesse 2012/06/28 15:31:22 Done.
615 print('Skipping test ($testName).'); 603 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( 604 commands.add(_compileCommand(
627 '$dir/$name', '$tempDir/$compiledName', 605 fromPath.toNativePath(), '$tempDir/$compiledName',
628 compiler, tempDir, vmOptions)); 606 compiler, tempDir, vmOptions));
629 } 607 }
630 } 608 }
631 609
632 // Construct the command that executes the browser test 610 // Construct the command that executes the browser test
633 List<String> args; 611 List<String> args;
634 if (runtime == 'ie' || runtime == 'ff' || runtime == 'chrome' || 612 if (runtime == 'ie' || runtime == 'ff' || runtime == 'chrome' ||
635 runtime == 'safari' || runtime == 'opera' || runtime == 'dartium') { 613 runtime == 'safari' || runtime == 'opera' || runtime == 'dartium') {
636 args = ['$dartDir/tools/testing/run_selenium.py', 614 args = [dartDir.append('tools/testing/run_selenium.py').toNativePath(),
637 '--browser=$runtime', 615 '--browser=$runtime',
638 '--timeout=${configuration["timeout"] - 2}', 616 '--timeout=${configuration["timeout"] - 2}',
639 '--out=$htmlPath']; 617 '--out=$htmlPath'];
640 if (runtime == 'dartium') { 618 if (runtime == 'dartium') {
641 args.add('--executable=$dartiumFilename'); 619 args.add('--executable=$dartiumFilename');
642 } 620 }
643 } else { 621 } else {
644 args = [ 622 args = [
645 '$dartDir/tools/testing/drt-trampoline.py', 623 dartDir.append('tools/testing/drt-trampoline.py').toNativePath(),
646 dumpRenderTreeFilename, 624 dumpRenderTreeFilename,
647 '--no-timeout' 625 '--no-timeout'
648 ]; 626 ];
649 if (runtime == 'drt' && compiler == 'none') { 627 if (runtime == 'drt' && compiler == 'none') {
650 var dartFlags = ['--ignore-unrecognized-flags']; 628 var dartFlags = ['--ignore-unrecognized-flags'];
651 if (configuration["checked"]) { 629 if (configuration["checked"]) {
652 dartFlags.add('--enable_asserts'); 630 dartFlags.add('--enable_asserts');
653 dartFlags.add("--enable_type_checks"); 631 dartFlags.add("--enable_type_checks");
654 } 632 }
655 dartFlags.addAll(vmOptions); 633 dartFlags.addAll(vmOptions);
(...skipping 13 matching lines...) Expand all
669 647
670 /** Helper to create a compilation command for a single input file. */ 648 /** Helper to create a compilation command for a single input file. */
671 Command _compileCommand(String inputFile, String outputFile, 649 Command _compileCommand(String inputFile, String outputFile,
672 String compiler, String dir, var vmOptions) { 650 String compiler, String dir, var vmOptions) {
673 String executable = TestUtils.compilerPath(configuration); 651 String executable = TestUtils.compilerPath(configuration);
674 List<String> args = TestUtils.standardOptions(configuration); 652 List<String> args = TestUtils.standardOptions(configuration);
675 switch (compiler) { 653 switch (compiler) {
676 case 'frog': 654 case 'frog':
677 String libdir = configuration['froglib']; 655 String libdir = configuration['froglib'];
678 if (libdir == '') { 656 if (libdir == '') {
679 libdir = '$dartDir/frog/lib'; 657 libdir = dartDir.append('frog/lib').toNativePath();
680 } 658 }
681 args.addAll(['--libdir=$libdir', 659 args.addAll(['--libdir=$libdir',
682 '--compile-only', 660 '--compile-only',
683 '--out=$outputFile']); 661 '--out=$outputFile']);
684 args.addAll(vmOptions); 662 args.addAll(vmOptions);
685 args.add(inputFile); 663 args.add(inputFile);
686 break; 664 break;
687 case 'dart2js': 665 case 'dart2js':
688 args.add('--out=$outputFile'); 666 args.add('--out=$outputFile');
689 args.add(inputFile); 667 args.add(inputFile);
(...skipping 15 matching lines...) Expand all
705 * an HTML page, with a testing framework based on scripting and DOM events. 683 * 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 684 * These scripts and pages are written to a generated_test directory
707 * inside the build directory of the checkout. 685 * inside the build directory of the checkout.
708 * 686 *
709 * Those tests which are already HTML web applications (web tests), with 687 * Those tests which are already HTML web applications (web tests), with
710 * resources including CSS files and HTML files, need to be compiled into 688 * resources including CSS files and HTML files, need to be compiled into
711 * a work directory where the relative URLS to the resources work. 689 * 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 690 * 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. 691 * of levels down in the checkout as the original path of the web test.
714 */ 692 */
715 String createOutputDirectory(String testPath, String optionsName) { 693 String createOutputDirectory(Path testPath, String optionsName) {
716 String testUniqueName = 694 Path testUniqueNamePath = testPath.relativeTo(TestUtils.dartDir());
717 testPath.substring(dartDir.length + 1, testPath.length - 5); 695 String testUniqueName = testUniqueNamePath.toString();
696 testUniqueName = testUniqueName.substring(0, testUniqueName.length - 5);
Anton Muhin 2012/06/27 13:11:24 isn't that to fetch the path w/o extension? if ye
Mads Ager (google) 2012/06/27 16:08:18 Something like: path = path.directoryPath.append(
Bill Hesse 2012/06/28 15:31:22 Done.
718 testUniqueName = testUniqueName.replaceAll('/', '_'); 697 testUniqueName = testUniqueName.replaceAll('/', '_');
719 if (!optionsName.isEmpty()) { 698 if (!optionsName.isEmpty()) {
720 testUniqueName = '$testUniqueName-$optionsName'; 699 testUniqueName = '$testUniqueName-$optionsName';
721 } 700 }
722 701
723 // Create '[build dir]/generated_tests/$compiler-$runtime/$testUniqueName', 702 // Create '[build dir]/generated_tests/$compiler-$runtime/$testUniqueName',
724 // including any intermediate directories that don't exist. 703 // including any intermediate directories that don't exist.
725 var generatedTestPath = Strings.join( 704 var generatedTestPath = Strings.join(
726 [TestUtils.buildDir(configuration), 705 [TestUtils.buildDir(configuration),
727 'generated_tests', 706 'generated_tests',
728 "${configuration['compiler']}-${configuration['runtime']}", 707 "${configuration['compiler']}-${configuration['runtime']}",
729 testUniqueName], '/'); 708 testUniqueName], '/');
730 709
731 TestUtils.mkdirRecursive('.', generatedTestPath); 710 TestUtils.mkdirRecursive(new Path('.'), new Path(generatedTestPath));
732 return new File(generatedTestPath).fullPathSync().replaceAll('\\', '/'); 711 return new File(generatedTestPath).fullPathSync().replaceAll('\\', '/');
733 } 712 }
734 713
735 String get scriptType() { 714 String get scriptType() {
736 switch (configuration['compiler']) { 715 switch (configuration['compiler']) {
737 case 'none': 716 case 'none':
738 return 'application/dart'; 717 return 'application/dart';
739 case 'frog': 718 case 'frog':
740 case 'dart2js': 719 case 'dart2js':
741 case 'dartc': 720 case 'dartc':
(...skipping 18 matching lines...) Expand all
760 739
761 String getHtmlName(String filename) { 740 String getHtmlName(String filename) {
762 var cleanFilename = filename.replaceAll('/', '_') 741 var cleanFilename = filename.replaceAll('/', '_')
763 .replaceAll(':', '_') 742 .replaceAll(':', '_')
764 .replaceAll('\\', '_'); 743 .replaceAll('\\', '_');
765 744
766 return "$cleanFilename" 745 return "$cleanFilename"
767 "${configuration['compiler']}-${configuration['runtime']}.html"; 746 "${configuration['compiler']}-${configuration['runtime']}.html";
768 } 747 }
769 748
770 String get dumpRenderTreeFilename() { 749 String get dumpRenderTreeFilename() {
Mads Ager (google) 2012/06/27 16:08:18 Should we make these return Path objects and wait
Bill Hesse 2012/06/28 15:31:22 Considering that one of the sources of the value i
771 if (configuration['drt'] != '') { 750 if (configuration['drt'] != '') {
772 return configuration['drt']; 751 return configuration['drt'];
773 } 752 }
774 if (Platform.operatingSystem == 'macos') { 753 if (Platform.operatingSystem == 'macos') {
775 return '$dartDir/client/tests/drt/DumpRenderTree.app/Contents/' 754 return dartDir.append('/client/tests/drt/DumpRenderTree.app/Contents/'
776 'MacOS/DumpRenderTree'; 755 'MacOS/DumpRenderTree').toNativePath();
777 } 756 }
778 return '$dartDir/client/tests/drt/DumpRenderTree'; 757 return dartDir.append('client/tests/drt/DumpRenderTree').toNativePath();
779 } 758 }
780 759
781 String get dartiumFilename() { 760 String get dartiumFilename() {
782 if (configuration['dartium'] != '') { 761 if (configuration['dartium'] != '') {
783 return configuration['dartium']; 762 return configuration['dartium'];
784 } 763 }
785 if (Platform.operatingSystem == 'macos') { 764 if (Platform.operatingSystem == 'macos') {
786 return '$dartDir/client/tests/dartium/Chromium.app/Contents/' 765 return dartDir.append('client/tests/dartium/Chromium.app/Contents/'
787 'MacOS/Chromium'; 766 'MacOS/Chromium').toNativePath();
788 } 767 }
789 return '$dartDir/client/tests/dartium/chrome'; 768 return dartDir.append('client/tests/dartium/chrome').toNativePath();
790 } 769 }
791 770
792 void testGeneratorStarted() { 771 void testGeneratorStarted() {
793 ++activeTestGenerators; 772 ++activeTestGenerators;
794 } 773 }
795 774
796 void testGeneratorDone() { 775 void testGeneratorDone() {
797 --activeTestGenerators; 776 --activeTestGenerators;
798 if (activeTestGenerators == 0 && listingDone) { 777 if (activeTestGenerators == 0 && listingDone) {
799 doDone(); 778 doDone();
800 } 779 }
801 } 780 }
802 781
803 void directoryListingDone(ignore) { 782 void directoryListingDone(ignore) {
804 listingDone = true; 783 listingDone = true;
805 if (activeTestGenerators == 0) { 784 if (activeTestGenerators == 0) {
806 doDone(); 785 doDone();
807 } 786 }
808 } 787 }
809 788
810 void completeHandler(TestCase testCase) { 789 void completeHandler(TestCase testCase) {
811 } 790 }
812 791
813 List<List<String>> argumentListsFromFile(String filename, 792 List<List<String>> argumentListsFromFile(Path filePath,
814 Map optionsFromFile) { 793 Map optionsFromFile) {
815 List args = TestUtils.standardOptions(configuration); 794 List args = TestUtils.standardOptions(configuration);
816 args.addAll(additionalOptions(filename)); 795 args.addAll(additionalOptions(filePath));
817 if (configuration['compiler'] == 'dartc') { 796 if (configuration['compiler'] == 'dartc') {
818 args.add('--error_format'); 797 args.add('--error_format');
819 args.add('machine'); 798 args.add('machine');
820 } 799 }
821 if ((configuration['compiler'] == 'frog') 800 if ((configuration['compiler'] == 'frog')
822 && (configuration['runtime'] == 'none')) { 801 && (configuration['runtime'] == 'none')) {
823 args.add('--compile-only'); 802 args.add('--compile-only');
824 } 803 }
825 804
826 bool isMultitest = optionsFromFile["isMultitest"]; 805 bool isMultitest = optionsFromFile["isMultitest"];
827 List<String> dartOptions = optionsFromFile["dartOptions"]; 806 List<String> dartOptions = optionsFromFile["dartOptions"];
828 List<List<String>> vmOptionsList = getVmOptions(optionsFromFile); 807 List<List<String>> vmOptionsList = getVmOptions(optionsFromFile);
829 Expect.isTrue(!isMultitest || dartOptions == null); 808 Expect.isTrue(!isMultitest || dartOptions == null);
830 if (dartOptions == null) { 809 if (dartOptions == null) {
831 args.add(filename); 810 args.add('$filePath');
Siggi Cherem (dart-lang) 2012/06/27 17:19:03 Not sure, but should this be toNativePath?
Bill Hesse 2012/06/28 15:31:22 Yes. On 2012/06/27 17:19:03, sigmund wrote:
832 } else { 811 } else {
833 var executable_name = dartOptions[0]; 812 var executable_name = dartOptions[0];
834 // TODO(ager): Get rid of this hack when the runtime checkout goes away. 813 // TODO(ager): Get rid of this hack when the runtime checkout goes away.
835 var file = new File(executable_name); 814 var file = new File(executable_name);
836 if (!file.existsSync()) { 815 if (!file.existsSync()) {
837 executable_name = '../$executable_name'; 816 executable_name = '../$executable_name';
838 Expect.isTrue(new File(executable_name).existsSync()); 817 Expect.isTrue(new File(executable_name).existsSync());
839 dartOptions[0] = executable_name; 818 dartOptions[0] = executable_name;
840 } 819 }
841 args.addAll(dartOptions); 820 args.addAll(dartOptions);
842 } 821 }
843 822
844 var result = new List<List<String>>(); 823 var result = new List<List<String>>();
845 Expect.isFalse(vmOptionsList.isEmpty(), "empty vmOptionsList"); 824 Expect.isFalse(vmOptionsList.isEmpty(), "empty vmOptionsList");
846 for (var vmOptions in vmOptionsList) { 825 for (var vmOptions in vmOptionsList) {
847 var options = new List<String>.from(vmOptions); 826 var options = new List<String>.from(vmOptions);
848 options.addAll(args); 827 options.addAll(args);
849 result.add(options); 828 result.add(options);
850 } 829 }
851 830
852 return result; 831 return result;
853 } 832 }
854 833
855 Map readOptionsFromFile(String filename) { 834 Map readOptionsFromFile(Path filePath) {
856 RegExp testOptionsRegExp = const RegExp(@"// VMOptions=(.*)"); 835 RegExp testOptionsRegExp = const RegExp(@"// VMOptions=(.*)");
857 RegExp dartOptionsRegExp = const RegExp(@"// DartOptions=(.*)"); 836 RegExp dartOptionsRegExp = const RegExp(@"// DartOptions=(.*)");
858 RegExp otherScriptsRegExp = const RegExp(@"// OtherScripts=(.*)"); 837 RegExp otherScriptsRegExp = const RegExp(@"// OtherScripts=(.*)");
859 RegExp multiTestRegExp = const RegExp(@"/// [0-9][0-9]:(.*)"); 838 RegExp multiTestRegExp = const RegExp(@"/// [0-9][0-9]:(.*)");
860 RegExp staticTypeRegExp = 839 RegExp staticTypeRegExp =
861 const RegExp(@"/// ([0-9][0-9]:){0,1}\s*static type warning"); 840 const RegExp(@"/// ([0-9][0-9]:){0,1}\s*static type warning");
862 RegExp compileTimeRegExp = 841 RegExp compileTimeRegExp =
863 const RegExp(@"/// ([0-9][0-9]:){0,1}\s*compile-time error"); 842 const RegExp(@"/// ([0-9][0-9]:){0,1}\s*compile-time error");
864 RegExp staticCleanRegExp = const RegExp(@"// @static-clean"); 843 RegExp staticCleanRegExp = const RegExp(@"// @static-clean");
865 RegExp leadingHashRegExp = const RegExp(@"^#", multiLine: true); 844 RegExp leadingHashRegExp = const RegExp(@"^#", multiLine: true);
866 RegExp isolateStubsRegExp = const RegExp(@"// IsolateStubs=(.*)"); 845 RegExp isolateStubsRegExp = const RegExp(@"// IsolateStubs=(.*)");
867 RegExp domImportRegExp = 846 RegExp domImportRegExp =
868 const RegExp(@"^#import.*(dart:(dom|html)|html\.dart).*\)", 847 const RegExp(@"^#import.*(dart:(dom|html)|html\.dart).*\)",
869 multiLine: true); 848 multiLine: true);
870 RegExp libraryDefinitionRegExp = 849 RegExp libraryDefinitionRegExp =
871 const RegExp(@"^#library\(", multiLine: true); 850 const RegExp(@"^#library\(", multiLine: true);
872 RegExp sourceOrImportRegExp = 851 RegExp sourceOrImportRegExp =
873 const RegExp(@"^#(source|import|resource)\(", multiLine: true); 852 const RegExp(@"^#(source|import|resource)\(", multiLine: true);
874 853
875 // Read the entire file into a byte buffer and transform it to a 854 // 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 855 // String. This will treat the file as ascii but the only parts
877 // we are interested in will be ascii in any case. 856 // we are interested in will be ascii in any case.
878 RandomAccessFile file = new File(filename).openSync(FileMode.READ); 857 RandomAccessFile file = new File.fromPath(filePath).openSync(FileMode.READ);
879 List chars = new List(file.lengthSync()); 858 List chars = new List(file.lengthSync());
880 var offset = 0; 859 var offset = 0;
881 while (offset != chars.length) { 860 while (offset != chars.length) {
882 offset += file.readListSync(chars, offset, chars.length - offset); 861 offset += file.readListSync(chars, offset, chars.length - offset);
883 } 862 }
884 file.closeSync(); 863 file.closeSync();
885 String contents = new String.fromCharCodes(chars); 864 String contents = new String.fromCharCodes(chars);
886 chars = null; 865 chars = null;
887 866
888 // Find the options in the file. 867 // Find the options in the file.
889 List<List> result = new List<List>(); 868 List<List> result = new List<List>();
890 List<String> dartOptions; 869 List<String> dartOptions;
891 bool isNegative = false; 870 bool isNegative = false;
892 bool isStaticClean = false; 871 bool isStaticClean = false;
893 872
894 Iterable<Match> matches = testOptionsRegExp.allMatches(contents); 873 Iterable<Match> matches = testOptionsRegExp.allMatches(contents);
895 for (var match in matches) { 874 for (var match in matches) {
896 result.add(match[1].split(' ').filter((e) => e != '')); 875 result.add(match[1].split(' ').filter((e) => e != ''));
897 } 876 }
898 if (result.isEmpty()) result.add([]); 877 if (result.isEmpty()) result.add([]);
899 878
900 matches = dartOptionsRegExp.allMatches(contents); 879 matches = dartOptionsRegExp.allMatches(contents);
901 for (var match in matches) { 880 for (var match in matches) {
902 if (dartOptions != null) { 881 if (dartOptions != null) {
903 throw new Exception( 882 throw new Exception(
904 'More than one "// DartOptions=" line in test $filename'); 883 'More than one "// DartOptions=" line in test $filePath');
905 } 884 }
906 dartOptions = match[1].split(' ').filter((e) => e != ''); 885 dartOptions = match[1].split(' ').filter((e) => e != '');
907 } 886 }
908 887
909 matches = staticCleanRegExp.allMatches(contents); 888 matches = staticCleanRegExp.allMatches(contents);
910 for (var match in matches) { 889 for (var match in matches) {
911 if (isStaticClean) { 890 if (isStaticClean) {
912 throw new Exception( 891 throw new Exception(
913 'More than one "// @static-clean=" line in test $filename'); 892 'More than one "// @static-clean=" line in test $filePath');
914 } 893 }
915 isStaticClean = true; 894 isStaticClean = true;
916 } 895 }
917 896
918 List<String> otherScripts = new List<String>(); 897 List<String> otherScripts = new List<String>();
919 matches = otherScriptsRegExp.allMatches(contents); 898 matches = otherScriptsRegExp.allMatches(contents);
920 for (var match in matches) { 899 for (var match in matches) {
921 otherScripts.addAll(match[1].split(' ').filter((e) => e != '')); 900 otherScripts.addAll(match[1].split(' ').filter((e) => e != ''));
922 } 901 }
923 902
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
974 List<String> _testDirs; 953 List<String> _testDirs;
975 int activityCount = 0; 954 int activityCount = 0;
976 955
977 DartcCompilationTestSuite(Map configuration, 956 DartcCompilationTestSuite(Map configuration,
978 String suiteName, 957 String suiteName,
979 String directoryPath, 958 String directoryPath,
980 List<String> this._testDirs, 959 List<String> this._testDirs,
981 List<String> expectations) 960 List<String> expectations)
982 : super(configuration, 961 : super(configuration,
983 suiteName, 962 suiteName,
984 directoryPath, 963 new Path.fromNative(directoryPath),
985 expectations); 964 expectations);
986 965
987 void activityStarted() { ++activityCount; } 966 void activityStarted() { ++activityCount; }
988 967
989 void activityCompleted() { 968 void activityCompleted() {
990 if (--activityCount == 0) { 969 if (--activityCount == 0) {
991 directoryListingDone(true); 970 directoryListingDone(true);
992 } 971 }
993 } 972 }
994 973
995 String shellPath() => TestUtils.compilerPath(configuration); 974 String shellPath() => TestUtils.compilerPath(configuration);
996 975
997 List<String> additionalOptions(String filename) { 976 List<String> additionalOptions(Path filePath) {
998 return ['--fatal-warnings', '--fatal-type-errors']; 977 return ['--fatal-warnings', '--fatal-type-errors'];
999 } 978 }
1000 979
1001 void processDirectory() { 980 void processDirectory() {
1002 directoryPath = '$dartDir/$directoryPath';
1003 // Enqueueing the directory listers is an activity. 981 // Enqueueing the directory listers is an activity.
1004 activityStarted(); 982 activityStarted();
1005 for (String testDir in _testDirs) { 983 for (String testDir in _testDirs) {
1006 Directory dir = new Directory("$directoryPath/$testDir"); 984 Directory dir = new Directory.fromPath(suiteDir.append(testDir));
1007 if (dir.existsSync()) { 985 if (dir.existsSync()) {
1008 activityStarted(); 986 activityStarted();
1009 var lister = dir.list(recursive: listRecursively()); 987 var lister = dir.list(recursive: listRecursively());
1010 lister.onFile = processFile; 988 lister.onFile = processFile;
1011 lister.onDone = (ignore) => activityCompleted(); 989 lister.onDone = (ignore) => activityCompleted();
1012 } 990 }
1013 } 991 }
1014 // Completed the enqueueing of listers. 992 // Completed the enqueueing of listers.
1015 activityCompleted(); 993 activityCompleted();
1016 } 994 }
(...skipping 10 matching lines...) Expand all
1027 String classPath; 1005 String classPath;
1028 List<String> testClasses; 1006 List<String> testClasses;
1029 Function doTest; 1007 Function doTest;
1030 Function doDone; 1008 Function doDone;
1031 TestExpectations testExpectations; 1009 TestExpectations testExpectations;
1032 1010
1033 JUnitTestSuite(Map this.configuration, 1011 JUnitTestSuite(Map this.configuration,
1034 String this.suiteName, 1012 String this.suiteName,
1035 String this.directoryPath, 1013 String this.directoryPath,
1036 String this.statusFilePath) 1014 String this.statusFilePath)
1037 : dartDir = TestUtils.dartDir(); 1015 : dartDir = TestUtils.dartDir().toNativePath();
1038 1016
1039 bool isTestFile(String filename) => filename.endsWith("Tests.java") && 1017 bool isTestFile(String filename) => filename.endsWith("Tests.java") &&
1040 !filename.contains('com/google/dart/compiler/vm') && 1018 !filename.contains('com/google/dart/compiler/vm') &&
1041 !filename.contains('com/google/dart/corelib/SharedTests.java'); 1019 !filename.contains('com/google/dart/corelib/SharedTests.java');
1042 1020
1043 void forEachTest(Function onTest, 1021 void forEachTest(Function onTest,
1044 Map testCacheIgnored, 1022 Map testCacheIgnored,
1045 [Function onDone = null]) { 1023 [Function onDone = null]) {
1046 doTest = onTest; 1024 doTest = onTest;
1047 doDone = (onDone != null) ? onDone : (() => null); 1025 doDone = (onDone != null) ? onDone : (() => null);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1131 ':'); // Path separator. 1109 ':'); // Path separator.
1132 } 1110 }
1133 } 1111 }
1134 1112
1135 1113
1136 class TestUtils { 1114 class TestUtils {
1137 /** 1115 /**
1138 * Creates a directory using a [relativePath] to an existing 1116 * Creates a directory using a [relativePath] to an existing
1139 * [base] directory if that [relativePath] does not already exist. 1117 * [base] directory if that [relativePath] does not already exist.
1140 */ 1118 */
1141 static Directory mkdirRecursive(String base, String relativePath) { 1119 static Directory mkdirRecursive(Path base, Path relativePath) {
1142 Directory baseDir = new Directory(base); 1120 Directory dir = new Directory.fromPath(base);
1143 Expect.isTrue(baseDir.existsSync(), 1121 Expect.isTrue(dir.existsSync(),
1144 "Expected ${base} to already exist"); 1122 "Expected ${dir} to already exist");
1145 var tempDir = new Directory(base); 1123 var segments = relativePath.segments();
1146 for (String dir in relativePath.split('/')) { 1124 for (String segment in segments) {
1147 base = "$base/$dir"; 1125 base = base.append(segment);
1148 tempDir = new Directory(base); 1126 dir = new Directory.fromPath(base);
1149 if (!tempDir.existsSync()) { 1127 if (!dir.existsSync()) {
1150 tempDir.createSync(); 1128 dir.createSync();
1151 } 1129 }
1152 Expect.isTrue(tempDir.existsSync(), "Failed to create ${tempDir.path}"); 1130 Expect.isTrue(dir.existsSync(), "Failed to create ${dir.path}");
1153 } 1131 }
1154 return tempDir; 1132 return dir;
1155 } 1133 }
1156 1134
1157 /** 1135 /**
1158 * Copy a [source] file to a new place. 1136 * Copy a [source] file to a new place.
1159 * Assumes that the directory for [dest] already exists. 1137 * Assumes that the directory for [dest] already exists.
1160 */ 1138 */
1161 static void copyFile(File source, File dest) { 1139 static Future copyFile(Path source, Path dest) {
1162 List contents = source.readAsBytesSync(); 1140 var output = new File.fromPath(dest).openOutputStream();
1163 RandomAccessFile handle = dest.openSync(FileMode.WRITE); 1141 new File.fromPath(source).openInputStream().pipe(output);
1164 handle.writeListSync(contents, 0, contents.length); 1142 var completer = new Completer();
1165 handle.closeSync(); 1143 output.onClosed = (){ completer.complete(null); };
1144 return completer.future;
1166 } 1145 }
1167 1146
1168 static String executableSuffix(String executable) { 1147 static String executableSuffix(String executable) {
1169 if (Platform.operatingSystem == 'windows') { 1148 if (Platform.operatingSystem == 'windows') {
1170 if (executable == 'd8' || executable == 'vm' || executable == 'none') { 1149 if (executable == 'd8' || executable == 'vm' || executable == 'none') {
1171 return '.exe'; 1150 return '.exe';
1172 } else { 1151 } else {
1173 return '.bat'; 1152 return '.bat';
1174 } 1153 }
1175 } 1154 }
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1260 } 1239 }
1261 return result; 1240 return result;
1262 } 1241 }
1263 1242
1264 static String buildDir(Map configuration) { 1243 static String buildDir(Map configuration) {
1265 String mode = (configuration['mode'] == 'debug') ? 'Debug' : 'Release'; 1244 String mode = (configuration['mode'] == 'debug') ? 'Debug' : 'Release';
1266 String arch = configuration['arch'].toUpperCase(); 1245 String arch = configuration['arch'].toUpperCase();
1267 return "${outputDir(configuration)}$mode$arch"; 1246 return "${outputDir(configuration)}$mode$arch";
1268 } 1247 }
1269 1248
1270 static String dartDir() { 1249 static Path dartDir() {
1271 String scriptPath = new Options().script.replaceAll('\\', '/'); 1250 File scriptF = new File(new Options().script);
Mads Ager (google) 2012/06/27 16:08:18 Spell out File and Path? This is so much nicer th
Bill Hesse 2012/06/28 15:31:22 Done.
1272 String toolsDir = scriptPath.substring(0, scriptPath.lastIndexOf('/')); 1251 Path scriptP = new Path.fromNative(scriptF.fullPathSync());
1273 return new File('$toolsDir/..').fullPathSync().replaceAll('\\', '/'); 1252 return scriptP.directoryPath.directoryPath;
1274 } 1253 }
1275 1254
1276 static List<String> standardOptions(Map configuration) { 1255 static List<String> standardOptions(Map configuration) {
1277 List args = ["--ignore-unrecognized-flags"]; 1256 List args = ["--ignore-unrecognized-flags"];
1278 if (configuration["checked"]) { 1257 if (configuration["checked"]) {
1279 args.add('--enable_asserts'); 1258 args.add('--enable_asserts');
1280 args.add("--enable_type_checks"); 1259 args.add("--enable_type_checks");
1281 } 1260 }
1282 if (configuration["compiler"] == "dart2js") { 1261 if (configuration["compiler"] == "dart2js") {
1283 args = []; 1262 args = [];
1284 if (configuration["checked"]) { 1263 if (configuration["checked"]) {
1285 args.add('--enable-checked-mode'); 1264 args.add('--enable-checked-mode');
1286 } 1265 }
1287 args.add("--verbose"); 1266 args.add("--verbose");
1288 if (!isBrowserRuntime(configuration['runtime'])) { 1267 if (!isBrowserRuntime(configuration['runtime'])) {
1289 args.add("--allow-mock-compilation"); 1268 args.add("--allow-mock-compilation");
1290 } 1269 }
1291 } 1270 }
1292 return args; 1271 return args;
1293 } 1272 }
1294 1273
1295 static bool isBrowserRuntime(String runtime) => 1274 static bool isBrowserRuntime(String runtime) =>
1296 const <String>['drt', 1275 const {'drt': 1,
1297 'dartium', 1276 'dartium': 1,
1298 'ie', 1277 'ie': 1,
1299 'safari', 1278 'safari': 1,
1300 'opera', 1279 'opera': 1,
1301 'chrome', 1280 'chrome': 1,
1302 'ff'].some((x) => x == runtime); 1281 'ff': 1}.containsKey(runtime);
Emily Fortuna 2012/06/26 18:26:24 Why make this a map here? How about: static bool
Bill Hesse 2012/06/27 09:35:03 It was a list, using contains, but that doesn't ta
Mads Ager (google) 2012/06/27 16:08:18 I agree with Emily. I think the code in test.dart
Emily Fortuna 2012/06/27 16:56:49 Yeah, for the sake of readability and clarity, I p
Bill Hesse 2012/06/28 15:31:22 OK, changed back, but using indexOf, instead of .s
1303 } 1282 }
1304 1283
1305 class SummaryReport { 1284 class SummaryReport {
1306 static int total = 0; 1285 static int total = 0;
1307 static int skipped = 0; 1286 static int skipped = 0;
1308 static int noCrash = 0; 1287 static int noCrash = 0;
1309 static int pass = 0; 1288 static int pass = 0;
1310 static int failOk = 0; 1289 static int failOk = 0;
1311 static int fail = 0; 1290 static int fail = 0;
1312 static int crash = 0; 1291 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 1325 * $noCrash tests are expected to be flaky but not crash
1347 * $pass tests are expected to pass 1326 * $pass tests are expected to pass
1348 * $failOk tests are expected to fail that we won't fix 1327 * $failOk tests are expected to fail that we won't fix
1349 * $fail tests are expected to fail that we should fix 1328 * $fail tests are expected to fail that we should fix
1350 * $crash tests are expected to crash that we should fix 1329 * $crash tests are expected to crash that we should fix
1351 * $timeout tests are allowed to timeout 1330 * $timeout tests are allowed to timeout
1352 """; 1331 """;
1353 print(report); 1332 print(report);
1354 } 1333 }
1355 } 1334 }
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