| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 // Test that the CPS IR code generator compiles programs and produces the |
| 6 // the expected output. |
| 7 |
| 8 import 'dart:io'; |
| 9 |
| 10 import 'package:async_helper/async_helper.dart'; |
| 11 import 'package:expect/expect.dart'; |
| 12 import 'package:compiler/src/apiimpl.dart' show |
| 13 CompilerImpl; |
| 14 import '../memory_compiler.dart'; |
| 15 import 'package:compiler/src/js/js.dart' as js; |
| 16 import 'package:compiler/src/elements/elements.dart' show |
| 17 ClassElement, |
| 18 Element; |
| 19 |
| 20 // Regular experession used to extract the method name that is used to match the |
| 21 // test output. By default we match the output of main. |
| 22 final RegExp elementNameRegExp = new RegExp(r'^// Method to test: (.*)$', |
| 23 multiLine: true); |
| 24 |
| 25 runTest(String filename, {bool update: false}) { |
| 26 var outputname = filename.replaceFirst('.dart', '.js'); |
| 27 String source = new File.fromUri(Platform.script.resolve('input/$filename')) |
| 28 .readAsStringSync(); |
| 29 var expectedFile = |
| 30 new File.fromUri(Platform.script.resolve('expected/$outputname')); |
| 31 String expected = expectedFile.existsSync() |
| 32 ? expectedFile.readAsStringSync() : ''; |
| 33 var match = elementNameRegExp.firstMatch(source); |
| 34 var elementName = match?.group(1); |
| 35 |
| 36 Map files = {TEST_MAIN_FILE: source}; |
| 37 asyncTest(() async { |
| 38 Uri uri = Uri.parse('memory:$TEST_MAIN_FILE'); |
| 39 String found = null; |
| 40 try { |
| 41 CompilationResult result = await runCompiler( |
| 42 entryPoint: uri, |
| 43 memorySourceFiles: files, |
| 44 options: <String>['--use-cps-ir']); |
| 45 Expect.isTrue(result.isSuccess); |
| 46 CompilerImpl compiler = result.compiler; |
| 47 if (expected != null) { |
| 48 String output = elementName == null |
| 49 ? _getCodeForMain(compiler) |
| 50 : _getCodeForMethod(compiler, elementName); |
| 51 // Include the input in a comment of the expected file to make it easier |
| 52 // to see the relation between input and output in code reviews. |
| 53 found = '// Expectation for test: \n' |
| 54 '// ${source.trim().replaceAll('\n', '\n// ')}\n\n' |
| 55 '$output\n'; |
| 56 } |
| 57 } catch (e, st) { |
| 58 print(e); |
| 59 print(st); |
| 60 var message = 'The following test failed to compile:\n' |
| 61 '${_formatTest(files)}'; |
| 62 if (update) { |
| 63 print('\n\n$message\n'); |
| 64 return; |
| 65 } else { |
| 66 Expect.fail(message); |
| 67 } |
| 68 } |
| 69 if (expected != found) { |
| 70 if (update) { |
| 71 expectedFile.writeAsStringSync(found); |
| 72 print('INFO: $expectedFile was updated'); |
| 73 } else { |
| 74 Expect.fail('Unexpected output for test:\n ' |
| 75 '${_formatTest(files).replaceAll('\n', '\n ')}\n' |
| 76 'Expected:\n ${expected.replaceAll('\n', '\n ')}\n' |
| 77 'but found:\n ${found?.replaceAll('\n', '\n ')}\n' |
| 78 '$regenerateCommand'); |
| 79 } |
| 80 } |
| 81 }); |
| 82 } |
| 83 |
| 84 String get regenerateCommand { |
| 85 var flags = Platform.packageRoot == null |
| 86 ? '' : '--package-root=${Platform.packageRoot} '; |
| 87 return ''' |
| 88 If you wish to update the test expectations, rerun this test passing "update" as |
| 89 an argument, as follows: |
| 90 |
| 91 dart $flags${Platform.script} update |
| 92 |
| 93 If you want to update more than one test at once, run: |
| 94 dart $flags${Platform.script.resolve('update_all.dart')} |
| 95 |
| 96 '''; |
| 97 } |
| 98 |
| 99 const String TEST_MAIN_FILE = 'test.dart'; |
| 100 |
| 101 String _formatTest(Map test) { |
| 102 return test[TEST_MAIN_FILE]; |
| 103 } |
| 104 |
| 105 String _getCodeForMain(CompilerImpl compiler) { |
| 106 Element mainFunction = compiler.mainFunction; |
| 107 js.Node ast = compiler.enqueuer.codegen.generatedCode[mainFunction]; |
| 108 return js.prettyPrint(ast, compiler).getText(); |
| 109 } |
| 110 |
| 111 String _getCodeForMethod(CompilerImpl compiler, |
| 112 String name) { |
| 113 Element foundElement; |
| 114 for (Element element in compiler.enqueuer.codegen.generatedCode.keys) { |
| 115 if (element.toString() == name) { |
| 116 if (foundElement != null) { |
| 117 Expect.fail('Multiple compiled elements are called $name'); |
| 118 } |
| 119 foundElement = element; |
| 120 } |
| 121 } |
| 122 |
| 123 if (foundElement == null) { |
| 124 Expect.fail('There is no compiled element called $name'); |
| 125 } |
| 126 |
| 127 js.Node ast = compiler.enqueuer.codegen.generatedCode[foundElement]; |
| 128 return js.prettyPrint(ast, compiler).getText(); |
| 129 } |
| OLD | NEW |