Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |