lib/serialization: do not abort when deserializing an unknown class
authorAlexis Laferrière <alexis.laf@xymus.net>
Tue, 7 Jul 2015 14:42:45 +0000 (10:42 -0400)
committerAlexis Laferrière <alexis.laf@xymus.net>
Tue, 7 Jul 2015 16:04:21 +0000 (12:04 -0400)
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>

lib/serialization/serialization.nit
tests/sav/nitce/test_binary_deserialization_alt1.res [new file with mode: 0644]
tests/sav/nitce/test_json_deserialization_alt1.res
tests/sav/test_binary_deserialization_alt2.res [new file with mode: 0644]
tests/test_binary_deserialization.nit

index b0dc728..9408af0 100644 (file)
@@ -106,7 +106,7 @@ abstract class Deserializer
        # This method should be redefined for each custom subclass of `Serializable`.
        # All refinement should look for a precise `class_name` and call super
        # on unsupported classes.
-       protected fun deserialize_class(class_name: String): Object do
+       protected fun deserialize_class(class_name: String): nullable Object do
                return deserialize_class_intern(class_name)
        end
 
@@ -115,9 +115,9 @@ abstract class Deserializer
        # Refinements to this method will be generated by the serialization phase.
        # To avoid conflicts, there should not be any other refinements to this method.
        # You can instead use `deserialize_class`.
-       protected fun deserialize_class_intern(class_name: String): Object do
-               print "Error: doesn't know how to deserialize class \"{class_name}\""
-               abort
+       protected fun deserialize_class_intern(class_name: String): nullable Object do
+               errors.add new Error("Deserialization Error: Doesn't know how to deserialize class \"{class_name}\"")
+               return null
        end
 
        # Should `self` keep trying to deserialize an object after an error?
diff --git a/tests/sav/nitce/test_binary_deserialization_alt1.res b/tests/sav/nitce/test_binary_deserialization_alt1.res
new file mode 100644 (file)
index 0000000..4d4a3a0
--- /dev/null
@@ -0,0 +1,36 @@
+# Src:
+<A: true a 0.123 1234 asdf false p4ssw0rd>
+# Dst:
+<A: true a 0.123 1234 asdf false p4ssw0rd>
+
+# Src:
+<B: <A: false b 123.123 2345 hjkl false p4ssw0rd> 1111 qwer>
+# Dst:
+<B: <A: false b 123.123 2345 hjkl false p4ssw0rd> 1111 qwer>
+
+# Src:
+<C: <A: true a 0.123 1234 asdf false p4ssw0rd> <B: <A: false b 123.123 2345 hjkl false p4ssw0rd> 1111 qwer>>
+# Dst:
+<C: <A: true a 0.123 1234 asdf false p4ssw0rd> <B: <A: false b 123.123 2345 hjkl false p4ssw0rd> 1111 qwer>>
+
+# Src:
+<D: <B: <A: false b 123.123 2345 new line ->
+<- false p4ssw0rd> 1111        f"\r\/> true>
+# Dst:
+<D: <B: <A: false b 123.123 2345 new line ->
+<- false p4ssw0rd> 1111        f"\r\/> true>
+
+Deserialization Error: Doesn't know how to deserialize class "Array", Deserialization Error: Wrong type on `E::a` expected `PlaceHolderTypeWhichShouldNotExist`, got `null`, Deserialization Error: Doesn't know how to deserialize class "Array", Deserialization Error: Wrong type on `E::b` expected `PlaceHolderTypeWhichShouldNotExist`, got `null`
+# Src:
+<E: a: hello, 1234, 123.4; b: hella, 2345, 234.5>
+# Dst:
+<E: a: hello, 1234, 123.4; b: hella, 2345, 234.5>
+
+Deserialization Error: Doesn't know how to deserialize class "F"
+Deserialization Error: Doesn't know how to deserialize class "F"
+Deserialization Error: Doesn't know how to deserialize class "HashSet", Deserialization Error: Wrong type on `G::hs` expected `PlaceHolderTypeWhichShouldNotExist`, got `null`, Deserialization Error: Doesn't know how to deserialize class "ArraySet", Deserialization Error: Wrong type on `G::s` expected `Set[String]`, got `null`, Deserialization Error: Doesn't know how to deserialize class "HashMap", Deserialization Error: Wrong type on `G::hm` expected `PlaceHolderTypeWhichShouldNotExist`, got `null`, Deserialization Error: Doesn't know how to deserialize class "ArrayMap", Deserialization Error: Wrong type on `G::am` expected `PlaceHolderTypeWhichShouldNotExist`, got `null`
+# Src:
+<G: hs: -1, 0; s: one, two; hm: one. 1, two. 2; am: three. 3, four. 4>
+# Dst:
+<G: hs: ; s: ; hm: ; am: >
+
index c53bde5..7681dab 100644 (file)
@@ -1,4 +1,3 @@
-Runtime error: Aborted (../lib/serialization/serialization.nit:120)
 # Nit:
 <A: true a 0.123 1234 asdf false p4ssw0rd>
 
