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 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
536 | 536 |
537 String htmlPath = '$tempDir/test.html'; | 537 String htmlPath = '$tempDir/test.html'; |
538 if (!isWebTest) { | 538 if (!isWebTest) { |
539 // test.dart will import the dart test directly, if it is a library, | 539 // test.dart will import the dart test directly, if it is a library, |
540 // or indirectly through test_as_library.dart, if it is not. | 540 // or indirectly through test_as_library.dart, if it is not. |
541 Path dartLibraryFilename = filePath; | 541 Path dartLibraryFilename = filePath; |
542 if (!isLibraryDefinition) { | 542 if (!isLibraryDefinition) { |
543 dartLibraryFilename = new Path('test_as_library.dart'); | 543 dartLibraryFilename = new Path('test_as_library.dart'); |
544 File file = new File('$tempDir/$dartLibraryFilename'); | 544 File file = new File('$tempDir/$dartLibraryFilename'); |
545 RandomAccessFile dartLibrary = file.openSync(FileMode.WRITE); | 545 RandomAccessFile dartLibrary = file.openSync(FileMode.WRITE); |
546 dartLibrary.writeStringSync(WrapDartTestInLibrary(filePath)); | 546 dartLibrary.writeStringSync(wrapDartTestInLibrary(filePath)); |
547 dartLibrary.closeSync(); | 547 dartLibrary.closeSync(); |
548 } | 548 } |
549 | 549 |
550 File file = new File(dartWrapperFilename); | 550 File file = new File(dartWrapperFilename); |
551 RandomAccessFile dartWrapper = file.openSync(FileMode.WRITE); | 551 RandomAccessFile dartWrapper = file.openSync(FileMode.WRITE); |
552 dartWrapper.writeStringSync( | 552 dartWrapper.writeStringSync( |
553 DartTestWrapper(dartDir, dartLibraryFilename)); | 553 dartTestWrapper(dartDir, dartLibraryFilename)); |
554 dartWrapper.closeSync(); | 554 dartWrapper.closeSync(); |
555 } else { | 555 } else { |
556 dartWrapperFilename = filename; | 556 dartWrapperFilename = filename; |
557 // TODO(whesse): Once test.py is retired, adjust the relative path in | 557 // TODO(whesse): Once test.py is retired, adjust the relative path in |
558 // the client/samples/dartcombat test to its css file, remove the | 558 // the client/samples/dartcombat test to its css file, remove the |
559 // "../../" from this path, and move this out of the isWebTest guard. | 559 // "../../" from this path, and move this out of the isWebTest guard. |
560 // Also remove getHtmlName, and just use test.html. | 560 // Also remove getHtmlName, and just use test.html. |
561 // TODO(efortuna): this shortening of htmlFilename is a band-aid until | 561 // TODO(efortuna): this shortening of htmlFilename is a band-aid until |
562 // the above TODO gets fixed. Windows cannot have paths that are longer | 562 // the above TODO gets fixed. Windows cannot have paths that are longer |
563 // than 260 characters, and without this hack, we were running past the | 563 // than 260 characters, and without this hack, we were running past the |
564 // the limit. | 564 // the limit. |
565 String htmlFilename = getHtmlName(filename); | 565 String htmlFilename = getHtmlName(filename); |
566 while ('$tempDir/../$htmlFilename'.length >= 260) { | 566 while ('$tempDir/../$htmlFilename'.length >= 260) { |
567 htmlFilename = htmlFilename.substring(htmlFilename.length~/2); | 567 htmlFilename = htmlFilename.substring(htmlFilename.length~/2); |
568 } | 568 } |
569 htmlPath = '$tempDir/../$htmlFilename'; | 569 htmlPath = '$tempDir/../$htmlFilename'; |
570 } | 570 } |
571 final String scriptPath = (compiler == 'none') ? | 571 final String scriptPath = (compiler == 'none') ? |
572 dartWrapperFilename : compiledDartWrapperFilename; | 572 dartWrapperFilename : compiledDartWrapperFilename; |
573 // Create the HTML file for the test. | 573 // Create the HTML file for the test. |
574 RandomAccessFile htmlTest = new File(htmlPath).openSync(FileMode.WRITE); | 574 RandomAccessFile htmlTest = new File(htmlPath).openSync(FileMode.WRITE); |
575 String filePrefix = ''; | 575 String filePrefix = ''; |
576 if (Platform.operatingSystem == 'windows') { | 576 if (Platform.operatingSystem == 'windows') { |
577 // Firefox on Windows does not like absolute file path names that start | 577 // Firefox on Windows does not like absolute file path names that start |
578 // with 'C:' adding 'file:///' solves the problem. | 578 // with 'C:' adding 'file:///' solves the problem. |
579 filePrefix = 'file:///'; | 579 filePrefix = 'file:///'; |
580 } | 580 } |
581 htmlTest.writeStringSync(GetHtmlContents( | 581 String content = null; |
| 582 Path dir = filePath.directoryPath; |
| 583 String nameNoExt = filePath.filenameWithoutExtension; |
| 584 Path pngPath = dir.append('$nameNoExt.png'); |
| 585 Path txtPath = dir.append('$nameNoExt.txt'); |
| 586 Path expectedOutput = null; |
| 587 if (new File.fromPath(pngPath).existsSync()) { |
| 588 expectedOutput = pngPath; |
| 589 content = getHtmlLayoutContents(scriptType, '$filePrefix$scriptPath'); |
| 590 } else if (new File.fromPath(txtPath).existsSync()) { |
| 591 expectedOutput = txtPath; |
| 592 content = getHtmlLayoutContents(scriptType, '$filePrefix$scriptPath'); |
| 593 } else { |
| 594 content = getHtmlContents( |
582 filename, | 595 filename, |
583 '$filePrefix${dartDir.append("lib/unittest/test_controller.js")}', | 596 '$filePrefix${dartDir.append("lib/unittest/test_controller.js")}', |
584 scriptType, | 597 scriptType, |
585 '$filePrefix$scriptPath')); | 598 '$filePrefix$scriptPath'); |
| 599 } |
| 600 htmlTest.writeStringSync(content); |
586 htmlTest.closeSync(); | 601 htmlTest.closeSync(); |
587 | 602 |
588 // Construct the command(s) that compile all the inputs needed by the | 603 // Construct the command(s) that compile all the inputs needed by the |
589 // browser test. For running Dart in DRT, this will be noop commands. | 604 // browser test. For running Dart in DRT, this will be noop commands. |
590 List<Command> commands = []; | 605 List<Command> commands = []; |
591 if (compiler != 'none') { | 606 if (compiler != 'none') { |
592 commands.add(_compileCommand( | 607 commands.add(_compileCommand( |
593 dartWrapperFilename, compiledDartWrapperFilename, | 608 dartWrapperFilename, compiledDartWrapperFilename, |
594 compiler, tempDir, vmOptions)); | 609 compiler, tempDir, vmOptions)); |
595 | 610 |
(...skipping 30 matching lines...) Expand all Loading... |
626 if (runtime == 'drt' && compiler == 'none') { | 641 if (runtime == 'drt' && compiler == 'none') { |
627 var dartFlags = ['--ignore-unrecognized-flags']; | 642 var dartFlags = ['--ignore-unrecognized-flags']; |
628 if (configuration["checked"]) { | 643 if (configuration["checked"]) { |
629 dartFlags.add('--enable_asserts'); | 644 dartFlags.add('--enable_asserts'); |
630 dartFlags.add("--enable_type_checks"); | 645 dartFlags.add("--enable_type_checks"); |
631 } | 646 } |
632 dartFlags.addAll(vmOptions); | 647 dartFlags.addAll(vmOptions); |
633 args.add('--dart-flags=${Strings.join(dartFlags, " ")}'); | 648 args.add('--dart-flags=${Strings.join(dartFlags, " ")}'); |
634 } | 649 } |
635 args.add(htmlPath); | 650 args.add(htmlPath); |
| 651 if (expectedOutput != null) { |
| 652 args.add('--out-expectation=$expectedOutput'); |
| 653 } |
636 } | 654 } |
637 commands.add(new Command('python', args)); | 655 commands.add(new Command('python', args)); |
638 | 656 |
639 // Create BrowserTestCase and queue it. | 657 // Create BrowserTestCase and queue it. |
640 var testCase = new BrowserTestCase('$suiteName/$testName', | 658 var testCase = new BrowserTestCase('$suiteName/$testName', |
641 commands, configuration, completeHandler, expectations, | 659 commands, configuration, completeHandler, expectations, |
642 optionsFromFile['isNegative']); | 660 optionsFromFile['isNegative']); |
643 doTest(testCase); | 661 doTest(testCase); |
644 } | 662 } |
645 } | 663 } |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
822 Expect.isFalse(vmOptionsList.isEmpty(), "empty vmOptionsList"); | 840 Expect.isFalse(vmOptionsList.isEmpty(), "empty vmOptionsList"); |
823 for (var vmOptions in vmOptionsList) { | 841 for (var vmOptions in vmOptionsList) { |
824 var options = new List<String>.from(vmOptions); | 842 var options = new List<String>.from(vmOptions); |
825 options.addAll(args); | 843 options.addAll(args); |
826 result.add(options); | 844 result.add(options); |
827 } | 845 } |
828 | 846 |
829 return result; | 847 return result; |
830 } | 848 } |
831 | 849 |
| 850 /** |
| 851 * Special options for individual tests are currently specified in various |
| 852 * ways: with comments directly in test files, by using certain imports, or by |
| 853 * creating additional files in the test directories. |
| 854 * |
| 855 * Here is a list of options that are used by 'test.dart' today: |
| 856 * - Flags can be passed to the vm or dartium process that runs the test by |
| 857 * adding a comment to the test file: |
| 858 * |
| 859 * // VMOptions=--flag1 --flag2 |
| 860 * |
| 861 * - Flags can be passed to the dart script that contains the test also |
| 862 * using comments, as follows: |
| 863 * |
| 864 * // DartOptions=--flag1 --flag2 |
| 865 * |
| 866 * - For tests that depend on compiling other files with dart2js (e.g. |
| 867 * isolate tests that use multiple source scripts), you can specify |
| 868 * additional files to compile using a comment too, as follows: |
| 869 * |
| 870 * // OtherScripts=file1.dart file2.dart |
| 871 * |
| 872 * - You can indicate whether a test is treated as a web-only test by |
| 873 * using an explicit import to the dart:html library: |
| 874 * |
| 875 * #import('dart:html'); |
| 876 * |
| 877 * Most tests are not web tests, but can (and will be) wrapped within |
| 878 * another script file to test them also on browser environments (e.g. |
| 879 * language and corelib tests are run this way). We deduce that if this |
| 880 * import is specified, the test was intended to be a web test and no |
| 881 * wrapping is necessary. |
| 882 * |
| 883 * - You can convert DRT web-tests into layout-web-tests by specifying a |
| 884 * test expectation file. An expectation file is located in the same |
| 885 * location as the test, it has the same file name, except for the extension |
| 886 * (which can be either .txt or .png). |
| 887 * |
| 888 * When there are no expectation files, 'test.dart' assumes tests fail if |
| 889 * the process return a non-zero exit code (in the case of web tests, we |
| 890 * check for PASS/FAIL indications in the test output). |
| 891 * |
| 892 * When there is an expectation file, tests are run differently: the test |
| 893 * code is run to the end of the event loop and 'test.dart' takes a snapshot |
| 894 * of what is rendered in the page at that moment. This snapshot is |
| 895 * represented either in text form, if the expectation ends in .txt, or as |
| 896 * an image, if the expectation ends in .png. 'test.dart' will compare the |
| 897 * snapshot to the expectation file. When tests fail, 'test.dart' saves the |
| 898 * new snapshot into a file so it can be visualized or copied over. |
| 899 * Expectations can be recorded for the first time by creating an empty file |
| 900 * with the right name (touch test_name_test.png), running the test, and |
| 901 * executing the copy command printed by the test script. |
| 902 */ |
832 Map readOptionsFromFile(Path filePath) { | 903 Map readOptionsFromFile(Path filePath) { |
833 RegExp testOptionsRegExp = const RegExp(@"// VMOptions=(.*)"); | 904 RegExp testOptionsRegExp = const RegExp(@"// VMOptions=(.*)"); |
834 RegExp dartOptionsRegExp = const RegExp(@"// DartOptions=(.*)"); | 905 RegExp dartOptionsRegExp = const RegExp(@"// DartOptions=(.*)"); |
835 RegExp otherScriptsRegExp = const RegExp(@"// OtherScripts=(.*)"); | 906 RegExp otherScriptsRegExp = const RegExp(@"// OtherScripts=(.*)"); |
836 RegExp multiTestRegExp = const RegExp(@"/// [0-9][0-9]:(.*)"); | 907 RegExp multiTestRegExp = const RegExp(@"/// [0-9][0-9]:(.*)"); |
837 RegExp staticTypeRegExp = | 908 RegExp staticTypeRegExp = |
838 const RegExp(@"/// ([0-9][0-9]:){0,1}\s*static type warning"); | 909 const RegExp(@"/// ([0-9][0-9]:){0,1}\s*static type warning"); |
839 RegExp compileTimeRegExp = | 910 RegExp compileTimeRegExp = |
840 const RegExp(@"/// ([0-9][0-9]:){0,1}\s*compile-time error"); | 911 const RegExp(@"/// ([0-9][0-9]:){0,1}\s*compile-time error"); |
841 RegExp staticCleanRegExp = const RegExp(@"// @static-clean"); | 912 RegExp staticCleanRegExp = const RegExp(@"// @static-clean"); |
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1323 * $noCrash tests are expected to be flaky but not crash | 1394 * $noCrash tests are expected to be flaky but not crash |
1324 * $pass tests are expected to pass | 1395 * $pass tests are expected to pass |
1325 * $failOk tests are expected to fail that we won't fix | 1396 * $failOk tests are expected to fail that we won't fix |
1326 * $fail tests are expected to fail that we should fix | 1397 * $fail tests are expected to fail that we should fix |
1327 * $crash tests are expected to crash that we should fix | 1398 * $crash tests are expected to crash that we should fix |
1328 * $timeout tests are allowed to timeout | 1399 * $timeout tests are allowed to timeout |
1329 """; | 1400 """; |
1330 print(report); | 1401 print(report); |
1331 } | 1402 } |
1332 } | 1403 } |
OLD | NEW |