| OLD | NEW |
| 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.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
| 4 | 4 |
| 5 library rasta.dart2js_test; | 5 library rasta.dart2js_test; |
| 6 | 6 |
| 7 import 'dart:async' show | 7 import 'dart:async' show |
| 8 Future, | 8 Future, |
| 9 Stream; | 9 Stream; |
| 10 | 10 |
| 11 import 'dart:io' show | 11 import 'dart:io' show |
| 12 File, | 12 File, |
| 13 IOSink, | 13 IOSink, |
| 14 Platform, | 14 Platform, |
| 15 Process, | 15 Process, |
| 16 stderr; | 16 stderr; |
| 17 | 17 |
| 18 import 'package:kernel/text/ast_to_text.dart' show | 18 import 'package:kernel/text/ast_to_text.dart' show |
| 19 Printer; | 19 Printer; |
| 20 | 20 |
| 21 import 'package:kernel/ast.dart' as ir; | 21 import 'package:kernel/ast.dart' as ir; |
| 22 | 22 |
| 23 import 'package:rasta/testing.dart' show | 23 import 'package:rasta/testing.dart' show |
| 24 TestDescription, | 24 TestDescription, |
| 25 dartSdk, | 25 dartSdk, |
| 26 listTests, | 26 listTests, |
| 27 startDart; | 27 startDart; |
| 28 | 28 |
| 29 import 'package:rasta/src/rastask.dart' show | 29 import 'package:rasta/src/rastask.dart' show |
| 30 Rastask, |
| 30 openWrite; | 31 openWrite; |
| 31 | 32 |
| 32 import '../../bin/rastak.dart' as rastak show main; | 33 import 'package:rasta/src/options.dart' show |
| 34 Options; |
| 33 | 35 |
| 34 const bool generateExpectations = | 36 const bool generateExpectations = |
| 35 const bool.fromEnvironment("generateExpectations"); | 37 const bool.fromEnvironment("generateExpectations"); |
| 36 | 38 |
| 37 Future<Null> addRegressions(Map<Uri, Uri> tests, Uri temp) async { | 39 Future<Null> addRegressions(Map<Uri, Uri> tests, Uri temp) async { |
| 38 Stream<TestDescription> regressions = listTests( | 40 Stream<TestDescription> regressions = listTests( |
| 39 <Uri>[Uri.base.resolve("test/kernel/regression/")], pattern: ".dart"); | 41 <Uri>[Uri.base.resolve("test/kernel/regression/")], pattern: ".dart"); |
| 40 await for (TestDescription regression in regressions) { | 42 await for (TestDescription regression in regressions) { |
| 41 tests[regression.uri] = temp.resolve("${regression.shortName}.bart"); | 43 tests[regression.uri] = temp.resolve("${regression.shortName}.bart"); |
| 42 } | 44 } |
| 43 } | 45 } |
| 44 | 46 |
| 45 Future<Null> main() async { | 47 Future<Null> main() async { |
| 48 Stopwatch wallClock = new Stopwatch()..start(); |
| 49 Rastask task = await Rastask.create( |
| 50 wallClock, <String>["--library", "${Platform.script}"]); |
| 51 await task.measureSubtask("runTests", () => runTests(task)); |
| 52 } |
| 53 |
| 54 Future<Null> runTests(Rastask task) async { |
| 55 await task.setup(); |
| 56 |
| 46 // When running via `testa.dart`, [Platform.script] is located in a temporary | 57 // When running via `testa.dart`, [Platform.script] is located in a temporary |
| 47 // directory. | 58 // directory. |
| 48 Uri temp = Platform.script; | 59 Uri temp = Platform.script; |
| 49 Map<Uri, Uri> tests = <Uri, Uri>{ | 60 Map<Uri, Uri> tests = <Uri, Uri>{ |
| 50 Uri.parse("dart:core"): temp.resolve("core.bart"), | 61 Uri.parse("dart:core"): temp.resolve("core.bart"), |
| 51 | 62 |
| 52 Uri.parse("package:compiler/src/dart2js.dart"): | 63 Uri.parse("package:compiler/src/dart2js.dart"): |
| 53 temp.resolve("dart2js.bart"), | 64 temp.resolve("dart2js.bart"), |
| 54 }; | 65 }; |
| 55 | 66 |
| 56 await addRegressions(tests, temp); | 67 await addRegressions(tests, temp); |
| 57 | 68 |
| 58 List<Uri> generated = <Uri>[]; | 69 List<Uri> generated = <Uri>[]; |
| 59 Map<Uri, Uri> mismatches = <Uri, Uri>{}; | 70 Map<Uri, Uri> mismatches = <Uri, Uri>{}; |
| 60 | 71 |
| 61 for (Uri source in tests.keys) { | 72 for (Uri source in tests.keys) { |
| 73 bool isRegression = source.path.contains("/regression/"); |
| 74 |
| 62 print("Rastarizing $source"); | 75 print("Rastarizing $source"); |
| 63 Uri bart = tests[source]; | 76 Uri bart = tests[source]; |
| 64 File output = new File.fromUri(bart); | 77 File output = new File.fromUri(bart); |
| 65 await output.parent.create(recursive: true); | 78 await output.parent.create(recursive: true); |
| 66 ir.TreeNode node = await rastak.main(<String>["$source", "$bart"], null); | |
| 67 | 79 |
| 68 await checkAgainstExpectations(node, generated, mismatches); | 80 Options options = new Options( |
| 81 source, bart, dependenciesFile: null, |
| 82 generateLibrary: isRegression ? isRegression : null, |
| 83 isVerbose: true, isBatch: false, pattern: null); |
| 69 | 84 |
| 70 Uri textOutput = bart.resolve("${bart.path}.txt"); | 85 ir.TreeNode node = await task.runOne(options); |
| 71 print("Kernelizing $bart to $textOutput"); | 86 |
| 72 Process process = await startDart( | 87 if (isRegression) { |
| 73 Uri.base.resolve("third_party/kernel/bin/dartk.dart"), | 88 await checkAgainstExpectations(node, generated, mismatches); |
| 74 <String>["--sdk=${dartSdk.toFilePath()}", "${bart.toFilePath()}"], | 89 } else { |
| 75 const <String>[]); | 90 await runDartk(bart); |
| 76 process.stdin.close(); | |
| 77 Future stdoutFuture = | |
| 78 process.stdout.pipe(new File.fromUri(textOutput).openWrite()); | |
| 79 Future stderrFuture = | |
| 80 process.stderr.listen((data) => stderr.add(data)).asFuture(); | |
| 81 int exitCode = await process.exitCode; | |
| 82 await stdoutFuture; | |
| 83 await stderrFuture; | |
| 84 if (exitCode != 0) { | |
| 85 throw "non-zero exit code ($exitCode) from rastak"; | |
| 86 } | 91 } |
| 87 } | 92 } |
| 88 if (generated.isNotEmpty) { | 93 if (generated.isNotEmpty) { |
| 89 throw "The following files were generated, " | 94 throw "The following files were generated, " |
| 90 "please check them and re-run this test: ${generated}"; | 95 "please check them and re-run this test: ${generated}"; |
| 91 } | 96 } |
| 92 if (mismatches.isNotEmpty) { | 97 if (mismatches.isNotEmpty) { |
| 93 StringBuffer sb = new StringBuffer(); | 98 StringBuffer sb = new StringBuffer(); |
| 94 mismatches.forEach((Uri test, Uri expectation) { | 99 mismatches.forEach((Uri test, Uri expectation) { |
| 95 sb.writeln("Output from '$test' doesn't match '$expectation'."); | 100 sb.writeln("Output from '$test' doesn't match '$expectation'."); |
| 96 }); | 101 }); |
| 97 throw "$sb"; | 102 throw "$sb"; |
| 98 } | 103 } |
| 99 } | 104 } |
| 100 | 105 |
| 101 Future<Null> checkAgainstExpectations( | 106 Future<Null> checkAgainstExpectations( |
| 102 ir.Node node, | 107 ir.Node node, |
| 103 List<Uri> generated, | 108 List<Uri> generated, |
| 104 Map<Uri, Uri> mismatches) async { | 109 Map<Uri, Uri> mismatches) async { |
| 105 ir.Library library = (node is ir.Program) ? node.mainMethod.parent : node; | 110 ir.Library library = (node is ir.Program) ? node.mainMethod.parent : node; |
| 106 Uri uri = library.importUri; | 111 Uri uri = library.importUri; |
| 107 | 112 |
| 108 // We only validate output of the small tests fully under our control. | |
| 109 if (!uri.path.contains("/regression/")) return; | |
| 110 | |
| 111 StringBuffer buffer = new StringBuffer(); | 113 StringBuffer buffer = new StringBuffer(); |
| 112 new Printer(buffer).writeLibraryFile(library); | 114 new Printer(buffer).writeLibraryFile(library); |
| 113 File expectedFile = new File("${uri.toFilePath()}.txt"); | 115 File expectedFile = new File("${uri.toFilePath()}.txt"); |
| 114 if (await expectedFile.exists()) { | 116 if (await expectedFile.exists()) { |
| 115 String expected = await expectedFile.readAsString(); | 117 String expected = await expectedFile.readAsString(); |
| 116 if (expected.trim() != "$buffer".trim()) { | 118 if (expected.trim() != "$buffer".trim()) { |
| 117 print("$uri doesn't match ${expectedFile.uri}"); | 119 print("$uri doesn't match ${expectedFile.uri}"); |
| 118 mismatches[uri] = expectedFile.uri; | 120 mismatches[uri] = expectedFile.uri; |
| 119 } | 121 } |
| 120 } else if (generateExpectations) { | 122 } else if (generateExpectations) { |
| 121 await openWrite(expectedFile.uri, (IOSink sink) { | 123 await openWrite(expectedFile.uri, (IOSink sink) { |
| 122 sink.write("$buffer".trim()); | 124 sink.write("$buffer".trim()); |
| 123 }); | 125 }); |
| 124 generated.add(expectedFile.uri); | 126 generated.add(expectedFile.uri); |
| 125 } else { | 127 } else { |
| 126 throw """ | 128 throw """ |
| 127 Please create file ${expectedFile.path} with this content: | 129 Please create file ${expectedFile.path} with this content: |
| 128 $buffer"""; | 130 $buffer"""; |
| 129 } | 131 } |
| 130 } | 132 } |
| 133 |
| 134 Future<Null> runDartk(Uri uri) async { |
| 135 Uri textOutput = uri.resolve("${uri.path}.txt"); |
| 136 print("Kernelizing $uri to $textOutput"); |
| 137 Process process = await startDart( |
| 138 Uri.base.resolve("third_party/kernel/bin/dartk.dart"), |
| 139 <String>["--sdk=${dartSdk.toFilePath()}", "${uri.toFilePath()}"], |
| 140 const <String>[]); |
| 141 process.stdin.close(); |
| 142 Future stdoutFuture = |
| 143 process.stdout.pipe(new File.fromUri(textOutput).openWrite()); |
| 144 Future stderrFuture = |
| 145 process.stderr.listen((data) => stderr.add(data)).asFuture(); |
| 146 int exitCode = await process.exitCode; |
| 147 await stdoutFuture; |
| 148 await stderrFuture; |
| 149 if (exitCode != 0) { |
| 150 throw "non-zero exit code ($exitCode) from dartk"; |
| 151 } |
| 152 } |
| OLD | NEW |