diff --git a/tests/json.nim b/tests/json.nim new file mode 100644 index 0000000..7bd155f --- /dev/null +++ b/tests/json.nim @@ -0,0 +1,7 @@ +import ./json/testDeserialize +import ./json/testDeserializeModes +import ./json/testPragmas +import ./json/testSerialize +import ./json/testSerializeModes + +{.warning[UnusedImport]: off.} diff --git a/tests/json/deserialize/objects.nim b/tests/json/deserialize/objects.nim new file mode 100644 index 0000000..0ae8cbe --- /dev/null +++ b/tests/json/deserialize/objects.nim @@ -0,0 +1,167 @@ +import std/unittest +import pkg/serde +import pkg/questionable +import pkg/questionable/results +import pkg/stew/byteutils + +suite "json - deserialize objects": + test "can deserialize json objects": + type MyObj = object + mystring: string + myint: int + myoption: ?bool + + let expected = MyObj(mystring: "abc", myint: 123, myoption: some true) + + let json = + !JsonNode.parse( + """{ + "mystring": "abc", + "myint": 123, + "myoption": true + }""" + ) + + check !MyObj.fromJson(json) == expected + + test "ignores serialize pragma when deserializing": + type MyObj = object + mystring {.serialize.}: string + mybool: bool + + let expected = MyObj(mystring: "abc", mybool: true) + + let json = + !JsonNode.parse( + """{ + "mystring": "abc", + "mybool": true + }""" + ) + + check !MyObj.fromJson(json) == expected + + test "deserializes objects with extra fields": + type MyObj = object + mystring: string + mybool: bool + + let expected = MyObj(mystring: "abc", mybool: true) + + let json = + !JsonNode.parse( + """{ + "mystring": "abc", + "mybool": true, + "extra": "extra" + }""" + ) + check !MyObj.fromJson(json) == expected + + test "deserializes objects with less fields": + type MyObj = object + mystring: string + mybool: bool + + let expected = MyObj(mystring: "abc", mybool: false) + + let json = + !JsonNode.parse( + """{ + "mystring": "abc" + }""" + ) + check !MyObj.fromJson(json) == expected + + test "deserializes ref objects": + type MyRef = ref object + mystring: string + myint: int + + let expected = MyRef(mystring: "abc", myint: 1) + + let json = + !JsonNode.parse( + """{ + "mystring": "abc", + "myint": 1 + }""" + ) + + let deserialized = !MyRef.fromJson(json) + check deserialized.mystring == expected.mystring + check deserialized.myint == expected.myint + + test "deserializes openArray[byte]": + type MyRef = ref object + mystring: string + myint: int + + let expected = MyRef(mystring: "abc", myint: 1) + let byteArray = """{ + "mystring": "abc", + "myint": 1 + }""".toBytes + + let deserialized = !MyRef.fromJson(byteArray) + check deserialized.mystring == expected.mystring + check deserialized.myint == expected.myint + +suite "json - deserialize objects from string": + test "deserializes objects from string": + type MyObj = object + mystring: string + myint: int + + let expected = MyObj(mystring: "abc", myint: 1) + let myObjJson = + """{ + "mystring": "abc", + "myint": 1 + }""" + + check !MyObj.fromJson(myObjJson) == expected + + test "deserializes ref objects from string": + type MyRef = ref object + mystring: string + myint: int + + let expected = MyRef(mystring: "abc", myint: 1) + let myRefJson = + """{ + "mystring": "abc", + "myint": 1 + }""" + + let deserialized = !MyRef.fromJson(myRefJson) + check deserialized.mystring == expected.mystring + check deserialized.myint == expected.myint + + test "deserializes seq of objects from string": + type MyObj = object + mystring: string + myint: int + + let expected = @[MyObj(mystring: "abc", myint: 1)] + let myObjsJson = + """[{ + "mystring": "abc", + "myint": 1 + }]""" + + check !seq[MyObj].fromJson(myObjsJson) == expected + + test "deserializes Option of object from string": + type MyObj = object + mystring: string + myint: int + + let expected = some MyObj(mystring: "abc", myint: 1) + let myObjJson = + """{ + "mystring": "abc", + "myint": 1 + }""" + + check !(Option[MyObj].fromJson(myObjJson)) == expected diff --git a/tests/json/deserialize/std.nim b/tests/json/deserialize/std.nim new file mode 100644 index 0000000..fd68a69 --- /dev/null +++ b/tests/json/deserialize/std.nim @@ -0,0 +1,56 @@ +import std/math +import std/unittest +import pkg/serde +import pkg/questionable +import pkg/questionable/results + +suite "json - deserialize std types": + test "deserializes NaN float": + check %NaN == newJString("nan") + + test "deserialize enum": + type MyEnum = enum + First + Second + + let json = newJString("Second") + check !MyEnum.fromJson(json) == Second + + test "deserializes Option[T] when has a value": + let json = newJInt(1) + check (!fromJson(?int, json) == some 1) + + test "deserializes Option[T] when doesn't have a value": + let json = newJNull() + check !fromJson(?int, json) == none int + + test "deserializes float": + let json = newJFloat(1.234) + check !float.fromJson(json) == 1.234 + + test "deserializes Inf float": + let json = newJString("inf") + check !float.fromJson(json) == Inf + + test "deserializes -Inf float": + let json = newJString("-inf") + check !float.fromJson(json) == -Inf + + test "deserializes NaN float": + let json = newJString("nan") + check (!float.fromJson(json)).isNaN + + test "deserializes array to sequence": + let expected = @[1, 2, 3] + let json = !JsonNode.parse("[1,2,3]") + check !seq[int].fromJson(json) == expected + + test "deserializes uints int.high or smaller": + let largeUInt: uint = uint(int.high) + let json = newJInt(BiggestInt(largeUInt)) + check !uint.fromJson(json) == largeUInt + + test "deserializes large uints": + let largeUInt: uint = uint(int.high) + 1'u + let json = newJString($BiggestUInt(largeUInt)) + check !uint.fromJson(json) == largeUInt diff --git a/tests/json/deserialize/stint.nim b/tests/json/deserialize/stint.nim new file mode 100644 index 0000000..b7428dd --- /dev/null +++ b/tests/json/deserialize/stint.nim @@ -0,0 +1,72 @@ +import std/options +import std/unittest +import pkg/stint +import pkg/serde +import pkg/questionable +import pkg/questionable/results + +suite "json - deserialize stint": + test "deserializes UInt256 from an empty JString": + let json = newJString("") + check !UInt256.fromJson(json) == 0.u256 + + test "deserializes UInt256 from an empty string": + check !UInt256.fromJson("") == 0.u256 + + test "deserializes ?UInt256 from an empty JString": + let json = newJString("") + check !Option[UInt256].fromJson(json) == 0.u256.some + + test "deserializes ?UInt256 from an empty string": + check !Option[UInt256].fromJson("") == 0.u256.some + + test "deserializes UInt256 from JString with no prefix": + let json = newJString("1") + check !UInt256.fromJson(json) == 1.u256 + + test "deserializes ?UInt256 from JString with no prefix": + let json = newJString("1") + check !Option[UInt256].fromJson(json) == 1.u256.some + + test "deserializes UInt256 from string with no prefix": + check !UInt256.fromJson("1") == 1.u256 + + test "deserializes ?UInt256 from string with no prefix": + check !Option[UInt256].fromJson("1") == 1.u256.some + + test "deserializes UInt256 from hex JString representation": + let json = newJString("0x1") + check !UInt256.fromJson(json) == 0x1.u256 + + test "deserializes ?UInt256 from hex JString representation": + let json = newJString("0x1") + check !Option[UInt256].fromJson(json) == 0x1.u256.some + + test "deserializes ?UInt256 from hex string representation": + check !Option[UInt256].fromJson("0x1") == 0x1.u256.some + + test "deserializes UInt256 from octal JString representation": + let json = newJString("0o1") + check !UInt256.fromJson(json) == 0o1.u256 + + test "deserializes ?UInt256 from octal JString representation": + let json = newJString("0o1") + check !Option[UInt256].fromJson(json) == 0o1.u256.some + + test "deserializes ?UInt256 from octal string representation": + check !Option[UInt256].fromJson("0o1") == 0o1.u256.some + + test "deserializes UInt256 from binary JString representation": + let json = newJString("0b1") + check !UInt256.fromJson(json) == 0b1.u256 + + test "deserializes ?UInt256 from binary JString representation": + let json = newJString("0b1") + check !Option[UInt256].fromJson(json) == 0b1.u256.some + + test "deserializes ?UInt256 from binary string representation": + check !Option[UInt256].fromJson("0b1") == 0b1.u256.some + + test "deserializes Int256 with no prefix": + let json = newJString("1") + check !Int256.fromJson(json) == 1.i256