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

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

Issue 11931030: Add a MapRule (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Changes from review comments Created 7 years, 11 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 | 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 'dart:json' as json; 7 import 'dart:json' as json;
8 import 'package:unittest/unittest.dart'; 8 import 'package:unittest/unittest.dart';
9 import 'package:serialization/serialization.dart'; 9 import 'package:serialization/serialization.dart';
10 import 'package:serialization/src/serialization_helpers.dart'; 10 import 'package:serialization/src/serialization_helpers.dart';
(...skipping 29 matching lines...) Expand all
40 // TODO(alanknight): Tests that rely on what index rules are going to be 40 // TODO(alanknight): Tests that rely on what index rules are going to be
41 // at are very fragile. At least abstract it to something calculated. 41 // at are very fragile. At least abstract it to something calculated.
42 var p1 = new Person()..name = 'Alice'..address = a1; 42 var p1 = new Person()..name = 'Alice'..address = a1;
43 var s = new Serialization() 43 var s = new Serialization()
44 ..addRuleFor(p1).configureForMaps() 44 ..addRuleFor(p1).configureForMaps()
45 ..addRuleFor(a1).configureForMaps(); 45 ..addRuleFor(a1).configureForMaps();
46 // TODO(alanknight): Need a better API for getting to flat state without 46 // TODO(alanknight): Need a better API for getting to flat state without
47 // actually writing. 47 // actually writing.
48 var w = new Writer(s); 48 var w = new Writer(s);
49 w.write(p1); 49 w.write(p1);
50 var flatPerson = w.states[3].first; 50 var personRule = s.rules.firstMatching(
51 (x) => x is BasicRule && x.type == reflect(p1).type);
52 var flatPerson = w.states[personRule.number].first;
51 var primStates = w.states.first; 53 var primStates = w.states.first;
52 expect(primStates.isEmpty, true); 54 expect(primStates.isEmpty, true);
53 expect(flatPerson["name"], "Alice"); 55 expect(flatPerson["name"], "Alice");
54 var ref = flatPerson["address"]; 56 var ref = flatPerson["address"];
55 expect(ref is Reference, true); 57 expect(ref is Reference, true);
56 expect(ref.ruleNumber, 4); 58 var addressRule = s.rules.firstMatching(
59 (x) => x is BasicRule && x.type == reflect(a1).type);
60 expect(ref.ruleNumber, addressRule.number);
57 expect(ref.objectNumber, 0); 61 expect(ref.objectNumber, 0);
58 expect(w.states[4].first['street'], 'N 34th'); 62 expect(w.states[addressRule.number].first['street'], 'N 34th');
59 }); 63 });
60 64
61 test('exclude fields', () { 65 test('exclude fields', () {
62 var s = new Serialization() 66 var s = new Serialization()
63 ..addRuleFor(a1, 67 ..addRuleFor(a1,
64 excludeFields: ['state', 'zip']).configureForMaps(); 68 excludeFields: ['state', 'zip']).configureForMaps();
65 var extracted = states(a1, s).first; 69 var extracted = states(a1, s).first;
66 expect(extracted.length, 2); 70 expect(extracted.length, 2);
67 expect(extracted['street'], 'N 34th'); 71 expect(extracted['street'], 'N 34th');
68 expect(extracted['city'], 'Seattle'); 72 expect(extracted['city'], 'Seattle');
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 expect(all.contains(n2), isTrue); 203 expect(all.contains(n2), isTrue);
200 expect(all.contains(n3), isTrue); 204 expect(all.contains(n3), isTrue);
201 expect(all.contains(n1.children), isTrue); 205 expect(all.contains(n1.children), isTrue);
202 }); 206 });
203 207
204 test('Flatten references in a cyclical structure', () { 208 test('Flatten references in a cyclical structure', () {
205 var s = new Serialization(); 209 var s = new Serialization();
206 var w = new Writer(s); 210 var w = new Writer(s);
207 w.trace = new Trace(w); 211 w.trace = new Trace(w);
208 w.write(n1); 212 w.write(n1);
209 expect(w.states.length, 4); // prims, lists, essential lists, basic 213 expect(w.states.length, 5); // prims, lists, essential lists, basic
210 var children = 0, name = 1, parent = 2; 214 var children = 0, name = 1, parent = 2;
211 List rootNode = w.states[3].where((x) => x[name] == "1").toList(); 215 var nodeRule = s.rules.firstMatching((x) => x is BasicRule);
216 List rootNode = w.states[nodeRule.number].where(
217 (x) => x[name] == "1").toList();
212 rootNode = rootNode.first; 218 rootNode = rootNode.first;
213 expect(rootNode[parent], isNull); 219 expect(rootNode[parent], isNull);
214 var list = w.states[1].first; 220 var list = w.states[1].first;
215 expect(w.stateForReference(rootNode[children]), list); 221 expect(w.stateForReference(rootNode[children]), list);
216 var parentNode = w.stateForReference(list[0])[parent]; 222 var parentNode = w.stateForReference(list[0])[parent];
217 expect(w.stateForReference(parentNode), rootNode); 223 expect(w.stateForReference(parentNode), rootNode);
218 }); 224 });
219 225
220 test('round-trip', () { 226 test('round-trip', () {
221 runRoundTripTest(nodeSerializerReflective); 227 runRoundTripTest(nodeSerializerReflective);
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 var writer = s.newWriter(new SimpleJsonFormat(storeRoundTripInfo: true)); 371 var writer = s.newWriter(new SimpleJsonFormat(storeRoundTripInfo: true));
366 var out = writer.write(p1); 372 var out = writer.write(p1);
367 var reader = s.newReader(new SimpleJsonFormat(storeRoundTripInfo: true)); 373 var reader = s.newReader(new SimpleJsonFormat(storeRoundTripInfo: true));
368 var p2 = reader.read(out); 374 var p2 = reader.read(out);
369 expect(p2.name, "Alice"); 375 expect(p2.name, "Alice");
370 var a2 = p2.address; 376 var a2 = p2.address;
371 expect(a2.street, "N 34th"); 377 expect(a2.street, "N 34th");
372 expect(a2.city, "Seattle"); 378 expect(a2.city, "Seattle");
373 }); 379 });
374 380
381 test("Straight JSON format, root is a Map", () {
382 // Note that we can't use the usual round-trip test because it has cycles.
383 var p1 = new Person()..name = 'Alice'..address = a1;
384 // Use maps for one rule, lists for the other.
385 var s = new Serialization()
386 ..addRuleFor(a1)
387 ..addRuleFor(p1).configureForMaps();
388 var format = new SimpleJsonFormat(storeRoundTripInfo: true);
389 var writer = s.newWriter(format);
390 var out = writer.write({"stuff" : p1});
391 var reader = s.newReader(format);
392 var p2 = reader.read(out)["stuff"];
393 expect(p2.name, "Alice");
394 var a2 = p2.address;
395 expect(a2.street, "N 34th");
396 expect(a2.city, "Seattle");
397 });
398
399
375 test("Straight JSON format, round-trip with named objects", () { 400 test("Straight JSON format, round-trip with named objects", () {
376 // Note that we can't use the usual round-trip test because it has cycles. 401 // Note that we can't use the usual round-trip test because it has cycles.
377 var p1 = new Person()..name = 'Alice'..address = a1; 402 var p1 = new Person()..name = 'Alice'..address = a1;
378 // Use maps for one rule, lists for the other. 403 // Use maps for one rule, lists for the other.
379 var s = new Serialization() 404 var s = new Serialization()
380 ..addRule(new NamedObjectRule()) 405 ..addRule(new NamedObjectRule())
381 ..addRuleFor(a1) 406 ..addRuleFor(a1)
382 ..addRuleFor(p1).configureForMaps() 407 ..addRuleFor(p1).configureForMaps()
383 ..namedObjects["foo"] = a1; 408 ..namedObjects["foo"] = a1;
384 var writer = s.newWriter(new SimpleJsonFormat(storeRoundTripInfo: true)); 409 var writer = s.newWriter(new SimpleJsonFormat(storeRoundTripInfo: true));
385 var out = writer.write(p1); 410 var out = writer.write(p1);
386 var reader = s.newReader(new SimpleJsonFormat(storeRoundTripInfo: true)); 411 var reader = s.newReader(new SimpleJsonFormat(storeRoundTripInfo: true));
387 var p2 = reader.read(out, {"foo" : 12}); 412 var p2 = reader.read(out, {"foo" : 12});
388 expect(p2.name, "Alice"); 413 expect(p2.name, "Alice");
389 var a2 = p2.address; 414 var a2 = p2.address;
390 expect(a2, 12); 415 expect(a2, 12);
391 }); 416 });
417
418 test("Maps", () {
419 var s = new Serialization()..selfDescribing = false;
420 var p1 = new Person()..name = 'Alice'..address = a1;
421 var data = new Map();
422 data["simple data"] = 1;
423 data[p1] = a1;
424 data[a1] = p1;
425 var formats = [new SimpleFlatFormat(), new SimpleMapFormat(),
426 new SimpleJsonFormat(storeRoundTripInfo: true)];
427 for (var eachFormat in formats) {
428 var output = s.write(data, eachFormat);
429 var reader = s.newReader(eachFormat);
430 var input = reader.read(output);
431 expect(input["simple data"], data["simple data"]);
432 var p2 = input.keys.firstMatching((x) => x is Person);
433 var a2 = input.keys.firstMatching((x) => x is Address);
434 if (eachFormat is SimpleJsonFormat) {
435 // JSON doesn't handle cycles, so these won't be identical.
436 expect(input[p2] is Address, isTrue);
437 expect(input[a2] is Person, isTrue);
438 var a3 = input[p2];
439 expect(a3.city, a2.city);
440 expect(a3.state, a2.state);
441 expect(a3.state, a2.state);
442 var p3 = input[a2];
443 expect(p3.name, p2.name);
444 expect(p3.rank, p2.rank);
445 expect(p3.address.city, a2.city);
446 } else {
447 expect(input[p2], same(a2));
448 expect(input[a2], same(p2));
449 }
450 }
451 });
452
453 test("Map with string keys stays that way", () {
454 var s = new Serialization()..addRuleFor(new Person());
455 var data = {"abc" : 1, "def" : "ghi"};
456 data["person"] = new Person()..name = "Foo";
457 var output = s.write(data, new SimpleMapFormat());
458 var mapRule = s.rules.firstMatching((x) => x is MapRule);
459 var map = json.parse(output)["data"][mapRule.number][0];
460 expect(map is Map, isTrue);
461 expect(map["abc"], 1);
462 expect(map["def"], "ghi");
463 expect(new Reader(s).asReference(map["person"]) is Reference, isTrue);
464 });
392 } 465 }
393 466
394 /****************************************************************************** 467 /******************************************************************************
395 * The end of the tests and the beginning of various helper functions to make 468 * The end of the tests and the beginning of various helper functions to make
396 * it easier to write the repetitive sections. 469 * it easier to write the repetitive sections.
397 ******************************************************************************/ 470 ******************************************************************************/
398 471
399 /** Create a Serialization for serializing Serializations. */ 472 /** Create a Serialization for serializing Serializations. */
400 Serialization metaSerialization() { 473 Serialization metaSerialization() {
401 // Make some bogus rule instances so we have something to feed rule creation 474 // Make some bogus rule instances so we have something to feed rule creation
402 // and get their types. If only we had class literals implemented... 475 // and get their types. If only we had class literals implemented...
403 var basicRule = new BasicRule(reflect(null).type, '', [], [], []); 476 var basicRule = new BasicRule(reflect(null).type, '', [], [], []);
404 477
405 var meta = new Serialization() 478 var meta = new Serialization()
406 ..selfDescribing = false 479 ..selfDescribing = false
407 ..addRuleFor(new ListRule()) 480 ..addRuleFor(new ListRule())
408 ..addRuleFor(new PrimitiveRule()) 481 ..addRuleFor(new PrimitiveRule())
409 // TODO(alanknight): Handle CustomRule as well. 482 // TODO(alanknight): Handle CustomRule as well.
410 // Note that we're passing in a constant for one of the fields. 483 // Note that we're passing in a constant for one of the fields.
411 ..addRuleFor(basicRule, 484 ..addRuleFor(basicRule,
412 constructorFields: ['type', 485 constructorFields: ['type',
413 'constructorName', 486 'constructorName',
414 'constructorFields', 'regularFields', []], 487 'constructorFields', 'regularFields', []],
415 fields: []) 488 fields: [])
416 ..addRuleFor(new Serialization()).setFieldWith('rules', 489 ..addRuleFor(new Serialization(), constructor: "blank")
417 (InstanceMirror s, List rules) { 490 .setFieldWith('rules',
491 (InstanceMirror s, List rules) {
418 rules.forEach((x) => s.reflectee.addRule(x)); 492 rules.forEach((x) => s.reflectee.addRule(x));
419 }) 493 })
420 ..addRule(new NamedObjectRule()) 494 ..addRule(new NamedObjectRule())
421 ..addRule(new MirrorRule()); 495 ..addRule(new MirrorRule());
422 return meta; 496 return meta;
423 } 497 }
424 498
425 /** 499 /**
426 * Read back a simple object, assumed to be the only one of its class in the 500 * Read back a simple object, assumed to be the only one of its class in the
427 * reader. 501 * reader.
428 */ 502 */
429 readBackSimple(Serialization s, object, Reader reader) { 503 readBackSimple(Serialization s, object, Reader reader) {
430 var rule = s.rulesFor(object, null).first; 504 var rule = s.rulesFor(object, null).first;
431 reader.inflateForRule(rule); 505 reader.inflateForRule(rule);
432 var list2 = reader.allObjectsForRule(rule).first; 506 var list2 = reader.allObjectsForRule(rule).first;
433 return list2; 507 return list2;
434 } 508 }
435 509
436 /** 510 /**
437 * Set up a basic reader with some fake data. Hard-codes the assumption 511 * Set up a basic reader with some fake data. Hard-codes the assumption
438 * of how many rules there are. 512 * of how many rules there are.
439 */ 513 */
440 Reader setUpReader(aSerialization, sampleData) { 514 Reader setUpReader(aSerialization, sampleData) {
441 var reader = new Reader(aSerialization); 515 var reader = new Reader(aSerialization);
442 // We're not sure which rule needs the sample data, so put it everywhere 516 // We're not sure which rule needs the sample data, so put it everywhere
443 // and trust that the extra will just be ignored. 517 // and trust that the extra will just be ignored.
444 reader.data = [[sampleData], [sampleData], [sampleData], [sampleData]]; 518 reader.data = new List.filled(10, [sampleData]);
445 return reader; 519 return reader;
446 } 520 }
447 521
448 /** Return a serialization for Node objects, using a reflective rule. */ 522 /** Return a serialization for Node objects, using a reflective rule. */
449 Serialization nodeSerializerReflective(Node n) { 523 Serialization nodeSerializerReflective(Node n) {
450 return new Serialization() 524 return new Serialization()
451 ..addRuleFor(n, constructorFields: ["name"]) 525 ..addRuleFor(n, constructorFields: ["name"])
452 ..namedObjects['Node'] = reflect(new Node('')).type; 526 ..namedObjects['Node'] = reflect(new Node('')).type;
453 } 527 }
454 528
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 641
568 /** A hard-coded rule for serializing Node instances. */ 642 /** A hard-coded rule for serializing Node instances. */
569 class NodeRule extends CustomRule { 643 class NodeRule extends CustomRule {
570 bool appliesTo(instance, _) => instance.runtimeType == Node; 644 bool appliesTo(instance, _) => instance.runtimeType == Node;
571 getState(instance) => [instance.parent, instance.name, instance.children]; 645 getState(instance) => [instance.parent, instance.name, instance.children];
572 create(state) => new Node(state[1]); 646 create(state) => new Node(state[1]);
573 setState(Node node, state) { 647 setState(Node node, state) {
574 node.parent = state[0]; 648 node.parent = state[0];
575 node.children = state[2]; 649 node.children = state[2];
576 } 650 }
577 } 651 }
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