| Index: pkg/serialization/test/serialization_test.dart
|
| diff --git a/pkg/serialization/test/serialization_test.dart b/pkg/serialization/test/serialization_test.dart
|
| index f4713a28255da989b246836916efc25ebf0452a0..d45f562ded99ed1e0558d3b2b1d0ec375bdfbc5b 100644
|
| --- a/pkg/serialization/test/serialization_test.dart
|
| +++ b/pkg/serialization/test/serialization_test.dart
|
| @@ -18,6 +18,9 @@ main() {
|
| a1.street = 'N 34th';
|
| a1.city = 'Seattle';
|
|
|
| + var formats = [new SimpleFlatFormat(), new SimpleMapFormat(),
|
| + new SimpleJsonFormat(storeRoundTripInfo: true)];
|
| +
|
| test('Basic extraction of a simple object', () {
|
| // TODO(alanknight): Switch these to use literal types. Issue
|
| var s = new Serialization()
|
| @@ -37,8 +40,6 @@ main() {
|
| });
|
|
|
| test('Slightly further with a simple object', () {
|
| - // TODO(alanknight): Tests that rely on what index rules are going to be
|
| - // at are very fragile. At least abstract it to something calculated.
|
| var p1 = new Person()..name = 'Alice'..address = a1;
|
| var s = new Serialization()
|
| ..addRuleFor(p1).configureForMaps()
|
| @@ -259,14 +260,23 @@ main() {
|
| // Create a meta-serializer, that serializes serializations, then
|
| // use it to serialize a basic serialization, then run a test on the
|
| // the result.
|
| - var s = new Serialization()
|
| + var s = new Serialization.blank()
|
| + // Add the rules in a deliberately unusual order.
|
| ..addRuleFor(new Node(''), constructorFields: ['name'])
|
| + ..addRule(new ListRule())
|
| + ..addRule(new PrimitiveRule())
|
| ..selfDescribing = false;
|
| var meta = metaSerialization();
|
| - var serialized = meta.write(s);
|
| - var s2 = new Reader(meta)
|
| - .read(serialized, {"Node" : reflect(new Node('')).type});
|
| - runRoundTripTest((x) => s2);
|
| + var metaWithMaps = metaSerializationUsingMaps();
|
| + for (var eachFormat in formats) {
|
| + for (var eachMeta in [meta, metaWithMaps]) {
|
| + var serialized = eachMeta.write(s, eachFormat);
|
| + var reader = new Reader(eachMeta, eachFormat);
|
| + var newSerialization = reader.read(serialized,
|
| + {"serialization_test.Node" : reflect(new Node('')).type});
|
| + runRoundTripTest((x) => newSerialization);
|
| + }
|
| + }
|
| });
|
|
|
| test("Verify we're not serializing lists twice if they're essential", () {
|
| @@ -320,7 +330,7 @@ main() {
|
| constructor: 'withData',
|
| constructorFields: ["street", "Kirkland", "WA", "98103"],
|
| fields: []);
|
| - String out = s.write(a1);
|
| + var out = s.write(a1);
|
| var newAddress = s.read(out);
|
| expect(newAddress.street, a1.street);
|
| expect(newAddress.city, "Kirkland");
|
| @@ -331,7 +341,7 @@ main() {
|
| test("Straight JSON format", () {
|
| var s = new Serialization();
|
| var writer = s.newWriter(new SimpleJsonFormat());
|
| - var out = writer.write(a1);
|
| + var out = json.stringify(writer.write(a1));
|
| var reconstituted = json.parse(out);
|
| expect(reconstituted.length, 4);
|
| expect(reconstituted[0], "Seattle");
|
| @@ -339,23 +349,23 @@ main() {
|
|
|
| test("Straight JSON format, nested objects", () {
|
| var p1 = new Person()..name = 'Alice'..address = a1;
|
| - var s = new Serialization();
|
| + var s = new Serialization()..selfDescribing = false;
|
| var addressRule = s.addRuleFor(a1)..configureForMaps();
|
| var personRule = s.addRuleFor(p1)..configureForMaps();
|
| var writer = s.newWriter(new SimpleJsonFormat(storeRoundTripInfo: true));
|
| - var out = writer.write(p1);
|
| + var out = json.stringify(writer.write(p1));
|
| var reconstituted = json.parse(out);
|
| var expected = {
|
| "name" : "Alice",
|
| "rank" : null,
|
| "serialNumber" : null,
|
| - "__rule" : personRule.number,
|
| + "_rule" : personRule.number,
|
| "address" : {
|
| "street" : "N 34th",
|
| "city" : "Seattle",
|
| "state" : null,
|
| "zip" : null,
|
| - "__rule" : addressRule.number
|
| + "_rule" : addressRule.number
|
| }
|
| };
|
| expect(expected, reconstituted);
|
| @@ -368,40 +378,65 @@ main() {
|
| var s = new Serialization()
|
| ..addRuleFor(a1)
|
| ..addRuleFor(p1).configureForMaps();
|
| - var writer = s.newWriter(new SimpleJsonFormat(storeRoundTripInfo: true));
|
| - var out = writer.write(p1);
|
| - var reader = s.newReader(new SimpleJsonFormat(storeRoundTripInfo: true));
|
| - var p2 = reader.read(out);
|
| + var p2 = writeAndReadBack(s,
|
| + new SimpleJsonFormat(storeRoundTripInfo: true), p1);
|
| expect(p2.name, "Alice");
|
| var a2 = p2.address;
|
| expect(a2.street, "N 34th");
|
| expect(a2.city, "Seattle");
|
| });
|
|
|
| - test("Straight JSON format, root is a Map", () {
|
| + test("Root is a Map", () {
|
| // Note that we can't use the usual round-trip test because it has cycles.
|
| var p1 = new Person()..name = 'Alice'..address = a1;
|
| // Use maps for one rule, lists for the other.
|
| var s = new Serialization()
|
| ..addRuleFor(a1)
|
| ..addRuleFor(p1).configureForMaps();
|
| - var format = new SimpleJsonFormat(storeRoundTripInfo: true);
|
| - var writer = s.newWriter(format);
|
| - var out = writer.write({"stuff" : p1});
|
| - var reader = s.newReader(format);
|
| - var p2 = reader.read(out)["stuff"];
|
| - expect(p2.name, "Alice");
|
| - var a2 = p2.address;
|
| + for (var eachFormat in formats) {
|
| + var w = s.newWriter(eachFormat);
|
| + var output = w.write({"stuff" : p1});
|
| + var r = s.newReader(w.format);
|
| + var result = r.read(output);
|
| + var p2 = result["stuff"];
|
| + expect(p2.name, "Alice");
|
| + var a2 = p2.address;
|
| + expect(a2.street, "N 34th");
|
| + expect(a2.city, "Seattle");
|
| + }
|
| + });
|
| +
|
| + test("Root is a List", () {
|
| + var s = new Serialization();
|
| + for (var eachFormat in formats) {
|
| + var result = writeAndReadBack(s, eachFormat, [a1]);
|
| + var a2 = result.first;
|
| expect(a2.street, "N 34th");
|
| expect(a2.city, "Seattle");
|
| + }
|
| });
|
|
|
| + test("Root is a simple object", () {
|
| + var s = new Serialization();
|
| + for (var eachFormat in formats) {
|
| + expect(writeAndReadBack(s, eachFormat, null), null);
|
| + expect(writeAndReadBack(s, eachFormat, [null]), [null]);
|
| + expect(writeAndReadBack(s, eachFormat, 3), 3);
|
| + expect(writeAndReadBack(s, eachFormat, [3]), [3]);
|
| + expect(writeAndReadBack(s, eachFormat, "hello"), "hello");
|
| + expect(writeAndReadBack(s, eachFormat, [3]), [3]);
|
| + expect(writeAndReadBack(s, eachFormat, {"hello" : "world"}),
|
| + {"hello" : "world"});
|
| + expect(writeAndReadBack(s, eachFormat, true), true);
|
| + }
|
| + });
|
|
|
| - test("Straight JSON format, round-trip with named objects", () {
|
| + test("Simple JSON format, round-trip with named objects", () {
|
| // Note that we can't use the usual round-trip test because it has cycles.
|
| var p1 = new Person()..name = 'Alice'..address = a1;
|
| // Use maps for one rule, lists for the other.
|
| var s = new Serialization()
|
| + ..selfDescribing = false
|
| ..addRule(new NamedObjectRule())
|
| ..addRuleFor(a1)
|
| ..addRuleFor(p1).configureForMaps()
|
| @@ -415,15 +450,13 @@ main() {
|
| expect(a2, 12);
|
| });
|
|
|
| - test("Maps", () {
|
| + test("More complicated Maps", () {
|
| var s = new Serialization()..selfDescribing = false;
|
| var p1 = new Person()..name = 'Alice'..address = a1;
|
| var data = new Map();
|
| data["simple data"] = 1;
|
| data[p1] = a1;
|
| data[a1] = p1;
|
| - var formats = [new SimpleFlatFormat(), new SimpleMapFormat(),
|
| - new SimpleJsonFormat(storeRoundTripInfo: true)];
|
| for (var eachFormat in formats) {
|
| var output = s.write(data, eachFormat);
|
| var reader = s.newReader(eachFormat);
|
| @@ -456,12 +489,13 @@ main() {
|
| data["person"] = new Person()..name = "Foo";
|
| var output = s.write(data, new SimpleMapFormat());
|
| var mapRule = s.rules.firstMatching((x) => x is MapRule);
|
| - var map = json.parse(output)["data"][mapRule.number][0];
|
| + var map = output["data"][mapRule.number][0];
|
| expect(map is Map, isTrue);
|
| expect(map["abc"], 1);
|
| expect(map["def"], "ghi");
|
| expect(new Reader(s).asReference(map["person"]) is Reference, isTrue);
|
| });
|
| +
|
| }
|
|
|
| /******************************************************************************
|
| @@ -469,6 +503,13 @@ main() {
|
| * it easier to write the repetitive sections.
|
| ******************************************************************************/
|
|
|
| +writeAndReadBack(Serialization s, Format format, object) {
|
| + var w = s.newWriter(format);
|
| + var output = w.write(object);
|
| + var r = s.newReader(w.format);
|
| + return r.read(output);
|
| +}
|
| +
|
| /** Create a Serialization for serializing Serializations. */
|
| Serialization metaSerialization() {
|
| // Make some bogus rule instances so we have something to feed rule creation
|
| @@ -492,7 +533,15 @@ Serialization metaSerialization() {
|
| rules.forEach((x) => s.reflectee.addRule(x));
|
| })
|
| ..addRule(new NamedObjectRule())
|
| - ..addRule(new MirrorRule());
|
| + ..addRule(new MirrorRule())
|
| + ..addRule(new MapRule());
|
| + return meta;
|
| +}
|
| +
|
| +Serialization metaSerializationUsingMaps() {
|
| + var meta = metaSerialization();
|
| + meta.rules.where((each) => each is BasicRule)
|
| + .forEach((x) => x.configureForMaps());
|
| return meta;
|
| }
|
|
|
| @@ -515,6 +564,7 @@ Reader setUpReader(aSerialization, sampleData) {
|
| var reader = new Reader(aSerialization);
|
| // We're not sure which rule needs the sample data, so put it everywhere
|
| // and trust that the extra will just be ignored.
|
| +
|
| var fillValue = [sampleData];
|
| var data = [];
|
| for (int i = 0; i < 10; i++) {
|
| @@ -641,7 +691,7 @@ runRoundTripTestFlat(serializerSetUp) {
|
| /** Extract the state from [object] using the rules in [s] and return it. */
|
| states(object, Serialization s) {
|
| var rules = s.rulesFor(object, null);
|
| - return rules.map((x) => x.extractState(object, doNothing)).toList();
|
| + return rules.map((x) => x.extractState(object, doNothing, null)).toList();
|
| }
|
|
|
| /** A hard-coded rule for serializing Node instances. */
|
|
|