Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Side by Side Diff: test/codegen_test.dart

Issue 1988503002: Move generated files to gen/. (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 ///
6 /// Runs Dart Dev Compiler on all input in the `codegen` directory and checks 7 /// Runs Dart Dev Compiler on all input in the `codegen` directory and checks
7 /// that the output is what we expected. 8 /// that the output is what we expected.
8 library dev_compiler.test.codegen_test; 9 library dev_compiler.test.codegen_test;
9 10
11 // TODO(rnystrom): This doesn't actually run any tests any more. It just
12 // compiles stuff. This should be changed to not use unittest and just be a
13 // regular program that outputs files.
14
10 import 'dart:convert' show JSON; 15 import 'dart:convert' show JSON;
11 import 'dart:io' show Directory, File, Platform; 16 import 'dart:io' show Directory, File, Platform;
12 import 'package:args/args.dart' show ArgParser, ArgResults; 17 import 'package:args/args.dart' show ArgParser, ArgResults;
13 import 'package:path/path.dart' as path; 18 import 'package:path/path.dart' as path;
14 import 'package:test/test.dart' show group, test; 19 import 'package:test/test.dart' show group, test;
15 20
16 import 'package:analyzer/analyzer.dart' 21 import 'package:analyzer/analyzer.dart'
17 show 22 show
18 ExportDirective, 23 ExportDirective,
19 ImportDirective, 24 ImportDirective,
20 StringLiteral, 25 StringLiteral,
21 UriBasedDirective, 26 UriBasedDirective,
22 parseDirectives; 27 parseDirectives;
23 import 'package:analyzer/src/generated/source.dart' show Source; 28 import 'package:analyzer/src/generated/source.dart' show Source;
24 import 'package:dev_compiler/src/analyzer/context.dart' show AnalyzerOptions; 29 import 'package:dev_compiler/src/analyzer/context.dart' show AnalyzerOptions;
25 import 'package:dev_compiler/src/compiler/compiler.dart' 30 import 'package:dev_compiler/src/compiler/compiler.dart'
26 show BuildUnit, CompilerOptions, ModuleCompiler; 31 show BuildUnit, CompilerOptions, ModuleCompiler;
27 import 'testing.dart' show testDirectory; 32 import 'testing.dart' show ddcDirectory, testDirectory;
28 import 'multitest.dart' show extractTestsFromMultitest, isMultiTest; 33 import 'multitest.dart' show extractTestsFromMultitest, isMultiTest;
29 import '../tool/build_sdk.dart' as build_sdk; 34 import '../tool/build_sdk.dart' as build_sdk;
30 import 'package:dev_compiler/src/compiler/compiler.dart'; 35 import 'package:dev_compiler/src/compiler/compiler.dart';
31 36
32 final ArgParser argParser = new ArgParser() 37 final ArgParser argParser = new ArgParser()
33 ..addOption('dart-sdk', help: 'Dart SDK Path', defaultsTo: null); 38 ..addOption('dart-sdk', help: 'Dart SDK Path', defaultsTo: null);
34 39
40 /// The `test/codegen` directory.
41 final codegenDir = path.join(testDirectory, 'codegen');
42
43 /// The generated directory where tests, expanded multitests, and other test
44 /// support libraries are copied to.
45 ///
46 /// The tests sometimes import utility libraries using a relative path.
47 /// Likewise, the multitests do too, and one multitest even imports its own
48 /// non-expanded form (!). To make that simpler, we copy the entire test tree
49 /// to a generated directory and expand that multitests in there too.
50 final codegenTestDir = path.join(ddcDirectory, 'gen', 'codegen_tests');
51
52 /// The generated directory where tests and packages compiled to JS are
53 /// output.
54 final codegenOutputDir = path.join(ddcDirectory, 'gen', 'codegen_output');
55
56 // TODO(jmesserly): switch this to a .packages file.
57 final packageUrlMappings = {
58 'package:expect/expect.dart': path.join(codegenDir, 'expect.dart'),
59 'package:async_helper/async_helper.dart':
60 path.join(codegenDir, 'async_helper.dart'),
61 'package:js/js.dart': path.join(codegenDir, 'packages', 'js', 'js.dart')
62 };
63
64 final codeCoverage = Platform.environment.containsKey('COVERALLS_TOKEN');
65
35 main(arguments) { 66 main(arguments) {
36 if (arguments == null) arguments = []; 67 if (arguments == null) arguments = [];
37 ArgResults args = argParser.parse(arguments); 68 ArgResults args = argParser.parse(arguments);
38 var filePattern = new RegExp(args.rest.length > 0 ? args.rest[0] : '.'); 69 var filePattern = new RegExp(args.rest.length > 0 ? args.rest[0] : '.');
39 70
40 var expectDir = path.join(inputDir, 'expect'); 71 var sdkDir = path.join(ddcDirectory, 'gen', 'patched_sdk');
72 var analyzerOptions = new AnalyzerOptions(
73 customUrlMappings: packageUrlMappings, dartSdkPath: sdkDir);
74 var compiler = new ModuleCompiler(analyzerOptions);
75
76 // Build packages tests depend on.
77 _buildAllPackages(compiler);
78
41 var testDirs = [ 79 var testDirs = [
42 'language', 80 'language',
43 'corelib', 81 'corelib',
44 path.join('lib', 'convert'), 82 path.join('lib', 'convert'),
45 path.join('lib', 'html'), 83 path.join('lib', 'html'),
46 path.join('lib', 'math'), 84 path.join('lib', 'math'),
47 path.join('lib', 'typed_data') 85 path.join('lib', 'typed_data')
48 ]; 86 ];
49 87
50 var multitests = expandMultiTests(testDirs, filePattern); 88 // Copy all of the test files and expanded multitest files to
51 89 // gen/codegen_tests. We'll compile from there.
52 // Build packages tests depend on 90 var testFiles = _setUpTests(testDirs, filePattern);
53 var generatedSdkDir = path.join(testDirectory, '..', 'tool', 'generated_sdk');
54 var analyzerOptions = new AnalyzerOptions(
55 customUrlMappings: packageUrlMappings, dartSdkPath: generatedSdkDir);
56 var compiler = new ModuleCompiler(analyzerOptions);
57
58 group('dartdevc package', () {
59 _buildPackages(compiler, expectDir);
60
61 test('matcher', () {
62 _buildPackage(compiler, expectDir, "matcher");
63 });
64
65 test('unittest', () {
66 _buildPackage(compiler, expectDir, "unittest");
67 });
68
69 test('stack_trace', () {
70 _buildPackage(compiler, expectDir, "stack_trace");
71 });
72
73 test('path', () {
74 _buildPackage(compiler, expectDir, "path");
75 });
76 });
77
78 test('dartdevc sunflower', () {
79 _buildSunflower(compiler, expectDir);
80 });
81 91
82 // Our default compiler options. Individual tests can override these. 92 // Our default compiler options. Individual tests can override these.
83 var defaultOptions = ['--no-source-map', '--no-summarize']; 93 var defaultOptions = ['--no-source-map', '--no-summarize'];
84 var compilerArgParser = CompilerOptions.addArguments(new ArgParser()); 94 var compilerArgParser = CompilerOptions.addArguments(new ArgParser());
85 95
86 var allDirs = [null]; 96 // Compile each test file to JS and put the result in gen/codegen_output.
87 allDirs.addAll(testDirs); 97 for (var testFile in testFiles) {
88 for (var dir in allDirs) { 98 var relativePath = path.relative(testFile, from: codegenTestDir);
89 if (codeCoverage && dir != null) continue;
90 99
91 group('dartdevc ' + path.join('test', 'codegen', dir), () { 100 // Only compile the top-level files for generating coverage.
92 var outDir = new Directory(path.join(expectDir, dir)); 101 if (codeCoverage && path.dirname(relativePath) != ".") continue;
93 if (!outDir.existsSync()) outDir.createSync(recursive: true);
94 102
95 var baseDir = path.join(inputDir, dir); 103 var name = path.withoutExtension(relativePath);
96 var testFiles = _findTests(baseDir, filePattern); 104 test('dartdevc $name', () {
97 for (var filePath in testFiles) { 105 var outDir = path.join(codegenOutputDir, path.dirname(relativePath));
98 if (multitests.contains(filePath)) continue; 106 _ensureDirectory(outDir);
99 107
100 var filename = path.basenameWithoutExtension(filePath); 108 // Check if we need to use special compile options.
109 var contents = new File(testFile).readAsStringSync();
110 var match =
111 new RegExp(r'// compile options: (.*)').matchAsPrefix(contents);
101 112
102 test('$filename.dart', () { 113 var args = defaultOptions.toList();
103 // Check if we need to use special compile options. 114 if (match != null) {
104 var contents = new File(filePath).readAsStringSync(); 115 args.addAll(match.group(1).split(' '));
105 var match = 116 }
106 new RegExp(r'// compile options: (.*)').matchAsPrefix(contents); 117 var options =
118 new CompilerOptions.fromArguments(compilerArgParser.parse(args));
107 119
108 var args = new List.from(defaultOptions); 120 // Collect any other files we've imported.
109 if (match != null) { 121 var files = new Set<String>();
110 args.addAll(match.group(1).split(' ')); 122 _collectTransitiveImports(contents, files, from: testFile);
111 } 123 var moduleName =
112 var options = 124 path.withoutExtension(path.relative(testFile, from: codegenTestDir));
113 new CompilerOptions.fromArguments(compilerArgParser.parse(args)); 125 var unit = new BuildUnit(
126 moduleName, path.dirname(testFile), files.toList(), _moduleForLibrary) ;
Jennifer Messerly 2016/05/17 17:43:52 some long lines
Bob Nystrom 2016/05/18 00:12:58 Oops! Done.
127 var module = compiler.compile(unit, options);
128 _writeModule(path.join(outDir, path.basenameWithoutExtension(testFile)), m odule);
114 129
115 // Collect any other files we've imported.
116 var files = new Set<String>();
117 _collectTransitiveImports(contents, files, from: filePath);
118 var moduleName =
119 path.withoutExtension(path.relative(filePath, from: inputDir));
120 var unit = new BuildUnit(
121 moduleName, baseDir, files.toList(), _moduleForLibrary);
122 var module = compiler.compile(unit, options);
123 _writeModule(path.join(outDir.path, filename), module);
124 });
125 }
126 }); 130 });
127 } 131 }
128 132
129 if (codeCoverage) { 133 if (codeCoverage) {
130 test('build_sdk code coverage', () { 134 test('build_sdk code coverage', () {
131 return build_sdk.main(['--dart-sdk', generatedSdkDir, '-o', expectDir]); 135 return build_sdk.main(['--dart-sdk', sdkDir, '-o', codegenOutputDir]);
132 }); 136 });
133 } 137 }
134 } 138 }
135 139
136 void _writeModule(String outPath, JSModuleFile result) { 140 void _writeModule(String outPath, JSModuleFile result) {
137 new Directory(path.dirname(outPath)).createSync(recursive: true); 141 _ensureDirectory(path.dirname(outPath));
138 142
139 String errors = result.errors.join('\n'); 143 String errors = result.errors.join('\n');
140 if (errors.isNotEmpty && !errors.endsWith('\n')) errors += '\n'; 144 if (errors.isNotEmpty && !errors.endsWith('\n')) errors += '\n';
141 new File(outPath + '.txt').writeAsStringSync(errors); 145 new File(outPath + '.txt').writeAsStringSync(errors);
142 146
143 var jsFile = new File(outPath + '.js'); 147 var jsFile = new File(outPath + '.js');
144 var errorFile = new File(outPath + '.err'); 148 var errorFile = new File(outPath + '.err');
145 149
146 if (result.isValid) { 150 if (result.isValid) {
147 jsFile.writeAsStringSync(result.code); 151 jsFile.writeAsStringSync(result.code);
(...skipping 11 matching lines...) Expand all
159 // Also write the errors to a '.err' file for easy counting. 163 // Also write the errors to a '.err' file for easy counting.
160 errorFile.writeAsStringSync(errors); 164 errorFile.writeAsStringSync(errors);
161 165
162 // There are errors, so delete any stale ".js" file. 166 // There are errors, so delete any stale ".js" file.
163 if (jsFile.existsSync()) { 167 if (jsFile.existsSync()) {
164 jsFile.deleteSync(); 168 jsFile.deleteSync();
165 } 169 }
166 } 170 }
167 } 171 }
168 172
169 void _buildSunflower(ModuleCompiler compiler, String expectDir) { 173 void _buildAllPackages(ModuleCompiler compiler) {
170 var baseDir = path.join(inputDir, 'sunflower'); 174 group('dartdevc package', () {
175 _buildPackages(compiler, codegenOutputDir);
176
177 var packages = ['matcher', 'unittest', 'stack_trace', 'path'];
178 for (var package in packages) {
179 test(package, () {
180 _buildPackage(compiler, codegenOutputDir, package);
181 });
182 }
183 });
184
185 test('dartdevc sunflower', () {
186 _buildSunflower(compiler, codegenOutputDir);
187 });
188 }
189
190 void _buildSunflower(ModuleCompiler compiler, String outputDir) {
191 var baseDir = path.join(codegenDir, 'sunflower');
171 var files = ['sunflower', 'circle', 'painter'] 192 var files = ['sunflower', 'circle', 'painter']
172 .map((f) => path.join(baseDir, '$f.dart')) 193 .map((f) => path.join(baseDir, '$f.dart'))
173 .toList(); 194 .toList();
174 var input = new BuildUnit('sunflower', baseDir, files, _moduleForLibrary); 195 var input = new BuildUnit('sunflower', baseDir, files, _moduleForLibrary);
175 var options = new CompilerOptions(summarizeApi: false); 196 var options = new CompilerOptions(summarizeApi: false);
176 197
177 var built = compiler.compile(input, options); 198 var built = compiler.compile(input, options);
178 _writeModule(path.join(expectDir, 'sunflower', 'sunflower'), built); 199 _writeModule(path.join(outputDir, 'sunflower', 'sunflower'), built);
179 } 200 }
180 201
181 void _buildPackages(ModuleCompiler compiler, String expectDir) { 202 void _buildPackages(ModuleCompiler compiler, String outputDir) {
182 // Note: we don't summarize these, as we're going to rely on our in-memory 203 // Note: we don't summarize these, as we're going to rely on our in-memory
183 // shared analysis context for caching, and `_moduleForLibrary` below 204 // shared analysis context for caching, and `_moduleForLibrary` below
184 // understands these are from other modules. 205 // understands these are from other modules.
185 var options = new CompilerOptions(sourceMap: false, summarizeApi: false); 206 var options = new CompilerOptions(sourceMap: false, summarizeApi: false);
186 207
187 for (var uri in packageUrlMappings.keys) { 208 for (var uri in packageUrlMappings.keys) {
188 assert(uri.startsWith('package:')); 209 assert(uri.startsWith('package:'));
189 var uriPath = uri.substring('package:'.length); 210 var uriPath = uri.substring('package:'.length);
190 var name = path.basenameWithoutExtension(uriPath); 211 var name = path.basenameWithoutExtension(uriPath);
191 test(name, () { 212 test(name, () {
192 var input = new BuildUnit(name, inputDir, [uri], _moduleForLibrary); 213 var input = new BuildUnit(name, codegenDir, [uri], _moduleForLibrary);
193 var built = compiler.compile(input, options); 214 var built = compiler.compile(input, options);
194 215
195 var outPath = path.join(expectDir, path.withoutExtension(uriPath)); 216 var outPath = path.join(outputDir, path.withoutExtension(uriPath));
196 _writeModule(outPath, built); 217 _writeModule(outPath, built);
197 }); 218 });
198 } 219 }
199 } 220 }
200 221
201 void _buildPackage(ModuleCompiler compiler, String expectDir, packageName) { 222 void _buildPackage(ModuleCompiler compiler, String outputDir, packageName) {
202 var options = new CompilerOptions(sourceMap: false, summarizeApi: false); 223 var options = new CompilerOptions(sourceMap: false, summarizeApi: false);
203 224
204 var packageRoot = path.join(inputDir, 'packages'); 225 var packageRoot = path.join(codegenDir, 'packages');
205 var packageInputDir = path.join(packageRoot, packageName); 226 var packageInputDir = path.join(packageRoot, packageName);
206 var files = new Directory(packageInputDir).listSync(recursive: true); 227 var files = new Directory(packageInputDir).listSync(recursive: true);
207 228
208 var unit = new BuildUnit( 229 var unit = new BuildUnit(
209 packageName, 230 packageName,
210 packageInputDir, 231 packageInputDir,
211 files 232 files
212 .where((entry) => entry.path.endsWith('dart')) 233 .where((entry) => entry.path.endsWith('dart'))
213 .map((entry) => entry.path) 234 .map((entry) => entry.path)
214 .toList(), 235 .toList(),
215 _moduleForLibrary); 236 _moduleForLibrary);
216 var module = compiler.compile(unit, options); 237 var module = compiler.compile(unit, options);
217 238
218 var outPath = path.join(expectDir, packageName, packageName); 239 var outPath = path.join(outputDir, packageName, packageName);
219 _writeModule(outPath, module); 240 _writeModule(outPath, module);
220 } 241 }
221 242
222 String _moduleForLibrary(Source source) { 243 String _moduleForLibrary(Source source) {
223 var scheme = source.uri.scheme; 244 var scheme = source.uri.scheme;
224 if (scheme == 'package') { 245 if (scheme == 'package') {
225 return source.uri.pathSegments.first; 246 return source.uri.pathSegments.first;
226 } 247 }
227 throw new Exception('Module not found for library "${source.fullName}"'); 248 throw new Exception('Module not found for library "${source.fullName}"');
228 } 249 }
229 250
230 /// Expands wacky multitests into a bunch of test files. 251 List<String> _setUpTests(List<String> testDirs, RegExp filePattern) {
231 /// 252 var testFiles = [];
232 /// We'll compile each one as if it was an input.
233 /// NOTE: this will write the individual test files to disk.
234 Set<String> expandMultiTests(List testDirs, RegExp filePattern) {
235 var multitests = new Set<String>();
236 253
237 for (var testDir in testDirs) { 254 for (var testDir in testDirs) {
238 var fullDir = path.join(inputDir, testDir); 255 for (var file in _listFiles(path.join(codegenDir, testDir), filePattern,
239 var testFiles = _findTests(fullDir, filePattern); 256 recursive: true)) {
257 var relativePath = path.relative(file, from: codegenDir);
258 var outputPath = path.join(codegenTestDir, relativePath);
240 259
241 for (var filePath in testFiles) { 260 _ensureDirectory(path.dirname(outputPath));
242 if (filePath.endsWith('_multi.dart')) continue;
243 261
244 var contents = new File(filePath).readAsStringSync(); 262 // Copy it over. We do this even for multitests because import_self_test
245 if (isMultiTest(contents)) { 263 // is a multitest, yet imports its own unexpanded form (!).
246 multitests.add(filePath); 264 new File(file).copySync(outputPath);
247 265
248 var tests = new Map<String, String>(); 266 if (file.endsWith("_test.dart")) {
249 var outcomes = new Map<String, Set<String>>(); 267 var contents = new File(file).readAsStringSync();
250 extractTestsFromMultitest(filePath, contents, tests, outcomes);
251 268
252 var filename = path.basenameWithoutExtension(filePath); 269 if (isMultiTest(contents)) {
253 tests.forEach((name, contents) { 270 // It's a multitest, so expand it and add all of the variants.
254 new File(path.join(fullDir, '${filename}_${name}_multi.dart')) 271 var tests = <String, String>{};
255 .writeAsStringSync(contents); 272 var outcomes = <String, Set<String>>{};
256 }); 273 extractTestsFromMultitest(file, contents, tests, outcomes);
274
275 var fileName = path.basenameWithoutExtension(file);
276 var outputDir = path.dirname(outputPath);
277 tests.forEach((name, contents) {
278 var multiFile =
279 path.join(outputDir, '${fileName}_${name}_multi.dart');
280 testFiles.add(multiFile);
281
282 new File(multiFile).writeAsStringSync(contents);
283 });
284 } else {
285 // It's a single test suite.
286 testFiles.add(outputPath);
287 }
257 } 288 }
258 } 289 }
259 } 290 }
260 return multitests; 291
292 // Also include the other special files that live at the top level directory.
293 for (var file in _listFiles(codegenDir, filePattern)) {
294 var relativePath = path.relative(file, from: codegenDir);
295 var outputPath = path.join(codegenTestDir, relativePath);
296
297 new File(file).copySync(outputPath);
298 if (file.endsWith(".dart")) {
299 testFiles.add(outputPath);
300 }
301 }
302
303 return testFiles;
261 } 304 }
262 305
263 // TODO(jmesserly): switch this to a .packages file. 306 /// Recursively creates [dir] if it doesn't exist.
264 final packageUrlMappings = { 307 void _ensureDirectory(String dir) {
265 'package:expect/expect.dart': path.join(inputDir, 'expect.dart'), 308 new Directory(dir).createSync(recursive: true);
266 'package:async_helper/async_helper.dart': 309 }
267 path.join(inputDir, 'async_helper.dart'),
268 'package:js/js.dart': path.join(inputDir, 'packages', 'js', 'js.dart')
269 };
270 310
271 final codeCoverage = Platform.environment.containsKey('COVERALLS_TOKEN'); 311 /// Lists all of the files within [dir] that match [filePattern].
312 Iterable<String> _listFiles(String dir, RegExp filePattern,
313 {bool recursive: false}) {
314 return new Directory(dir)
315 .listSync(recursive: recursive, followLinks: false)
316 .where((entry) {
317 if (entry is! File) return false;
272 318
273 final inputDir = path.join(testDirectory, 'codegen'); 319 var filePath = entry.path;
320 if (!filePattern.hasMatch(filePath)) return false;
274 321
275 Iterable<String> _findTests(String dir, RegExp filePattern) { 322 return true;
276 var files = new Directory(dir) 323 }).map((file) => file.path);
277 .listSync()
278 .where((f) => f is File)
279 .map((f) => f.path)
280 .where((p) => p.endsWith('.dart') && filePattern.hasMatch(p));
281 if (dir != inputDir) {
282 files = files
283 .where((p) => p.endsWith('_test.dart') || p.endsWith('_multi.dart'));
284 }
285 return files;
286 } 324 }
287 325
288 /// Parse directives from [contents] and find the complete set of transitive 326 /// Parse directives from [contents] and find the complete set of transitive
289 /// imports, reading files as needed. 327 /// imports, reading files as needed.
290 /// 328 ///
291 /// This will not include dart:* libraries, as those are implicitly available. 329 /// This will not include dart:* libraries, as those are implicitly available.
292 void _collectTransitiveImports(String contents, Set<String> libraries, 330 void _collectTransitiveImports(String contents, Set<String> libraries,
293 {String packageRoot, String from}) { 331 {String packageRoot, String from}) {
294 var uri = from; 332 var uri = from;
295 if (packageRoot != null && path.isWithin(packageRoot, from)) { 333 if (packageRoot != null && path.isWithin(packageRoot, from)) {
(...skipping 23 matching lines...) Expand all
319 /// Simplified from ParseDartTask.resolveDirective. 357 /// Simplified from ParseDartTask.resolveDirective.
320 String _resolveDirective(UriBasedDirective directive) { 358 String _resolveDirective(UriBasedDirective directive) {
321 StringLiteral uriLiteral = directive.uri; 359 StringLiteral uriLiteral = directive.uri;
322 String uriContent = uriLiteral.stringValue; 360 String uriContent = uriLiteral.stringValue;
323 if (uriContent != null) { 361 if (uriContent != null) {
324 uriContent = uriContent.trim(); 362 uriContent = uriContent.trim();
325 directive.uriContent = uriContent; 363 directive.uriContent = uriContent;
326 } 364 }
327 return directive.validate() == null ? uriContent : null; 365 return directive.validate() == null ? uriContent : null;
328 } 366 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698