Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Unified Diff: tests/compiler/dart2js/serialization_test_helper.dart

Issue 1870133002: Refactor serialization test files. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Fix Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tests/compiler/dart2js/serialization_test_data.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tests/compiler/dart2js/serialization_test_helper.dart
diff --git a/tests/compiler/dart2js/serialization_test_helper.dart b/tests/compiler/dart2js/serialization_test_helper.dart
new file mode 100644
index 0000000000000000000000000000000000000000..97d5134952b05c7bdb0c00f5867be557775455fb
--- /dev/null
+++ b/tests/compiler/dart2js/serialization_test_helper.dart
@@ -0,0 +1,365 @@
+// Copyright (c) 2016, 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.
+
+library dart2js.serialization_test_helper;
+
+import 'dart:io';
+import 'memory_compiler.dart';
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/common/resolution.dart';
+import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/constants/constructors.dart';
+import 'package:compiler/src/constants/expressions.dart';
+import 'package:compiler/src/dart_types.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/diagnostics/invariant.dart';
+import 'package:compiler/src/elements/elements.dart';
+import 'package:compiler/src/elements/visitor.dart';
+import 'package:compiler/src/ordered_typeset.dart';
+import 'package:compiler/src/serialization/element_serialization.dart';
+import 'package:compiler/src/serialization/equivalence.dart';
+import 'package:compiler/src/serialization/json_serializer.dart';
+import 'package:compiler/src/serialization/serialization.dart';
+
+
+/// Strategy for checking equivalence.
+///
+/// Use this strategy to fail early with contextual information in the event of
+/// inequivalence.
+class CheckStrategy implements TestStrategy {
+ const CheckStrategy();
+
+ @override
+ bool test(var object1, var object2, String property, var value1, var value2,
+ [bool equivalence(a, b) = equality]) {
+ return check(object1, object2, property, value1, value2, equivalence);
+ }
+
+ @override
+ bool testLists(
+ Object object1, Object object2, String property,
+ List list1, List list2,
+ [bool elementEquivalence(a, b) = equality]) {
+ return checkListEquivalence(
+ object1, object2, property, list1, list2,
+ (o1, o2, p, v1, v2) {
+ if (!elementEquivalence(v1, v2)) {
+ throw "$o1.$p = '${v1}' <> "
+ "$o2.$p = '${v2}'";
+ }
+ return true;
+ });
+ }
+
+ @override
+ bool testSets(
+ var object1, var object2, String property,
+ Iterable set1, Iterable set2,
+ [bool elementEquivalence(a, b) = equality]) {
+ return checkSetEquivalence(
+ object1, object2,property, set1, set2, elementEquivalence);
+ }
+
+ @override
+ bool testElements(
+ Object object1, Object object2, String property,
+ Element element1, Element element2) {
+ return checkElementIdentities(
+ object1, object2, property, element1, element2);
+ }
+
+ @override
+ bool testTypes(
+ Object object1, Object object2, String property,
+ DartType type1, DartType type2) {
+ return checkTypes(object1, object2, property, type1, type2);
+ }
+
+ @override
+ bool testConstants(
+ Object object1, Object object2, String property,
+ ConstantExpression exp1, ConstantExpression exp2) {
+ return checkConstants(object1, object2, property, exp1, exp2);
+ }
+
+ @override
+ bool testTypeLists(
+ Object object1, Object object2, String property,
+ List<DartType> list1, List<DartType> list2) {
+ return checkTypeLists(object1, object2, property, list1, list2);
+ }
+
+ @override
+ bool testConstantLists(
+ Object object1, Object object2, String property,
+ List<ConstantExpression> list1,
+ List<ConstantExpression> list2) {
+ return checkConstantLists(object1, object2, property, list1, list2);
+ }
+}
+
+/// Check that the values [property] of [object1] and [object2], [value1] and
+/// [value2] respectively, are equal and throw otherwise.
+bool check(var object1, var object2, String property, var value1, var value2,
+ [bool equivalence(a, b) = equality]) {
+ if (!equivalence(value1, value2)) {
+ throw "property='$property' "
+ "object1=$object1 (${object1.runtimeType}), value='${value1}' <> "
+ "object2=$object2 (${object2.runtimeType}), value='${value2}'";
+ }
+ return true;
+}
+
+/// Check equivalence of the two lists, [list1] and [list2], using
+/// [checkEquivalence] to check the pair-wise equivalence.
+///
+/// Uses [object1], [object2] and [property] to provide context for failures.
+bool checkListEquivalence(
+ Object object1, Object object2, String property,
+ Iterable list1, Iterable list2,
+ void checkEquivalence(o1, o2, property, a, b)) {
+ for (int i = 0; i < list1.length && i < list2.length; i++) {
+ checkEquivalence(
+ object1, object2, property,
+ list1.elementAt(i), list2.elementAt(i));
+ }
+ for (int i = list1.length; i < list2.length; i++) {
+ throw
+ 'Missing equivalent for element '
+ '#$i ${list2.elementAt(i)} in `${property}` on $object2.\n'
+ '`${property}` on $object1:\n ${list1.join('\n ')}\n'
+ '`${property}` on $object2:\n ${list2.join('\n ')}';
+ }
+ for (int i = list2.length; i < list1.length; i++) {
+ throw
+ 'Missing equivalent for element '
+ '#$i ${list1.elementAt(i)} in `${property}` on $object1.\n'
+ '`${property}` on $object1:\n ${list1.join('\n ')}\n'
+ '`${property}` on $object2:\n ${list2.join('\n ')}';
+ }
+ return true;
+}
+
+/// Computes the set difference between [set1] and [set2] using
+/// [elementEquivalence] to determine element equivalence.
+///
+/// Elements both in [set1] and [set2] are added to [common], elements in [set1]
+/// but not in [set2] are added to [unfound], and the set of elements in [set2]
+/// but not in [set1] are returned.
+Set computeSetDifference(
+ Iterable set1,
+ Iterable set2,
+ List common,
+ List unfound,
+ [bool sameElement(a, b) = equality]) {
+ // TODO(johnniwinther): Avoid the quadratic cost here. Some ideas:
+ // - convert each set to a list and sort it first, then compare by walking
+ // both lists in parallel
+ // - map each element to a canonical object, create a map containing those
+ // mappings, use the mapped sets to compare (then operations like
+ // set.difference would work)
+ Set remaining = set2.toSet();
+ for (var element1 in set1) {
+ bool found = false;
+ for (var element2 in remaining) {
+ if (sameElement(element1, element2)) {
+ found = true;
+ remaining.remove(element2);
+ break;
+ }
+ }
+ if (found) {
+ common.add(element1);
+ } else {
+ unfound.add(element1);
+ }
+ }
+ return remaining;
+}
+
+/// Check equivalence of the two iterables, [set1] and [set1], as sets using
+/// [elementEquivalence] to compute the pair-wise equivalence.
+///
+/// Uses [object1], [object2] and [property] to provide context for failures.
+bool checkSetEquivalence(
+ var object1,
+ var object2,
+ String property,
+ Iterable set1,
+ Iterable set2,
+ bool sameElement(a, b)) {
+ List common = [];
+ List unfound = [];
+ Set remaining =
+ computeSetDifference(set1, set2, common, unfound, sameElement);
+ if (unfound.isNotEmpty || remaining.isNotEmpty) {
+ String message =
+ "Set mismatch for `$property` on $object1 vs $object2: \n"
+ "Common:\n ${common.join('\n ')}\n"
+ "Unfound:\n ${unfound.join('\n ')}\n"
+ "Extra: \n ${remaining.join('\n ')}";
+ throw message;
+ }
+ return true;
+}
+
+/// Checks the equivalence of the identity (but not properties) of [element1]
+/// and [element2].
+///
+/// Uses [object1], [object2] and [property] to provide context for failures.
+bool checkElementIdentities(
+ Object object1, Object object2, String property,
+ Element element1, Element element2) {
+ if (identical(element1, element2)) return true;
+ if (element1 == null || element2 == null) {
+ return check(object1, object2, property, element1, element2);
+ } else {
+ return const ElementIdentityEquivalence(const CheckStrategy())
+ .visit(element1, element2);
+ }
+}
+
+/// Checks the pair-wise equivalence of the identity (but not properties) of the
+/// elements in [list] and [list2].
+///
+/// Uses [object1], [object2] and [property] to provide context for failures.
+bool checkElementListIdentities(
+ Object object1, Object object2, String property,
+ Iterable<Element> list1, Iterable<Element> list2) {
+ return checkListEquivalence(
+ object1, object2, property,
+ list1, list2, checkElementIdentities);
+}
+
+/// Checks the equivalence of [type1] and [type2].
+///
+/// Uses [object1], [object2] and [property] to provide context for failures.
+bool checkTypes(
+ Object object1, Object object2, String property,
+ DartType type1, DartType type2) {
+ if (identical(type1, type2)) return true;
+ if (type1 == null || type2 == null) {
+ return check(object1, object2, property, type1, type2);
+ } else {
+ return const TypeEquivalence(const CheckStrategy()).visit(type1, type2);
+ }
+}
+
+/// Checks the pair-wise equivalence of the types in [list1] and [list2].
+///
+/// Uses [object1], [object2] and [property] to provide context for failures.
+bool checkTypeLists(
+ Object object1, Object object2, String property,
+ List<DartType> list1, List<DartType> list2) {
+ return checkListEquivalence(
+ object1, object2, property, list1, list2, checkTypes);
+}
+
+/// Checks the equivalence of [exp1] and [exp2].
+///
+/// Uses [object1], [object2] and [property] to provide context for failures.
+bool checkConstants(
+ Object object1, Object object2, String property,
+ ConstantExpression exp1, ConstantExpression exp2) {
+ if (identical(exp1, exp2)) return true;
+ if (exp1 == null || exp2 == null) {
+ return check(object1, object2, property, exp1, exp2);
+ } else {
+ return const ConstantEquivalence(const CheckStrategy()).visit(exp1, exp2);
+ }
+}
+
+/// Checks the pair-wise equivalence of the contants in [list1] and [list2].
+///
+/// Uses [object1], [object2] and [property] to provide context for failures.
+bool checkConstantLists(
+ Object object1, Object object2, String property,
+ List<ConstantExpression> list1,
+ List<ConstantExpression> list2) {
+ return checkListEquivalence(
+ object1, object2, property,
+ list1, list2, checkConstants);
+}
+
+
+/// Check member property equivalence between all members common to [compiler1]
+/// and [compiler2].
+void checkLoadedLibraryMembers(
+ Compiler compiler1,
+ Compiler compiler2,
+ bool hasProperty(Element member1),
+ void checkMemberProperties(Compiler compiler1, Element member1,
+ Compiler compiler2, Element member2,
+ {bool verbose}),
+ {bool verbose: false}) {
+
+ void checkMembers(Element member1, Element member2) {
+ if (member1.isClass && member2.isClass) {
+ ClassElement class1 = member1;
+ ClassElement class2 = member2;
+ class1.forEachLocalMember((m1) {
+ checkMembers(m1, class2.lookupLocalMember(m1.name));
+ });
+ return;
+ }
+
+ if (!hasProperty(member1)) {
+ return;
+ }
+
+ if (member2 == null) {
+ return;
+ }
+
+ if (areElementsEquivalent(member1, member2)) {
+ checkMemberProperties(
+ compiler1, member1,
+ compiler2, member2,
+ verbose: verbose);
+ }
+ }
+
+ for (LibraryElement library1 in compiler1.libraryLoader.libraries) {
+ LibraryElement library2 =
+ compiler2.libraryLoader.lookupLibrary(library1.canonicalUri);
+ if (library2 != null) {
+ library1.forEachLocalMember((Element member1) {
+ checkMembers(member1, library2.localLookup(member1.name));
+ });
+
+ }
+ }
+}
+
+/// Check equivalence of all resolution impacts.
+void checkAllImpacts(
+ Compiler compiler1,
+ Compiler compiler2,
+ {bool verbose: false}) {
+ checkLoadedLibraryMembers(
+ compiler1,
+ compiler2,
+ (Element member1) {
+ return compiler1.resolution.hasResolutionImpact(member1);
+ },
+ checkImpacts,
+ verbose: true);
+}
+
+/// Check equivalence of resolution impact for [member1] and [member2].
+void checkImpacts(Compiler compiler1, Element member1,
+ Compiler compiler2, Element member2,
+ {bool verbose: false}) {
+ ResolutionImpact impact1 = compiler1.resolution.getResolutionImpact(member1);
+ ResolutionImpact impact2 =
+ compiler2.serialization.deserializer.getResolutionImpact(member2);
+
+ if (impact1 == null || impact2 == null) return;
+
+ if (verbose) {
+ print('Checking impacts for $member1 vs $member2');
+ }
+
+ testResolutionImpactEquivalence(impact1, impact2, const CheckStrategy());
+}
« no previous file with comments | « tests/compiler/dart2js/serialization_test_data.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698