| 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 ${const bool.fromEnvironment('woohoo')} | 
|  | 89 To update the test expectations, rerun this test passing "update" as an | 
|  | 90 argument, as follows: | 
|  | 91 | 
|  | 92   dart $flags${Platform.script} update | 
|  | 93 | 
|  | 94 To update more than one test at once, run: | 
|  | 95   dart $flags${Platform.script.resolve('update_all.dart')} | 
|  | 96 | 
|  | 97 '''; | 
|  | 98 } | 
|  | 99 | 
|  | 100 const String TEST_MAIN_FILE = 'test.dart'; | 
|  | 101 | 
|  | 102 String _formatTest(Map test) { | 
|  | 103   return test[TEST_MAIN_FILE]; | 
|  | 104 } | 
|  | 105 | 
|  | 106 String _getCodeForMain(CompilerImpl compiler) { | 
|  | 107   Element mainFunction = compiler.mainFunction; | 
|  | 108   js.Node ast = compiler.enqueuer.codegen.generatedCode[mainFunction]; | 
|  | 109   return js.prettyPrint(ast, compiler).getText(); | 
|  | 110 } | 
|  | 111 | 
|  | 112 String _getCodeForMethod(CompilerImpl compiler, | 
|  | 113                         String name) { | 
|  | 114   Element foundElement; | 
|  | 115   for (Element element in compiler.enqueuer.codegen.generatedCode.keys) { | 
|  | 116     if (element.toString() == name) { | 
|  | 117       if (foundElement != null) { | 
|  | 118         Expect.fail('Multiple compiled elements are called $name'); | 
|  | 119       } | 
|  | 120       foundElement = element; | 
|  | 121     } | 
|  | 122   } | 
|  | 123 | 
|  | 124   if (foundElement == null) { | 
|  | 125     Expect.fail('There is no compiled element called $name'); | 
|  | 126   } | 
|  | 127 | 
|  | 128   js.Node ast = compiler.enqueuer.codegen.generatedCode[foundElement]; | 
|  | 129   return js.prettyPrint(ast, compiler).getText(); | 
|  | 130 } | 
| OLD | NEW | 
|---|