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

Side by Side Diff: tests/compiler/dart2js/serialization_test_helper.dart

Issue 1934883002: Refactor unittests (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 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 unified diff | Download patch
OLDNEW
(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 library dart2js.serialization_test_helper;
6
7 import 'dart:io';
8 import 'memory_compiler.dart';
9 import 'package:async_helper/async_helper.dart';
10 import 'package:compiler/src/common/resolution.dart';
11 import 'package:compiler/src/commandline_options.dart';
12 import 'package:compiler/src/constants/constructors.dart';
13 import 'package:compiler/src/constants/expressions.dart';
14 import 'package:compiler/src/dart_types.dart';
15 import 'package:compiler/src/compiler.dart';
16 import 'package:compiler/src/diagnostics/invariant.dart';
17 import 'package:compiler/src/elements/elements.dart';
18 import 'package:compiler/src/elements/visitor.dart';
19 import 'package:compiler/src/ordered_typeset.dart';
20 import 'package:compiler/src/serialization/element_serialization.dart';
21 import 'package:compiler/src/serialization/equivalence.dart';
22 import 'package:compiler/src/serialization/json_serializer.dart';
23 import 'package:compiler/src/serialization/serialization.dart';
24
25
26 /// Strategy for checking equivalence.
27 ///
28 /// Use this strategy to fail early with contextual information in the event of
29 /// inequivalence.
30 class CheckStrategy implements TestStrategy {
31 const CheckStrategy();
32
33 @override
34 bool test(var object1, var object2, String property, var value1, var value2,
35 [bool equivalence(a, b) = equality]) {
36 return check(object1, object2, property, value1, value2, equivalence);
37 }
38
39 @override
40 bool testLists(
41 Object object1, Object object2, String property,
42 List list1, List list2,
43 [bool elementEquivalence(a, b) = equality]) {
44 return checkListEquivalence(
45 object1, object2, property, list1, list2,
46 (o1, o2, p, v1, v2) {
47 if (!elementEquivalence(v1, v2)) {
48 throw "$o1.$p = '${v1}' <> "
49 "$o2.$p = '${v2}'";
50 }
51 return true;
52 });
53 }
54
55 @override
56 bool testSets(
57 var object1, var object2, String property,
58 Iterable set1, Iterable set2,
59 [bool elementEquivalence(a, b) = equality]) {
60 return checkSetEquivalence(
61 object1, object2,property, set1, set2, elementEquivalence);
62 }
63
64 @override
65 bool testElements(
66 Object object1, Object object2, String property,
67 Element element1, Element element2) {
68 return checkElementIdentities(
69 object1, object2, property, element1, element2);
70 }
71
72 @override
73 bool testTypes(
74 Object object1, Object object2, String property,
75 DartType type1, DartType type2) {
76 return checkTypes(object1, object2, property, type1, type2);
77 }
78
79 @override
80 bool testConstants(
81 Object object1, Object object2, String property,
82 ConstantExpression exp1, ConstantExpression exp2) {
83 return checkConstants(object1, object2, property, exp1, exp2);
84 }
85
86 @override
87 bool testTypeLists(
88 Object object1, Object object2, String property,
89 List<DartType> list1, List<DartType> list2) {
90 return checkTypeLists(object1, object2, property, list1, list2);
91 }
92
93 @override
94 bool testConstantLists(
95 Object object1, Object object2, String property,
96 List<ConstantExpression> list1,
97 List<ConstantExpression> list2) {
98 return checkConstantLists(object1, object2, property, list1, list2);
99 }
100 }
101
102 /// Check that the values [property] of [object1] and [object2], [value1] and
103 /// [value2] respectively, are equal and throw otherwise.
104 bool check(var object1, var object2, String property, var value1, var value2,
105 [bool equivalence(a, b) = equality]) {
106 if (!equivalence(value1, value2)) {
107 throw "property='$property'\n "
108 "object1=$object1 (${object1.runtimeType})\n "
109 "value=${value1 == null ? "null" : "'$value1'"} "
110 "(${value1.runtimeType}) <>\n "
111 "object2=$object2 (${object2.runtimeType})\n "
112 "value=${value2 == null ? "null" : "'$value2'"} "
113 "(${value2.runtimeType})";
114 }
115 return true;
116 }
117
118 /// Check equivalence of the two lists, [list1] and [list2], using
119 /// [checkEquivalence] to check the pair-wise equivalence.
120 ///
121 /// Uses [object1], [object2] and [property] to provide context for failures.
122 bool checkListEquivalence(
123 Object object1, Object object2, String property,
124 Iterable list1, Iterable list2,
125 void checkEquivalence(o1, o2, property, a, b)) {
126 for (int i = 0; i < list1.length && i < list2.length; i++) {
127 checkEquivalence(
128 object1, object2, property,
129 list1.elementAt(i), list2.elementAt(i));
130 }
131 for (int i = list1.length; i < list2.length; i++) {
132 throw
133 'Missing equivalent for element '
134 '#$i ${list2.elementAt(i)} in `${property}` on $object2.\n'
135 '`${property}` on $object1:\n ${list1.join('\n ')}\n'
136 '`${property}` on $object2:\n ${list2.join('\n ')}';
137 }
138 for (int i = list2.length; i < list1.length; i++) {
139 throw
140 'Missing equivalent for element '
141 '#$i ${list1.elementAt(i)} in `${property}` on $object1.\n'
142 '`${property}` on $object1:\n ${list1.join('\n ')}\n'
143 '`${property}` on $object2:\n ${list2.join('\n ')}';
144 }
145 return true;
146 }
147
148 /// Computes the set difference between [set1] and [set2] using
149 /// [elementEquivalence] to determine element equivalence.
150 ///
151 /// Elements both in [set1] and [set2] are added to [common], elements in [set1]
152 /// but not in [set2] are added to [unfound], and the set of elements in [set2]
153 /// but not in [set1] are returned.
154 Set computeSetDifference(
155 Iterable set1,
156 Iterable set2,
157 List common,
158 List unfound,
159 [bool sameElement(a, b) = equality]) {
160 // TODO(johnniwinther): Avoid the quadratic cost here. Some ideas:
161 // - convert each set to a list and sort it first, then compare by walking
162 // both lists in parallel
163 // - map each element to a canonical object, create a map containing those
164 // mappings, use the mapped sets to compare (then operations like
165 // set.difference would work)
166 Set remaining = set2.toSet();
167 for (var element1 in set1) {
168 bool found = false;
169 for (var element2 in remaining) {
170 if (sameElement(element1, element2)) {
171 found = true;
172 remaining.remove(element2);
173 break;
174 }
175 }
176 if (found) {
177 common.add(element1);
178 } else {
179 unfound.add(element1);
180 }
181 }
182 return remaining;
183 }
184
185 /// Check equivalence of the two iterables, [set1] and [set1], as sets using
186 /// [elementEquivalence] to compute the pair-wise equivalence.
187 ///
188 /// Uses [object1], [object2] and [property] to provide context for failures.
189 bool checkSetEquivalence(
190 var object1,
191 var object2,
192 String property,
193 Iterable set1,
194 Iterable set2,
195 bool sameElement(a, b)) {
196 List common = [];
197 List unfound = [];
198 Set remaining =
199 computeSetDifference(set1, set2, common, unfound, sameElement);
200 if (unfound.isNotEmpty || remaining.isNotEmpty) {
201 String message =
202 "Set mismatch for `$property` on $object1 vs $object2: \n"
203 "Common:\n ${common.join('\n ')}\n"
204 "Unfound:\n ${unfound.join('\n ')}\n"
205 "Extra: \n ${remaining.join('\n ')}";
206 throw message;
207 }
208 return true;
209 }
210
211 /// Checks the equivalence of the identity (but not properties) of [element1]
212 /// and [element2].
213 ///
214 /// Uses [object1], [object2] and [property] to provide context for failures.
215 bool checkElementIdentities(
216 Object object1, Object object2, String property,
217 Element element1, Element element2) {
218 if (identical(element1, element2)) return true;
219 return check(object1, object2,
220 property, element1, element2, areElementsEquivalent);
221 }
222
223 /// Checks the pair-wise equivalence of the identity (but not properties) of the
224 /// elements in [list] and [list2].
225 ///
226 /// Uses [object1], [object2] and [property] to provide context for failures.
227 bool checkElementListIdentities(
228 Object object1, Object object2, String property,
229 Iterable<Element> list1, Iterable<Element> list2) {
230 return checkListEquivalence(
231 object1, object2, property,
232 list1, list2, checkElementIdentities);
233 }
234
235 /// Checks the equivalence of [type1] and [type2].
236 ///
237 /// Uses [object1], [object2] and [property] to provide context for failures.
238 bool checkTypes(
239 Object object1, Object object2, String property,
240 DartType type1, DartType type2) {
241 if (identical(type1, type2)) return true;
242 if (type1 == null || type2 == null) {
243 return check(object1, object2, property, type1, type2);
244 } else {
245 return const TypeEquivalence(const CheckStrategy()).visit(type1, type2);
246 }
247 }
248
249 /// Checks the pair-wise equivalence of the types in [list1] and [list2].
250 ///
251 /// Uses [object1], [object2] and [property] to provide context for failures.
252 bool checkTypeLists(
253 Object object1, Object object2, String property,
254 List<DartType> list1, List<DartType> list2) {
255 return checkListEquivalence(
256 object1, object2, property, list1, list2, checkTypes);
257 }
258
259 /// Checks the equivalence of [exp1] and [exp2].
260 ///
261 /// Uses [object1], [object2] and [property] to provide context for failures.
262 bool checkConstants(
263 Object object1, Object object2, String property,
264 ConstantExpression exp1, ConstantExpression exp2) {
265 if (identical(exp1, exp2)) return true;
266 if (exp1 == null || exp2 == null) {
267 return check(object1, object2, property, exp1, exp2);
268 } else {
269 return const ConstantEquivalence(const CheckStrategy()).visit(exp1, exp2);
270 }
271 }
272
273 /// Checks the pair-wise equivalence of the contants in [list1] and [list2].
274 ///
275 /// Uses [object1], [object2] and [property] to provide context for failures.
276 bool checkConstantLists(
277 Object object1, Object object2, String property,
278 List<ConstantExpression> list1,
279 List<ConstantExpression> list2) {
280 return checkListEquivalence(
281 object1, object2, property,
282 list1, list2, checkConstants);
283 }
284
285
286 /// Check member property equivalence between all members common to [compiler1]
287 /// and [compiler2].
288 void checkLoadedLibraryMembers(
289 Compiler compiler1,
290 Compiler compiler2,
291 bool hasProperty(Element member1),
292 void checkMemberProperties(Compiler compiler1, Element member1,
293 Compiler compiler2, Element member2,
294 {bool verbose}),
295 {bool verbose: false}) {
296
297 void checkMembers(Element member1, Element member2) {
298 if (member1.isClass && member2.isClass) {
299 ClassElement class1 = member1;
300 ClassElement class2 = member2;
301 if (!class1.isResolved) return;
302
303 class1.forEachLocalMember((m1) {
304 checkMembers(m1, class2.localLookup(m1.name));
305 });
306 ClassElement superclass1 = class1.superclass;
307 ClassElement superclass2 = class2.superclass;
308 while (superclass1 != null && superclass1.isUnnamedMixinApplication) {
309 for (ConstructorElement c1 in superclass1.constructors) {
310 checkMembers(c1, superclass2.lookupConstructor(c1.name));
311 }
312 superclass1 = superclass1.superclass;
313 superclass2 = superclass2.superclass;
314 }
315 return;
316 }
317
318 if (!hasProperty(member1)) {
319 return;
320 }
321
322 if (member2 == null) {
323 throw 'Missing member for ${member1}';
324 }
325
326 if (areElementsEquivalent(member1, member2)) {
327 checkMemberProperties(
328 compiler1, member1,
329 compiler2, member2,
330 verbose: verbose);
331 }
332 }
333
334 for (LibraryElement library1 in compiler1.libraryLoader.libraries) {
335 LibraryElement library2 =
336 compiler2.libraryLoader.lookupLibrary(library1.canonicalUri);
337 if (library2 != null) {
338 library1.forEachLocalMember((Element member1) {
339 checkMembers(member1, library2.localLookup(member1.name));
340 });
341
342 }
343 }
344 }
345
346 /// Check equivalence of all resolution impacts.
347 void checkAllImpacts(
348 Compiler compiler1,
349 Compiler compiler2,
350 {bool verbose: false}) {
351 checkLoadedLibraryMembers(
352 compiler1,
353 compiler2,
354 (Element member1) {
355 return compiler1.resolution.hasResolutionImpact(member1);
356 },
357 checkImpacts,
358 verbose: verbose);
359 }
360
361 /// Check equivalence of resolution impact for [member1] and [member2].
362 void checkImpacts(Compiler compiler1, Element member1,
363 Compiler compiler2, Element member2,
364 {bool verbose: false}) {
365 ResolutionImpact impact1 = compiler1.resolution.getResolutionImpact(member1);
366 ResolutionImpact impact2 = compiler2.resolution.getResolutionImpact(member2);
367
368 if (impact1 == null && impact2 == null) return;
369
370 if (verbose) {
371 print('Checking impacts for $member1 vs $member2');
372 }
373
374 if (impact1 == null) {
375 throw 'Missing impact for $member1. $member2 has $impact2';
376 }
377 if (impact2 == null) {
378 throw 'Missing impact for $member2. $member1 has $impact1';
379 }
380
381 testResolutionImpactEquivalence(impact1, impact2, const CheckStrategy());
382 }
OLDNEW
« no previous file with comments | « tests/compiler/dart2js/serialization_test_data.dart ('k') | tests/compiler/dart2js/sourcemaps/data/invokes_test_file.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698