| 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 |