OLD | NEW |
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 | 12 |
13 part 'test_models.dart'; | 13 part 'test_models.dart'; |
14 | 14 |
15 main() { | 15 main() { |
16 var p1 = new Person(); | 16 var p1 = new Person(); |
17 var a1 = new Address(); | 17 var a1 = new Address(); |
18 a1.street = 'N 34th'; | 18 a1.street = 'N 34th'; |
19 a1.city = 'Seattle'; | 19 a1.city = 'Seattle'; |
20 | 20 |
| 21 var formats = [new SimpleFlatFormat(), new SimpleMapFormat(), |
| 22 new SimpleJsonFormat(storeRoundTripInfo: true)]; |
| 23 |
21 test('Basic extraction of a simple object', () { | 24 test('Basic extraction of a simple object', () { |
22 // TODO(alanknight): Switch these to use literal types. Issue | 25 // TODO(alanknight): Switch these to use literal types. Issue |
23 var s = new Serialization() | 26 var s = new Serialization() |
24 ..addRuleFor(a1).configureForMaps(); | 27 ..addRuleFor(a1).configureForMaps(); |
25 Map extracted = states(a1, s).first; | 28 Map extracted = states(a1, s).first; |
26 expect(extracted.length, 4); | 29 expect(extracted.length, 4); |
27 expect(extracted['street'], 'N 34th'); | 30 expect(extracted['street'], 'N 34th'); |
28 expect(extracted['city'], 'Seattle'); | 31 expect(extracted['city'], 'Seattle'); |
29 expect(extracted['state'], null); | 32 expect(extracted['state'], null); |
30 expect(extracted['zip'], null); | 33 expect(extracted['zip'], null); |
31 Reader reader = setUpReader(s, extracted); | 34 Reader reader = setUpReader(s, extracted); |
32 Address a2 = readBackSimple(s, a1, reader); | 35 Address a2 = readBackSimple(s, a1, reader); |
33 expect(a2.street, 'N 34th'); | 36 expect(a2.street, 'N 34th'); |
34 expect(a2.city, 'Seattle'); | 37 expect(a2.city, 'Seattle'); |
35 expect(a2.state,null); | 38 expect(a2.state,null); |
36 expect(a2.zip, null); | 39 expect(a2.zip, null); |
37 }); | 40 }); |
38 | 41 |
39 test('Slightly further with a simple object', () { | 42 test('Slightly further with a simple object', () { |
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. | |
42 var p1 = new Person()..name = 'Alice'..address = a1; | 43 var p1 = new Person()..name = 'Alice'..address = a1; |
43 var s = new Serialization() | 44 var s = new Serialization() |
44 ..addRuleFor(p1).configureForMaps() | 45 ..addRuleFor(p1).configureForMaps() |
45 ..addRuleFor(a1).configureForMaps(); | 46 ..addRuleFor(a1).configureForMaps(); |
46 // TODO(alanknight): Need a better API for getting to flat state without | 47 // TODO(alanknight): Need a better API for getting to flat state without |
47 // actually writing. | 48 // actually writing. |
48 var w = new Writer(s); | 49 var w = new Writer(s); |
49 w.write(p1); | 50 w.write(p1); |
50 var personRule = s.rules.firstMatching( | 51 var personRule = s.rules.firstMatching( |
51 (x) => x is BasicRule && x.type == reflect(p1).type); | 52 (x) => x is BasicRule && x.type == reflect(p1).type); |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 }); | 253 }); |
253 | 254 |
254 test('round-trip with Node CustomRule, to maps', () { | 255 test('round-trip with Node CustomRule, to maps', () { |
255 runRoundTripTest(nodeSerializerCustom); | 256 runRoundTripTest(nodeSerializerCustom); |
256 }); | 257 }); |
257 | 258 |
258 test('eating your own tail', () { | 259 test('eating your own tail', () { |
259 // Create a meta-serializer, that serializes serializations, then | 260 // Create a meta-serializer, that serializes serializations, then |
260 // use it to serialize a basic serialization, then run a test on the | 261 // use it to serialize a basic serialization, then run a test on the |
261 // the result. | 262 // the result. |
262 var s = new Serialization() | 263 var s = new Serialization.blank() |
| 264 // Add the rules in a deliberately unusual order. |
263 ..addRuleFor(new Node(''), constructorFields: ['name']) | 265 ..addRuleFor(new Node(''), constructorFields: ['name']) |
| 266 ..addRule(new ListRule()) |
| 267 ..addRule(new PrimitiveRule()) |
264 ..selfDescribing = false; | 268 ..selfDescribing = false; |
265 var meta = metaSerialization(); | 269 var meta = metaSerialization(); |
266 var serialized = meta.write(s); | 270 var metaWithMaps = metaSerializationUsingMaps(); |
267 var s2 = new Reader(meta) | 271 for (var eachFormat in formats) { |
268 .read(serialized, {"Node" : reflect(new Node('')).type}); | 272 for (var eachMeta in [meta, metaWithMaps]) { |
269 runRoundTripTest((x) => s2); | 273 var serialized = eachMeta.write(s, eachFormat); |
| 274 var reader = new Reader(eachMeta, eachFormat); |
| 275 var newSerialization = reader.read(serialized, |
| 276 {"serialization_test.Node" : reflect(new Node('')).type}); |
| 277 runRoundTripTest((x) => newSerialization); |
| 278 } |
| 279 } |
270 }); | 280 }); |
271 | 281 |
272 test("Verify we're not serializing lists twice if they're essential", () { | 282 test("Verify we're not serializing lists twice if they're essential", () { |
273 Node n1 = new Node("1"), n2 = new Node("2"), n3 = new Node("3"); | 283 Node n1 = new Node("1"), n2 = new Node("2"), n3 = new Node("3"); |
274 n1.children = [n2, n3]; | 284 n1.children = [n2, n3]; |
275 n2.parent = n1; | 285 n2.parent = n1; |
276 n3.parent = n1; | 286 n3.parent = n1; |
277 var s = new Serialization() | 287 var s = new Serialization() |
278 ..addRuleFor(n1, constructorFields: ["name"]). | 288 ..addRuleFor(n1, constructorFields: ["name"]). |
279 setFieldWith("children", (parent, child) => | 289 setFieldWith("children", (parent, child) => |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 expect(identical(m2.parent, m3.parent), isTrue); | 323 expect(identical(m2.parent, m3.parent), isTrue); |
314 }); | 324 }); |
315 | 325 |
316 test("Constant values as fields", () { | 326 test("Constant values as fields", () { |
317 var s = new Serialization() | 327 var s = new Serialization() |
318 ..selfDescribing = false | 328 ..selfDescribing = false |
319 ..addRuleFor(a1, | 329 ..addRuleFor(a1, |
320 constructor: 'withData', | 330 constructor: 'withData', |
321 constructorFields: ["street", "Kirkland", "WA", "98103"], | 331 constructorFields: ["street", "Kirkland", "WA", "98103"], |
322 fields: []); | 332 fields: []); |
323 String out = s.write(a1); | 333 var out = s.write(a1); |
324 var newAddress = s.read(out); | 334 var newAddress = s.read(out); |
325 expect(newAddress.street, a1.street); | 335 expect(newAddress.street, a1.street); |
326 expect(newAddress.city, "Kirkland"); | 336 expect(newAddress.city, "Kirkland"); |
327 expect(newAddress.state, "WA"); | 337 expect(newAddress.state, "WA"); |
328 expect(newAddress.zip, "98103"); | 338 expect(newAddress.zip, "98103"); |
329 }); | 339 }); |
330 | 340 |
331 test("Straight JSON format", () { | 341 test("Straight JSON format", () { |
332 var s = new Serialization(); | 342 var s = new Serialization(); |
333 var writer = s.newWriter(new SimpleJsonFormat()); | 343 var writer = s.newWriter(new SimpleJsonFormat()); |
334 var out = writer.write(a1); | 344 var out = json.stringify(writer.write(a1)); |
335 var reconstituted = json.parse(out); | 345 var reconstituted = json.parse(out); |
336 expect(reconstituted.length, 4); | 346 expect(reconstituted.length, 4); |
337 expect(reconstituted[0], "Seattle"); | 347 expect(reconstituted[0], "Seattle"); |
338 }); | 348 }); |
339 | 349 |
340 test("Straight JSON format, nested objects", () { | 350 test("Straight JSON format, nested objects", () { |
341 var p1 = new Person()..name = 'Alice'..address = a1; | 351 var p1 = new Person()..name = 'Alice'..address = a1; |
342 var s = new Serialization(); | 352 var s = new Serialization()..selfDescribing = false; |
343 var addressRule = s.addRuleFor(a1)..configureForMaps(); | 353 var addressRule = s.addRuleFor(a1)..configureForMaps(); |
344 var personRule = s.addRuleFor(p1)..configureForMaps(); | 354 var personRule = s.addRuleFor(p1)..configureForMaps(); |
345 var writer = s.newWriter(new SimpleJsonFormat(storeRoundTripInfo: true)); | 355 var writer = s.newWriter(new SimpleJsonFormat(storeRoundTripInfo: true)); |
346 var out = writer.write(p1); | 356 var out = json.stringify(writer.write(p1)); |
347 var reconstituted = json.parse(out); | 357 var reconstituted = json.parse(out); |
348 var expected = { | 358 var expected = { |
349 "name" : "Alice", | 359 "name" : "Alice", |
350 "rank" : null, | 360 "rank" : null, |
351 "serialNumber" : null, | 361 "serialNumber" : null, |
352 "__rule" : personRule.number, | 362 "_rule" : personRule.number, |
353 "address" : { | 363 "address" : { |
354 "street" : "N 34th", | 364 "street" : "N 34th", |
355 "city" : "Seattle", | 365 "city" : "Seattle", |
356 "state" : null, | 366 "state" : null, |
357 "zip" : null, | 367 "zip" : null, |
358 "__rule" : addressRule.number | 368 "_rule" : addressRule.number |
359 } | 369 } |
360 }; | 370 }; |
361 expect(expected, reconstituted); | 371 expect(expected, reconstituted); |
362 }); | 372 }); |
363 | 373 |
364 test("Straight JSON format, round-trip", () { | 374 test("Straight JSON format, round-trip", () { |
365 // Note that we can't use the usual round-trip test because it has cycles. | 375 // Note that we can't use the usual round-trip test because it has cycles. |
366 var p1 = new Person()..name = 'Alice'..address = a1; | 376 var p1 = new Person()..name = 'Alice'..address = a1; |
367 // Use maps for one rule, lists for the other. | 377 // Use maps for one rule, lists for the other. |
368 var s = new Serialization() | 378 var s = new Serialization() |
369 ..addRuleFor(a1) | 379 ..addRuleFor(a1) |
370 ..addRuleFor(p1).configureForMaps(); | 380 ..addRuleFor(p1).configureForMaps(); |
371 var writer = s.newWriter(new SimpleJsonFormat(storeRoundTripInfo: true)); | 381 var p2 = writeAndReadBack(s, |
372 var out = writer.write(p1); | 382 new SimpleJsonFormat(storeRoundTripInfo: true), p1); |
373 var reader = s.newReader(new SimpleJsonFormat(storeRoundTripInfo: true)); | |
374 var p2 = reader.read(out); | |
375 expect(p2.name, "Alice"); | 383 expect(p2.name, "Alice"); |
376 var a2 = p2.address; | 384 var a2 = p2.address; |
377 expect(a2.street, "N 34th"); | 385 expect(a2.street, "N 34th"); |
378 expect(a2.city, "Seattle"); | 386 expect(a2.city, "Seattle"); |
379 }); | 387 }); |
380 | 388 |
381 test("Straight JSON format, root is a Map", () { | 389 test("Root is a Map", () { |
382 // Note that we can't use the usual round-trip test because it has cycles. | 390 // Note that we can't use the usual round-trip test because it has cycles. |
383 var p1 = new Person()..name = 'Alice'..address = a1; | 391 var p1 = new Person()..name = 'Alice'..address = a1; |
384 // Use maps for one rule, lists for the other. | 392 // Use maps for one rule, lists for the other. |
385 var s = new Serialization() | 393 var s = new Serialization() |
386 ..addRuleFor(a1) | 394 ..addRuleFor(a1) |
387 ..addRuleFor(p1).configureForMaps(); | 395 ..addRuleFor(p1).configureForMaps(); |
388 var format = new SimpleJsonFormat(storeRoundTripInfo: true); | 396 for (var eachFormat in formats) { |
389 var writer = s.newWriter(format); | 397 var w = s.newWriter(eachFormat); |
390 var out = writer.write({"stuff" : p1}); | 398 var output = w.write({"stuff" : p1}); |
391 var reader = s.newReader(format); | 399 var r = s.newReader(w.format); |
392 var p2 = reader.read(out)["stuff"]; | 400 var result = r.read(output); |
393 expect(p2.name, "Alice"); | 401 var p2 = result["stuff"]; |
394 var a2 = p2.address; | 402 expect(p2.name, "Alice"); |
| 403 var a2 = p2.address; |
| 404 expect(a2.street, "N 34th"); |
| 405 expect(a2.city, "Seattle"); |
| 406 } |
| 407 }); |
| 408 |
| 409 test("Root is a List", () { |
| 410 var s = new Serialization(); |
| 411 for (var eachFormat in formats) { |
| 412 var result = writeAndReadBack(s, eachFormat, [a1]); |
| 413 var a2 = result.first; |
395 expect(a2.street, "N 34th"); | 414 expect(a2.street, "N 34th"); |
396 expect(a2.city, "Seattle"); | 415 expect(a2.city, "Seattle"); |
| 416 } |
397 }); | 417 }); |
398 | 418 |
| 419 test("Root is a simple object", () { |
| 420 var s = new Serialization(); |
| 421 for (var eachFormat in formats) { |
| 422 expect(writeAndReadBack(s, eachFormat, null), null); |
| 423 expect(writeAndReadBack(s, eachFormat, [null]), [null]); |
| 424 expect(writeAndReadBack(s, eachFormat, 3), 3); |
| 425 expect(writeAndReadBack(s, eachFormat, [3]), [3]); |
| 426 expect(writeAndReadBack(s, eachFormat, "hello"), "hello"); |
| 427 expect(writeAndReadBack(s, eachFormat, [3]), [3]); |
| 428 expect(writeAndReadBack(s, eachFormat, {"hello" : "world"}), |
| 429 {"hello" : "world"}); |
| 430 expect(writeAndReadBack(s, eachFormat, true), true); |
| 431 } |
| 432 }); |
399 | 433 |
400 test("Straight JSON format, round-trip with named objects", () { | 434 test("Simple JSON format, round-trip with named objects", () { |
401 // Note that we can't use the usual round-trip test because it has cycles. | 435 // Note that we can't use the usual round-trip test because it has cycles. |
402 var p1 = new Person()..name = 'Alice'..address = a1; | 436 var p1 = new Person()..name = 'Alice'..address = a1; |
403 // Use maps for one rule, lists for the other. | 437 // Use maps for one rule, lists for the other. |
404 var s = new Serialization() | 438 var s = new Serialization() |
| 439 ..selfDescribing = false |
405 ..addRule(new NamedObjectRule()) | 440 ..addRule(new NamedObjectRule()) |
406 ..addRuleFor(a1) | 441 ..addRuleFor(a1) |
407 ..addRuleFor(p1).configureForMaps() | 442 ..addRuleFor(p1).configureForMaps() |
408 ..namedObjects["foo"] = a1; | 443 ..namedObjects["foo"] = a1; |
409 var writer = s.newWriter(new SimpleJsonFormat(storeRoundTripInfo: true)); | 444 var writer = s.newWriter(new SimpleJsonFormat(storeRoundTripInfo: true)); |
410 var out = writer.write(p1); | 445 var out = writer.write(p1); |
411 var reader = s.newReader(new SimpleJsonFormat(storeRoundTripInfo: true)); | 446 var reader = s.newReader(new SimpleJsonFormat(storeRoundTripInfo: true)); |
412 var p2 = reader.read(out, {"foo" : 12}); | 447 var p2 = reader.read(out, {"foo" : 12}); |
413 expect(p2.name, "Alice"); | 448 expect(p2.name, "Alice"); |
414 var a2 = p2.address; | 449 var a2 = p2.address; |
415 expect(a2, 12); | 450 expect(a2, 12); |
416 }); | 451 }); |
417 | 452 |
418 test("Maps", () { | 453 test("More complicated Maps", () { |
419 var s = new Serialization()..selfDescribing = false; | 454 var s = new Serialization()..selfDescribing = false; |
420 var p1 = new Person()..name = 'Alice'..address = a1; | 455 var p1 = new Person()..name = 'Alice'..address = a1; |
421 var data = new Map(); | 456 var data = new Map(); |
422 data["simple data"] = 1; | 457 data["simple data"] = 1; |
423 data[p1] = a1; | 458 data[p1] = a1; |
424 data[a1] = p1; | 459 data[a1] = p1; |
425 var formats = [new SimpleFlatFormat(), new SimpleMapFormat(), | |
426 new SimpleJsonFormat(storeRoundTripInfo: true)]; | |
427 for (var eachFormat in formats) { | 460 for (var eachFormat in formats) { |
428 var output = s.write(data, eachFormat); | 461 var output = s.write(data, eachFormat); |
429 var reader = s.newReader(eachFormat); | 462 var reader = s.newReader(eachFormat); |
430 var input = reader.read(output); | 463 var input = reader.read(output); |
431 expect(input["simple data"], data["simple data"]); | 464 expect(input["simple data"], data["simple data"]); |
432 var p2 = input.keys.firstMatching((x) => x is Person); | 465 var p2 = input.keys.firstMatching((x) => x is Person); |
433 var a2 = input.keys.firstMatching((x) => x is Address); | 466 var a2 = input.keys.firstMatching((x) => x is Address); |
434 if (eachFormat is SimpleJsonFormat) { | 467 if (eachFormat is SimpleJsonFormat) { |
435 // JSON doesn't handle cycles, so these won't be identical. | 468 // JSON doesn't handle cycles, so these won't be identical. |
436 expect(input[p2] is Address, isTrue); | 469 expect(input[p2] is Address, isTrue); |
(...skipping 12 matching lines...) Expand all Loading... |
449 } | 482 } |
450 } | 483 } |
451 }); | 484 }); |
452 | 485 |
453 test("Map with string keys stays that way", () { | 486 test("Map with string keys stays that way", () { |
454 var s = new Serialization()..addRuleFor(new Person()); | 487 var s = new Serialization()..addRuleFor(new Person()); |
455 var data = {"abc" : 1, "def" : "ghi"}; | 488 var data = {"abc" : 1, "def" : "ghi"}; |
456 data["person"] = new Person()..name = "Foo"; | 489 data["person"] = new Person()..name = "Foo"; |
457 var output = s.write(data, new SimpleMapFormat()); | 490 var output = s.write(data, new SimpleMapFormat()); |
458 var mapRule = s.rules.firstMatching((x) => x is MapRule); | 491 var mapRule = s.rules.firstMatching((x) => x is MapRule); |
459 var map = json.parse(output)["data"][mapRule.number][0]; | 492 var map = output["data"][mapRule.number][0]; |
460 expect(map is Map, isTrue); | 493 expect(map is Map, isTrue); |
461 expect(map["abc"], 1); | 494 expect(map["abc"], 1); |
462 expect(map["def"], "ghi"); | 495 expect(map["def"], "ghi"); |
463 expect(new Reader(s).asReference(map["person"]) is Reference, isTrue); | 496 expect(new Reader(s).asReference(map["person"]) is Reference, isTrue); |
464 }); | 497 }); |
| 498 |
465 } | 499 } |
466 | 500 |
467 /****************************************************************************** | 501 /****************************************************************************** |
468 * The end of the tests and the beginning of various helper functions to make | 502 * The end of the tests and the beginning of various helper functions to make |
469 * it easier to write the repetitive sections. | 503 * it easier to write the repetitive sections. |
470 ******************************************************************************/ | 504 ******************************************************************************/ |
471 | 505 |
| 506 writeAndReadBack(Serialization s, Format format, object) { |
| 507 var w = s.newWriter(format); |
| 508 var output = w.write(object); |
| 509 var r = s.newReader(w.format); |
| 510 return r.read(output); |
| 511 } |
| 512 |
472 /** Create a Serialization for serializing Serializations. */ | 513 /** Create a Serialization for serializing Serializations. */ |
473 Serialization metaSerialization() { | 514 Serialization metaSerialization() { |
474 // Make some bogus rule instances so we have something to feed rule creation | 515 // Make some bogus rule instances so we have something to feed rule creation |
475 // and get their types. If only we had class literals implemented... | 516 // and get their types. If only we had class literals implemented... |
476 var basicRule = new BasicRule(reflect(null).type, '', [], [], []); | 517 var basicRule = new BasicRule(reflect(null).type, '', [], [], []); |
477 | 518 |
478 var meta = new Serialization() | 519 var meta = new Serialization() |
479 ..selfDescribing = false | 520 ..selfDescribing = false |
480 ..addRuleFor(new ListRule()) | 521 ..addRuleFor(new ListRule()) |
481 ..addRuleFor(new PrimitiveRule()) | 522 ..addRuleFor(new PrimitiveRule()) |
482 // TODO(alanknight): Handle CustomRule as well. | 523 // TODO(alanknight): Handle CustomRule as well. |
483 // Note that we're passing in a constant for one of the fields. | 524 // Note that we're passing in a constant for one of the fields. |
484 ..addRuleFor(basicRule, | 525 ..addRuleFor(basicRule, |
485 constructorFields: ['type', | 526 constructorFields: ['type', |
486 'constructorName', | 527 'constructorName', |
487 'constructorFields', 'regularFields', []], | 528 'constructorFields', 'regularFields', []], |
488 fields: []) | 529 fields: []) |
489 ..addRuleFor(new Serialization(), constructor: "blank") | 530 ..addRuleFor(new Serialization(), constructor: "blank") |
490 .setFieldWith('rules', | 531 .setFieldWith('rules', |
491 (InstanceMirror s, List rules) { | 532 (InstanceMirror s, List rules) { |
492 rules.forEach((x) => s.reflectee.addRule(x)); | 533 rules.forEach((x) => s.reflectee.addRule(x)); |
493 }) | 534 }) |
494 ..addRule(new NamedObjectRule()) | 535 ..addRule(new NamedObjectRule()) |
495 ..addRule(new MirrorRule()); | 536 ..addRule(new MirrorRule()) |
| 537 ..addRule(new MapRule()); |
496 return meta; | 538 return meta; |
497 } | 539 } |
498 | 540 |
| 541 Serialization metaSerializationUsingMaps() { |
| 542 var meta = metaSerialization(); |
| 543 meta.rules.where((each) => each is BasicRule) |
| 544 .forEach((x) => x.configureForMaps()); |
| 545 return meta; |
| 546 } |
| 547 |
499 /** | 548 /** |
500 * Read back a simple object, assumed to be the only one of its class in the | 549 * Read back a simple object, assumed to be the only one of its class in the |
501 * reader. | 550 * reader. |
502 */ | 551 */ |
503 readBackSimple(Serialization s, object, Reader reader) { | 552 readBackSimple(Serialization s, object, Reader reader) { |
504 var rule = s.rulesFor(object, null).first; | 553 var rule = s.rulesFor(object, null).first; |
505 reader.inflateForRule(rule); | 554 reader.inflateForRule(rule); |
506 var list2 = reader.allObjectsForRule(rule).first; | 555 var list2 = reader.allObjectsForRule(rule).first; |
507 return list2; | 556 return list2; |
508 } | 557 } |
509 | 558 |
510 /** | 559 /** |
511 * Set up a basic reader with some fake data. Hard-codes the assumption | 560 * Set up a basic reader with some fake data. Hard-codes the assumption |
512 * of how many rules there are. | 561 * of how many rules there are. |
513 */ | 562 */ |
514 Reader setUpReader(aSerialization, sampleData) { | 563 Reader setUpReader(aSerialization, sampleData) { |
515 var reader = new Reader(aSerialization); | 564 var reader = new Reader(aSerialization); |
516 // We're not sure which rule needs the sample data, so put it everywhere | 565 // We're not sure which rule needs the sample data, so put it everywhere |
517 // and trust that the extra will just be ignored. | 566 // and trust that the extra will just be ignored. |
| 567 |
518 var fillValue = [sampleData]; | 568 var fillValue = [sampleData]; |
519 var data = []; | 569 var data = []; |
520 for (int i = 0; i < 10; i++) { | 570 for (int i = 0; i < 10; i++) { |
521 data.add(fillValue); | 571 data.add(fillValue); |
522 } | 572 } |
523 reader.data = data; | 573 reader.data = data; |
524 return reader; | 574 return reader; |
525 } | 575 } |
526 | 576 |
527 /** Return a serialization for Node objects, using a reflective rule. */ | 577 /** Return a serialization for Node objects, using a reflective rule. */ |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
634 expect(m2.name, "2"); | 684 expect(m2.name, "2"); |
635 expect(m3.name, "3"); | 685 expect(m3.name, "3"); |
636 expect(m2.parent, m1); | 686 expect(m2.parent, m1); |
637 expect(m3.parent, m1); | 687 expect(m3.parent, m1); |
638 expect(m1.parent, isNull); | 688 expect(m1.parent, isNull); |
639 } | 689 } |
640 | 690 |
641 /** Extract the state from [object] using the rules in [s] and return it. */ | 691 /** Extract the state from [object] using the rules in [s] and return it. */ |
642 states(object, Serialization s) { | 692 states(object, Serialization s) { |
643 var rules = s.rulesFor(object, null); | 693 var rules = s.rulesFor(object, null); |
644 return rules.map((x) => x.extractState(object, doNothing)).toList(); | 694 return rules.map((x) => x.extractState(object, doNothing, null)).toList(); |
645 } | 695 } |
646 | 696 |
647 /** A hard-coded rule for serializing Node instances. */ | 697 /** A hard-coded rule for serializing Node instances. */ |
648 class NodeRule extends CustomRule { | 698 class NodeRule extends CustomRule { |
649 bool appliesTo(instance, _) => instance.runtimeType == Node; | 699 bool appliesTo(instance, _) => instance.runtimeType == Node; |
650 getState(instance) => [instance.parent, instance.name, instance.children]; | 700 getState(instance) => [instance.parent, instance.name, instance.children]; |
651 create(state) => new Node(state[1]); | 701 create(state) => new Node(state[1]); |
652 setState(Node node, state) { | 702 setState(Node node, state) { |
653 node.parent = state[0]; | 703 node.parent = state[0]; |
654 node.children = state[2]; | 704 node.children = state[2]; |
655 } | 705 } |
656 } | 706 } |
OLD | NEW |