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 library multitest; | 5 library multitest; |
6 | 6 |
7 import "dart:async"; | 7 import "dart:async"; |
8 import "dart:io"; | 8 import "dart:io"; |
9 | 9 |
10 import "path.dart"; | 10 import "path.dart"; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 // aaa | 54 // aaa |
55 // eee /// 10: ok | 55 // eee /// 10: ok |
56 // fff | 56 // fff |
57 // | 57 // |
58 // Note that it is possible to indicate more than one acceptable outcome | 58 // Note that it is possible to indicate more than one acceptable outcome |
59 // in the case of dynamic and static type warnings | 59 // in the case of dynamic and static type warnings |
60 // aaa | 60 // aaa |
61 // ddd /// 07: static type warning, dynamic type error | 61 // ddd /// 07: static type warning, dynamic type error |
62 // fff | 62 // fff |
63 | 63 |
64 void ExtractTestsFromMultitest(Path filePath, | 64 void ExtractTestsFromMultitest(Path filePath, Map<String, String> tests, |
65 Map<String, String> tests, | 65 Map<String, Set<String>> outcomes) { |
66 Map<String, Set<String>> outcomes) { | |
67 // Read the entire file into a byte buffer and transform it to a | 66 // Read the entire file into a byte buffer and transform it to a |
68 // String. This will treat the file as ascii but the only parts | 67 // String. This will treat the file as ascii but the only parts |
69 // we are interested in will be ascii in any case. | 68 // we are interested in will be ascii in any case. |
70 List bytes = new File(filePath.toNativePath()).readAsBytesSync(); | 69 List bytes = new File(filePath.toNativePath()).readAsBytesSync(); |
71 String contents = decodeUtf8(bytes); | 70 String contents = decodeUtf8(bytes); |
72 int first_newline = contents.indexOf('\n'); | 71 int first_newline = contents.indexOf('\n'); |
73 final String line_separator = | 72 final String line_separator = (first_newline == 0 || |
74 (first_newline == 0 || contents[first_newline - 1] != '\r') | 73 contents[first_newline - 1] != '\r') ? '\n' : '\r\n'; |
75 ? '\n' | |
76 : '\r\n'; | |
77 List<String> lines = contents.split(line_separator); | 74 List<String> lines = contents.split(line_separator); |
78 if (lines.last == '') lines.removeLast(); | 75 if (lines.last == '') lines.removeLast(); |
79 bytes = null; | 76 bytes = null; |
80 contents = null; | 77 contents = null; |
81 Set<String> validMultitestOutcomes = new Set<String>.from( | 78 Set<String> validMultitestOutcomes = new Set<String>.from([ |
82 ['ok', 'compile-time error', 'runtime error', | 79 'ok', |
83 'static type warning', 'dynamic type error', | 80 'compile-time error', |
84 'checked mode compile-time error']); | 81 'runtime error', |
| 82 'static type warning', |
| 83 'dynamic type error', |
| 84 'checked mode compile-time error' |
| 85 ]); |
85 | 86 |
86 // Create the set of multitests, which will have a new test added each | 87 // Create the set of multitests, which will have a new test added each |
87 // time we see a multitest line with a new key. | 88 // time we see a multitest line with a new key. |
88 Map<String, List<String>> testsAsLines = new Map<String, List<String>>(); | 89 Map<String, List<String>> testsAsLines = new Map<String, List<String>>(); |
89 | 90 |
90 // Add the default case with key "none". | 91 // Add the default case with key "none". |
91 testsAsLines['none'] = new List<String>(); | 92 testsAsLines['none'] = new List<String>(); |
92 outcomes['none'] = new Set<String>(); | 93 outcomes['none'] = new Set<String>(); |
93 | 94 |
94 int lineCount = 0; | 95 int lineCount = 0; |
95 for (String line in lines) { | 96 for (String line in lines) { |
96 lineCount++; | 97 lineCount++; |
97 var annotation = new _Annotation.from(line); | 98 var annotation = new _Annotation.from(line); |
98 if (annotation != null) { | 99 if (annotation != null) { |
99 testsAsLines.putIfAbsent(annotation.key, | 100 testsAsLines.putIfAbsent( |
100 () => new List<String>.from(testsAsLines["none"])); | 101 annotation.key, () => new List<String>.from(testsAsLines["none"])); |
101 // Add line to test with annotation.key as key, empty line to the rest. | 102 // Add line to test with annotation.key as key, empty line to the rest. |
102 for (var key in testsAsLines.keys) { | 103 for (var key in testsAsLines.keys) { |
103 testsAsLines[key].add(annotation.key == key ? line : ""); | 104 testsAsLines[key].add(annotation.key == key ? line : ""); |
104 } | 105 } |
105 outcomes.putIfAbsent(annotation.key, () => new Set<String>()); | 106 outcomes.putIfAbsent(annotation.key, () => new Set<String>()); |
106 if (annotation.rest != 'continued') { | 107 if (annotation.rest != 'continued') { |
107 for (String nextOutcome in annotation.outcomesList) { | 108 for (String nextOutcome in annotation.outcomesList) { |
108 if (validMultitestOutcomes.contains(nextOutcome)) { | 109 if (validMultitestOutcomes.contains(nextOutcome)) { |
109 outcomes[annotation.key].add(nextOutcome); | 110 outcomes[annotation.key].add(nextOutcome); |
110 } else { | 111 } else { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 .map((s) => s.trim()) | 166 .map((s) => s.trim()) |
166 .where((s) => s.length > 0) | 167 .where((s) => s.length > 0) |
167 .toList(); | 168 .toList(); |
168 if (parts.length <= 1) { | 169 if (parts.length <= 1) { |
169 return null; | 170 return null; |
170 } | 171 } |
171 | 172 |
172 var annotation = new _Annotation(); | 173 var annotation = new _Annotation(); |
173 annotation.key = parts[0]; | 174 annotation.key = parts[0]; |
174 annotation.rest = parts[1]; | 175 annotation.rest = parts[1]; |
175 annotation.outcomesList = annotation.rest.split(',') | 176 annotation.outcomesList = |
176 .map((s) => s.trim()).toList(); | 177 annotation.rest.split(',').map((s) => s.trim()).toList(); |
177 return annotation; | 178 return annotation; |
178 } | 179 } |
179 } | 180 } |
180 | 181 |
181 // Find all relative imports and copy them into the dir that contains | 182 // Find all relative imports and copy them into the dir that contains |
182 // the generated tests. | 183 // the generated tests. |
183 Set<String> _findAllRelativeImports(Path topLibrary) { | 184 Set<String> _findAllRelativeImports(Path topLibrary) { |
184 Set<Path> toSearch = new Set<Path>.from([topLibrary]); | 185 Set<Path> toSearch = new Set<Path>.from([topLibrary]); |
185 Set<String> foundImports = new Set<String>(); | 186 Set<String> foundImports = new Set<String>(); |
186 Path libraryDir = topLibrary.directoryPath; | 187 Path libraryDir = topLibrary.directoryPath; |
(...skipping 25 matching lines...) Expand all Loading... |
212 } | 213 } |
213 foundImports.add(relativePath.toString()); | 214 foundImports.add(relativePath.toString()); |
214 toSearch.add(libraryDir.join(relativePath)); | 215 toSearch.add(libraryDir.join(relativePath)); |
215 } | 216 } |
216 } | 217 } |
217 } | 218 } |
218 } | 219 } |
219 return foundImports; | 220 return foundImports; |
220 } | 221 } |
221 | 222 |
222 Future doMultitest(Path filePath, String outputDir, Path suiteDir, | 223 Future doMultitest( |
223 CreateTest doTest) { | 224 Path filePath, String outputDir, Path suiteDir, CreateTest doTest) { |
224 void writeFile(String filepath, String content) { | 225 void writeFile(String filepath, String content) { |
225 final File file = new File(filepath); | 226 final File file = new File(filepath); |
226 | 227 |
227 if (file.existsSync()) { | 228 if (file.existsSync()) { |
228 var oldContent = file.readAsStringSync(); | 229 var oldContent = file.readAsStringSync(); |
229 if (oldContent == content) { | 230 if (oldContent == content) { |
230 // Don't write to the file if the content is the same | 231 // Don't write to the file if the content is the same |
231 return; | 232 return; |
232 } | 233 } |
233 } | 234 } |
(...skipping 13 matching lines...) Expand all Loading... |
247 Set<String> importsToCopy = _findAllRelativeImports(filePath); | 248 Set<String> importsToCopy = _findAllRelativeImports(filePath); |
248 List<Future> futureCopies = []; | 249 List<Future> futureCopies = []; |
249 for (String relativeImport in importsToCopy) { | 250 for (String relativeImport in importsToCopy) { |
250 Path importPath = new Path(relativeImport); | 251 Path importPath = new Path(relativeImport); |
251 // Make sure the target directory exists. | 252 // Make sure the target directory exists. |
252 Path importDir = importPath.directoryPath; | 253 Path importDir = importPath.directoryPath; |
253 if (!importDir.isEmpty) { | 254 if (!importDir.isEmpty) { |
254 TestUtils.mkdirRecursive(targetDir, importDir); | 255 TestUtils.mkdirRecursive(targetDir, importDir); |
255 } | 256 } |
256 // Copy file. | 257 // Copy file. |
257 futureCopies.add(TestUtils.copyFile(sourceDir.join(importPath), | 258 futureCopies.add(TestUtils.copyFile( |
258 targetDir.join(importPath))); | 259 sourceDir.join(importPath), targetDir.join(importPath))); |
259 } | 260 } |
260 | 261 |
261 // Wait until all imports are copied before scheduling test cases. | 262 // Wait until all imports are copied before scheduling test cases. |
262 return Future.wait(futureCopies).then((_) { | 263 return Future.wait(futureCopies).then((_) { |
263 String baseFilename = filePath.filenameWithoutExtension; | 264 String baseFilename = filePath.filenameWithoutExtension; |
264 for (String key in tests.keys) { | 265 for (String key in tests.keys) { |
265 final Path multitestFilename = | 266 final Path multitestFilename = |
266 targetDir.append('${baseFilename}_$key.dart'); | 267 targetDir.append('${baseFilename}_$key.dart'); |
267 writeFile(multitestFilename.toNativePath(), tests[key]); | 268 writeFile(multitestFilename.toNativePath(), tests[key]); |
268 Set<String> outcome = outcomes[key]; | 269 Set<String> outcome = outcomes[key]; |
269 bool hasStaticWarning = outcome.contains('static type warning'); | 270 bool hasStaticWarning = outcome.contains('static type warning'); |
270 bool hasRuntimeErrors = outcome.contains('runtime error'); | 271 bool hasRuntimeErrors = outcome.contains('runtime error'); |
271 bool hasCompileError = outcome.contains('compile-time error'); | 272 bool hasCompileError = outcome.contains('compile-time error'); |
272 bool isNegativeIfChecked = outcome.contains('dynamic type error'); | 273 bool isNegativeIfChecked = outcome.contains('dynamic type error'); |
273 bool hasCompileErrorIfChecked = | 274 bool hasCompileErrorIfChecked = |
274 outcome.contains('checked mode compile-time error'); | 275 outcome.contains('checked mode compile-time error'); |
275 doTest(multitestFilename, | 276 doTest(multitestFilename, filePath, hasCompileError, hasRuntimeErrors, |
276 filePath, | 277 isNegativeIfChecked: isNegativeIfChecked, |
277 hasCompileError, | 278 hasCompileErrorIfChecked: hasCompileErrorIfChecked, |
278 hasRuntimeErrors, | 279 hasStaticWarning: hasStaticWarning, |
279 isNegativeIfChecked: isNegativeIfChecked, | 280 multitestKey: key); |
280 hasCompileErrorIfChecked: hasCompileErrorIfChecked, | |
281 hasStaticWarning: hasStaticWarning, | |
282 multitestKey: key); | |
283 } | 281 } |
284 | 282 |
285 return null; | 283 return null; |
286 }); | 284 }); |
287 } | 285 } |
288 | 286 |
289 | |
290 Path CreateMultitestDirectory(String outputDir, Path suiteDir) { | 287 Path CreateMultitestDirectory(String outputDir, Path suiteDir) { |
291 Directory generatedTestDir = new Directory('$outputDir/generated_tests'); | 288 Directory generatedTestDir = new Directory('$outputDir/generated_tests'); |
292 if (!new Directory(outputDir).existsSync()) { | 289 if (!new Directory(outputDir).existsSync()) { |
293 new Directory(outputDir).createSync(); | 290 new Directory(outputDir).createSync(); |
294 } | 291 } |
295 if (!generatedTestDir.existsSync()) { | 292 if (!generatedTestDir.existsSync()) { |
296 generatedTestDir.createSync(); | 293 generatedTestDir.createSync(); |
297 } | 294 } |
298 var split = suiteDir.segments(); | 295 var split = suiteDir.segments(); |
299 if (split.last == 'src') { | 296 if (split.last == 'src') { |
300 // TODO(sigmund): remove this once all tests are migrated to use | 297 // TODO(sigmund): remove this once all tests are migrated to use |
301 // TestSuite.forDirectory. | 298 // TestSuite.forDirectory. |
302 split.removeLast(); | 299 split.removeLast(); |
303 } | 300 } |
304 String path = '${generatedTestDir.path}/${split.last}'; | 301 String path = '${generatedTestDir.path}/${split.last}'; |
305 Directory dir = new Directory(path); | 302 Directory dir = new Directory(path); |
306 if (!dir.existsSync()) { | 303 if (!dir.existsSync()) { |
307 dir.createSync(); | 304 dir.createSync(); |
308 } | 305 } |
309 return new Path(new File(path).absolute.path); | 306 return new Path(new File(path).absolute.path); |
310 } | 307 } |
OLD | NEW |