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

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

Issue 23447003: Change reflective serialization rules to be able to take type literals (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 3 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/test/no_library_test.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';
11 import 'package:serialization/src/mirrors_helpers.dart'; 11 import 'package:serialization/src/mirrors_helpers.dart';
12 import 'dart:isolate'; 12 import 'dart:isolate';
13 13
14 part 'test_models.dart'; 14 part 'test_models.dart';
15 15
16 void main() { 16 void main() {
17 var p1 = new Person(); 17 var p1 = new Person();
18 var a1 = new Address(); 18 var a1 = new Address();
19 a1.street = 'N 34th'; 19 a1.street = 'N 34th';
20 a1.city = 'Seattle'; 20 a1.city = 'Seattle';
21 21
22 var formats = [const InternalMapFormat(), 22 var formats = [const InternalMapFormat(),
23 const SimpleFlatFormat(), const SimpleMapFormat(), 23 const SimpleFlatFormat(), const SimpleMapFormat(),
24 const SimpleJsonFormat(storeRoundTripInfo: true)]; 24 const SimpleJsonFormat(storeRoundTripInfo: true)];
25 25
26 test('Basic extraction of a simple object', () { 26 test('Basic extraction of a simple object', () {
27 // TODO(alanknight): Switch these to use literal types. Issue 27 // TODO(alanknight): Switch these to use literal types. Issue
28 var s = new Serialization() 28 var s = new Serialization()
29 ..addRuleFor(a1).configureForMaps(); 29 ..addRuleFor(Address).configureForMaps();
30 Map extracted = states(a1, s).first; 30 Map extracted = states(a1, s).first;
31 expect(extracted.length, 4); 31 expect(extracted.length, 4);
32 expect(extracted['street'], 'N 34th'); 32 expect(extracted['street'], 'N 34th');
33 expect(extracted['city'], 'Seattle'); 33 expect(extracted['city'], 'Seattle');
34 expect(extracted['state'], null); 34 expect(extracted['state'], null);
35 expect(extracted['zip'], null); 35 expect(extracted['zip'], null);
36 Reader reader = setUpReader(s, extracted); 36 Reader reader = setUpReader(s, extracted);
37 Address a2 = readBackSimple(s, a1, reader); 37 Address a2 = readBackSimple(s, a1, reader);
38 expect(a2.street, 'N 34th'); 38 expect(a2.street, 'N 34th');
39 expect(a2.city, 'Seattle'); 39 expect(a2.city, 'Seattle');
40 expect(a2.state,null); 40 expect(a2.state,null);
41 expect(a2.zip, null); 41 expect(a2.zip, null);
42 }); 42 });
43 43
44 test('Slightly further with a simple object', () { 44 test('Slightly further with a simple object', () {
45 var p1 = new Person()..name = 'Alice'..address = a1; 45 var p1 = new Person()..name = 'Alice'..address = a1;
46 var s = new Serialization() 46 var s = new Serialization()
47 ..addRuleFor(p1).configureForMaps() 47 ..addRuleFor(Person).configureForMaps()
48 ..addRuleFor(a1).configureForMaps(); 48 ..addRuleFor(Address).configureForMaps();
49 // TODO(alanknight): Need a better API for getting to flat state without 49 // TODO(alanknight): Need a better API for getting to flat state without
50 // actually writing. 50 // actually writing.
51 var w = new Writer(s, const InternalMapFormat()); 51 var w = new Writer(s, const InternalMapFormat());
52 w.write(p1); 52 w.write(p1);
53 var personRule = s.rules.firstWhere( 53 var personRule = s.rules.firstWhere(
54 (x) => x is BasicRule && x.type == reflect(p1).type); 54 (x) => x is BasicRule && x.type == reflect(p1).type);
55 var flatPerson = w.states[personRule.number].first; 55 var flatPerson = w.states[personRule.number].first;
56 var primStates = w.states.first; 56 var primStates = w.states.first;
57 expect(primStates.isEmpty, true); 57 expect(primStates.isEmpty, true);
58 expect(flatPerson["name"], "Alice"); 58 expect(flatPerson["name"], "Alice");
59 var ref = flatPerson["address"]; 59 var ref = flatPerson["address"];
60 expect(ref is Reference, true); 60 expect(ref is Reference, true);
61 var addressRule = s.rules.firstWhere( 61 var addressRule = s.rules.firstWhere(
62 (x) => x is BasicRule && x.type == reflect(a1).type); 62 (x) => x is BasicRule && x.type == reflect(a1).type);
63 expect(ref.ruleNumber, addressRule.number); 63 expect(ref.ruleNumber, addressRule.number);
64 expect(ref.objectNumber, 0); 64 expect(ref.objectNumber, 0);
65 expect(w.states[addressRule.number].first['street'], 'N 34th'); 65 expect(w.states[addressRule.number].first['street'], 'N 34th');
66 }); 66 });
67 67
68 test('exclude fields', () { 68 test('exclude fields', () {
69 var s = new Serialization() 69 var s = new Serialization()
70 ..addRuleFor(a1, 70 ..addRuleFor(Address,
71 excludeFields: ['state', 'zip']).configureForMaps(); 71 excludeFields: ['state', 'zip']).configureForMaps();
72 var extracted = states(a1, s).first; 72 var extracted = states(a1, s).first;
73 expect(extracted.length, 2); 73 expect(extracted.length, 2);
74 expect(extracted['street'], 'N 34th'); 74 expect(extracted['street'], 'N 34th');
75 expect(extracted['city'], 'Seattle'); 75 expect(extracted['city'], 'Seattle');
76 Reader reader = setUpReader(s, extracted); 76 Reader reader = setUpReader(s, extracted);
77 Address a2 = readBackSimple(s, a1, reader); 77 Address a2 = readBackSimple(s, a1, reader);
78 expect(a2.state, null); 78 expect(a2.state, null);
79 expect(a2.city, 'Seattle'); 79 expect(a2.city, 'Seattle');
80 }); 80 });
(...skipping 10 matching lines...) Expand all
91 var list2 = readBackSimple(s, list, reader); 91 var list2 = readBackSimple(s, list, reader);
92 expect(list, list2); 92 expect(list, list2);
93 }); 93 });
94 94
95 test('different kinds of fields', () { 95 test('different kinds of fields', () {
96 var x = new Various.Foo("d", "e"); 96 var x = new Various.Foo("d", "e");
97 x.a = "a"; 97 x.a = "a";
98 x.b = "b"; 98 x.b = "b";
99 x._c = "c"; 99 x._c = "c";
100 var s = new Serialization() 100 var s = new Serialization()
101 ..addRuleFor(x, 101 ..addRuleFor(Various,
102 constructor: "Foo", 102 constructor: "Foo",
103 constructorFields: ["d", "e"]); 103 constructorFields: ["d", "e"]);
104 var state = states(x, s).first; 104 var state = states(x, s).first;
105 expect(state.length, 4); 105 expect(state.length, 4);
106 var expected = "abde"; 106 var expected = "abde";
107 for (var i in [0,1,2,3]) { 107 for (var i in [0,1,2,3]) {
108 expect(state[i], expected[i]); 108 expect(state[i], expected[i]);
109 } 109 }
110 Reader reader = setUpReader(s, state); 110 Reader reader = setUpReader(s, state);
111 Various y = readBackSimple(s, x, reader); 111 Various y = readBackSimple(s, x, reader);
(...skipping 14 matching lines...) Expand all
126 expect((stream..next()).next(), 4); 126 expect((stream..next()).next(), 4);
127 expect(stream.position, 2); 127 expect(stream.position, 2);
128 // The Symbol class does not allow us to create symbols for private 128 // The Symbol class does not allow us to create symbols for private
129 // variables. However, the mirror system uses them. So we get the symbol 129 // variables. However, the mirror system uses them. So we get the symbol
130 // we want from the mirror. 130 // we want from the mirror.
131 // TODO(alanknight): Either delete this test and decide we shouldn't 131 // TODO(alanknight): Either delete this test and decide we shouldn't
132 // attempt to access private variables or fix this properly. 132 // attempt to access private variables or fix this properly.
133 var _collectionSym = reflect(stream).type.variables.keys.firstWhere( 133 var _collectionSym = reflect(stream).type.variables.keys.firstWhere(
134 (x) => MirrorSystem.getName(x) == "_collection"); 134 (x) => MirrorSystem.getName(x) == "_collection");
135 var s = new Serialization() 135 var s = new Serialization()
136 ..addRuleFor(stream, 136 ..addRuleFor(Stream,
137 constructorFields: [_collectionSym]); 137 constructorFields: [_collectionSym]);
138 var state = states(stream, s).first; 138 var state = states(stream, s).first;
139 // Define names for the variable offsets to make this more readable. 139 // Define names for the variable offsets to make this more readable.
140 var _collection = 0, position = 1; 140 var _collection = 0, position = 1;
141 expect(state[_collection],[3,4,5]); 141 expect(state[_collection],[3,4,5]);
142 expect(state[position], 2); 142 expect(state[position], 2);
143 }); 143 });
144 144
145 test('date', () { 145 test('date', () {
146 var date = new DateTime.now(); 146 var date = new DateTime.now();
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 test('round-trip with Node CustomRule, to maps', () { 282 test('round-trip with Node CustomRule, to maps', () {
283 runRoundTripTest(nodeSerializerCustom); 283 runRoundTripTest(nodeSerializerCustom);
284 }); 284 });
285 285
286 test('eating your own tail', () { 286 test('eating your own tail', () {
287 // Create a meta-serializer, that serializes serializations, then 287 // Create a meta-serializer, that serializes serializations, then
288 // use it to serialize a basic serialization, then run a test on the 288 // use it to serialize a basic serialization, then run a test on the
289 // the result. 289 // the result.
290 var s = new Serialization.blank() 290 var s = new Serialization.blank()
291 // Add the rules in a deliberately unusual order. 291 // Add the rules in a deliberately unusual order.
292 ..addRuleFor(new Node(''), constructorFields: ['name']) 292 ..addRuleFor(Node, constructorFields: ['name'])
293 ..addRule(new ListRule()) 293 ..addRule(new ListRule())
294 ..addRule(new PrimitiveRule()) 294 ..addRule(new PrimitiveRule())
295 ..selfDescribing = false; 295 ..selfDescribing = false;
296 var meta = metaSerialization(); 296 var meta = metaSerialization();
297 var metaWithMaps = metaSerializationUsingMaps(); 297 var metaWithMaps = metaSerializationUsingMaps();
298 for (var eachFormat in formats) { 298 for (var eachFormat in formats) {
299 for (var eachMeta in [meta, metaWithMaps]) { 299 for (var eachMeta in [meta, metaWithMaps]) {
300 var serialized = eachMeta.write(s, format: eachFormat); 300 var serialized = eachMeta.write(s, format: eachFormat);
301 var newSerialization = eachMeta.read(serialized, format: eachFormat, 301 var newSerialization = eachMeta.read(serialized, format: eachFormat,
302 externals: {"serialization_test.Node" : reflect(new Node('')).type} 302 externals: {"serialization_test.Node" : reflect(new Node('')).type}
303 ); 303 );
304 runRoundTripTest((x) => newSerialization); 304 runRoundTripTest((x) => newSerialization);
305 } 305 }
306 } 306 }
307 }); 307 });
308 308
309 test("Verify we're not serializing lists twice if they're essential", () { 309 test("Verify we're not serializing lists twice if they're essential", () {
310 Node n1 = new Node("1"), n2 = new Node("2"), n3 = new Node("3"); 310 Node n1 = new Node("1"), n2 = new Node("2"), n3 = new Node("3");
311 n1.children = [n2, n3]; 311 n1.children = [n2, n3];
312 n2.parent = n1; 312 n2.parent = n1;
313 n3.parent = n1; 313 n3.parent = n1;
314 var s = new Serialization() 314 var s = new Serialization()
315 ..addRuleFor(n1, constructorFields: ["name"]). 315 ..addRuleFor(Node, constructorFields: ["name"]).
316 setFieldWith("children", (parent, child) => 316 setFieldWith("children", (parent, child) =>
317 parent.reflectee.children = child); 317 parent.reflectee.children = child);
318 var w = new Writer(s); 318 var w = new Writer(s);
319 w.write(n1); 319 w.write(n1);
320 expect(w.rules[2] is ListRuleEssential, isTrue); 320 expect(w.rules[2] is ListRuleEssential, isTrue);
321 expect(w.rules[1] is ListRule, isTrue); 321 expect(w.rules[1] is ListRule, isTrue);
322 expect(w.states[1].length, 0); 322 expect(w.states[1].length, 0);
323 expect(w.states[2].length, 1); 323 expect(w.states[2].length, 1);
324 s = new Serialization() 324 s = new Serialization()
325 ..addRuleFor(n1, constructorFields: ["name"]); 325 ..addRuleFor(Node, constructorFields: ["name"]);
326 w = new Writer(s); 326 w = new Writer(s);
327 w.write(n1); 327 w.write(n1);
328 expect(w.states[1].length, 1); 328 expect(w.states[1].length, 1);
329 expect(w.states[2].length, 0); 329 expect(w.states[2].length, 0);
330 }); 330 });
331 331
332 test('Identity of equal objects preserved', () { 332 test('Identity of equal objects preserved', () {
333 Node n1 = new NodeEqualByName("foo"), 333 Node n1 = new NodeEqualByName("foo"),
334 n2 = new NodeEqualByName("foo"), 334 n2 = new NodeEqualByName("foo"),
335 n3 = new NodeEqualByName("3"); 335 n3 = new NodeEqualByName("3");
336 n1.children = [n2, n3]; 336 n1.children = [n2, n3];
337 n2.parent = n1; 337 n2.parent = n1;
338 n3.parent = n1; 338 n3.parent = n1;
339 var s = new Serialization() 339 var s = new Serialization()
340 ..selfDescribing = false 340 ..selfDescribing = false
341 ..addRuleFor(n1, constructorFields: ["name"]); 341 ..addRuleFor(NodeEqualByName, constructorFields: ["name"]);
342 var m1 = writeAndReadBack(s, null, n1); 342 var m1 = writeAndReadBack(s, null, n1);
343 var m2 = m1.children.first; 343 var m2 = m1.children.first;
344 var m3 = m1.children.last; 344 var m3 = m1.children.last;
345 expect(m1, m2); 345 expect(m1, m2);
346 expect(identical(m1, m2), isFalse); 346 expect(identical(m1, m2), isFalse);
347 expect(m1 == m3, isFalse); 347 expect(m1 == m3, isFalse);
348 expect(identical(m2.parent, m3.parent), isTrue); 348 expect(identical(m2.parent, m3.parent), isTrue);
349 }); 349 });
350 350
351 test("Constant values as fields", () { 351 test("Constant values as fields", () {
352 var s = new Serialization() 352 var s = new Serialization()
353 ..selfDescribing = false 353 ..selfDescribing = false
354 ..addRuleFor(a1, 354 ..addRuleFor(Address,
355 constructor: 'withData', 355 constructor: 'withData',
356 constructorFields: ["street", "Kirkland", "WA", "98103"], 356 constructorFields: ["street", "Kirkland", "WA", "98103"],
357 fields: []); 357 fields: []);
358 var out = s.write(a1); 358 var out = s.write(a1);
359 var newAddress = s.read(out); 359 var newAddress = s.read(out);
360 expect(newAddress.street, a1.street); 360 expect(newAddress.street, a1.street);
361 expect(newAddress.city, "Kirkland"); 361 expect(newAddress.city, "Kirkland");
362 expect(newAddress.state, "WA"); 362 expect(newAddress.state, "WA");
363 expect(newAddress.zip, "98103"); 363 expect(newAddress.zip, "98103");
364 }); 364 });
365 365
366 test("Straight JSON format", () { 366 test("Straight JSON format", () {
367 var s = new Serialization(); 367 var s = new Serialization();
368 var writer = s.newWriter(const SimpleJsonFormat()); 368 var writer = s.newWriter(const SimpleJsonFormat());
369 var out = json.stringify(writer.write(a1)); 369 var out = json.stringify(writer.write(a1));
370 var reconstituted = json.parse(out); 370 var reconstituted = json.parse(out);
371 expect(reconstituted.length, 4); 371 expect(reconstituted.length, 4);
372 expect(reconstituted[0], "Seattle"); 372 expect(reconstituted[0], "Seattle");
373 }); 373 });
374 374
375 test("Straight JSON format, nested objects", () { 375 test("Straight JSON format, nested objects", () {
376 var p1 = new Person()..name = 'Alice'..address = a1; 376 var p1 = new Person()..name = 'Alice'..address = a1;
377 var s = new Serialization()..selfDescribing = false; 377 var s = new Serialization()..selfDescribing = false;
378 var addressRule = s.addRuleFor(a1)..configureForMaps(); 378 var addressRule = s.addRuleFor(Address)..configureForMaps();
379 var personRule = s.addRuleFor(p1)..configureForMaps(); 379 var personRule = s.addRuleFor(Person)..configureForMaps();
380 var writer = s.newWriter(const SimpleJsonFormat(storeRoundTripInfo: true)); 380 var writer = s.newWriter(const SimpleJsonFormat(storeRoundTripInfo: true));
381 var out = json.stringify(writer.write(p1)); 381 var out = json.stringify(writer.write(p1));
382 var reconstituted = json.parse(out); 382 var reconstituted = json.parse(out);
383 var expected = { 383 var expected = {
384 "name" : "Alice", 384 "name" : "Alice",
385 "rank" : null, 385 "rank" : null,
386 "serialNumber" : null, 386 "serialNumber" : null,
387 "_rule" : personRule.number, 387 "_rule" : personRule.number,
388 "address" : { 388 "address" : {
389 "street" : "N 34th", 389 "street" : "N 34th",
390 "city" : "Seattle", 390 "city" : "Seattle",
391 "state" : null, 391 "state" : null,
392 "zip" : null, 392 "zip" : null,
393 "_rule" : addressRule.number 393 "_rule" : addressRule.number
394 } 394 }
395 }; 395 };
396 expect(expected, reconstituted); 396 expect(expected, reconstituted);
397 }); 397 });
398 398
399 test("Straight JSON format, round-trip", () { 399 test("Straight JSON format, round-trip", () {
400 // Note that we can't use the usual round-trip test because it has cycles. 400 // Note that we can't use the usual round-trip test because it has cycles.
401 var p1 = new Person()..name = 'Alice'..address = a1; 401 var p1 = new Person()..name = 'Alice'..address = a1;
402 // Use maps for one rule, lists for the other. 402 // Use maps for one rule, lists for the other.
403 var s = new Serialization() 403 var s = new Serialization()
404 ..addRuleFor(a1) 404 ..addRuleFor(Address)
405 ..addRuleFor(p1).configureForMaps(); 405 ..addRuleFor(Person).configureForMaps();
406 var p2 = writeAndReadBack(s, 406 var p2 = writeAndReadBack(s,
407 const SimpleJsonFormat(storeRoundTripInfo: true), p1); 407 const SimpleJsonFormat(storeRoundTripInfo: true), p1);
408 expect(p2.name, "Alice"); 408 expect(p2.name, "Alice");
409 var a2 = p2.address; 409 var a2 = p2.address;
410 expect(a2.street, "N 34th"); 410 expect(a2.street, "N 34th");
411 expect(a2.city, "Seattle"); 411 expect(a2.city, "Seattle");
412 }); 412 });
413 413
414 test("Straight JSON format, non-string key", () { 414 test("Straight JSON format, non-string key", () {
415 // This tests what happens if we have a key that's not a string. That's 415 // This tests what happens if we have a key that's not a string. That's
416 // not allowed by json, so we don't actually turn it into a json string, 416 // not allowed by json, so we don't actually turn it into a json string,
417 // but someone might reasonably convert to a json-able structure without 417 // but someone might reasonably convert to a json-able structure without
418 // going through the string representation. 418 // going through the string representation.
419 var p1 = new Person()..name = 'Alice'..address = a1; 419 var p1 = new Person()..name = 'Alice'..address = a1;
420 var s = new Serialization() 420 var s = new Serialization()
421 ..addRule(new PersonRuleReturningMapWithNonStringKey()); 421 ..addRule(new PersonRuleReturningMapWithNonStringKey());
422 var p2 = writeAndReadBack(s, 422 var p2 = writeAndReadBack(s,
423 const SimpleJsonFormat(storeRoundTripInfo: true), p1); 423 const SimpleJsonFormat(storeRoundTripInfo: true), p1);
424 expect(p2.name, "Alice"); 424 expect(p2.name, "Alice");
425 expect(p2.address.street, "N 34th"); 425 expect(p2.address.street, "N 34th");
426 }); 426 });
427 427
428 test("Root is a Map", () { 428 test("Root is a Map", () {
429 // Note that we can't use the usual round-trip test because it has cycles. 429 // Note that we can't use the usual round-trip test because it has cycles.
430 var p1 = new Person()..name = 'Alice'..address = a1; 430 var p1 = new Person()..name = 'Alice'..address = a1;
431 // Use maps for one rule, lists for the other. 431 // Use maps for one rule, lists for the other.
432 var s = new Serialization() 432 var s = new Serialization()
433 // Deliberately left as passing instances to test backward-compatibility.
433 ..addRuleFor(a1) 434 ..addRuleFor(a1)
434 ..addRuleFor(p1).configureForMaps(); 435 ..addRuleFor(p1).configureForMaps();
435 for (var eachFormat in formats) { 436 for (var eachFormat in formats) {
436 var w = s.newWriter(eachFormat); 437 var w = s.newWriter(eachFormat);
437 var output = w.write({"stuff" : p1}); 438 var output = w.write({"stuff" : p1});
438 var result = s.read(output, format: w.format); 439 var result = s.read(output, format: w.format);
439 var p2 = result["stuff"]; 440 var p2 = result["stuff"];
440 expect(p2.name, "Alice"); 441 expect(p2.name, "Alice");
441 var a2 = p2.address; 442 var a2 = p2.address;
442 expect(a2.street, "N 34th"); 443 expect(a2.street, "N 34th");
(...skipping 26 matching lines...) Expand all
469 } 470 }
470 }); 471 });
471 472
472 test("Simple JSON format, round-trip with named objects", () { 473 test("Simple JSON format, round-trip with named objects", () {
473 // Note that we can't use the usual round-trip test because it has cycles. 474 // Note that we can't use the usual round-trip test because it has cycles.
474 var p1 = new Person()..name = 'Alice'..address = a1; 475 var p1 = new Person()..name = 'Alice'..address = a1;
475 // Use maps for one rule, lists for the other. 476 // Use maps for one rule, lists for the other.
476 var s = new Serialization() 477 var s = new Serialization()
477 ..selfDescribing = false 478 ..selfDescribing = false
478 ..addRule(new NamedObjectRule()) 479 ..addRule(new NamedObjectRule())
479 ..addRuleFor(a1) 480 ..addRuleFor(Address)
480 ..addRuleFor(p1).configureForMaps() 481 ..addRuleFor(Person).configureForMaps()
481 ..namedObjects["foo"] = a1; 482 ..namedObjects["foo"] = a1;
482 var format = const SimpleJsonFormat(storeRoundTripInfo: true); 483 var format = const SimpleJsonFormat(storeRoundTripInfo: true);
483 var out = s.write(p1, format: format); 484 var out = s.write(p1, format: format);
484 var p2 = s.read(out, format: format, externals: {"foo" : 12}); 485 var p2 = s.read(out, format: format, externals: {"foo" : 12});
485 expect(p2.name, "Alice"); 486 expect(p2.name, "Alice");
486 var a2 = p2.address; 487 var a2 = p2.address;
487 expect(a2, 12); 488 expect(a2, 12);
488 }); 489 });
489 490
490 test("More complicated Maps", () { 491 test("More complicated Maps", () {
(...skipping 22 matching lines...) Expand all
513 expect(p3.rank, p2.rank); 514 expect(p3.rank, p2.rank);
514 expect(p3.address.city, a2.city); 515 expect(p3.address.city, a2.city);
515 } else { 516 } else {
516 expect(input[p2], same(a2)); 517 expect(input[p2], same(a2));
517 expect(input[a2], same(p2)); 518 expect(input[a2], same(p2));
518 } 519 }
519 } 520 }
520 }); 521 });
521 522
522 test("Map with string keys stays that way", () { 523 test("Map with string keys stays that way", () {
523 var s = new Serialization()..addRuleFor(new Person()); 524 var s = new Serialization()..addRuleFor(Person);
524 var data = {"abc" : 1, "def" : "ghi"}; 525 var data = {"abc" : 1, "def" : "ghi"};
525 data["person"] = new Person()..name = "Foo"; 526 data["person"] = new Person()..name = "Foo";
526 var output = s.write(data, format: const InternalMapFormat()); 527 var output = s.write(data, format: const InternalMapFormat());
527 var mapRule = s.rules.firstWhere((x) => x is MapRule); 528 var mapRule = s.rules.firstWhere((x) => x is MapRule);
528 var map = output["data"][mapRule.number][0]; 529 var map = output["data"][mapRule.number][0];
529 expect(map is Map, isTrue); 530 expect(map is Map, isTrue);
530 expect(map["abc"], 1); 531 expect(map["abc"], 1);
531 expect(map["def"], "ghi"); 532 expect(map["def"], "ghi");
532 expect(map["person"] is Reference, isTrue); 533 expect(map["person"] is Reference, isTrue);
533 }); 534 });
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 } 583 }
583 584
584 /** Create a Serialization for serializing Serializations. */ 585 /** Create a Serialization for serializing Serializations. */
585 Serialization metaSerialization() { 586 Serialization metaSerialization() {
586 // Make some bogus rule instances so we have something to feed rule creation 587 // Make some bogus rule instances so we have something to feed rule creation
587 // and get their types. If only we had class literals implemented... 588 // and get their types. If only we had class literals implemented...
588 var basicRule = new BasicRule(reflect(null).type, '', [], [], []); 589 var basicRule = new BasicRule(reflect(null).type, '', [], [], []);
589 590
590 var meta = new Serialization() 591 var meta = new Serialization()
591 ..selfDescribing = false 592 ..selfDescribing = false
592 ..addRuleFor(new ListRule()) 593 ..addRuleFor(ListRule)
593 ..addRuleFor(new PrimitiveRule()) 594 ..addRuleFor(PrimitiveRule)
594 // TODO(alanknight): Handle CustomRule as well. 595 // TODO(alanknight): Handle CustomRule as well.
595 // Note that we're passing in a constant for one of the fields. 596 // Note that we're passing in a constant for one of the fields.
596 ..addRuleFor(basicRule, 597 ..addRuleFor(BasicRule,
597 constructorFields: ['type', 598 constructorFields: ['type',
598 'constructorName', 599 'constructorName',
599 'constructorFields', 'regularFields', []], 600 'constructorFields', 'regularFields', []],
600 fields: []) 601 fields: [])
601 ..addRuleFor(new Serialization(), constructor: "blank") 602 ..addRuleFor(Serialization, constructor: "blank")
602 .setFieldWith('rules', 603 .setFieldWith('rules',
603 (InstanceMirror s, List rules) { 604 (InstanceMirror s, List rules) {
604 rules.forEach((x) => s.reflectee.addRule(x)); 605 rules.forEach((x) => s.reflectee.addRule(x));
605 }) 606 })
606 ..addRule(new NamedObjectRule()) 607 ..addRule(new NamedObjectRule())
607 ..addRule(new MirrorRule()) 608 ..addRule(new MirrorRule())
608 ..addRule(new MapRule()); 609 ..addRule(new MapRule());
609 return meta; 610 return meta;
610 } 611 }
611 612
(...skipping 29 matching lines...) Expand all
641 for (int i = 0; i < 10; i++) { 642 for (int i = 0; i < 10; i++) {
642 data.add(fillValue); 643 data.add(fillValue);
643 } 644 }
644 reader.data = data; 645 reader.data = data;
645 return reader; 646 return reader;
646 } 647 }
647 648
648 /** Return a serialization for Node objects, using a reflective rule. */ 649 /** Return a serialization for Node objects, using a reflective rule. */
649 Serialization nodeSerializerReflective(Node n) { 650 Serialization nodeSerializerReflective(Node n) {
650 return new Serialization() 651 return new Serialization()
651 ..addRuleFor(n, constructorFields: ["name"]) 652 ..addRuleFor(Node, constructorFields: ["name"])
652 ..namedObjects['Node'] = reflect(new Node('')).type; 653 ..namedObjects['Node'] = reflect(new Node('')).type;
653 } 654 }
654 655
655 /** 656 /**
656 * Return a serialization for Node objects but using Maps for the internal 657 * Return a serialization for Node objects but using Maps for the internal
657 * representation rather than lists. 658 * representation rather than lists.
658 */ 659 */
659 Serialization nodeSerializerUsingMaps(Node n) { 660 Serialization nodeSerializerUsingMaps(Node n) {
660 return new Serialization() 661 return new Serialization()
661 ..addRuleFor(n, constructorFields: ["name"]).configureForMaps() 662 // Get the type using runtimeType to verify that works.
663 ..addRuleFor(n.runtimeType, constructorFields: ["name"]).configureForMaps()
662 ..namedObjects['Node'] = reflect(new Node('')).type; 664 ..namedObjects['Node'] = reflect(new Node('')).type;
663 } 665 }
664 666
665 /** 667 /**
666 * Return a serialization for Node objects but using Maps for the internal 668 * Return a serialization for Node objects but using Maps for the internal
667 * representation rather than lists. 669 * representation rather than lists.
668 */ 670 */
669 Serialization nodeSerializerCustom(Node n) { 671 Serialization nodeSerializerCustom(Node n) {
670 return new Serialization() 672 return new Serialization()
671 ..addRule(new NodeRule()); 673 ..addRule(new NodeRule());
672 } 674 }
673 675
674 /** 676 /**
675 * Return a serialization for Node objects where the "parent" instance 677 * Return a serialization for Node objects where the "parent" instance
676 * variable is considered essential state. 678 * variable is considered essential state.
677 */ 679 */
678 Serialization nodeSerializerWithEssentialParent(Node n) { 680 Serialization nodeSerializerWithEssentialParent(Node n) {
679 // Force the node rule to be first, in order to make a cycle which would 681 // Force the node rule to be first, in order to make a cycle which would
680 // not cause a problem if we handled the list first, because the list 682 // not cause a problem if we handled the list first, because the list
681 // considers all of its state non-essential, thus breaking the cycle. 683 // considers all of its state non-essential, thus breaking the cycle.
682 var s = new Serialization.blank() 684 var s = new Serialization.blank()
683 ..addRuleFor( 685 ..addRuleFor(
684 n, 686 Node,
685 constructor: "parentEssential", 687 constructor: "parentEssential",
686 constructorFields: ["parent"]) 688 constructorFields: ["parent"])
687 ..addDefaultRules() 689 ..addDefaultRules()
688 ..namedObjects['Node'] = reflect(new Node('')).type 690 ..namedObjects['Node'] = reflect(new Node('')).type
689 ..selfDescribing = false; 691 ..selfDescribing = false;
690 return s; 692 return s;
691 } 693 }
692 694
693 /** Return a serialization for Node objects using a ClosureToMapRule. */ 695 /** Return a serialization for Node objects using a ClosureToMapRule. */
694 Serialization nodeSerializerNonReflective(Node n) { 696 Serialization nodeSerializerNonReflective(Node n) {
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 806
805 /** 807 /**
806 * Function used in an isolate to make sure that the output passes through 808 * Function used in an isolate to make sure that the output passes through
807 * isolate serialization properly. 809 * isolate serialization properly.
808 */ 810 */
809 void echo() { 811 void echo() {
810 port.receive((msg, reply) { 812 port.receive((msg, reply) {
811 reply.send(msg); 813 reply.send(msg);
812 }); 814 });
813 } 815 }
OLDNEW
« no previous file with comments | « pkg/serialization/test/no_library_test.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698