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