tests: test the tolerance of the JSON deserializer on custom JSON code
authorAlexis Laferrière <alexis.laf@xymus.net>
Mon, 29 Jun 2015 01:31:00 +0000 (21:31 -0400)
committerAlexis Laferrière <alexis.laf@xymus.net>
Mon, 29 Jun 2015 23:02:32 +0000 (19:02 -0400)
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>

tests/sav/test_json_deserialization_plain.res [new file with mode: 0644]
tests/sav/test_json_deserialization_plain_alt2.res [new file with mode: 0644]
tests/test_json_deserialization_plain.nit [new file with mode: 0644]

diff --git a/tests/sav/test_json_deserialization_plain.res b/tests/sav/test_json_deserialization_plain.res
new file mode 100644 (file)
index 0000000..ef8399f
--- /dev/null
@@ -0,0 +1,32 @@
+# JSON: {"__kind": "obj", "__id": 0, "__class": "MyClass", "i": 123, "s": "hello", "f": 123.456, "a": ["one", "two"], "o": null}
+# Nit: <MyClass i:123 s:hello f:123.456 a:[one, two] o:<null>>
+
+# JSON: {"__class": "MyClass", "i": 123, "s": "hello", "f": 123.456, "a": ["one", "two"], "o": null}
+# Nit: <MyClass i:123 s:hello f:123.456 a:[one, two] o:<null>>
+
+# JSON: {"s": "hello", "o": null, "i": 123, "f": 123.456, "__class": "MyClass", "a": ["one", "two"]}
+# Nit: <MyClass i:123 s:hello f:123.456 a:[one, two] o:<null>>
+
+# JSON: {"__class": "MyClass", "i": 123, "s": "hello", "f": 123.456, "o": null, "a": ["one", "two"], "Some random attribute": 777}
+# Nit: <MyClass i:123 s:hello f:123.456 a:[one, two] o:<null>>
+
+# JSON: {"__class": "MyClass", "i": 123, "s": "hello", "f": 123.456, "a": ["one", "two"]}
+# Errors: 'Deserialization Error: JSON object has not attribute 'o'.'
+# Nit: <MyClass i:123 s:hello f:123.456 a:[one, two] o:<null>>
+
+# JSON: {"__class": "MyClass", "i": 123, "s": "hello", "f": 123.456, "a": ["one", "two"], "o":
+       {"__class": "MyClass", "i": 456, "s": "world", "f": 654.321, "a": ["1", "2"], "o": null}}
+# Nit: <MyClass i:123 s:hello f:123.456 a:[one, two] o:<MyClass i:456 s:world f:654.321 a:[1, 2] o:<null>>>
+
+# JSON: {"i": 123, "s": "hello", "f": 123.456, "a": ["one", "two"], "o": null}
+# Errors: 'Serialization Error: JSON object declaration does not declare a `__class`.'
+# Nit: <JsonObject i:123, s:hello, f:123.456, a:[one,two], o:<null>>
+
+# JSON: {"__class": "MyClass", "i": 123, "s": "hello", "f": 123.456, "a": ["one", "two"], "o": "Not the right type"}
+# Errors: 'Deserialization Error: Wrong type on `MyClass::o` expected `nullable MyClass`, got `FlatString`'
+# Nit: <MyClass i:123 s:hello f:123.456 a:[one, two] o:<null>>
+
+# JSON: not valid json
+# Errors: 'Error Parsing JSON: [1:1-1:2] Unexpected character 'n'; is acceptable instead: value'
+# Nit: null
+
diff --git a/tests/sav/test_json_deserialization_plain_alt2.res b/tests/sav/test_json_deserialization_plain_alt2.res
new file mode 100644 (file)
index 0000000..54e5a4d
--- /dev/null
@@ -0,0 +1,3 @@
+Runtime error: Uninitialized attribute _s (alt/test_json_deserialization_plain_alt2.nit:22)
+# JSON: {"__class": "MyClass", "i": 123, "o": null}
+# Errors: 'Deserialization Error: JSON object has not attribute 's'.', 'Deserialization Error: Wrong type on `MyClass::s` expected `String`, got `null`', 'Deserialization Error: JSON object has not attribute 'f'.', 'Deserialization Error: Wrong type on `MyClass::f` expected `Float`, got `null`', 'Deserialization Error: JSON object has not attribute 'a'.', 'Deserialization Error: Wrong type on `MyClass::a` expected `Array[String]`, got `null`'
diff --git a/tests/test_json_deserialization_plain.nit b/tests/test_json_deserialization_plain.nit
new file mode 100644 (file)
index 0000000..e577eda
--- /dev/null
@@ -0,0 +1,82 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json::serialization
+import json::static
+
+class MyClass
+       serialize
+
+       var i: Int
+       var s: String
+       var f: Float
+       var a: Array[String]
+       var o: nullable MyClass
+
+       redef fun to_s do return "<MyClass i:{i} s:{s} f:{f} a:[{a.join(", ")}] o:{o or else "<null>"}>"
+end
+
+redef class JsonObject
+       redef fun to_s do return "<JsonObject "+join(", ", ":")+">"
+end
+
+var tests = new Array[String]
+
+# Complete object, as would it be generated by serialization services
+tests.add """
+{"__kind": "obj", "__id": 0, "__class": "MyClass", "i": 123, "s": "hello", "f": 123.456, "a": ["one", "two"], "o": null}"""
+
+# Skipping the `__kind` and `__id` is allowed
+tests.add """
+{"__class": "MyClass", "i": 123, "s": "hello", "f": 123.456, "a": ["one", "two"], "o": null}"""
+
+# The attributes can be in any order
+tests.add """
+{"s": "hello", "o": null, "i": 123, "f": 123.456, "__class": "MyClass", "a": ["one", "two"]}"""
+
+# Extra attributes are ignored
+tests.add """
+{"__class": "MyClass", "i": 123, "s": "hello", "f": 123.456, "o": null, "a": ["one", "two"], "Some random attribute": 777}"""
+
+# Skipping `o` will cause an error but the attribute will be set to `null`
+tests.add """
+{"__class": "MyClass", "i": 123, "s": "hello", "f": 123.456, "a": ["one", "two"]}"""
+
+# Nest different classes
+tests.add """
+{"__class": "MyClass", "i": 123, "s": "hello", "f": 123.456, "a": ["one", "two"], "o":
+       {"__class": "MyClass", "i": 456, "s": "world", "f": 654.321, "a": ["1", "2"], "o": null}}"""
+
+# No `__class` is not advised and will raise an error, but it will be received as a `JsonObject`
+tests.add """
+{"i": 123, "s": "hello", "f": 123.456, "a": ["one", "two"], "o": null}"""
+
+# Invalid type on `o`
+tests.add """
+{"__class": "MyClass", "i": 123, "s": "hello", "f": 123.456, "a": ["one", "two"], "o": "Not the right type"}"""
+
+# Deserializing an invalid JSON string will raise an error
+tests.add "not valid json"
+
+# Missing attributes will raise errors and will crash on access
+#alt2#tests = ["""{"__class": "MyClass", "i": 123, "o": null}"""]
+
+for o in tests do
+       var deserializer = new JsonDeserializer(o)
+       var deserialized = deserializer.deserialize
+
+       print "# JSON: {o}"
+       if deserializer.errors.not_empty then print "# Errors: '{deserializer.errors.join("', '")}'"
+       print "# Nit: {deserialized or else "null"}\n"
+end