--- /dev/null
+# 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
+
--- /dev/null
+# 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