[dart2js] Adding tests for angularInfo conversion for runtime coverage
Change-Id: I143565cb2c36c551ed7e1189ffbcf64fb9b2a5de
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/252560
Reviewed-by: Joshua Litt <joshualitt@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>
diff --git a/pkg/dart2js_info/pubspec.yaml b/pkg/dart2js_info/pubspec.yaml
index 04e3c7b..68bab56 100644
--- a/pkg/dart2js_info/pubspec.yaml
+++ b/pkg/dart2js_info/pubspec.yaml
@@ -20,6 +20,7 @@
# Use 'any' constraints here; we get our versions from the DEPS file.
dev_dependencies:
+ expect: any
lints: any
test: any
diff --git a/pkg/dart2js_info/test/classes/class_filter.txt b/pkg/dart2js_info/test/classes/class_filter.txt
new file mode 100644
index 0000000..aa011aa
--- /dev/null
+++ b/pkg/dart2js_info/test/classes/class_filter.txt
@@ -0,0 +1,5 @@
+dart:_rti - _Universe
+dart:core - Error
+testroot:classes.dart - Subsub1
+testroot:classes.dart - Super
+package:expect/expect.dart - Expect
diff --git a/pkg/dart2js_info/test/classes/classes.dart b/pkg/dart2js_info/test/classes/classes.dart
new file mode 100644
index 0000000..d7b49e0
--- /dev/null
+++ b/pkg/dart2js_info/test/classes/classes.dart
@@ -0,0 +1,45 @@
+import 'package:expect/expect.dart';
+
+class Super<T> {
+ void method(T t) {
+ print(t.runtimeType);
+ }
+}
+
+class Mixin {
+ void method(int t) {
+ print(t + 1);
+ }
+}
+
+class Clazz = Super<int> with Mixin;
+
+class Subclass extends Clazz {
+ void test() {
+ void Function(int) f = super.method;
+ f(42);
+ print(f);
+ }
+}
+
+class Subsub1 extends Subclass {
+ void a(dynamic x) {
+ print(x);
+ }
+}
+
+class Subsub2 extends Subclass {
+ void a(dynamic x) {
+ print(x);
+ print(x);
+ }
+}
+
+main() {
+ Super<Object> s = Subclass()..test();
+ Expect.throws(() => s.method(''));
+ dynamic x = Subsub1();
+ x.a(x);
+ x = Subsub2();
+ x.a(x);
+}
diff --git a/pkg/dart2js_info/test/classes/classes.js.info.data b/pkg/dart2js_info/test/classes/classes.js.info.data
new file mode 100644
index 0000000..cc738e1
--- /dev/null
+++ b/pkg/dart2js_info/test/classes/classes.js.info.data
Binary files differ
diff --git a/pkg/dart2js_info/test/runtime_coverage_test.dart b/pkg/dart2js_info/test/runtime_coverage_test.dart
new file mode 100644
index 0000000..9d5d048
--- /dev/null
+++ b/pkg/dart2js_info/test/runtime_coverage_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Tests for dart2js_info's runtime_coverage command.
+//
+// Regenerate files with dart2js flags:
+// --multi-root-scheme='testroot'
+// --multi-root='$PATH_TO_TEST_ROOT'
+// --entry-uri='testroot:$TEST_FILE.dart'
+// --dump-info=binary
+// --packages=$PATH_TO_SDK/.dart_tool/package_config.json
+
+import 'dart:io';
+
+import 'package:dart2js_info/binary_serialization.dart';
+import 'package:dart2js_info/src/util.dart';
+import 'package:test/test.dart';
+
+import '../bin/src/runtime_coverage_analysis.dart';
+
+void main() {
+ group('runtime coverage', () {
+ group('class filter (angular info)', () {
+ final infoBinaryFile =
+ File.fromUri(Platform.script.resolve('classes/classes.js.info.data'));
+ final allInfo = decode(infoBinaryFile.readAsBytesSync());
+ final classFilters =
+ File.fromUri(Platform.script.resolve('classes/class_filter.txt'))
+ .readAsLinesSync();
+ final runtimeClassInfos = <String, RuntimeClassInfo>{};
+
+ setUp(() {
+ runtimeClassInfos.clear();
+ });
+
+ test('class filters are formatted properly', () {
+ for (final filterString in classFilters) {
+ expect(filterString.contains(' - '), isTrue);
+ }
+ });
+
+ test('AngularInfo conversions throws on invalid schemes', () {
+ expect(
+ () => RuntimeClassInfo.fromAngularInfo(
+ 'no/scheme/here.dart - ClassName'),
+ throwsArgumentError);
+ expect(
+ () => RuntimeClassInfo.fromAngularInfo('noscheme.dart - ClassName'),
+ throwsArgumentError);
+ });
+
+ test('class filters parse and annotate properly', () {
+ // Process class filters.
+ for (final filterString in classFilters) {
+ final runtimeClassInfo =
+ RuntimeClassInfo.fromAngularInfo(filterString);
+ expect(runtimeClassInfo.annotated, isFalse);
+ runtimeClassInfos[runtimeClassInfo.key] = runtimeClassInfo;
+ }
+
+ // Annotate class filters with their corresponding ClassInfo.
+ for (final classInfo in allInfo.classes) {
+ final name = qualifiedName(classInfo);
+ final nameWithoutScheme =
+ name.substring(name.indexOf(':') + 1, name.length);
+ final runtimeClassInfo = runtimeClassInfos[nameWithoutScheme];
+ if (runtimeClassInfo != null) {
+ runtimeClassInfo.annotateWithClassInfo(classInfo);
+ expect(runtimeClassInfos[runtimeClassInfo.key], isNotNull);
+ }
+ }
+
+ // Check that all class info objects are annotated.
+ for (final runtimeClassInfo in runtimeClassInfos.values) {
+ expect(runtimeClassInfo.annotated, isTrue);
+ }
+ });
+ });
+ });
+}