| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 #library("multitest"); | 5 #library("multitest"); |
| 6 | 6 |
| 7 // Multitests are Dart test scripts containing lines of the form | 7 // Multitests are Dart test scripts containing lines of the form |
| 8 // " [some dart code] /// [key]: [error type]" | 8 // " [some dart code] /// [key]: [error type]" |
| 9 // | 9 // |
| 10 // For each key in the file, a new test file is made containing all | 10 // For each key in the file, a new test file is made containing all |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 contents = null; | 68 contents = null; |
| 69 Set<String> validMultitestOutcomes = new Set<String>.from( | 69 Set<String> validMultitestOutcomes = new Set<String>.from( |
| 70 ['compile-time error', 'runtime error', | 70 ['compile-time error', 'runtime error', |
| 71 'static type error', 'dynamic type error', '']); | 71 'static type error', 'dynamic type error', '']); |
| 72 | 72 |
| 73 List<String> testTemplate = new List<String>(); | 73 List<String> testTemplate = new List<String>(); |
| 74 testTemplate.add('// Test created from multitest named $filename.'); | 74 testTemplate.add('// Test created from multitest named $filename.'); |
| 75 // Create the set of multitests, which will have a new test added each | 75 // Create the set of multitests, which will have a new test added each |
| 76 // time we see a multitest line with a new key. | 76 // time we see a multitest line with a new key. |
| 77 Map<String, List<String>> testsAsLines = new Map<String, List<String>>(); | 77 Map<String, List<String>> testsAsLines = new Map<String, List<String>>(); |
| 78 | 78 |
| 79 // Matches #import( or #source( followed by " or ' followed by anything |
| 80 // except dart: or /, at the beginning of a line. |
| 81 RegExp relativeImportRegExp = |
| 82 const RegExp('^#(import|source)[(]["\'](?!(dart:|/))'); |
| 79 for (String line in lines) { | 83 for (String line in lines) { |
| 80 if (line.contains('///')) { | 84 if (line.contains('///')) { |
| 81 var parts = line.split('///')[1].split(':'); | 85 var parts = line.split('///')[1].split(':'); |
| 82 var key = parts[0].trim(); | 86 var key = parts[0].trim(); |
| 83 var rest = parts[1].trim(); | 87 var rest = parts[1].trim(); |
| 84 if (testsAsLines.containsKey(key)) { | 88 if (testsAsLines.containsKey(key)) { |
| 85 Expect.equals('continued', rest); | 89 Expect.equals('continued', rest); |
| 86 testsAsLines[key].add(line); | 90 testsAsLines[key].add(line); |
| 87 } else { | 91 } else { |
| 88 (testsAsLines[key] = new List<String>.from(testTemplate)).add(line); | 92 (testsAsLines[key] = new List<String>.from(testTemplate)).add(line); |
| 89 outcomes[key] = rest; | 93 outcomes[key] = rest; |
| 90 Expect.isTrue(validMultitestOutcomes.contains(rest)); | 94 Expect.isTrue(validMultitestOutcomes.contains(rest)); |
| 91 } | 95 } |
| 92 } else { | 96 } else { |
| 93 if ((line.startsWith('#import(') || line.startsWith('#source(')) && | |
| 94 !line.contains("dart:")) { | |
| 95 // TODO(whesse): Rewrite relative paths to reflect temporary directory. | |
| 96 tests = []; | |
| 97 outcomes = []; | |
| 98 return; | |
| 99 } | |
| 100 testTemplate.add(line); | 97 testTemplate.add(line); |
| 101 for (var test in testsAsLines.getValues()) test.add(line); | 98 for (var test in testsAsLines.getValues()) test.add(line); |
| 102 } | 99 } |
| 100 // Warn if any import or source tags have relative paths. |
| 101 if (relativeImportRegExp.hasMatch(line)) { |
| 102 print('Warning: Multitest cannot contain relative imports:'); |
| 103 print(' $filename: $line'); |
| 104 } |
| 103 } | 105 } |
| 104 // Add the template, with no multitest lines, as a test with key 'none'. | 106 // Add the template, with no multitest lines, as a test with key 'none'. |
| 105 testsAsLines['none'] = testTemplate; | 107 testsAsLines['none'] = testTemplate; |
| 106 outcomes['none'] = ''; | 108 outcomes['none'] = ''; |
| 107 | 109 |
| 108 // Copy all the tests into the output map tests, as multiline strings. | 110 // Copy all the tests into the output map tests, as multiline strings. |
| 109 for (String key in testsAsLines.getKeys()) { | 111 for (String key in testsAsLines.getKeys()) { |
| 110 tests[key] = | 112 tests[key] = |
| 111 Strings.join(testsAsLines[key], line_separator) + line_separator; | 113 Strings.join(testsAsLines[key], line_separator) + line_separator; |
| 112 } | 114 } |
| 113 } | 115 } |
| 114 | 116 |
| 115 | 117 |
| 116 void DoMultitest(String filename, | 118 void DoMultitest(String filename, |
| 119 String buildDir, |
| 120 String testDir, |
| 117 Function doTest(List<String> args, | 121 Function doTest(List<String> args, |
| 118 bool isNegative, | 122 bool isNegative, |
| 119 bool isNegativeIfChecked)) { | 123 bool isNegativeIfChecked)) { |
| 120 // Each new test is a single String value in the Map tests. | 124 // Each new test is a single String value in the Map tests. |
| 121 Map<String, String> tests = new Map<String, String>(); | 125 Map<String, String> tests = new Map<String, String>(); |
| 122 Map<String, String> outcomes = new Map<String, String>(); | 126 Map<String, String> outcomes = new Map<String, String>(); |
| 123 ExtractTestsFromMultitest(filename, tests, outcomes); | 127 ExtractTestsFromMultitest(filename, tests, outcomes); |
| 128 |
| 129 String directory = CreateMultitestDirectory(buildDir, testDir); |
| 124 String pathSeparator = new Platform().pathSeparator(); | 130 String pathSeparator = new Platform().pathSeparator(); |
| 125 int start = filename.lastIndexOf(pathSeparator) + 1; | 131 int start = filename.lastIndexOf(pathSeparator) + 1; |
| 126 int end = filename.indexOf('.dart', start); | 132 int end = filename.indexOf('.dart', start); |
| 127 String baseFilename = filename.substring(start, end); | 133 String baseFilename = filename.substring(start, end); |
| 128 Directory dir = new Directory(""); | 134 Iterator currentKey = tests.getKeys().iterator(); |
| 129 dir.errorHandler = | 135 WriteMultitestToFileAndQueueIt(tests, outcomes, currentKey, |
| 130 (error) { Expect.fail("Error creating temp directory: $error"); }; | 136 '$directory$pathSeparator$baseFilename', doTest); |
| 131 | |
| 132 dir.createTempHandler = () { | |
| 133 String path = dir.path + new Platform().pathSeparator(); | |
| 134 Iterator currentKey = tests.getKeys().iterator(); | |
| 135 WriteMultitestToFileAndQueueIt(tests, outcomes, currentKey, | |
| 136 '$path$baseFilename', doTest); | |
| 137 }; | |
| 138 | |
| 139 dir.createTemp(); | |
| 140 } | 137 } |
| 141 | 138 |
| 142 | 139 |
| 143 // Write multiple tests to files, using tail recursion in a callback | 140 // Write multiple tests to files, using tail recursion in a callback |
| 144 // to serialize the file operations, rather than opening all files at once. | 141 // to serialize the file operations, rather than opening all files at once. |
| 145 WriteMultitestToFileAndQueueIt(Map<String, String> tests, | 142 WriteMultitestToFileAndQueueIt(Map<String, String> tests, |
| 146 Map<String, String> outcomes, | 143 Map<String, String> outcomes, |
| 147 Iterator currentKey, | 144 Iterator currentKey, |
| 148 String basePath, | 145 String basePath, |
| 149 Function doTest) { | 146 Function doTest) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 171 bool isNegativeIfChecked = outcome.contains('type error'); | 168 bool isNegativeIfChecked = outcome.contains('type error'); |
| 172 doTest(filename, isNegative, isNegativeIfChecked); | 169 doTest(filename, isNegative, isNegativeIfChecked); |
| 173 // TODO(whesse): Register files and directories to be deleted. | 170 // TODO(whesse): Register files and directories to be deleted. |
| 174 // They should be registered in a persistent list, so they can | 171 // They should be registered in a persistent list, so they can |
| 175 // be deleted later even if the test script is interrupted. | 172 // be deleted later even if the test script is interrupted. |
| 176 WriteMultitestToFileAndQueueIt(tests, outcomes, currentKey, | 173 WriteMultitestToFileAndQueueIt(tests, outcomes, currentKey, |
| 177 basePath, doTest); | 174 basePath, doTest); |
| 178 }; | 175 }; |
| 179 file.create(); | 176 file.create(); |
| 180 } | 177 } |
| 178 |
| 179 String CreateMultitestDirectory(String buildDir, String testDir) { |
| 180 final String generatedTestDirectory = 'generated_tests/'; |
| 181 Directory parent_dir = new Directory(buildDir + generatedTestDirectory); |
| 182 if (!parent_dir.existsSync()) { |
| 183 parent_dir.createSync(); |
| 184 } |
| 185 final String prefix = 'tests/'; |
| 186 final String suffix = '/src'; |
| 187 Expect.isTrue(testDir.startsWith(prefix)); |
| 188 Expect.isTrue(testDir.endsWith(suffix)); |
| 189 String path = parent_dir.path + |
| 190 testDir.substring(prefix.length, testDir.length - suffix.length); |
| 191 Directory dir = new Directory(path); |
| 192 if (!dir.existsSync()) { |
| 193 dir.createSync(); |
| 194 } |
| 195 return path; |
| 196 } |
| OLD | NEW |