OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 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. |
| 4 |
| 5 // Test the exit code of dart2js in case of exceptions, fatal errors, errors, |
| 6 // warnings, etc. |
| 7 |
| 8 |
| 9 import 'dart:async'; |
| 10 import 'dart:io' show Platform; |
| 11 |
| 12 import 'package:async_helper/async_helper.dart'; |
| 13 import 'package:expect/expect.dart'; |
| 14 |
| 15 import '../../../sdk/lib/_internal/compiler/compiler.dart' as api; |
| 16 import '../../../sdk/lib/_internal/compiler/implementation/dart2js.dart' as entr
y; |
| 17 import '../../../sdk/lib/_internal/compiler/implementation/dart2jslib.dart'; |
| 18 import '../../../sdk/lib/_internal/compiler/implementation/apiimpl.dart' as apii
mpl; |
| 19 import '../../../sdk/lib/_internal/compiler/implementation/elements/elements.dar
t'; |
| 20 import '../../../sdk/lib/_internal/compiler/implementation/scanner/scannerlib.da
rt'; |
| 21 import '../../../sdk/lib/_internal/compiler/implementation/util/util.dart'; |
| 22 |
| 23 class TestCompiler extends apiimpl.Compiler { |
| 24 final String testMarker; |
| 25 final String testType; |
| 26 final Function onTest; |
| 27 |
| 28 TestCompiler(api.CompilerInputProvider inputProvider, |
| 29 api.CompilerOutputProvider outputProvider, |
| 30 api.DiagnosticHandler handler, |
| 31 Uri libraryRoot, |
| 32 Uri packageRoot, |
| 33 List<String> options, |
| 34 Map<String, dynamic> environment, |
| 35 String this.testMarker, |
| 36 String this.testType, |
| 37 Function this.onTest) |
| 38 : super(inputProvider, outputProvider, handler, libraryRoot, |
| 39 packageRoot, options, environment) { |
| 40 scanner = new TestScanner(this); |
| 41 test('Compiler'); |
| 42 } |
| 43 |
| 44 Future<bool> run(Uri uri) { |
| 45 test('Compiler.run'); |
| 46 return super.run(uri); |
| 47 } |
| 48 |
| 49 TreeElements analyzeElement(Element element) { |
| 50 test('Compiler.analyzeElement'); |
| 51 return super.analyzeElement(element); |
| 52 } |
| 53 |
| 54 void codegen(CodegenWorkItem work, CodegenEnqueuer world) { |
| 55 test('Compiler.codegen'); |
| 56 super.codegen(work, world); |
| 57 } |
| 58 |
| 59 withCurrentElement(Element element, f()) { |
| 60 return super.withCurrentElement(element, () { |
| 61 test('Compiler.withCurrentElement'); |
| 62 return f(); |
| 63 }); |
| 64 } |
| 65 |
| 66 test(String marker) { |
| 67 if (marker == testMarker) { |
| 68 switch (testType) { |
| 69 case 'assert': |
| 70 onTest(testMarker, testType); |
| 71 assert(false); |
| 72 break; |
| 73 case 'invariant': |
| 74 onTest(testMarker, testType); |
| 75 invariant(CURRENT_ELEMENT_SPANNABLE, false, message: marker); |
| 76 break; |
| 77 case 'warning': |
| 78 onTest(testMarker, testType); |
| 79 reportWarningCode(CURRENT_ELEMENT_SPANNABLE, |
| 80 MessageKind.GENERIC, {'text': marker}); |
| 81 break; |
| 82 case 'error': |
| 83 onTest(testMarker, testType); |
| 84 reportError(CURRENT_ELEMENT_SPANNABLE, |
| 85 MessageKind.GENERIC, {'text': marker}); |
| 86 break; |
| 87 case 'fatalError': |
| 88 onTest(testMarker, testType); |
| 89 reportFatalError(CURRENT_ELEMENT_SPANNABLE, |
| 90 MessageKind.GENERIC, {'text': marker}); |
| 91 break; |
| 92 case 'NoSuchMethodError': |
| 93 onTest(testMarker, testType); |
| 94 null.foo; |
| 95 break; |
| 96 case '': |
| 97 onTest(testMarker, testType); |
| 98 break; |
| 99 } |
| 100 } |
| 101 } |
| 102 } |
| 103 |
| 104 class TestScanner extends ScannerTask { |
| 105 TestScanner(TestCompiler compiler) : super(compiler); |
| 106 |
| 107 TestCompiler get compiler => super.compiler; |
| 108 |
| 109 void scanElements(CompilationUnitElement compilationUnit) { |
| 110 compiler.test('ScannerTask.scanElements'); |
| 111 super.scanElements(compilationUnit); |
| 112 } |
| 113 } |
| 114 |
| 115 int checkedResults = 0; |
| 116 |
| 117 Future testExitCode(String marker, String type, int expectedExitCode) { |
| 118 bool testOccurred = false; |
| 119 |
| 120 void onTest(String testMarker, String testType) { |
| 121 if (testMarker == marker && testType == type) { |
| 122 testOccurred = true; |
| 123 } |
| 124 } |
| 125 return new Future(() { |
| 126 Future<String> compile(Uri script, |
| 127 Uri libraryRoot, |
| 128 Uri packageRoot, |
| 129 api.CompilerInputProvider inputProvider, |
| 130 api.DiagnosticHandler handler, |
| 131 [List<String> options = const [], |
| 132 api.CompilerOutputProvider outputProvider, |
| 133 Map<String, dynamic> environment = const {}]) { |
| 134 libraryRoot = Platform.script.resolve('../../../sdk/'); |
| 135 outputProvider = NullSink.outputProvider; |
| 136 handler = (uri, begin, end, message, kind) {}; |
| 137 Compiler compiler = new TestCompiler(inputProvider, |
| 138 outputProvider, |
| 139 handler, |
| 140 libraryRoot, |
| 141 packageRoot, |
| 142 options, |
| 143 environment, |
| 144 marker, |
| 145 type, |
| 146 onTest); |
| 147 return compiler.run(script).then((_) { |
| 148 String code = compiler.assembledCode; |
| 149 if (code != null && outputProvider != null) { |
| 150 String outputType = 'js'; |
| 151 if (options.contains('--output-type=dart')) { |
| 152 outputType = 'dart'; |
| 153 } |
| 154 outputProvider('', outputType) |
| 155 ..add(code) |
| 156 ..close(); |
| 157 code = ''; // Non-null signals success. |
| 158 } |
| 159 return code; |
| 160 }); |
| 161 } |
| 162 |
| 163 int foundExitCode; |
| 164 |
| 165 checkResult() { |
| 166 Expect.isTrue(testOccurred, 'testExitCode($marker, $type) did not occur'); |
| 167 if (foundExitCode == null) foundExitCode = 0; |
| 168 print('testExitCode($marker, $type) ' |
| 169 'exitCode=$foundExitCode expected=$expectedExitCode'); |
| 170 Expect.equals(expectedExitCode, foundExitCode, |
| 171 'testExitCode($marker, $type) ' |
| 172 'exitCode=$foundExitCode expected=${expectedExitCode}'); |
| 173 checkedResults++; |
| 174 } |
| 175 |
| 176 void exit(exitCode) { |
| 177 if (foundExitCode == null) { |
| 178 foundExitCode = exitCode; |
| 179 } |
| 180 }; |
| 181 |
| 182 entry.exitFunc = exit; |
| 183 entry.compileFunc = compile; |
| 184 |
| 185 Future result = entry.internalMain( |
| 186 ["tests/compiler/dart2js/exit_code_helper.dart"]); |
| 187 return result.whenComplete(checkResult); |
| 188 }); |
| 189 } |
| 190 |
| 191 Future testExitCodes(String marker, Map<String,int> expectedExitCodes) { |
| 192 return Future.forEach(expectedExitCodes.keys, (String type) { |
| 193 return testExitCode(marker, type, expectedExitCodes[type]); |
| 194 }); |
| 195 } |
| 196 |
| 197 void main() { |
| 198 const beforeRun = const { |
| 199 '': 0, |
| 200 'NoSuchMethodError': 253, |
| 201 'assert': 253, |
| 202 'invariant': 253 |
| 203 }; |
| 204 |
| 205 const duringRun = const { |
| 206 '': 0, |
| 207 'NoSuchMethodError': 253, |
| 208 'assert': 253, |
| 209 'invariant': 253, |
| 210 'warning': 0, |
| 211 'error': 1, |
| 212 'fatalError': 1, |
| 213 }; |
| 214 |
| 215 const tests = const { |
| 216 'Compiler': beforeRun, |
| 217 'Compiler.run': beforeRun, |
| 218 'ScannerTask.scanElements': duringRun, |
| 219 'Compiler.withCurrentElement': duringRun, |
| 220 'Compiler.analyzeElement': duringRun, |
| 221 'Compiler.codegen': duringRun, |
| 222 }; |
| 223 |
| 224 asyncStart(); |
| 225 Future.forEach(tests.keys, (marker) { |
| 226 return testExitCodes(marker, tests[marker]); |
| 227 }).then((_) { |
| 228 Expect.equals(beforeRun.length * 2 + duringRun.length * 4, |
| 229 checkedResults); |
| 230 asyncEnd(); |
| 231 }); |
| 232 } |
OLD | NEW |