@@ -37,4 +36,39 @@ Runtime error: Aborted (../lib/serialization/serialization.nit:120)
 <D: <B: <A: false b 123.123 2345 new line ->
 <- false p4ssw0rd> 1111        f"\r\/> true>
 
-Error: doesn't know how to deserialize class "Array"
+# Nit:
+<E: a: hello, 1234, 123.4; b: hella, 2345, 234.5>
+
+# Json:
+{"__kind": "obj", "__id": 0, "__class": "E", "a": {"__kind": "obj", "__id": 1, "__class": "Array", "__items": ["hello", 1234, 123.4]}, "b": {"__kind": "obj", "__id": 2, "__class": "Array", "__items": ["hella", 2345, 234.5]}}
+
+# Back in Nit:
+<E: a: hello, 1234, 123.4; b: hella, 2345, 234.5>
+
+# Nit:
+<E: 2222>
+
+# Json:
+{"__kind": "obj", "__id": 0, "__class": "F", "n": 2222}
+
+# Back in Nit:
+null
+
+# Nit:
+<E: 33.33>
+
+# Json:
+{"__kind": "obj", "__id": 0, "__class": "F", "n": 33.33}
+
+# Back in Nit:
+null
+
+# Nit:
+<G: hs: -1, 0; s: one, two; hm: one. 1, two. 2; am: three. 3, four. 4>
+
+# Json:
+{"__kind": "obj", "__id": 0, "__class": "G", "hs": {"__kind": "obj", "__id": 1, "__class": "HashSet", "__items": [-1, 0]}, "s": {"__kind": "obj", "__id": 2, "__class": "ArraySet", "__items": ["one", "two"]}, "hm": {"__kind": "obj", "__id": 3, "__class": "HashMap", "__length": 2, "__keys": ["one", "two"], "__values": [1, 2]}, "am": {"__kind": "obj", "__id": 4, "__class": "ArrayMap", "__length": 2, "__keys": ["three", "four"], "__values": ["3", "4"]}}
+
+# Back in Nit:
+<G: hs: ; s: ; hm: ; am: >
+
diff --git a/tests/sav/test_binary_deserialization_alt2.res b/tests/sav/test_binary_deserialization_alt2.res
new file mode 100644 (file)
index 0000000..474fef8
--- /dev/null
@@ -0,0 +1 @@
+Deserialization Error: Doesn't know how to deserialize class "NoSerializeClass"
index 007ff54..c6bcd0a 100644 (file)
@@ -16,16 +16,24 @@ import test_deserialization
 import binary::serialization
 #alt1# import test_deserialization_serial
 
+class NoSerializeClass
+       super Serializable
+
+       var some_attribute: String
+end
+
 var entities = new TestEntities
 
-var tests = entities.without_generics#alt1#
+var tests = entities.without_generics#alt1##alt2#
 #alt1#var tests = entities.with_generics
+#alt2#var tests = [new NoSerializeClass("will not deserialize")]
 
 var dir = "out/test_binary_deserialization"
 if not dir.file_exists then dir.mkdir
 
-var path = dir / "alt0"#alt1#
+var path = dir / "alt0"#alt1##alt2#
 #alt1#var path = dir / "alt1"
+#alt2#var path = dir / "alt2"
 
 var writer = new FileWriter.open(path)
 var serializer = new BinarySerializer(writer)
@@ -39,10 +47,15 @@ var deserializer = new BinaryDeserializer(reader)
 for o in tests do
        var dst = deserializer.deserialize
 
-       assert dst != null
-       assert o.is_same_type(dst)
+       if deserializer.errors.not_empty then
+               print deserializer.errors.join(", ")
+       end
+
+       if dst != null then
+               assert o.is_same_type(dst)
 
-       print "# Src:\n{o}"
-       print "# Dst:\n{dst}\n"
+               print "# Src:\n{o}"
+               print "# Dst:\n{dst}\n"
+       end
 end
 reader.close