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

Side by Side Diff: pkg/serialization/test/serialization_test.dart

Issue 11578037: Replicating CL https://chromiumcodereview.appspot.com/11553012/ (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years 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 | Annotate | Revision Log
« no previous file with comments | « pkg/serialization/lib/src/serialization_rule.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 library serialization_test; 5 library serialization_test;
6 6
7 import '../../unittest/lib/unittest.dart'; 7 import '../../unittest/lib/unittest.dart';
8 import '../lib/serialization.dart'; 8 import '../lib/serialization.dart';
9 import '../lib/src/serialization_helpers.dart'; 9 import '../lib/src/serialization_helpers.dart';
10 import '../lib/src/mirrors_helpers.dart'; 10 import '../lib/src/mirrors_helpers.dart';
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 var list = w.states[1].first; 213 var list = w.states[1].first;
214 expect(w.stateForReference(rootNode[children]), list); 214 expect(w.stateForReference(rootNode[children]), list);
215 var parentNode = w.stateForReference(list[0])[parent]; 215 var parentNode = w.stateForReference(list[0])[parent];
216 expect(w.stateForReference(parentNode), rootNode); 216 expect(w.stateForReference(parentNode), rootNode);
217 }); 217 });
218 218
219 test('round-trip', () { 219 test('round-trip', () {
220 runRoundTripTest(nodeSerializerReflective); 220 runRoundTripTest(nodeSerializerReflective);
221 }); 221 });
222 222
223 test('round-trip hard-coded', () { 223 test('round-trip ClosureRule', () {
224 runRoundTripTest(nodeSerializerNonReflective); 224 runRoundTripTest(nodeSerializerNonReflective);
225 }); 225 });
226 226
227 test('round-trip with essential parent', () { 227 test('round-trip with essential parent', () {
228 runRoundTripTest(nodeSerializerWithEssentialParent); 228 runRoundTripTest(nodeSerializerWithEssentialParent);
229 }); 229 });
230 230
231 test('round-trip, flat format', () { 231 test('round-trip, flat format', () {
232 runRoundTripTestFlat(nodeSerializerReflective); 232 runRoundTripTestFlat(nodeSerializerReflective);
233 }); 233 });
234 234
235 test('round-trip using Maps', () { 235 test('round-trip using Maps', () {
236 runRoundTripTest(nodeSerializerUsingMaps); 236 runRoundTripTest(nodeSerializerUsingMaps);
237 }); 237 });
238 238
239 test('round-trip with Node CustomRule', () {
240 runRoundTripTestFlat(nodeSerializerCustom);
241 });
242
243 test('round-trip with Node CustomRule, to maps', () {
244 runRoundTripTest(nodeSerializerCustom);
245 });
246
239 test('eating your own tail', () { 247 test('eating your own tail', () {
240 // Create a meta-serializer, that serializes serializations, then 248 // Create a meta-serializer, that serializes serializations, then
241 // use it to serialize a basic serialization, then run a test on the 249 // use it to serialize a basic serialization, then run a test on the
242 // the result. 250 // the result.
243 var s = new Serialization() 251 var s = new Serialization()
244 ..addRuleFor(new Node(''), constructorFields: ['name']) 252 ..addRuleFor(new Node(''), constructorFields: ['name'])
245 ..selfDescribing = false; 253 ..selfDescribing = false;
246 var meta = metaSerialization(); 254 var meta = metaSerialization();
247 var serialized = meta.write(s); 255 var serialized = meta.write(s);
248 var s2 = new Reader(meta) 256 var s2 = new Reader(meta)
249 .readOne(serialized, {"Node" : reflect(new Node('')).type}); 257 .read(serialized, {"Node" : reflect(new Node('')).type});
250 runRoundTripTest((x) => s2); 258 runRoundTripTest((x) => s2);
251 }); 259 });
252 260
253 test("Verify we're not serializing lists twice if they're essential", () { 261 test("Verify we're not serializing lists twice if they're essential", () {
254 Node n1 = new Node("1"), n2 = new Node("2"), n3 = new Node("3"); 262 Node n1 = new Node("1"), n2 = new Node("2"), n3 = new Node("3");
255 n1.children = [n2, n3]; 263 n1.children = [n2, n3];
256 n2.parent = n1; 264 n2.parent = n1;
257 n3.parent = n1; 265 n3.parent = n1;
258 var s = new Serialization() 266 var s = new Serialization()
259 ..addRuleFor(n1, constructorFields: ["name"]). 267 ..addRuleFor(n1, constructorFields: ["name"]).
(...skipping 18 matching lines...) Expand all
278 n2 = new NodeEqualByName("foo"), 286 n2 = new NodeEqualByName("foo"),
279 n3 = new NodeEqualByName("3"); 287 n3 = new NodeEqualByName("3");
280 n1.children = [n2, n3]; 288 n1.children = [n2, n3];
281 n2.parent = n1; 289 n2.parent = n1;
282 n3.parent = n1; 290 n3.parent = n1;
283 var s = new Serialization() 291 var s = new Serialization()
284 ..selfDescribing = false 292 ..selfDescribing = false
285 ..addRuleFor(n1, constructorFields: ["name"]); 293 ..addRuleFor(n1, constructorFields: ["name"]);
286 var w = new Writer(s); 294 var w = new Writer(s);
287 var r = new Reader(s); 295 var r = new Reader(s);
288 var m1 = r.read(w.write(n1)).first; 296 var m1 = r.read(w.write(n1));
289 var m2 = m1.children.first; 297 var m2 = m1.children.first;
290 var m3 = m1.children.last; 298 var m3 = m1.children.last;
291 expect(m1, m2); 299 expect(m1, m2);
292 expect(identical(m1, m2), isFalse); 300 expect(identical(m1, m2), isFalse);
293 expect(m1 == m3, isFalse); 301 expect(m1 == m3, isFalse);
294 expect(identical(m2.parent, m3.parent), isTrue); 302 expect(identical(m2.parent, m3.parent), isTrue);
295 }); 303 });
296 304
297 } 305 }
298 306
299 /****************************************************************************** 307 /******************************************************************************
300 * The end of the tests and the beginning of various helper functions to make 308 * The end of the tests and the beginning of various helper functions to make
301 * it easier to write the repetitive sections. 309 * it easier to write the repetitive sections.
302 ******************************************************************************/ 310 ******************************************************************************/
303 311
304 /** Create a Serialization for serializing Serializations. */ 312 /** Create a Serialization for serializing Serializations. */
305 Serialization metaSerialization() { 313 Serialization metaSerialization() {
306 // Make some bogus rule instances so we have something to feed rule creation 314 // Make some bogus rule instances so we have something to feed rule creation
307 // and get their types. If only we had class literals implemented... 315 // and get their types. If only we had class literals implemented...
308 var closureRule = new ClosureToMapRule.stub([].runtimeType);
309 var basicRule = new BasicRule(reflect(null).type, '', [], [], []); 316 var basicRule = new BasicRule(reflect(null).type, '', [], [], []);
310 317
311 var meta = new Serialization() 318 var meta = new Serialization()
312 ..selfDescribing = false 319 ..selfDescribing = false
313 ..addRuleFor(new ListRule()) 320 ..addRuleFor(new ListRule())
314 ..addRuleFor(new PrimitiveRule()) 321 ..addRuleFor(new PrimitiveRule())
315 // TODO(alanknight): Handle the ClosureToMapRule as well. 322 // TODO(alanknight): Handle CustomRule as well.
316 // Note that we're passing in a constant for one of the fields. 323 // Note that we're passing in a constant for one of the fields.
317 ..addRuleFor(basicRule, 324 ..addRuleFor(basicRule,
318 constructorFields: ['typeWrapped', 325 constructorFields: ['typeWrapped',
319 'constructorName', 326 'constructorName',
320 'constructorFields', 'regularFields', []], 327 'constructorFields', 'regularFields', []],
321 fields: []) 328 fields: [])
322 ..addRuleFor(new Serialization()).specialTreatmentFor('rules', 329 ..addRuleFor(new Serialization()).specialTreatmentFor('rules',
323 (InstanceMirror s, List rules) { 330 (InstanceMirror s, List rules) {
324 rules.forEach((x) => s.reflectee.addRule(x)); 331 rules.forEach((x) => s.reflectee.addRule(x));
325 }) 332 })
326 ..addRule(new ClassMirrorRule()); 333 ..addRule(new NamedObjectRule())
334 ..addRule(new MirrorRule());
327 return meta; 335 return meta;
328 } 336 }
329 337
330 /** 338 /**
331 * Read back a simple object, assumed to be the only one of its class in the 339 * Read back a simple object, assumed to be the only one of its class in the
332 * reader. 340 * reader.
333 */ 341 */
334 readBackSimple(Serialization s, object, Reader reader) { 342 readBackSimple(Serialization s, object, Reader reader) {
335 var rule = s.rulesFor(object)[0]; 343 var rule = s.rulesFor(object, null)[0];
336 reader.inflateForRule(rule); 344 reader.inflateForRule(rule);
337 var list2 = reader.allObjectsForRule(rule)[0]; 345 var list2 = reader.allObjectsForRule(rule)[0];
338 return list2; 346 return list2;
339 } 347 }
340 348
341 /** 349 /**
342 * Set up a basic reader with some fake data. Hard-codes the assumption 350 * Set up a basic reader with some fake data. Hard-codes the assumption
343 * of how many rules there are. 351 * of how many rules there are.
344 */ 352 */
345 Reader setUpReader(aSerialization, sampleData) { 353 Reader setUpReader(aSerialization, sampleData) {
346 var reader = new Reader(aSerialization); 354 var reader = new Reader(aSerialization);
347 // We're not sure which rule needs the sample data, so put it everywhere 355 // We're not sure which rule needs the sample data, so put it everywhere
348 // and trust that the extra will just be ignored. 356 // and trust that the extra will just be ignored.
349 reader.data = [[sampleData], [sampleData], [sampleData], [sampleData]]; 357 reader.data = [[sampleData], [sampleData], [sampleData], [sampleData]];
350 return reader; 358 return reader;
351 } 359 }
352 360
353 /** Return a serialization for Node objects, using a reflective rule. */ 361 /** Return a serialization for Node objects, using a reflective rule. */
354 Serialization nodeSerializerReflective(Node n) { 362 Serialization nodeSerializerReflective(Node n) {
355 return new Serialization() 363 return new Serialization()
356 ..addRuleFor(n, constructorFields: ["name"]) 364 ..addRuleFor(n, constructorFields: ["name"])
357 ..externalObjects['Node'] = reflect(new Node('')).type; 365 ..namedObjects['Node'] = reflect(new Node('')).type;
358 } 366 }
359 367
360 /** 368 /**
361 * Return a serialization for Node objects but using Maps for the internal 369 * Return a serialization for Node objects but using Maps for the internal
362 * representation rather than lists. 370 * representation rather than lists.
363 */ 371 */
364 Serialization nodeSerializerUsingMaps(Node n) { 372 Serialization nodeSerializerUsingMaps(Node n) {
365 return new Serialization() 373 return new Serialization()
366 ..addRuleFor(n, constructorFields: ["name"]).configureForMaps() 374 ..addRuleFor(n, constructorFields: ["name"]).configureForMaps()
367 ..externalObjects['Node'] = reflect(new Node('')).type; 375 ..namedObjects['Node'] = reflect(new Node('')).type;
368 } 376 }
369 377
370 /** 378 /**
379 * Return a serialization for Node objects but using Maps for the internal
380 * representation rather than lists.
381 */
382 Serialization nodeSerializerCustom(Node n) {
383 return new Serialization()
384 ..addRule(new NodeRule());
385 }
386
387 /**
371 * Return a serialization for Node objects where the "parent" instance 388 * Return a serialization for Node objects where the "parent" instance
372 * variable is considered essential state. 389 * variable is considered essential state.
373 */ 390 */
374 Serialization nodeSerializerWithEssentialParent(Node n) { 391 Serialization nodeSerializerWithEssentialParent(Node n) {
375 // Force the node rule to be first, in order to make a cycle which would 392 // Force the node rule to be first, in order to make a cycle which would
376 // not cause a problem if we handled the list first, because the list 393 // not cause a problem if we handled the list first, because the list
377 // considers all of its state non-essential, thus breaking the cycle. 394 // considers all of its state non-essential, thus breaking the cycle.
378 var s = new Serialization.blank() 395 var s = new Serialization.blank()
379 ..addRuleFor( 396 ..addRuleFor(
380 n, 397 n,
381 constructor: "parentEssential", 398 constructor: "parentEssential",
382 constructorFields: ["parent"]) 399 constructorFields: ["parent"])
383 ..addDefaultRules() 400 ..addDefaultRules()
384 ..externalObjects['Node'] = reflect(new Node('')).type 401 ..namedObjects['Node'] = reflect(new Node('')).type
385 ..selfDescribing = false; 402 ..selfDescribing = false;
386 return s; 403 return s;
387 } 404 }
388 405
389 /** Return a serialization for Node objects using a ClosureToMapRule. */ 406 /** Return a serialization for Node objects using a ClosureToMapRule. */
390 Serialization nodeSerializerNonReflective(Node n) { 407 Serialization nodeSerializerNonReflective(Node n) {
391 var rule = new ClosureToMapRule( 408 var rule = new ClosureRule(
392 n.runtimeType, 409 n.runtimeType,
393 (o) => {"name" : o.name, "children" : o.children, "parent" : o.parent}, 410 (o) => {"name" : o.name, "children" : o.children, "parent" : o.parent},
394 (map) => new Node(map["name"]), 411 (map) => new Node(map["name"]),
395 (map, object) { 412 (object, map) {
396 object 413 object
397 ..children = map["children"] 414 ..children = map["children"]
398 ..parent = map["parent"]; 415 ..parent = map["parent"];
399 }); 416 });
400 return new Serialization() 417 return new Serialization()
401 ..selfDescribing = false 418 ..selfDescribing = false
402 ..addRule(rule); 419 ..addRule(rule);
403 } 420 }
404 421
405 /** 422 /**
406 * Run a round-trip test on a simple tree of nodes, using a serialization 423 * Run a round-trip test on a simple tree of nodes, using a serialization
407 * that's returned by the [serializerSetup] function. 424 * that's returned by the [serializerSetup] function.
408 */ 425 */
409 runRoundTripTest(Function serializerSetUp) { 426 runRoundTripTest(Function serializerSetUp) {
410 Node n1 = new Node("1"), n2 = new Node("2"), n3 = new Node("3"); 427 Node n1 = new Node("1"), n2 = new Node("2"), n3 = new Node("3");
411 n1.children = [n2, n3]; 428 n1.children = [n2, n3];
412 n2.parent = n1; 429 n2.parent = n1;
413 n3.parent = n1; 430 n3.parent = n1;
414 var s = serializerSetUp(n1); 431 var s = serializerSetUp(n1);
415 var output = s.write(n2); 432 var output = s.write(n2);
416 var s2 = serializerSetUp(n1); 433 var s2 = serializerSetUp(n1);
417 var reader = new Reader(s2); 434 var reader = new Reader(s2);
418 var m2 = reader.readOne(output); 435 var m2 = reader.read(output);
419 var m1 = m2.parent; 436 var m1 = m2.parent;
420 expect(m1 is Node, isTrue); 437 expect(m1 is Node, isTrue);
421 var children = m1.children; 438 var children = m1.children;
422 expect(m1.name,"1"); 439 expect(m1.name,"1");
423 var m3 = m1.children.last; 440 var m3 = m1.children.last;
424 expect(m2.name, "2"); 441 expect(m2.name, "2");
425 expect(m3.name, "3"); 442 expect(m3.name, "3");
426 expect(m2.parent, m1); 443 expect(m2.parent, m1);
427 expect(m3.parent, m1); 444 expect(m3.parent, m1);
428 expect(m1.parent, isNull); 445 expect(m1.parent, isNull);
429 } 446 }
430 447
431 /** 448 /**
432 * Run a round-trip test on a simple of nodes, but using the flat format 449 * Run a round-trip test on a simple of nodes, but using the flat format
433 * rather than the maps. 450 * rather than the maps.
434 */ 451 */
435 runRoundTripTestFlat(serializerSetUp) { 452 runRoundTripTestFlat(serializerSetUp) {
436 Node n1 = new Node("1"), n2 = new Node("2"), n3 = new Node("3"); 453 Node n1 = new Node("1"), n2 = new Node("2"), n3 = new Node("3");
437 n1.children = [n2, n3]; 454 n1.children = [n2, n3];
438 n2.parent = n1; 455 n2.parent = n1;
439 n3.parent = n1; 456 n3.parent = n1;
440 var s = serializerSetUp(n1); 457 var s = serializerSetUp(n1);
441 var output = s.writeFlat(n2); 458 var output = s.writeFlat(n2);
442 expect(output is List, isTrue); 459 expect(output is List, isTrue);
443 var s2 = serializerSetUp(n1); 460 var s2 = serializerSetUp(n1);
444 var reader = new Reader(s2); 461 var reader = new Reader(s2);
445 var m2 = reader.readFlat(output).first; 462 var m2 = reader.readFlat(output);
446 var m1 = m2.parent; 463 var m1 = m2.parent;
447 expect(m1 is Node, isTrue); 464 expect(m1 is Node, isTrue);
448 var children = m1.children; 465 var children = m1.children;
449 expect(m1.name,"1"); 466 expect(m1.name,"1");
450 var m3 = m1.children.last; 467 var m3 = m1.children.last;
451 expect(m2.name, "2"); 468 expect(m2.name, "2");
452 expect(m3.name, "3"); 469 expect(m3.name, "3");
453 expect(m2.parent, m1); 470 expect(m2.parent, m1);
454 expect(m3.parent, m1); 471 expect(m3.parent, m1);
455 expect(m1.parent, isNull); 472 expect(m1.parent, isNull);
456 } 473 }
457 474
458 /** Extract the state from [object] using the rules in [s] and return it. */ 475 /** Extract the state from [object] using the rules in [s] and return it. */
459 states(Object object, Serialization s) { 476 states(object, Serialization s) {
460 var rules = s.rulesFor(object); 477 var rules = s.rulesFor(object, null);
461 return rules.map((x) => x.extractState(object, doNothing)); 478 return rules.map((x) => x.extractState(object, doNothing));
479 }
480
481 /** A hard-coded rule for serializing Node instances. */
482 class NodeRule extends CustomRule {
483 bool appliesTo(instance, _) => instance is Node;
484 getState(instance) => [instance.parent, instance.name, instance.children];
485 create(state) => new Node(state[1]);
486 setState(Node node, state) {
487 node.parent = state[0];
488 node.children = state[2];
489 }
462 } 490 }
OLDNEW
« no previous file with comments | « pkg/serialization/lib/src/serialization_rule.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698