| 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, |
| 11 * and creating [TestCase]s for those files that meet the relevant criteria. | 11 * and creating [TestCase]s for those files that meet the relevant criteria. |
| 12 * - Preparing tests, including copying files and frameworks to temporary | 12 * - Preparing tests, including copying files and frameworks to temporary |
| 13 * directories, and computing the command line and arguments to be run. | 13 * directories, and computing the command line and arguments to be run. |
| 14 */ | 14 */ |
| 15 library test_suite; | 15 library test_suite; |
| 16 | 16 |
| 17 import "dart:async"; | 17 import "dart:async"; |
| 18 import "dart:io"; | 18 import "dart:io"; |
| 19 import "drt_updater.dart"; | 19 import "drt_updater.dart"; |
| 20 import "html_test.dart" as htmlTest; |
| 20 import "multitest.dart"; | 21 import "multitest.dart"; |
| 21 import "status_file_parser.dart"; | 22 import "status_file_parser.dart"; |
| 22 import "test_runner.dart"; | 23 import "test_runner.dart"; |
| 23 import "utils.dart"; | 24 import "utils.dart"; |
| 24 import "http_server.dart" show PREFIX_BUILDDIR, PREFIX_DARTDIR; | 25 import "http_server.dart" show PREFIX_BUILDDIR, PREFIX_DARTDIR; |
| 25 | 26 |
| 26 import "compiler_configuration.dart" show | 27 import "compiler_configuration.dart" show |
| 27 CommandArtifact, | 28 CommandArtifact, |
| 28 CompilerConfiguration; | 29 CompilerConfiguration; |
| 29 | 30 |
| 30 import "runtime_configuration.dart" show | 31 import "runtime_configuration.dart" show |
| 31 RuntimeConfiguration; | 32 RuntimeConfiguration; |
| 32 | 33 |
| 33 part "browser_test.dart"; | 34 part "browser_test.dart"; |
| 34 | 35 |
| 35 | 36 |
| 36 RegExp multiHtmlTestGroupRegExp = new RegExp(r"\s*[^/]\s*group\('[^,']*"); | 37 RegExp multiHtmlTestGroupRegExp = new RegExp(r"\s*[^/]\s*group\('[^,']*"); |
| 37 RegExp multiHtmlTestRegExp = new RegExp(r"useHtmlIndividualConfiguration()"); | 38 RegExp multiHtmlTestRegExp = new RegExp(r"useHtmlIndividualConfiguration()"); |
| 38 // Require at least one non-space character before '///' | 39 // Require at least one non-space character before '///' |
| 39 RegExp multiTestRegExp = new RegExp(r"\S *" | 40 RegExp multiTestRegExp = new RegExp(r"\S *" |
| 40 r"/// \w+:(.*)"); | 41 r"/// \w+:(.*)"); |
| 41 | 42 |
| 42 /** | 43 /** |
| 43 * A simple function that tests [arg] and returns `true` or `false`. | 44 * A simple function that tests [arg] and returns `true` or `false`. |
| 44 */ | 45 */ |
| 45 typedef bool Predicate<T>(T arg); | 46 typedef bool Predicate<T>(T arg); |
| 46 | 47 |
| 47 typedef void CreateTest(Path filePath, | 48 typedef void CreateTest(Path filePath, |
| 49 Path originTestPath, |
| 48 bool hasCompileError, | 50 bool hasCompileError, |
| 49 bool hasRuntimeError, | 51 bool hasRuntimeError, |
| 50 {bool isNegativeIfChecked, | 52 {bool isNegativeIfChecked, |
| 51 bool hasCompileErrorIfChecked, | 53 bool hasCompileErrorIfChecked, |
| 52 bool hasStaticWarning, | 54 bool hasStaticWarning, |
| 53 String multitestKey, | 55 String multitestKey}); |
| 54 Path originTestPath}); | |
| 55 | 56 |
| 56 typedef void VoidFunction(); | 57 typedef void VoidFunction(); |
| 57 | 58 |
| 58 /** | 59 /** |
| 59 * Calls [function] asynchronously. Returns a future that completes with the | 60 * Calls [function] asynchronously. Returns a future that completes with the |
| 60 * result of the function. If the function is `null`, returns a future that | 61 * result of the function. If the function is `null`, returns a future that |
| 61 * completes immediately with `null`. | 62 * completes immediately with `null`. |
| 62 */ | 63 */ |
| 63 Future asynchronously(function()) { | 64 Future asynchronously(function()) { |
| 64 if (function == null) return new Future.value(null); | 65 if (function == null) return new Future.value(null); |
| 65 | 66 |
| 66 var completer = new Completer(); | 67 var completer = new Completer(); |
| 67 Timer.run(() => completer.complete(function())); | 68 Timer.run(() => completer.complete(function())); |
| 68 | 69 |
| 69 return completer.future; | 70 return completer.future; |
| 70 } | 71 } |
| 71 | 72 |
| 73 |
| 72 /** A completer that waits until all added [Future]s complete. */ | 74 /** A completer that waits until all added [Future]s complete. */ |
| 73 // TODO(rnystrom): Copied from web_components. Remove from here when it gets | 75 // TODO(rnystrom): Copied from web_components. Remove from here when it gets |
| 74 // added to dart:core. (See #6626.) | 76 // added to dart:core. (See #6626.) |
| 75 class FutureGroup { | 77 class FutureGroup { |
| 76 static const _FINISHED = -1; | 78 static const _FINISHED = -1; |
| 77 int _pending = 0; | 79 int _pending = 0; |
| 78 Completer<List> _completer = new Completer<List>(); | 80 Completer<List> _completer = new Completer<List>(); |
| 79 final List<Future> futures = <Future>[]; | 81 final List<Future> futures = <Future>[]; |
| 80 bool wasCompleted = false; | 82 bool wasCompleted = false; |
| 81 | 83 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 103 wasCompleted = true; | 105 wasCompleted = true; |
| 104 } | 106 } |
| 105 } | 107 } |
| 106 }); | 108 }); |
| 107 futures.add(handledTaskFuture); | 109 futures.add(handledTaskFuture); |
| 108 } | 110 } |
| 109 | 111 |
| 110 Future<List> get future => _completer.future; | 112 Future<List> get future => _completer.future; |
| 111 } | 113 } |
| 112 | 114 |
| 115 |
| 113 /** | 116 /** |
| 114 * A TestSuite represents a collection of tests. It creates a [TestCase] | 117 * A TestSuite represents a collection of tests. It creates a [TestCase] |
| 115 * object for each test to be run, and passes the test cases to a callback. | 118 * object for each test to be run, and passes the test cases to a callback. |
| 116 * | 119 * |
| 117 * Most TestSuites represent a directory or directory tree containing tests, | 120 * Most TestSuites represent a directory or directory tree containing tests, |
| 118 * and a status file containing the expected results when these tests are run. | 121 * and a status file containing the expected results when these tests are run. |
| 119 */ | 122 */ |
| 120 abstract class TestSuite { | 123 abstract class TestSuite { |
| 121 final Map configuration; | 124 final Map configuration; |
| 122 final String suiteName; | 125 final String suiteName; |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 }).catchError((error) { | 559 }).catchError((error) { |
| 557 print("Fatal error occured: $error"); | 560 print("Fatal error occured: $error"); |
| 558 exit(1); | 561 exit(1); |
| 559 }); | 562 }); |
| 560 }); | 563 }); |
| 561 } | 564 } |
| 562 } | 565 } |
| 563 | 566 |
| 564 | 567 |
| 565 class TestInformation { | 568 class TestInformation { |
| 569 Path filePath; |
| 566 Path originTestPath; | 570 Path originTestPath; |
| 567 Path filePath; | |
| 568 Map optionsFromFile; | 571 Map optionsFromFile; |
| 569 bool hasCompileError; | 572 bool hasCompileError; |
| 570 bool hasRuntimeError; | 573 bool hasRuntimeError; |
| 571 bool isNegativeIfChecked; | 574 bool isNegativeIfChecked; |
| 572 bool hasCompileErrorIfChecked; | 575 bool hasCompileErrorIfChecked; |
| 573 bool hasStaticWarning; | 576 bool hasStaticWarning; |
| 574 String multitestKey; | 577 String multitestKey; |
| 575 | 578 |
| 576 TestInformation(this.filePath, this.optionsFromFile, | 579 TestInformation(this.filePath, this.originTestPath, this.optionsFromFile, |
| 577 this.hasCompileError, this.hasRuntimeError, | 580 this.hasCompileError, this.hasRuntimeError, |
| 578 this.isNegativeIfChecked, this.hasCompileErrorIfChecked, | 581 this.isNegativeIfChecked, this.hasCompileErrorIfChecked, |
| 579 this.hasStaticWarning, | 582 this.hasStaticWarning, |
| 580 {this.multitestKey, this.originTestPath}) { | 583 {this.multitestKey: ''}) { |
| 581 assert(filePath.isAbsolute); | 584 assert(filePath.isAbsolute); |
| 582 if (originTestPath == null) originTestPath = filePath; | |
| 583 } | 585 } |
| 584 } | 586 } |
| 585 | 587 |
| 588 |
| 589 class HtmlTestInformation extends TestInformation { |
| 590 List<String> expectedMessages; |
| 591 List<String> scripts; |
| 592 |
| 593 HtmlTestInformation(Path filePath, this.expectedMessages, this.scripts) |
| 594 : super(filePath, filePath, |
| 595 {'isMultitest': false, 'isMultiHtmlTest': false}, |
| 596 false, false, false, false, false) {} |
| 597 } |
| 598 |
| 599 |
| 586 /** | 600 /** |
| 587 * A standard [TestSuite] implementation that searches for tests in a | 601 * A standard [TestSuite] implementation that searches for tests in a |
| 588 * directory, and creates [TestCase]s that compile and/or run them. | 602 * directory, and creates [TestCase]s that compile and/or run them. |
| 589 */ | 603 */ |
| 590 class StandardTestSuite extends TestSuite { | 604 class StandardTestSuite extends TestSuite { |
| 591 final Path suiteDir; | 605 final Path suiteDir; |
| 592 final List<String> statusFilePaths; | 606 final List<String> statusFilePaths; |
| 593 TestExpectations testExpectations; | 607 TestExpectations testExpectations; |
| 594 List<TestInformation> cachedTests; | 608 List<TestInformation> cachedTests; |
| 595 final Path dartDir; | 609 final Path dartDir; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 | 678 |
| 665 List<Uri> get dart2JsBootstrapDependencies => _dart2JsBootstrapDependencies; | 679 List<Uri> get dart2JsBootstrapDependencies => _dart2JsBootstrapDependencies; |
| 666 | 680 |
| 667 /** | 681 /** |
| 668 * The default implementation assumes a file is a test if | 682 * The default implementation assumes a file is a test if |
| 669 * it ends in "Test.dart". | 683 * it ends in "Test.dart". |
| 670 */ | 684 */ |
| 671 bool isTestFile(String filename) { | 685 bool isTestFile(String filename) { |
| 672 // Use the specified predicate, if provided. | 686 // Use the specified predicate, if provided. |
| 673 if (isTestFilePredicate != null) return isTestFilePredicate(filename); | 687 if (isTestFilePredicate != null) return isTestFilePredicate(filename); |
| 674 | |
| 675 return filename.endsWith("Test.dart"); | 688 return filename.endsWith("Test.dart"); |
| 676 } | 689 } |
| 677 | 690 |
| 691 bool isHtmlTestFile(String filename) => filename.endsWith('_htmltest.html'); |
| 692 |
| 678 List<String> additionalOptions(Path filePath) => []; | 693 List<String> additionalOptions(Path filePath) => []; |
| 679 | 694 |
| 680 Map<String, String> localPackageDirectories; | 695 Map<String, String> localPackageDirectories; |
| 681 | 696 |
| 682 void forEachTest(Function onTest, Map testCache, [VoidFunction onDone]) { | 697 void forEachTest(Function onTest, Map testCache, [VoidFunction onDone]) { |
| 683 discoverPackagesInRepository().then((Map packageDirectories) { | 698 discoverPackagesInRepository().then((Map packageDirectories) { |
| 684 localPackageDirectories = packageDirectories; | 699 localPackageDirectories = packageDirectories; |
| 685 return updateDartium(); | 700 return updateDartium(); |
| 686 }).then((_) { | 701 }).then((_) { |
| 687 doTest = onTest; | 702 doTest = onTest; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 761 group.add(listCompleter.future); | 776 group.add(listCompleter.future); |
| 762 | 777 |
| 763 var lister = dir.list(recursive: listRecursively) | 778 var lister = dir.list(recursive: listRecursively) |
| 764 .listen((FileSystemEntity fse) { | 779 .listen((FileSystemEntity fse) { |
| 765 if (fse is File) enqueueFile(fse.path, group); | 780 if (fse is File) enqueueFile(fse.path, group); |
| 766 }, | 781 }, |
| 767 onDone: listCompleter.complete); | 782 onDone: listCompleter.complete); |
| 768 } | 783 } |
| 769 | 784 |
| 770 void enqueueFile(String filename, FutureGroup group) { | 785 void enqueueFile(String filename, FutureGroup group) { |
| 786 if (isHtmlTestFile(filename)) { |
| 787 var info = htmlTest.getInformation(filename); |
| 788 if (info == null) { |
| 789 DebugLogger.error( |
| 790 "HtmlTest $filename does not contain required annotations"); |
| 791 return; |
| 792 } |
| 793 cachedTests.add(info); |
| 794 enqueueTestCaseFromTestInformation(info); |
| 795 return; |
| 796 } |
| 771 if (!isTestFile(filename)) return; | 797 if (!isTestFile(filename)) return; |
| 772 Path filePath = new Path(filename); | 798 Path filePath = new Path(filename); |
| 773 | 799 |
| 774 // Only run the tests that match the pattern. | 800 // Only run the tests that match the pattern. |
| 775 if (filePath.filename.endsWith('test_config.dart')) return; | 801 if (filePath.filename.endsWith('test_config.dart')) return; |
| 776 | 802 |
| 777 var optionsFromFile = readOptionsFromFile(filePath); | 803 var optionsFromFile = readOptionsFromFile(filePath); |
| 778 CreateTest createTestCase = makeTestCaseCreator(optionsFromFile); | 804 CreateTest createTestCase = makeTestCaseCreator(optionsFromFile); |
| 779 | 805 |
| 780 if (optionsFromFile['isMultitest']) { | 806 if (optionsFromFile['isMultitest']) { |
| 781 group.add(doMultitest(filePath, buildDir, suiteDir, createTestCase)); | 807 group.add(doMultitest(filePath, buildDir, suiteDir, createTestCase)); |
| 782 } else { | 808 } else { |
| 783 createTestCase(filePath, | 809 createTestCase(filePath, |
| 810 filePath, |
| 784 optionsFromFile['hasCompileError'], | 811 optionsFromFile['hasCompileError'], |
| 785 optionsFromFile['hasRuntimeError'], | 812 optionsFromFile['hasRuntimeError'], |
| 786 hasStaticWarning: optionsFromFile['hasStaticWarning']); | 813 hasStaticWarning: optionsFromFile['hasStaticWarning']); |
| 787 } | 814 } |
| 788 } | 815 } |
| 789 | 816 |
| 790 static Path _findPubspecYamlFile(Path filePath) { | 817 static Path _findPubspecYamlFile(Path filePath) { |
| 791 final existsCache = TestUtils.existsCache; | 818 final existsCache = TestUtils.existsCache; |
| 792 | 819 |
| 793 Path root = TestUtils.dartDir; | 820 Path root = TestUtils.dartDir; |
| 794 assert ("$filePath".startsWith("$root")); | 821 assert ("$filePath".startsWith("$root")); |
| 795 | 822 |
| 796 // We start with the parent directory of [filePath] and go up until | 823 // We start with the parent directory of [filePath] and go up until |
| 797 // the root directory (excluding the root). | 824 // the root directory (excluding the root). |
| 798 List<String> segments = | 825 List<String> segments = |
| 799 filePath.directoryPath.relativeTo(root).segments(); | 826 filePath.directoryPath.relativeTo(root).segments(); |
| 800 while (segments.length > 0) { | 827 while (segments.length > 0) { |
| 801 var pubspecYamlPath = | 828 var pubspecYamlPath = |
| 802 new Path(segments.join('/')).append('pubspec.yaml'); | 829 new Path(segments.join('/')).append('pubspec.yaml'); |
| 803 if (existsCache.doesFileExist(pubspecYamlPath.toNativePath())) { | 830 if (existsCache.doesFileExist(pubspecYamlPath.toNativePath())) { |
| 804 return root.join(pubspecYamlPath); | 831 return root.join(pubspecYamlPath); |
| 805 } | 832 } |
| 806 segments.removeLast(); | 833 segments.removeLast(); |
| 807 } | 834 } |
| 808 return null; | 835 return null; |
| 809 } | 836 } |
| 810 | 837 |
| 811 void enqueueTestCaseFromTestInformation(TestInformation info) { | 838 void enqueueTestCaseFromTestInformation(TestInformation info) { |
| 839 String testName = buildTestCaseDisplayName(suiteDir, info.originTestPath, |
| 840 multitestName: info.multitestKey); |
| 841 Set<Expectation> expectations = testExpectations.expectations(testName); |
| 842 if (info is HtmlTestInformation && |
| 843 TestUtils.isBrowserRuntime(configuration['runtime'])) { |
| 844 enqueueBrowserTest([], null, info, testName, expectations); |
| 845 return; |
| 846 } |
| 812 var filePath = info.filePath; | 847 var filePath = info.filePath; |
| 813 var optionsFromFile = info.optionsFromFile; | 848 var optionsFromFile = info.optionsFromFile; |
| 814 | 849 |
| 815 Map buildSpecialPackageRoot(Path pubspecYamlFile) { | 850 Map buildSpecialPackageRoot(Path pubspecYamlFile) { |
| 816 var commands = <Command>[]; | 851 var commands = <Command>[]; |
| 817 var packageDir = pubspecYamlFile.directoryPath; | 852 var packageDir = pubspecYamlFile.directoryPath; |
| 818 var packageName = packageDir.filename; | 853 var packageName = packageDir.filename; |
| 819 | 854 |
| 820 var checkoutDirectory = | 855 var checkoutDirectory = |
| 821 createPubspecCheckoutDirectory(packageDir); | 856 createPubspecCheckoutDirectory(packageDir); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 869 'package-root' : newPackageRoot, | 904 'package-root' : newPackageRoot, |
| 870 }; | 905 }; |
| 871 } | 906 } |
| 872 | 907 |
| 873 // If this test is inside a package, we will check if there is a | 908 // If this test is inside a package, we will check if there is a |
| 874 // pubspec.yaml file and if so, create a custom package root for it. | 909 // pubspec.yaml file and if so, create a custom package root for it. |
| 875 List<Command> baseCommands = <Command>[]; | 910 List<Command> baseCommands = <Command>[]; |
| 876 Path packageRoot; | 911 Path packageRoot; |
| 877 if (configuration['use_repository_packages'] || | 912 if (configuration['use_repository_packages'] || |
| 878 configuration['use_public_packages']) { | 913 configuration['use_public_packages']) { |
| 879 Path pubspecYamlFile = _findPubspecYamlFile(filePath); | 914 Path pubspecYamlFile = _findPubspecYamlFile(filePath); |
| 880 if (pubspecYamlFile != null) { | 915 if (pubspecYamlFile != null) { |
| 881 var result = buildSpecialPackageRoot(pubspecYamlFile); | 916 var result = buildSpecialPackageRoot(pubspecYamlFile); |
| 882 baseCommands.addAll(result['commands']); | 917 baseCommands.addAll(result['commands']); |
| 883 packageRoot = result['package-root']; | 918 packageRoot = result['package-root']; |
| 884 if (optionsFromFile['packageRoot'] == null || | 919 if (optionsFromFile['packageRoot'] == null || |
| 885 optionsFromFile['packageRoot'] == "") { | 920 optionsFromFile['packageRoot'] == "") { |
| 886 optionsFromFile['packageRoot'] = packageRoot.toNativePath(); | 921 optionsFromFile['packageRoot'] = packageRoot.toNativePath(); |
| 887 } | 922 } |
| 888 } | 923 } |
| 889 } | 924 } |
| 890 if (configuration['package_root'] != null) { | 925 if (configuration['package_root'] != null) { |
| 891 packageRoot = new Path(configuration['package_root']); | 926 packageRoot = new Path(configuration['package_root']); |
| 892 optionsFromFile['packageRoot'] = packageRoot.toNativePath(); | 927 optionsFromFile['packageRoot'] = packageRoot.toNativePath(); |
| 893 } | 928 } |
| 894 | 929 |
| 895 String testName = buildTestCaseDisplayName(suiteDir, info.originTestPath, | |
| 896 multitestName: optionsFromFile['isMultitest'] ? info.multitestKey : ""); | |
| 897 | |
| 898 Set<Expectation> expectations = testExpectations.expectations(testName); | |
| 899 if (new CompilerConfiguration(configuration).hasCompiler && | 930 if (new CompilerConfiguration(configuration).hasCompiler && |
| 900 expectCompileError(info)) { | 931 expectCompileError(info)) { |
| 901 // If a compile-time error is expected, and we're testing a | 932 // If a compile-time error is expected, and we're testing a |
| 902 // compiler, we never need to attempt to run the program (in a | 933 // compiler, we never need to attempt to run the program (in a |
| 903 // browser or otherwise). | 934 // browser or otherwise). |
| 904 enqueueStandardTest(baseCommands, info, testName, expectations); | 935 enqueueStandardTest(baseCommands, info, testName, expectations); |
| 905 } else if (TestUtils.isBrowserRuntime(configuration['runtime'])) { | 936 } else if (TestUtils.isBrowserRuntime(configuration['runtime'])) { |
| 906 if (info.optionsFromFile['isMultiHtmlTest']) { | 937 if (info.optionsFromFile['isMultiHtmlTest']) { |
| 907 // A browser multi-test has multiple expectations for one test file. | 938 // A browser multi-test has multiple expectations for one test file. |
| 908 // Find all the different sub-test expecations for one entire test file. | 939 // Find all the different sub-test expecations for one entire test file. |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1013 runtimeConfiguration.computeRuntimeCommands( | 1044 runtimeConfiguration.computeRuntimeCommands( |
| 1014 this, | 1045 this, |
| 1015 CommandBuilder.instance, | 1046 CommandBuilder.instance, |
| 1016 compilationArtifact, | 1047 compilationArtifact, |
| 1017 runtimeArguments, | 1048 runtimeArguments, |
| 1018 environmentOverrides)); | 1049 environmentOverrides)); |
| 1019 } | 1050 } |
| 1020 | 1051 |
| 1021 CreateTest makeTestCaseCreator(Map optionsFromFile) { | 1052 CreateTest makeTestCaseCreator(Map optionsFromFile) { |
| 1022 return (Path filePath, | 1053 return (Path filePath, |
| 1054 Path originTestPath, |
| 1023 bool hasCompileError, | 1055 bool hasCompileError, |
| 1024 bool hasRuntimeError, | 1056 bool hasRuntimeError, |
| 1025 {bool isNegativeIfChecked: false, | 1057 {bool isNegativeIfChecked: false, |
| 1026 bool hasCompileErrorIfChecked: false, | 1058 bool hasCompileErrorIfChecked: false, |
| 1027 bool hasStaticWarning: false, | 1059 bool hasStaticWarning: false, |
| 1028 String multitestKey, | 1060 String multitestKey}) { |
| 1029 Path originTestPath}) { | |
| 1030 // Cache the test information for each test case. | 1061 // Cache the test information for each test case. |
| 1031 var info = new TestInformation(filePath, | 1062 var info = new TestInformation(filePath, |
| 1063 originTestPath, |
| 1032 optionsFromFile, | 1064 optionsFromFile, |
| 1033 hasCompileError, | 1065 hasCompileError, |
| 1034 hasRuntimeError, | 1066 hasRuntimeError, |
| 1035 isNegativeIfChecked, | 1067 isNegativeIfChecked, |
| 1036 hasCompileErrorIfChecked, | 1068 hasCompileErrorIfChecked, |
| 1037 hasStaticWarning, | 1069 hasStaticWarning, |
| 1038 multitestKey: multitestKey, | 1070 multitestKey: multitestKey); |
| 1039 originTestPath: originTestPath); | |
| 1040 cachedTests.add(info); | 1071 cachedTests.add(info); |
| 1041 enqueueTestCaseFromTestInformation(info); | 1072 enqueueTestCaseFromTestInformation(info); |
| 1042 }; | 1073 }; |
| 1043 } | 1074 } |
| 1044 | 1075 |
| 1045 /** | 1076 /** |
| 1046 * _createUrlPathFromFile takes a [file], which is either located in the dart | 1077 * _createUrlPathFromFile takes a [file], which is either located in the dart |
| 1047 * or in the build directory, and will return a String representing | 1078 * or in the build directory, and will return a String representing |
| 1048 * the relative path to either the dart or the build directory. | 1079 * the relative path to either the dart or the build directory. |
| 1049 * Thus, the returned [String] will be the path component of the URL | 1080 * Thus, the returned [String] will be the path component of the URL |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1127 // on to the browser (it may be test specific). | 1158 // on to the browser (it may be test specific). |
| 1128 | 1159 |
| 1129 // TODO(kustermann/ricow): This method should be refactored. | 1160 // TODO(kustermann/ricow): This method should be refactored. |
| 1130 Map optionsFromFile = info.optionsFromFile; | 1161 Map optionsFromFile = info.optionsFromFile; |
| 1131 Path filePath = info.filePath; | 1162 Path filePath = info.filePath; |
| 1132 String filename = filePath.toString(); | 1163 String filename = filePath.toString(); |
| 1133 | 1164 |
| 1134 final String compiler = configuration['compiler']; | 1165 final String compiler = configuration['compiler']; |
| 1135 final String runtime = configuration['runtime']; | 1166 final String runtime = configuration['runtime']; |
| 1136 | 1167 |
| 1168 if (info is HtmlTestInformation) { |
| 1169 if (compiler != 'none' || runtime != 'dartium') { |
| 1170 // TODO(whesse): Enable compilation of scripts to dart2js, and |
| 1171 // rewriting of script links in html file. Currently unimplemented. |
| 1172 return; |
| 1173 } |
| 1174 if (info.scripts.length > 0) { |
| 1175 // TODO(whesse): Copy scripts into output directory. |
| 1176 return; |
| 1177 } |
| 1178 final String tempDir = createOutputDirectory(info.filePath, ''); |
| 1179 final String htmlFile = '$tempDir/${filePath.filename}'; |
| 1180 new File(htmlFile).writeAsStringSync(htmlTest.getContents(info)); |
| 1181 |
| 1182 String testDisplayName = '$suiteName/$testName'; |
| 1183 var htmlPath = _createUrlPathFromFile(new Path(htmlFile)); |
| 1184 var fullHtmlPath = _getUriForBrowserTest(info, htmlPath, |
| 1185 null, null); |
| 1186 var commands = [CommandBuilder.instance.getBrowserHtmlTestCommand( |
| 1187 runtime, fullHtmlPath, configuration, info.expectedMessages)]; |
| 1188 var testCase = new BrowserTestCase(testDisplayName, |
| 1189 commands, configuration, expectations, |
| 1190 info, isNegative(info), fullHtmlPath); |
| 1191 enqueueNewTestCase(testCase); |
| 1192 return; |
| 1193 } |
| 1194 |
| 1137 for (var vmOptions in getVmOptions(optionsFromFile)) { | 1195 for (var vmOptions in getVmOptions(optionsFromFile)) { |
| 1138 // Create a unique temporary directory for each set of vmOptions. | 1196 // Create a unique temporary directory for each set of vmOptions. |
| 1139 // TODO(dart:429): Replace separate replaceAlls with a RegExp when | 1197 // TODO(dart:429): Replace separate replaceAlls with a RegExp when |
| 1140 // replaceAll(RegExp, String) is implemented. | 1198 // replaceAll(RegExp, String) is implemented. |
| 1141 String optionsName = ''; | 1199 String optionsName = ''; |
| 1142 if (getVmOptions(optionsFromFile).length > 1) { | 1200 if (getVmOptions(optionsFromFile).length > 1) { |
| 1143 optionsName = vmOptions.join('-').replaceAll('-','') | 1201 optionsName = vmOptions.join('-').replaceAll('-','') |
| 1144 .replaceAll('=','') | 1202 .replaceAll('=','') |
| 1145 .replaceAll('/',''); | 1203 .replaceAll('/',''); |
| 1146 } | 1204 } |
| (...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1664 "otherScripts": <String>[], | 1722 "otherScripts": <String>[], |
| 1665 "isMultitest": isMultitest, | 1723 "isMultitest": isMultitest, |
| 1666 "isMultiHtmlTest": false, | 1724 "isMultiHtmlTest": false, |
| 1667 "subtestNames": <String>[], | 1725 "subtestNames": <String>[], |
| 1668 "isolateStubs": '', | 1726 "isolateStubs": '', |
| 1669 "containsDomImport": false, | 1727 "containsDomImport": false, |
| 1670 }; | 1728 }; |
| 1671 } | 1729 } |
| 1672 } | 1730 } |
| 1673 | 1731 |
| 1732 |
| 1674 /// Used for testing packages in on off settings, i.e., we pass in the actual | 1733 /// Used for testing packages in on off settings, i.e., we pass in the actual |
| 1675 /// directory that we want to test. | 1734 /// directory that we want to test. |
| 1676 class PKGTestSuite extends StandardTestSuite { | 1735 class PKGTestSuite extends StandardTestSuite { |
| 1677 | 1736 |
| 1678 PKGTestSuite(Map configuration, Path directoryPath) | 1737 PKGTestSuite(Map configuration, Path directoryPath) |
| 1679 : super(configuration, | 1738 : super(configuration, |
| 1680 directoryPath.filename, | 1739 directoryPath.filename, |
| 1681 directoryPath, | 1740 directoryPath, |
| 1682 ["$directoryPath/.status"], | 1741 ["$directoryPath/.status"], |
| 1683 isTestFilePredicate: (f) => f.endsWith('_test.dart'), | 1742 isTestFilePredicate: (f) => f.endsWith('_test.dart'), |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1746 Directory dir = new Directory(suiteDir.append(testDir).toNativePath()); | 1805 Directory dir = new Directory(suiteDir.append(testDir).toNativePath()); |
| 1747 if (dir.existsSync()) { | 1806 if (dir.existsSync()) { |
| 1748 enqueueDirectory(dir, group); | 1807 enqueueDirectory(dir, group); |
| 1749 } | 1808 } |
| 1750 } | 1809 } |
| 1751 | 1810 |
| 1752 return group.future; | 1811 return group.future; |
| 1753 } | 1812 } |
| 1754 } | 1813 } |
| 1755 | 1814 |
| 1815 |
| 1756 class AnalyzeLibraryTestSuite extends DartcCompilationTestSuite { | 1816 class AnalyzeLibraryTestSuite extends DartcCompilationTestSuite { |
| 1757 AnalyzeLibraryTestSuite(Map configuration) | 1817 AnalyzeLibraryTestSuite(Map configuration) |
| 1758 : super(configuration, | 1818 : super(configuration, |
| 1759 'analyze_library', | 1819 'analyze_library', |
| 1760 'sdk', | 1820 'sdk', |
| 1761 ['lib'], | 1821 ['lib'], |
| 1762 ['tests/lib/analyzer/analyze_library.status']); | 1822 ['tests/lib/analyzer/analyze_library.status']); |
| 1763 | 1823 |
| 1764 List<String> additionalOptions(Path filePath, {bool showSdkWarnings}) { | 1824 List<String> additionalOptions(Path filePath, {bool showSdkWarnings}) { |
| 1765 var options = super.additionalOptions(filePath); | 1825 var options = super.additionalOptions(filePath); |
| 1766 // NOTE: This flag has been deprecated. | 1826 // NOTE: This flag has been deprecated. |
| 1767 options.add('--show-sdk-warnings'); | 1827 options.add('--show-sdk-warnings'); |
| 1768 return options; | 1828 return options; |
| 1769 } | 1829 } |
| 1770 | 1830 |
| 1771 bool isTestFile(String filename) { | 1831 bool isTestFile(String filename) { |
| 1772 var sep = Platform.pathSeparator; | 1832 var sep = Platform.pathSeparator; |
| 1773 // NOTE: We exclude tests and patch files for now. | 1833 // NOTE: We exclude tests and patch files for now. |
| 1774 return filename.endsWith(".dart") && | 1834 return filename.endsWith(".dart") && |
| 1775 !filename.endsWith("_test.dart") && | 1835 !filename.endsWith("_test.dart") && |
| 1776 !filename.contains("_internal/compiler/js_lib"); | 1836 !filename.contains("_internal/compiler/js_lib"); |
| 1777 } | 1837 } |
| 1778 | 1838 |
| 1779 bool get listRecursively => true; | 1839 bool get listRecursively => true; |
| 1780 } | 1840 } |
| 1781 | 1841 |
| 1842 |
| 1782 class PkgBuildTestSuite extends TestSuite { | 1843 class PkgBuildTestSuite extends TestSuite { |
| 1783 final String statusFilePath; | 1844 final String statusFilePath; |
| 1784 | 1845 |
| 1785 PkgBuildTestSuite(Map configuration, String suiteName, this.statusFilePath) | 1846 PkgBuildTestSuite(Map configuration, String suiteName, this.statusFilePath) |
| 1786 : super(configuration, suiteName) { | 1847 : super(configuration, suiteName) { |
| 1787 assert(configuration['use_sdk']);; | 1848 assert(configuration['use_sdk']);; |
| 1788 } | 1849 } |
| 1789 | 1850 |
| 1790 void forEachTest(void onTest(TestCase testCase), _, [void onDone()]) { | 1851 void forEachTest(void onTest(TestCase testCase), _, [void onDone()]) { |
| 1791 bool fileExists(Path path) => new File(path.toNativePath()).existsSync(); | 1852 bool fileExists(Path path) => new File(path.toNativePath()).existsSync(); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1906 return _cache[uri.path]; | 1967 return _cache[uri.path]; |
| 1907 } | 1968 } |
| 1908 var file = new File(new Path(uri.path).toNativePath()); | 1969 var file = new File(new Path(uri.path).toNativePath()); |
| 1909 _cache[uri.path] = file.existsSync() ? file.lastModifiedSync() : null; | 1970 _cache[uri.path] = file.existsSync() ? file.lastModifiedSync() : null; |
| 1910 return _cache[uri.path]; | 1971 return _cache[uri.path]; |
| 1911 } | 1972 } |
| 1912 return new DateTime.now(); | 1973 return new DateTime.now(); |
| 1913 } | 1974 } |
| 1914 } | 1975 } |
| 1915 | 1976 |
| 1977 |
| 1916 class ExistsCache { | 1978 class ExistsCache { |
| 1917 Map<String, bool> _cache = <String, bool>{}; | 1979 Map<String, bool> _cache = <String, bool>{}; |
| 1918 | 1980 |
| 1919 /** | 1981 /** |
| 1920 * Returns true if the file in [path] exists, false otherwise. | 1982 * Returns true if the file in [path] exists, false otherwise. |
| 1921 * | 1983 * |
| 1922 * The information will be cached. | 1984 * The information will be cached. |
| 1923 */ | 1985 */ |
| 1924 bool doesFileExist(String path) { | 1986 bool doesFileExist(String path) { |
| 1925 if (!_cache.containsKey(path)) { | 1987 if (!_cache.containsKey(path)) { |
| 1926 _cache[path] = new File(path).existsSync(); | 1988 _cache[path] = new File(path).existsSync(); |
| 1927 } | 1989 } |
| 1928 return _cache[path]; | 1990 return _cache[path]; |
| 1929 } | 1991 } |
| 1930 } | 1992 } |
| 1931 | 1993 |
| 1994 |
| 1932 class TestUtils { | 1995 class TestUtils { |
| 1933 /** | 1996 /** |
| 1934 * Any script using TestUtils must set dartDirUri to a file:// URI | 1997 * Any script using TestUtils must set dartDirUri to a file:// URI |
| 1935 * pointing to the root of the Dart checkout. | 1998 * pointing to the root of the Dart checkout. |
| 1936 */ | 1999 */ |
| 1937 static setDartDirUri(uri) { | 2000 static setDartDirUri(uri) { |
| 1938 dartDirUri = uri; | 2001 dartDirUri = uri; |
| 1939 dartDir = new Path(uri.toFilePath()); | 2002 dartDir = new Path(uri.toFilePath()); |
| 1940 } | 2003 } |
| 1941 static Uri dartDirUri; | 2004 static Uri dartDirUri; |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2268 if (path.startsWith(key)) { | 2331 if (path.startsWith(key)) { |
| 2269 path = path.replaceFirst(key, PATH_REPLACEMENTS[key]); | 2332 path = path.replaceFirst(key, PATH_REPLACEMENTS[key]); |
| 2270 break; | 2333 break; |
| 2271 } | 2334 } |
| 2272 } | 2335 } |
| 2273 } | 2336 } |
| 2274 return path; | 2337 return path; |
| 2275 } | 2338 } |
| 2276 } | 2339 } |
| 2277 | 2340 |
| 2341 |
| 2278 class SummaryReport { | 2342 class SummaryReport { |
| 2279 static int total = 0; | 2343 static int total = 0; |
| 2280 static int skipped = 0; | 2344 static int skipped = 0; |
| 2281 static int skippedByDesign = 0; | 2345 static int skippedByDesign = 0; |
| 2282 static int noCrash = 0; | 2346 static int noCrash = 0; |
| 2283 static int pass = 0; | 2347 static int pass = 0; |
| 2284 static int failOk = 0; | 2348 static int failOk = 0; |
| 2285 static int fail = 0; | 2349 static int fail = 0; |
| 2286 static int crash = 0; | 2350 static int crash = 0; |
| 2287 static int timeout = 0; | 2351 static int timeout = 0; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2337 * $pass tests are expected to pass | 2401 * $pass tests are expected to pass |
| 2338 * $failOk tests are expected to fail that we won't fix | 2402 * $failOk tests are expected to fail that we won't fix |
| 2339 * $fail tests are expected to fail that we should fix | 2403 * $fail tests are expected to fail that we should fix |
| 2340 * $crash tests are expected to crash that we should fix | 2404 * $crash tests are expected to crash that we should fix |
| 2341 * $timeout tests are allowed to timeout | 2405 * $timeout tests are allowed to timeout |
| 2342 * $compileErrorSkip tests are skipped on browsers due to compile-time error | 2406 * $compileErrorSkip tests are skipped on browsers due to compile-time error |
| 2343 """; | 2407 """; |
| 2344 print(report); | 2408 print(report); |
| 2345 } | 2409 } |
| 2346 } | 2410 } |
| OLD | NEW |