Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 /// Tests code generation. | 5 /// Tests code generation. |
| 6 /// Runs Dart Dev Compiler on all input in the `codegen` directory and checks | 6 /// Runs Dart Dev Compiler on all input in the `codegen` directory and checks |
| 7 /// that the output is what we expected. | 7 /// that the output is what we expected. |
| 8 library dev_compiler.test.codegen_test; | 8 library dev_compiler.test.codegen_test; |
| 9 | 9 |
| 10 import 'dart:io'; | 10 import 'dart:io'; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 58 | 58 |
| 59 tearDown(() { | 59 tearDown(() { |
| 60 if (loggerSub != null) { | 60 if (loggerSub != null) { |
| 61 loggerSub.cancel(); | 61 loggerSub.cancel(); |
| 62 loggerSub = null; | 62 loggerSub = null; |
| 63 } | 63 } |
| 64 }); | 64 }); |
| 65 | 65 |
| 66 var expectDir = path.join(inputDir, 'expect'); | 66 var expectDir = path.join(inputDir, 'expect'); |
| 67 | 67 |
| 68 bool compile(String entryPoint, AnalysisContext context, | 68 BatchCompiler createCompiler(AnalysisContext context, |
| 69 {bool checkSdk: false, bool sourceMaps: false, bool closure: false}) { | 69 {bool checkSdk: false, bool sourceMaps: false, bool closure: false}) { |
| 70 // TODO(jmesserly): add a way to specify flags in the test file, so | 70 // TODO(jmesserly): add a way to specify flags in the test file, so |
| 71 // they're more self-contained. | 71 // they're more self-contained. |
| 72 var runtimeDir = path.join(path.dirname(testDirectory), 'lib', 'runtime'); | 72 var runtimeDir = path.join(path.dirname(testDirectory), 'lib', 'runtime'); |
| 73 var options = new CompilerOptions( | 73 var options = new CompilerOptions( |
| 74 codegenOptions: new CodegenOptions( | 74 codegenOptions: new CodegenOptions( |
| 75 outputDir: expectDir, | 75 outputDir: expectDir, |
| 76 emitSourceMaps: sourceMaps, | 76 emitSourceMaps: sourceMaps, |
| 77 closure: closure, | 77 closure: closure, |
| 78 forceCompile: checkSdk), | 78 forceCompile: checkSdk), |
| 79 useColors: false, | 79 useColors: false, |
| 80 checkSdk: checkSdk, | 80 checkSdk: checkSdk, |
| 81 runtimeDir: runtimeDir, | 81 runtimeDir: runtimeDir, |
| 82 inputs: [entryPoint], | |
| 83 inputBaseDir: inputDir); | 82 inputBaseDir: inputDir); |
| 84 var reporter = createErrorReporter(context, options); | 83 var reporter = createErrorReporter(context, options); |
| 85 return new BatchCompiler(context, options, reporter: reporter).run(); | 84 return new BatchCompiler(context, options, reporter: reporter); |
| 85 } | |
| 86 | |
| 87 bool compile(BatchCompiler compiler, String filePath) { | |
| 88 compiler.compileFromUriString(filePath, (String url) { | |
|
Jennifer Messerly
2015/10/02 18:22:36
it might be simpler to just pass it the per file m
| |
| 89 // Write compiler messages to disk. | |
| 90 var messagePath = '${path.withoutExtension(url)}.txt'; | |
| 91 var file = new File(messagePath); | |
| 92 var message = ''' | |
| 93 // Messages from compiling ${path.basenameWithoutExtension(url)}.dart | |
|
Jennifer Messerly
2015/10/02 18:22:36
another thought here... when I was looking at maki
| |
| 94 $compilerMessages'''; | |
| 95 file.writeAsStringSync(message); | |
| 96 compilerMessages.clear(); | |
| 97 }); | |
| 98 return !compiler.failure; | |
| 86 } | 99 } |
| 87 | 100 |
| 88 var multitests = new Set<String>(); | 101 var multitests = new Set<String>(); |
| 89 { | 102 { |
| 90 // Expand wacky multitests into a bunch of test files. | 103 // Expand wacky multitests into a bunch of test files. |
| 91 // We'll compile each one as if it was an input. | 104 // We'll compile each one as if it was an input. |
| 92 var languageDir = path.join(inputDir, 'language'); | 105 var languageDir = path.join(inputDir, 'language'); |
| 93 var testFiles = _findTests(languageDir, filePattern); | 106 var testFiles = _findTests(languageDir, filePattern); |
| 94 | 107 |
| 95 for (var filePath in testFiles) { | 108 for (var filePath in testFiles) { |
| 96 if (filePath.endsWith('_multi.dart')) continue; | 109 if (filePath.endsWith('_multi.dart')) continue; |
| 97 | 110 |
| 98 var contents = new File(filePath).readAsStringSync(); | 111 var contents = new File(filePath).readAsStringSync(); |
| 99 if (isMultiTest(contents)) { | 112 if (isMultiTest(contents)) { |
| 100 multitests.add(filePath); | 113 multitests.add(filePath); |
| 101 | 114 |
| 102 var tests = new Map<String, String>(); | 115 var tests = new Map<String, String>(); |
| 103 var outcomes = new Map<String, Set<String>>(); | 116 var outcomes = new Map<String, Set<String>>(); |
| 104 extractTestsFromMultitest(filePath, contents, tests, outcomes); | 117 extractTestsFromMultitest(filePath, contents, tests, outcomes); |
| 105 | 118 |
| 106 var filename = path.basenameWithoutExtension(filePath); | 119 var filename = path.basenameWithoutExtension(filePath); |
| 107 tests.forEach((name, contents) { | 120 tests.forEach((name, contents) { |
| 108 new File(path.join(languageDir, '${filename}_${name}_multi.dart')) | 121 new File(path.join(languageDir, '${filename}_${name}_multi.dart')) |
| 109 .writeAsStringSync(contents); | 122 .writeAsStringSync(contents); |
| 110 }); | 123 }); |
| 111 } | 124 } |
| 112 } | 125 } |
| 113 } | 126 } |
| 114 | 127 |
| 128 var batchCompiler = createCompiler(realSdkContext); | |
| 129 | |
| 115 for (var dir in [null, 'language']) { | 130 for (var dir in [null, 'language']) { |
| 116 if (codeCoverage && dir == 'language') continue; | 131 if (codeCoverage && dir == 'language') continue; |
| 117 | 132 |
| 118 group('dartdevc ' + path.join('test', 'codegen', dir), () { | 133 group('dartdevc ' + path.join('test', 'codegen', dir), () { |
| 119 var outDir = new Directory(path.join(expectDir, dir)); | 134 var outDir = new Directory(path.join(expectDir, dir)); |
| 120 if (!outDir.existsSync()) outDir.createSync(recursive: true); | 135 if (!outDir.existsSync()) outDir.createSync(recursive: true); |
| 121 | 136 |
| 122 var testFiles = _findTests(path.join(inputDir, dir), filePattern); | 137 var testFiles = _findTests(path.join(inputDir, dir), filePattern); |
| 123 for (var filePath in testFiles) { | 138 for (var filePath in testFiles) { |
| 124 if (multitests.contains(filePath)) continue; | 139 if (multitests.contains(filePath)) continue; |
| 125 | 140 |
| 126 var filename = path.basenameWithoutExtension(filePath); | 141 var filename = path.basenameWithoutExtension(filePath); |
| 127 | 142 |
| 128 test('$filename.dart', () { | 143 test('$filename.dart', () { |
| 129 compilerMessages.writeln('// Messages from compiling $filename.dart'); | |
| 130 | |
| 131 // TODO(jmesserly): this was added to get some coverage of source maps | 144 // TODO(jmesserly): this was added to get some coverage of source maps |
| 132 // and closure annotations. | 145 // and closure annotations. |
| 133 // We need a more comprehensive strategy to test them. | 146 // We need a more comprehensive strategy to test them. |
| 134 var sourceMaps = filename == 'map_keys'; | 147 var sourceMaps = filename == 'map_keys'; |
| 135 var closure = filename == 'closure'; | 148 var closure = filename == 'closure'; |
| 136 var success = compile(filePath, realSdkContext, | 149 var success; |
| 137 sourceMaps: sourceMaps, closure: closure); | 150 // TODO(vsm): Is it okay to reuse the same context here? If there is |
|
Jennifer Messerly
2015/10/02 18:22:36
yeah, good TODO. I think this is because I didn't
| |
| 138 | 151 // overlap between test files, we may need separate ones for each |
| 139 // Write compiler messages to disk. | 152 // compiler. |
| 140 new File(path.join(outDir.path, '$filename.txt')) | 153 var compiler = (sourceMaps || closure) |
| 141 .writeAsStringSync('$compilerMessages'); | 154 ? createCompiler(realSdkContext, |
| 155 sourceMaps: sourceMaps, closure: closure) | |
| 156 : batchCompiler; | |
| 157 success = compile(compiler, filePath); | |
| 142 | 158 |
| 143 var outFile = new File(path.join(outDir.path, '$filename.js')); | 159 var outFile = new File(path.join(outDir.path, '$filename.js')); |
| 144 expect(!success || outFile.existsSync(), true, | 160 expect(!success || outFile.existsSync(), true, |
| 145 reason: '${outFile.path} was created if compilation succeeds'); | 161 reason: '${outFile.path} was created if compilation succeeds'); |
| 146 }); | 162 }); |
| 147 } | 163 } |
| 148 }); | 164 }); |
| 149 } | 165 } |
| 150 | 166 |
| 151 if (codeCoverage) { | 167 if (codeCoverage) { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 166 | 182 |
| 167 test('devc dart:core', () { | 183 test('devc dart:core', () { |
| 168 var testSdkContext = createAnalysisContextWithSources( | 184 var testSdkContext = createAnalysisContextWithSources( |
| 169 new StrongModeOptions(), | 185 new StrongModeOptions(), |
| 170 new SourceResolverOptions( | 186 new SourceResolverOptions( |
| 171 dartSdkPath: | 187 dartSdkPath: |
| 172 path.join(testDirectory, '..', 'tool', 'generated_sdk'))); | 188 path.join(testDirectory, '..', 'tool', 'generated_sdk'))); |
| 173 | 189 |
| 174 // Get the test SDK. We use a checked in copy so test expectations can | 190 // Get the test SDK. We use a checked in copy so test expectations can |
| 175 // be generated against a specific SDK version. | 191 // be generated against a specific SDK version. |
| 176 compile('dart:core', testSdkContext, checkSdk: true); | 192 var compiler = createCompiler(testSdkContext, checkSdk: true); |
| 193 compile(compiler, 'dart:core'); | |
| 177 var outFile = new File(path.join(expectDir, 'dart/core.js')); | 194 var outFile = new File(path.join(expectDir, 'dart/core.js')); |
| 178 expect(outFile.existsSync(), true, | 195 expect(outFile.existsSync(), true, |
| 179 reason: '${outFile.path} was created for dart:core'); | 196 reason: '${outFile.path} was created for dart:core'); |
| 180 }); | 197 }); |
| 181 }); | 198 }); |
| 182 } | 199 } |
| 183 | 200 |
| 184 var expectedRuntime = | 201 var expectedRuntime = |
| 185 defaultRuntimeFiles.map((f) => 'dev_compiler/runtime/$f'); | 202 defaultRuntimeFiles.map((f) => 'dev_compiler/runtime/$f'); |
| 186 | 203 |
| 187 test('devc jscodegen sunflower.html', () { | 204 test('devc jscodegen sunflower.html', () { |
| 188 var filePath = path.join(inputDir, 'sunflower', 'sunflower.html'); | 205 var filePath = path.join(inputDir, 'sunflower', 'sunflower.html'); |
| 189 compilerMessages.writeln('// Messages from compiling sunflower.html'); | 206 var success = compile(batchCompiler, filePath); |
| 190 | |
| 191 var success = compile(filePath, realSdkContext); | |
| 192 | |
| 193 // Write compiler messages to disk. | |
| 194 new File(path.join(expectDir, 'sunflower', 'sunflower.txt')) | |
| 195 .writeAsStringSync(compilerMessages.toString()); | |
| 196 | 207 |
| 197 var expectedFiles = ['sunflower.html', 'sunflower.js',]; | 208 var expectedFiles = ['sunflower.html', 'sunflower.js',]; |
| 198 | 209 |
| 199 for (var filepath in expectedFiles) { | 210 for (var filepath in expectedFiles) { |
| 200 var outFile = new File(path.join(expectDir, 'sunflower', filepath)); | 211 var outFile = new File(path.join(expectDir, 'sunflower', filepath)); |
| 201 expect(outFile.existsSync(), success, | 212 expect(outFile.existsSync(), success, |
| 202 reason: '${outFile.path} was created iff compilation succeeds'); | 213 reason: '${outFile.path} was created iff compilation succeeds'); |
| 203 } | 214 } |
| 204 }); | 215 }); |
| 205 | 216 |
| 206 test('devc jscodegen html_input.html', () { | 217 test('devc jscodegen html_input.html', () { |
| 207 var filePath = path.join(inputDir, 'html_input.html'); | 218 var filePath = path.join(inputDir, 'html_input.html'); |
| 208 compilerMessages.writeln('// Messages from compiling html_input.html'); | 219 var success = compile(batchCompiler, filePath); |
| 209 | |
| 210 var success = compile(filePath, realSdkContext); | |
| 211 | |
| 212 // Write compiler messages to disk. | |
| 213 new File(path.join(expectDir, 'html_input.txt')) | |
| 214 .writeAsStringSync(compilerMessages.toString()); | |
| 215 | 220 |
| 216 var expectedFiles = [ | 221 var expectedFiles = [ |
| 217 'html_input.html', | 222 'html_input.html', |
| 218 'dir/html_input_a.js', | 223 'dir/html_input_a.js', |
| 219 'dir/html_input_b.js', | 224 'dir/html_input_b.js', |
| 220 'dir/html_input_c.js', | 225 'dir/html_input_c.js', |
| 221 'dir/html_input_d.js', | 226 'dir/html_input_d.js', |
| 222 'dir/html_input_e.js' | 227 'dir/html_input_e.js' |
| 223 ]..addAll(expectedRuntime); | 228 ]..addAll(expectedRuntime); |
| 224 | 229 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 236 print('[AnalysisEngine] error $message $exception'); | 241 print('[AnalysisEngine] error $message $exception'); |
| 237 } | 242 } |
| 238 | 243 |
| 239 @override void logError2(String message, Object exception) { | 244 @override void logError2(String message, Object exception) { |
| 240 print('[AnalysisEngine] error $message $exception'); | 245 print('[AnalysisEngine] error $message $exception'); |
| 241 } | 246 } |
| 242 | 247 |
| 243 void logInformation(String message, [CaughtException exception]) {} | 248 void logInformation(String message, [CaughtException exception]) {} |
| 244 void logInformation2(String message, Object exception) {} | 249 void logInformation2(String message, Object exception) {} |
| 245 } | 250 } |
| OLD | NEW |