| 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 'package:unittest/unittest.dart'; | 8 import 'package:unittest/unittest.dart'; |
| 8 import 'package:serialization/serialization.dart'; | 9 import 'package:serialization/serialization.dart'; |
| 9 import 'package:serialization/src/serialization_helpers.dart'; | 10 import 'package:serialization/src/serialization_helpers.dart'; |
| 10 import 'package:serialization/src/mirrors_helpers.dart'; | 11 import 'package:serialization/src/mirrors_helpers.dart'; |
| 11 | 12 |
| 12 part 'test_models.dart'; | 13 part 'test_models.dart'; |
| 13 | 14 |
| 14 main() { | 15 main() { |
| 15 var p1 = new Person(); | 16 var p1 = new Person(); |
| 16 var a1 = new Address(); | 17 var a1 = new Address(); |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 }); | 230 }); |
| 230 | 231 |
| 231 test('round-trip, flat format', () { | 232 test('round-trip, flat format', () { |
| 232 runRoundTripTestFlat(nodeSerializerReflective); | 233 runRoundTripTestFlat(nodeSerializerReflective); |
| 233 }); | 234 }); |
| 234 | 235 |
| 235 test('round-trip using Maps', () { | 236 test('round-trip using Maps', () { |
| 236 runRoundTripTest(nodeSerializerUsingMaps); | 237 runRoundTripTest(nodeSerializerUsingMaps); |
| 237 }); | 238 }); |
| 238 | 239 |
| 240 test('round-trip, flat format, using maps', () { |
| 241 runRoundTripTestFlat(nodeSerializerUsingMaps); |
| 242 }); |
| 243 |
| 239 test('round-trip with Node CustomRule', () { | 244 test('round-trip with Node CustomRule', () { |
| 240 runRoundTripTestFlat(nodeSerializerCustom); | 245 runRoundTripTestFlat(nodeSerializerCustom); |
| 241 }); | 246 }); |
| 242 | 247 |
| 243 test('round-trip with Node CustomRule, to maps', () { | 248 test('round-trip with Node CustomRule, to maps', () { |
| 244 runRoundTripTest(nodeSerializerCustom); | 249 runRoundTripTest(nodeSerializerCustom); |
| 245 }); | 250 }); |
| 246 | 251 |
| 247 test('eating your own tail', () { | 252 test('eating your own tail', () { |
| 248 // Create a meta-serializer, that serializes serializations, then | 253 // Create a meta-serializer, that serializes serializations, then |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 expect(identical(m2.parent, m3.parent), isTrue); | 307 expect(identical(m2.parent, m3.parent), isTrue); |
| 303 }); | 308 }); |
| 304 | 309 |
| 305 test("Constant values as fields", () { | 310 test("Constant values as fields", () { |
| 306 var s = new Serialization() | 311 var s = new Serialization() |
| 307 ..selfDescribing = false | 312 ..selfDescribing = false |
| 308 ..addRuleFor(a1, | 313 ..addRuleFor(a1, |
| 309 constructor: 'withData', | 314 constructor: 'withData', |
| 310 constructorFields: ["street", "Kirkland", "WA", "98103"], | 315 constructorFields: ["street", "Kirkland", "WA", "98103"], |
| 311 fields: []); | 316 fields: []); |
| 312 var out = s.write(a1); | 317 String out = s.write(a1); |
| 313 var newAddress = s.read(out); | 318 var newAddress = s.read(out); |
| 314 expect(newAddress.street, a1.street); | 319 expect(newAddress.street, a1.street); |
| 315 expect(newAddress.city, "Kirkland"); | 320 expect(newAddress.city, "Kirkland"); |
| 316 expect(newAddress.state, "WA"); | 321 expect(newAddress.state, "WA"); |
| 317 expect(newAddress.zip, "98103"); | 322 expect(newAddress.zip, "98103"); |
| 318 }); | 323 }); |
| 319 | 324 |
| 325 test("Straight JSON format", () { |
| 326 var s = new Serialization(); |
| 327 var writer = s.newWriter(new SimpleJsonFormat()); |
| 328 var out = writer.write(a1); |
| 329 var reconstituted = json.parse(out); |
| 330 expect(reconstituted.length, 4); |
| 331 expect(reconstituted[0], "Seattle"); |
| 332 }); |
| 333 |
| 334 test("Straight JSON format, nested objects", () { |
| 335 var p1 = new Person()..name = 'Alice'..address = a1; |
| 336 var s = new Serialization(); |
| 337 var addressRule = s.addRuleFor(a1)..configureForMaps(); |
| 338 var personRule = s.addRuleFor(p1)..configureForMaps(); |
| 339 var writer = s.newWriter(new SimpleJsonFormat(storeRoundTripInfo: true)); |
| 340 var out = writer.write(p1); |
| 341 var reconstituted = json.parse(out); |
| 342 var expected = { |
| 343 "name" : "Alice", |
| 344 "rank" : null, |
| 345 "serialNumber" : null, |
| 346 "__rule" : personRule.number, |
| 347 "address" : { |
| 348 "street" : "N 34th", |
| 349 "city" : "Seattle", |
| 350 "state" : null, |
| 351 "zip" : null, |
| 352 "__rule" : addressRule.number |
| 353 } |
| 354 }; |
| 355 expect(expected, reconstituted); |
| 356 }); |
| 357 |
| 358 test("Straight JSON format, round-trip", () { |
| 359 // Note that we can't use the usual round-trip test because it has cycles. |
| 360 var p1 = new Person()..name = 'Alice'..address = a1; |
| 361 // Use maps for one rule, lists for the other. |
| 362 var s = new Serialization() |
| 363 ..addRuleFor(a1) |
| 364 ..addRuleFor(p1).configureForMaps(); |
| 365 var writer = s.newWriter(new SimpleJsonFormat(storeRoundTripInfo: true)); |
| 366 var out = writer.write(p1); |
| 367 var reader = s.newReader(new SimpleJsonFormat(storeRoundTripInfo: true)); |
| 368 var p2 = reader.read(out); |
| 369 expect(p2.name, "Alice"); |
| 370 var a2 = p2.address; |
| 371 expect(a2.street, "N 34th"); |
| 372 expect(a2.city, "Seattle"); |
| 373 }); |
| 374 |
| 375 test("Straight JSON format, round-trip with named objects", () { |
| 376 // Note that we can't use the usual round-trip test because it has cycles. |
| 377 var p1 = new Person()..name = 'Alice'..address = a1; |
| 378 // Use maps for one rule, lists for the other. |
| 379 var s = new Serialization() |
| 380 ..addRule(new NamedObjectRule()) |
| 381 ..addRuleFor(a1) |
| 382 ..addRuleFor(p1).configureForMaps() |
| 383 ..namedObjects["foo"] = a1; |
| 384 var writer = s.newWriter(new SimpleJsonFormat(storeRoundTripInfo: true)); |
| 385 var out = writer.write(p1); |
| 386 var reader = s.newReader(new SimpleJsonFormat(storeRoundTripInfo: true)); |
| 387 var p2 = reader.read(out, {"foo" : 12}); |
| 388 expect(p2.name, "Alice"); |
| 389 var a2 = p2.address; |
| 390 expect(a2, 12); |
| 391 }); |
| 320 } | 392 } |
| 321 | 393 |
| 322 /****************************************************************************** | 394 /****************************************************************************** |
| 323 * The end of the tests and the beginning of various helper functions to make | 395 * The end of the tests and the beginning of various helper functions to make |
| 324 * it easier to write the repetitive sections. | 396 * it easier to write the repetitive sections. |
| 325 ******************************************************************************/ | 397 ******************************************************************************/ |
| 326 | 398 |
| 327 /** Create a Serialization for serializing Serializations. */ | 399 /** Create a Serialization for serializing Serializations. */ |
| 328 Serialization metaSerialization() { | 400 Serialization metaSerialization() { |
| 329 // Make some bogus rule instances so we have something to feed rule creation | 401 // Make some bogus rule instances so we have something to feed rule creation |
| (...skipping 18 matching lines...) Expand all Loading... |
| 348 ..addRule(new NamedObjectRule()) | 420 ..addRule(new NamedObjectRule()) |
| 349 ..addRule(new MirrorRule()); | 421 ..addRule(new MirrorRule()); |
| 350 return meta; | 422 return meta; |
| 351 } | 423 } |
| 352 | 424 |
| 353 /** | 425 /** |
| 354 * Read back a simple object, assumed to be the only one of its class in the | 426 * Read back a simple object, assumed to be the only one of its class in the |
| 355 * reader. | 427 * reader. |
| 356 */ | 428 */ |
| 357 readBackSimple(Serialization s, object, Reader reader) { | 429 readBackSimple(Serialization s, object, Reader reader) { |
| 358 var rule = s.rulesFor(object, null)[0]; | 430 var rule = s.rulesFor(object, null).first; |
| 359 reader.inflateForRule(rule); | 431 reader.inflateForRule(rule); |
| 360 var list2 = reader.allObjectsForRule(rule)[0]; | 432 var list2 = reader.allObjectsForRule(rule).first; |
| 361 return list2; | 433 return list2; |
| 362 } | 434 } |
| 363 | 435 |
| 364 /** | 436 /** |
| 365 * Set up a basic reader with some fake data. Hard-codes the assumption | 437 * Set up a basic reader with some fake data. Hard-codes the assumption |
| 366 * of how many rules there are. | 438 * of how many rules there are. |
| 367 */ | 439 */ |
| 368 Reader setUpReader(aSerialization, sampleData) { | 440 Reader setUpReader(aSerialization, sampleData) { |
| 369 var reader = new Reader(aSerialization); | 441 var reader = new Reader(aSerialization); |
| 370 // We're not sure which rule needs the sample data, so put it everywhere | 442 // We're not sure which rule needs the sample data, so put it everywhere |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 /** | 535 /** |
| 464 * Run a round-trip test on a simple of nodes, but using the flat format | 536 * Run a round-trip test on a simple of nodes, but using the flat format |
| 465 * rather than the maps. | 537 * rather than the maps. |
| 466 */ | 538 */ |
| 467 runRoundTripTestFlat(serializerSetUp) { | 539 runRoundTripTestFlat(serializerSetUp) { |
| 468 Node n1 = new Node("1"), n2 = new Node("2"), n3 = new Node("3"); | 540 Node n1 = new Node("1"), n2 = new Node("2"), n3 = new Node("3"); |
| 469 n1.children = [n2, n3]; | 541 n1.children = [n2, n3]; |
| 470 n2.parent = n1; | 542 n2.parent = n1; |
| 471 n3.parent = n1; | 543 n3.parent = n1; |
| 472 var s = serializerSetUp(n1); | 544 var s = serializerSetUp(n1); |
| 473 var output = s.writeFlat(n2); | 545 var output = s.write(n2, new SimpleFlatFormat()); |
| 474 expect(output is List, isTrue); | 546 expect(output is List, isTrue); |
| 475 var s2 = serializerSetUp(n1); | 547 var s2 = serializerSetUp(n1); |
| 476 var reader = new Reader(s2); | 548 var reader = new Reader(s2, new SimpleFlatFormat()); |
| 477 var m2 = reader.readFlat(output); | 549 var m2 = reader.read(output); |
| 478 var m1 = m2.parent; | 550 var m1 = m2.parent; |
| 479 expect(m1 is Node, isTrue); | 551 expect(m1 is Node, isTrue); |
| 480 var children = m1.children; | 552 var children = m1.children; |
| 481 expect(m1.name,"1"); | 553 expect(m1.name,"1"); |
| 482 var m3 = m1.children.last; | 554 var m3 = m1.children.last; |
| 483 expect(m2.name, "2"); | 555 expect(m2.name, "2"); |
| 484 expect(m3.name, "3"); | 556 expect(m3.name, "3"); |
| 485 expect(m2.parent, m1); | 557 expect(m2.parent, m1); |
| 486 expect(m3.parent, m1); | 558 expect(m3.parent, m1); |
| 487 expect(m1.parent, isNull); | 559 expect(m1.parent, isNull); |
| 488 } | 560 } |
| 489 | 561 |
| 490 /** Extract the state from [object] using the rules in [s] and return it. */ | 562 /** Extract the state from [object] using the rules in [s] and return it. */ |
| 491 states(object, Serialization s) { | 563 states(object, Serialization s) { |
| 492 var rules = s.rulesFor(object, null); | 564 var rules = s.rulesFor(object, null); |
| 493 return rules.mappedBy((x) => x.extractState(object, doNothing)).toList(); | 565 return rules.mappedBy((x) => x.extractState(object, doNothing)).toList(); |
| 494 } | 566 } |
| 495 | 567 |
| 496 /** A hard-coded rule for serializing Node instances. */ | 568 /** A hard-coded rule for serializing Node instances. */ |
| 497 class NodeRule extends CustomRule { | 569 class NodeRule extends CustomRule { |
| 498 bool appliesTo(instance, _) => instance is Node; | 570 bool appliesTo(instance, _) => instance.runtimeType == Node; |
| 499 getState(instance) => [instance.parent, instance.name, instance.children]; | 571 getState(instance) => [instance.parent, instance.name, instance.children]; |
| 500 create(state) => new Node(state[1]); | 572 create(state) => new Node(state[1]); |
| 501 setState(Node node, state) { | 573 setState(Node node, state) { |
| 502 node.parent = state[0]; | 574 node.parent = state[0]; |
| 503 node.children = state[2]; | 575 node.children = state[2]; |
| 504 } | 576 } |
| 505 } | 577 } |
| OLD | NEW |