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'; |
11 import 'package:analyzer/src/generated/engine.dart' | 11 import 'package:analyzer/src/generated/engine.dart' |
12 show AnalysisContext, AnalysisEngine, Logger; | 12 show AnalysisContext, AnalysisEngine, Logger; |
13 import 'package:analyzer/src/generated/java_engine.dart' show CaughtException; | 13 import 'package:analyzer/src/generated/java_engine.dart' show CaughtException; |
14 import 'package:args/args.dart'; | 14 import 'package:args/args.dart'; |
15 import 'package:logging/logging.dart' show Level; | 15 import 'package:logging/logging.dart' show Level; |
16 import 'package:path/path.dart' as path; | 16 import 'package:path/path.dart' as path; |
17 import 'package:test/test.dart'; | 17 import 'package:test/test.dart'; |
18 | 18 |
19 import 'package:dev_compiler/devc.dart'; | 19 import 'package:dev_compiler/devc.dart'; |
20 import 'package:dev_compiler/strong_mode.dart'; | 20 import 'package:dev_compiler/strong_mode.dart'; |
21 import 'package:dev_compiler/src/compiler.dart' show defaultRuntimeFiles; | 21 import 'package:dev_compiler/src/compiler.dart' show defaultRuntimeFiles; |
22 import 'package:dev_compiler/src/options.dart'; | 22 import 'package:dev_compiler/src/options.dart'; |
23 | 23 |
24 import 'testing.dart' show realSdkContext, testDirectory; | 24 import 'testing.dart' show realSdkContext, testDirectory; |
| 25 import 'multitest.dart'; |
25 | 26 |
26 final ArgParser argParser = new ArgParser() | 27 final ArgParser argParser = new ArgParser() |
27 ..addOption('dart-sdk', help: 'Dart SDK Path', defaultsTo: null); | 28 ..addOption('dart-sdk', help: 'Dart SDK Path', defaultsTo: null); |
28 | 29 |
| 30 Iterable<String> _findTests(String dir, RegExp filePattern) { |
| 31 return new Directory(dir) |
| 32 .listSync() |
| 33 .where((f) => f is File) |
| 34 .map((f) => f.path) |
| 35 .where((p) => p.endsWith('.dart') && filePattern.hasMatch(p)); |
| 36 } |
| 37 |
29 main(arguments) { | 38 main(arguments) { |
30 if (arguments == null) arguments = []; | 39 if (arguments == null) arguments = []; |
31 ArgResults args = argParser.parse(arguments); | 40 ArgResults args = argParser.parse(arguments); |
32 var filePattern = new RegExp(args.rest.length > 0 ? args.rest[0] : '.'); | 41 var filePattern = new RegExp(args.rest.length > 0 ? args.rest[0] : '.'); |
33 var compilerMessages = new StringBuffer(); | 42 var compilerMessages = new StringBuffer(); |
34 var loggerSub; | 43 var loggerSub; |
35 | 44 |
36 setUp(() { | 45 setUp(() { |
37 compilerMessages.clear(); | 46 compilerMessages.clear(); |
38 loggerSub = setupLogger(Level.CONFIG, compilerMessages.writeln); | 47 loggerSub = setupLogger(Level.CONFIG, compilerMessages.writeln); |
(...skipping 29 matching lines...) Expand all Loading... |
68 } | 77 } |
69 | 78 |
70 // Remove old output, and `packages` symlinks which mess up the diff. | 79 // Remove old output, and `packages` symlinks which mess up the diff. |
71 var dir = new Directory(expectDir); | 80 var dir = new Directory(expectDir); |
72 if (dir.existsSync()) dir.deleteSync(recursive: true); | 81 if (dir.existsSync()) dir.deleteSync(recursive: true); |
73 var packagesDirs = new Directory(inputDir) | 82 var packagesDirs = new Directory(inputDir) |
74 .listSync(recursive: true) | 83 .listSync(recursive: true) |
75 .where((d) => d is Directory && path.basename(d.path) == 'packages'); | 84 .where((d) => d is Directory && path.basename(d.path) == 'packages'); |
76 packagesDirs.forEach((d) => d.deleteSync()); | 85 packagesDirs.forEach((d) => d.deleteSync()); |
77 | 86 |
| 87 { |
| 88 // Expand wacky multitests into a bunch of test files. |
| 89 // We'll compile each one as if it was an input. |
| 90 var languageDir = path.join(inputDir, 'language'); |
| 91 var testFiles = _findTests(languageDir, filePattern); |
| 92 |
| 93 for (var filePath in testFiles) { |
| 94 if (filePath.endsWith('_multi.dart')) continue; |
| 95 |
| 96 var contents = new File(filePath).readAsStringSync(); |
| 97 if (isMultiTest(contents)) { |
| 98 var tests = new Map<String, String>(); |
| 99 var outcomes = new Map<String, Set<String>>(); |
| 100 extractTestsFromMultitest(filePath, contents, tests, outcomes); |
| 101 |
| 102 // For now skip all tests that aren't `ok` or `runtime error` |
| 103 outcomes.forEach((name, Set<String> outcomes) { |
| 104 // TODO(jmesserly): unfortunately we can't communicate this status |
| 105 // to the test runner, so if an error is expected, it's encoded in |
| 106 // language-tests.js. We should probably encode expected error in the |
| 107 // name, and then have our runner just load all multi tests it finds, |
| 108 // using the file name to expect either success or failure. |
| 109 outcomes.remove('ok'); |
| 110 outcomes.remove('runtime error'); |
| 111 if (outcomes.isNotEmpty) { |
| 112 // Skip all other outcomes. |
| 113 // |
| 114 // They are handled by analyzer/static type system, and |
| 115 // therefore are not interesting to run. |
| 116 tests.remove(name); |
| 117 } |
| 118 }); |
| 119 |
| 120 var filename = path.basenameWithoutExtension(filePath); |
| 121 tests.forEach((name, contents) { |
| 122 new File(path.join(languageDir, '${filename}_${name}_multi.dart')) |
| 123 .writeAsStringSync(contents); |
| 124 }); |
| 125 } |
| 126 } |
| 127 } |
| 128 |
78 for (var dir in [null, 'language']) { | 129 for (var dir in [null, 'language']) { |
79 group('dartdevc ' + path.join('test', 'codegen', dir), () { | 130 group('dartdevc ' + path.join('test', 'codegen', dir), () { |
80 var testFiles = new Directory(path.join(inputDir, dir)) | 131 var outDir = path.join(expectDir, dir); |
81 .listSync() | |
82 .where((f) => f is File) | |
83 .map((f) => f.path) | |
84 .where((p) => p.endsWith('.dart') && filePattern.hasMatch(p)); | |
85 | 132 |
| 133 var testFiles = _findTests(path.join(inputDir, dir), filePattern); |
86 for (var filePath in testFiles) { | 134 for (var filePath in testFiles) { |
87 var filename = path.basenameWithoutExtension(filePath); | 135 var filename = path.basenameWithoutExtension(filePath); |
88 | 136 |
89 test('$filename.dart', () { | 137 test('$filename.dart', () { |
90 compilerMessages.writeln('// Messages from compiling $filename.dart'); | 138 compilerMessages.writeln('// Messages from compiling $filename.dart'); |
91 | 139 |
92 // TODO(jmesserly): this was added to get some coverage of source maps | 140 // TODO(jmesserly): this was added to get some coverage of source maps |
93 // We need a more comprehensive strategy to test them. | 141 // We need a more comprehensive strategy to test them. |
94 var sourceMaps = filename == 'map_keys'; | 142 var sourceMaps = filename == 'map_keys'; |
95 var success = | 143 var success = |
96 compile(filePath, realSdkContext, sourceMaps: sourceMaps); | 144 compile(filePath, realSdkContext, sourceMaps: sourceMaps); |
97 | 145 |
98 // Write compiler messages to disk. | 146 // Write compiler messages to disk. |
99 var outDir = path.join(expectDir, dir); | |
100 new File(path.join(outDir, '$filename.txt')) | 147 new File(path.join(outDir, '$filename.txt')) |
101 .writeAsStringSync(compilerMessages.toString()); | 148 .writeAsStringSync('$compilerMessages'); |
102 | 149 |
103 var outFile = new File(path.join(outDir, '$filename.js')); | 150 var outFile = new File(path.join(outDir, '$filename.js')); |
104 expect(outFile.existsSync(), success, | 151 expect(outFile.existsSync(), success, |
105 reason: '${outFile.path} was created iff compilation succeeds'); | 152 reason: '${outFile.path} was created iff compilation succeeds'); |
106 | |
107 // TODO(jmesserly): ideally we'd diff the output here. For now it | |
108 // happens in the containing shell script. | |
109 }); | 153 }); |
110 } | 154 } |
111 }); | 155 }); |
112 } | 156 } |
113 | 157 |
114 if (Platform.environment.containsKey('COVERALLS_TOKEN')) { | 158 if (Platform.environment.containsKey('COVERALLS_TOKEN')) { |
115 group('sdk', () { | 159 group('sdk', () { |
116 // The analyzer does not bubble exception messages for certain internal | 160 // The analyzer does not bubble exception messages for certain internal |
117 // dart:* library failures, such as failing to find | 161 // dart:* library failures, such as failing to find |
118 // "_internal/libraries.dart". Instead it produces an opaque "failed to | 162 // "_internal/libraries.dart". Instead it produces an opaque "failed to |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 print('[AnalysisEngine] error $message $exception'); | 243 print('[AnalysisEngine] error $message $exception'); |
200 } | 244 } |
201 | 245 |
202 @override void logError2(String message, Object exception) { | 246 @override void logError2(String message, Object exception) { |
203 print('[AnalysisEngine] error $message $exception'); | 247 print('[AnalysisEngine] error $message $exception'); |
204 } | 248 } |
205 | 249 |
206 void logInformation(String message, [CaughtException exception]) {} | 250 void logInformation(String message, [CaughtException exception]) {} |
207 void logInformation2(String message, Object exception) {} | 251 void logInformation2(String message, Object exception) {} |
208 } | 252 } |
OLD | NEW |