| 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 import 'dart:async'; | 5 import 'dart:async'; |
| 6 import 'package:async_helper/async_helper.dart'; | 6 import 'package:async_helper/async_helper.dart'; |
| 7 import 'package:expect/expect.dart'; | 7 import 'package:expect/expect.dart'; |
| 8 import 'sourcemap_helper.dart'; | 8 import 'sourcemap_helper.dart'; |
| 9 import 'sourcemap_html_helper.dart'; | |
| 10 import 'package:compiler/src/filenames.dart'; | |
| 11 | 9 |
| 12 main(List<String> arguments) { | 10 main(List<String> arguments) { |
| 13 bool showAll = false; | |
| 14 bool measure = false; | |
| 15 Uri outputUri; | |
| 16 Set<String> configurations = new Set<String>(); | 11 Set<String> configurations = new Set<String>(); |
| 12 Set<String> files = new Set<String>(); |
| 17 for (String argument in arguments) { | 13 for (String argument in arguments) { |
| 18 if (argument.startsWith('-')) { | 14 if (TEST_CONFIGURATIONS.containsKey(argument)) { |
| 19 if (argument == '-a') { | 15 configurations.add(argument); |
| 20 /// Generate visualization for all user methods. | 16 } else if (TEST_FILES.containsKey(argument)) { |
| 21 showAll = true; | 17 files.add(argument); |
| 22 } else if (argument == '-m') { | |
| 23 /// Measure instead of reporting the number of missing code points. | |
| 24 measure = true; | |
| 25 } else if (argument.startsWith('--out=')) { | |
| 26 /// Generate visualization for the first configuration. | |
| 27 outputUri = Uri.base.resolve( | |
| 28 nativeToUriPath(argument.substring('--out='.length))); | |
| 29 } else if (argument.startsWith('-o')) { | |
| 30 /// Generate visualization for the first configuration. | |
| 31 outputUri = Uri.base.resolve( | |
| 32 nativeToUriPath(argument.substring('-o'.length))); | |
| 33 } else { | |
| 34 print("Unknown option '$argument'."); | |
| 35 return; | |
| 36 } | |
| 37 } else { | 18 } else { |
| 38 if (TEST_CONFIGURATIONS.containsKey(argument)) { | 19 print("Unknown configuration or file '$argument'. " |
| 39 configurations.add(argument); | 20 "Must be one of '${TEST_CONFIGURATIONS.keys.join("', '")}' or " |
| 40 } else { | 21 "'${TEST_FILES.keys.join("', '")}'."); |
| 41 print("Unknown configuration '$argument'. " | 22 return; |
| 42 "Must be one of '${TEST_CONFIGURATIONS.keys.join("', '")}'"); | |
| 43 return; | |
| 44 } | |
| 45 } | 23 } |
| 46 } | 24 } |
| 47 | 25 |
| 48 if (configurations.isEmpty) { | 26 if (configurations.isEmpty) { |
| 49 configurations.addAll(TEST_CONFIGURATIONS.keys); | 27 configurations.addAll(TEST_CONFIGURATIONS.keys); |
| 28 configurations.remove('old'); |
| 50 } | 29 } |
| 51 String outputConfig = configurations.first; | 30 if (files.isEmpty) { |
| 31 files.addAll(TEST_FILES.keys); |
| 32 } |
| 52 | 33 |
| 53 asyncTest(() async { | 34 asyncTest(() async { |
| 54 List<Measurement> measurements = <Measurement>[]; | 35 bool missingCodePointsFound = false; |
| 55 for (String config in configurations) { | 36 for (String config in configurations) { |
| 56 List<String> options = TEST_CONFIGURATIONS[config]; | 37 List<String> options = TEST_CONFIGURATIONS[config]; |
| 57 Measurement measurement = await runTests( | 38 for (String file in files) { |
| 58 config, | 39 String filename = TEST_FILES[file]; |
| 59 options, | 40 TestResult result = await runTests(config, filename, options); |
| 60 showAll: showAll, | 41 if (result.failureMap.isNotEmpty) { |
| 61 measure: measure, | 42 result.failureMap.forEach((info, missingCodePoints) { |
| 62 outputUri: outputConfig == config ? outputUri : null); | 43 print("Missing code points for ${info.element} in '$filename' " |
| 63 if (measurement != null) { | 44 "in config '$config':"); |
| 64 measurements.add(measurement); | 45 for (CodePoint codePoint in missingCodePoints) { |
| 46 print(" $codePoint"); |
| 47 } |
| 48 }); |
| 49 missingCodePointsFound = true; |
| 50 } |
| 65 } | 51 } |
| 66 } | 52 } |
| 67 for (Measurement measurement in measurements) { | 53 Expect.isFalse(missingCodePointsFound, |
| 68 print(measurement); | 54 "Missing code points found. " |
| 69 } | 55 "Run the test with a URI option, " |
| 56 "`source_mapping_test_viewer [--out=<uri>] [configs] [tests]`, to " |
| 57 "create a html visualization of the missing code points."); |
| 70 }); | 58 }); |
| 71 } | 59 } |
| 72 | 60 |
| 73 const Map<String, List<String>> TEST_CONFIGURATIONS = const { | 61 const Map<String, List<String>> TEST_CONFIGURATIONS = const { |
| 74 'old': const [], | |
| 75 'ssa': const ['--use-new-source-info', ], | 62 'ssa': const ['--use-new-source-info', ], |
| 76 'cps': const ['--use-new-source-info', '--use-cps-ir'], | 63 'cps': const ['--use-new-source-info', '--use-cps-ir'], |
| 64 'old': const [], |
| 77 }; | 65 }; |
| 78 | 66 |
| 79 Future<Measurement> runTests( | 67 const Map<String, String> TEST_FILES = const <String, String>{ |
| 68 'invokes': 'tests/compiler/dart2js/sourcemaps/invokes_test_file.dart', |
| 69 'operators': 'tests/compiler/dart2js/sourcemaps/operators_test_file.dart', |
| 70 }; |
| 71 |
| 72 Future<TestResult> runTests( |
| 80 String config, | 73 String config, |
| 74 String filename, |
| 81 List<String> options, | 75 List<String> options, |
| 82 {bool showAll: false, | 76 {bool verbose: true}) async { |
| 83 Uri outputUri, | |
| 84 bool measure: false}) async { | |
| 85 if (config == 'old' && !measure) return null; | |
| 86 | |
| 87 String filename = | |
| 88 'tests/compiler/dart2js/sourcemaps/invokes_test_file.dart'; | |
| 89 SourceMapProcessor processor = new SourceMapProcessor(filename); | 77 SourceMapProcessor processor = new SourceMapProcessor(filename); |
| 90 List<SourceMapInfo> infoList = await processor.process( | 78 List<SourceMapInfo> infoList = await processor.process( |
| 91 ['--csp', '--disable-inlining'] | 79 ['--csp', '--disable-inlining'] |
| 92 ..addAll(options), | 80 ..addAll(options), |
| 93 verbose: !measure); | 81 verbose: verbose); |
| 94 List<SourceMapInfo> userInfoList = <SourceMapInfo>[]; | 82 TestResult result = new TestResult(config, filename, processor); |
| 95 List<SourceMapInfo> failureList = <SourceMapInfo>[]; | |
| 96 Measurement measurement = new Measurement(config); | |
| 97 for (SourceMapInfo info in infoList) { | 83 for (SourceMapInfo info in infoList) { |
| 98 if (info.element.library.isPlatformLibrary) continue; | 84 if (info.element.library.isPlatformLibrary) continue; |
| 99 userInfoList.add(info); | 85 result.userInfoList.add(info); |
| 100 Iterable<CodePoint> missingCodePoints = | 86 Iterable<CodePoint> missingCodePoints = |
| 101 info.codePoints.where((c) => c.isMissing); | 87 info.codePoints.where((c) => c.isMissing); |
| 102 measurement.missing += missingCodePoints.length; | 88 if (missingCodePoints.isNotEmpty) { |
| 103 measurement.count += info.codePoints.length; | 89 result.failureMap[info] = missingCodePoints; |
| 104 if (!measure) { | |
| 105 if (!missingCodePoints.isEmpty) { | |
| 106 print("Missing code points for ${info.element} in '$filename':"); | |
| 107 for (CodePoint codePoint in missingCodePoints) { | |
| 108 print(" $codePoint"); | |
| 109 } | |
| 110 failureList.add(info); | |
| 111 } | |
| 112 } | 90 } |
| 113 } | 91 } |
| 114 if (failureList.isNotEmpty) { | 92 return result; |
| 115 if (outputUri == null) { | |
| 116 if (!measure) { | |
| 117 Expect.fail( | |
| 118 "Missing code points found. " | |
| 119 "Run the test with a URI option, " | |
| 120 "`source_mapping_test --out=<uri> $config`, to " | |
| 121 "create a html visualization of the missing code points."); | |
| 122 } | |
| 123 } else { | |
| 124 createTraceSourceMapHtml(outputUri, processor, | |
| 125 showAll ? userInfoList : failureList); | |
| 126 } | |
| 127 } else if (outputUri != null) { | |
| 128 createTraceSourceMapHtml(outputUri, processor, userInfoList); | |
| 129 } | |
| 130 return measurement; | |
| 131 } | 93 } |
| 132 | 94 |
| 133 class Measurement { | 95 class TestResult { |
| 134 final String config; | 96 final String config; |
| 135 int missing = 0; | 97 final String file; |
| 136 int count = 0; | 98 final SourceMapProcessor processor; |
| 99 List<SourceMapInfo> userInfoList = <SourceMapInfo>[]; |
| 100 Map<SourceMapInfo, Iterable<CodePoint>> failureMap = |
| 101 <SourceMapInfo, Iterable<CodePoint>>{}; |
| 137 | 102 |
| 138 Measurement(this.config); | 103 TestResult(this.config, this.file, this.processor); |
| 139 | |
| 140 String toString() { | |
| 141 double percentage = 100 * missing / count; | |
| 142 return "Config '${config}': $missing of $count ($percentage%) missing"; | |
| 143 } | |
| 144 } | 104 } |
| OLD | NEW |