| 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 |