mirror of
https://github.com/logos-storage/nim-serde.git
synced 2026-01-07 16:13:06 +00:00
cleanup test files
This commit is contained in:
parent
f1ec805ec0
commit
beac0e2a32
@ -580,86 +580,7 @@ func getFloat*(n: CborNode; default = 0.0): float =
|
|||||||
default
|
default
|
||||||
|
|
||||||
|
|
||||||
proc fromCbor*[T](v: var T; n: CborNode): bool =
|
proc fromCbor*[T](v: var T; n: CborNode): ?!void =
|
||||||
## Return `true` if `v` can be converted from a given `CborNode`.
|
|
||||||
## Can be extended and overriden with `fromCborHook(v: var T; n: CborNode)`
|
|
||||||
## for specific types of `T`.
|
|
||||||
when T is CborNode:
|
|
||||||
v = n
|
|
||||||
result = true
|
|
||||||
elif compiles(fromCborHook(v, n)):
|
|
||||||
result = fromCborHook(v, n)
|
|
||||||
elif T is distinct:
|
|
||||||
result = fromCbor(distinctBase v, n)
|
|
||||||
elif T is SomeUnsignedInt:
|
|
||||||
if n.kind == cborUnsigned:
|
|
||||||
v = T n.uint
|
|
||||||
result = v.BiggestUInt == n.uint
|
|
||||||
elif T is SomeSignedInt:
|
|
||||||
if n.kind == cborUnsigned:
|
|
||||||
v = T n.uint
|
|
||||||
result = v.BiggestUInt == n.uint
|
|
||||||
elif n.kind == cborNegative:
|
|
||||||
v = T n.int
|
|
||||||
result = v.BiggestInt == n.int
|
|
||||||
elif T is bool:
|
|
||||||
if n.isBool:
|
|
||||||
v = n.getBool
|
|
||||||
result = true
|
|
||||||
elif T is SomeFloat:
|
|
||||||
if n.kind == cborFloat:
|
|
||||||
v = T n.float
|
|
||||||
result = true
|
|
||||||
elif T is seq[byte]:
|
|
||||||
if n.kind == cborBytes:
|
|
||||||
v = n.bytes
|
|
||||||
result = true
|
|
||||||
elif T is string:
|
|
||||||
if n.kind == cborText:
|
|
||||||
v = n.text
|
|
||||||
result = true
|
|
||||||
elif T is seq:
|
|
||||||
if n.kind == cborArray:
|
|
||||||
result = true
|
|
||||||
v.setLen n.seq.len
|
|
||||||
for i, e in n.seq:
|
|
||||||
result = result and fromCbor(v[i], e)
|
|
||||||
if not result:
|
|
||||||
v.setLen 0
|
|
||||||
break
|
|
||||||
elif T is tuple:
|
|
||||||
if n.kind == cborArray and n.seq.len == T.tupleLen:
|
|
||||||
result = true
|
|
||||||
var i: int
|
|
||||||
for f in fields(v):
|
|
||||||
result = result and fromCbor(f, n.seq[i])
|
|
||||||
if not result: break
|
|
||||||
inc i
|
|
||||||
elif T is ref:
|
|
||||||
if n.isNull:
|
|
||||||
v = nil
|
|
||||||
result = true
|
|
||||||
else:
|
|
||||||
if isNil(v): new(v)
|
|
||||||
result = fromCbor(v[], n)
|
|
||||||
elif T is object:
|
|
||||||
if n.kind == cborMap:
|
|
||||||
result = true
|
|
||||||
var
|
|
||||||
i: int
|
|
||||||
key = CborNode(kind: cborText)
|
|
||||||
for s, _ in fieldPairs(v):
|
|
||||||
key.text = s
|
|
||||||
if not n.map.hasKey key:
|
|
||||||
result = false
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
result = fromCbor(v.dot(s), n.map[key])
|
|
||||||
if not result: break
|
|
||||||
inc i
|
|
||||||
result = result and (i == n.map.len)
|
|
||||||
|
|
||||||
proc fromCborQ2*[T](v: var T; n: CborNode): ?!void =
|
|
||||||
## Return a Result containing the value if `v` can be converted from a given `CborNode`,
|
## Return a Result containing the value if `v` can be converted from a given `CborNode`,
|
||||||
## or an error if conversion fails.
|
## or an error if conversion fails.
|
||||||
## Can be extended and overriden with `fromCborHook(v: var T; n: CborNode)`
|
## Can be extended and overriden with `fromCborHook(v: var T; n: CborNode)`
|
||||||
@ -671,7 +592,7 @@ proc fromCborQ2*[T](v: var T; n: CborNode): ?!void =
|
|||||||
elif compiles(fromCborHook(v, n)):
|
elif compiles(fromCborHook(v, n)):
|
||||||
return fromCborHook(v, n)
|
return fromCborHook(v, n)
|
||||||
elif T is distinct:
|
elif T is distinct:
|
||||||
return fromCborQ2(distinctBase v, n)
|
return fromCbor(distinctBase v, n)
|
||||||
elif T is SomeUnsignedInt:
|
elif T is SomeUnsignedInt:
|
||||||
exceptCborKind(T, {cborUnsigned}, n)
|
exceptCborKind(T, {cborUnsigned}, n)
|
||||||
v = T n.uint
|
v = T n.uint
|
||||||
@ -714,7 +635,7 @@ proc fromCborQ2*[T](v: var T; n: CborNode): ?!void =
|
|||||||
exceptCborKind(T, {cborArray}, n)
|
exceptCborKind(T, {cborArray}, n)
|
||||||
v.setLen n.seq.len
|
v.setLen n.seq.len
|
||||||
for i, e in n.seq:
|
for i, e in n.seq:
|
||||||
let itemResult = fromCborQ2(v[i], e)
|
let itemResult = fromCbor(v[i], e)
|
||||||
if itemResult.isFailure:
|
if itemResult.isFailure:
|
||||||
v.setLen 0
|
v.setLen 0
|
||||||
return failure(itemResult.error)
|
return failure(itemResult.error)
|
||||||
@ -725,7 +646,7 @@ proc fromCborQ2*[T](v: var T; n: CborNode): ?!void =
|
|||||||
return failure(newCborError("Expected tuple of length " & $T.tupleLen))
|
return failure(newCborError("Expected tuple of length " & $T.tupleLen))
|
||||||
var i: int
|
var i: int
|
||||||
for f in fields(v):
|
for f in fields(v):
|
||||||
let itemResult = fromCborQ2(f, n.seq[i])
|
let itemResult = fromCbor(f, n.seq[i])
|
||||||
if itemResult.isFailure:
|
if itemResult.isFailure:
|
||||||
return failure(itemResult.error)
|
return failure(itemResult.error)
|
||||||
inc i
|
inc i
|
||||||
@ -736,7 +657,7 @@ proc fromCborQ2*[T](v: var T; n: CborNode): ?!void =
|
|||||||
return success()
|
return success()
|
||||||
else:
|
else:
|
||||||
if isNil(v): new(v)
|
if isNil(v): new(v)
|
||||||
return fromCborQ2(v[], n)
|
return fromCbor(v[], n)
|
||||||
elif T is object:
|
elif T is object:
|
||||||
exceptCborKind(T, {cborMap}, n)
|
exceptCborKind(T, {cborMap}, n)
|
||||||
var
|
var
|
||||||
@ -747,7 +668,7 @@ proc fromCborQ2*[T](v: var T; n: CborNode): ?!void =
|
|||||||
if not n.map.hasKey key:
|
if not n.map.hasKey key:
|
||||||
return failure(newCborError("Missing field: " & s))
|
return failure(newCborError("Missing field: " & s))
|
||||||
else:
|
else:
|
||||||
let fieldResult = fromCborQ2(v.dot(s), n.map[key])
|
let fieldResult = fromCbor(v.dot(s), n.map[key])
|
||||||
if fieldResult.isFailure:
|
if fieldResult.isFailure:
|
||||||
return failure(fieldResult.error)
|
return failure(fieldResult.error)
|
||||||
inc i
|
inc i
|
||||||
|
|||||||
@ -1,260 +0,0 @@
|
|||||||
# File: /Users/rahul/Work/repos/nim-serde/tests/cbor_questionable.nim
|
|
||||||
|
|
||||||
import std/unittest
|
|
||||||
import std/options
|
|
||||||
import std/streams
|
|
||||||
import pkg/serde
|
|
||||||
import pkg/questionable
|
|
||||||
import pkg/questionable/results
|
|
||||||
|
|
||||||
# Custom type for testing
|
|
||||||
type
|
|
||||||
CustomPoint = object
|
|
||||||
x: int
|
|
||||||
y: int
|
|
||||||
|
|
||||||
CustomColor = enum
|
|
||||||
Red, Green, Blue
|
|
||||||
|
|
||||||
CustomObject = object
|
|
||||||
name: string
|
|
||||||
point: CustomPoint
|
|
||||||
color: CustomColor
|
|
||||||
|
|
||||||
Person = object
|
|
||||||
name: string
|
|
||||||
age: int
|
|
||||||
isActive: bool
|
|
||||||
|
|
||||||
Inner = object
|
|
||||||
s: string
|
|
||||||
nums: seq[int]
|
|
||||||
|
|
||||||
CompositeNested = object
|
|
||||||
u: uint64
|
|
||||||
n: int
|
|
||||||
b: seq[byte]
|
|
||||||
t: string
|
|
||||||
arr: seq[int]
|
|
||||||
tag: float
|
|
||||||
flag: bool
|
|
||||||
inner: Inner
|
|
||||||
innerArr: seq[Inner]
|
|
||||||
coordinates: tuple[x: int, y: int, label: string]
|
|
||||||
refInner: ref Inner
|
|
||||||
|
|
||||||
proc fromCborHook*(v: var CustomColor, n: CborNode): ?!void =
|
|
||||||
if n.kind == cborNegative:
|
|
||||||
v = CustomColor(n.int)
|
|
||||||
result = success()
|
|
||||||
else:
|
|
||||||
result = failure(newSerdeError("Expected signed integer, got " & $n.kind))
|
|
||||||
|
|
||||||
# Custom fromCborHook for CustomPoint
|
|
||||||
proc fromCborHook*(v: var CustomPoint, n: CborNode): ?!void =
|
|
||||||
if n.kind == cborArray and n.seq.len == 2:
|
|
||||||
var x, y: int
|
|
||||||
let xResult = fromCborQ2(x, n.seq[0])
|
|
||||||
if xResult.isFailure:
|
|
||||||
return failure(xResult.error)
|
|
||||||
|
|
||||||
let yResult = fromCborQ2(y, n.seq[1])
|
|
||||||
if yResult.isFailure:
|
|
||||||
return failure(yResult.error)
|
|
||||||
|
|
||||||
v = CustomPoint(x: x, y: y)
|
|
||||||
result = success()
|
|
||||||
else:
|
|
||||||
result = failure(newSerdeError("Expected array of length 2 for CustomPoint"))
|
|
||||||
|
|
||||||
# Helper function to create CBOR data for testing
|
|
||||||
proc createPointCbor(x, y: int): CborNode =
|
|
||||||
result = CborNode(kind: cborArray)
|
|
||||||
result.seq = @[
|
|
||||||
CborNode(kind: cborUnsigned, uint: x.uint64),
|
|
||||||
CborNode(kind: cborUnsigned, uint: y.uint64)
|
|
||||||
]
|
|
||||||
|
|
||||||
proc createObjectCbor(name: string, point: CustomPoint,
|
|
||||||
color: CustomColor): CborNode =
|
|
||||||
result = CborNode(kind: cborMap)
|
|
||||||
result.map = initOrderedTable[CborNode, CborNode]()
|
|
||||||
|
|
||||||
# Add name field
|
|
||||||
result.map[CborNode(kind: cborText, text: "name")] =
|
|
||||||
CborNode(kind: cborText, text: name)
|
|
||||||
|
|
||||||
# Add point field
|
|
||||||
result.map[CborNode(kind: cborText, text: "point")] =
|
|
||||||
createPointCbor(point.x, point.y)
|
|
||||||
|
|
||||||
# Add color field
|
|
||||||
result.map[CborNode(kind: cborText, text: "color")] =
|
|
||||||
CborNode(kind: cborNegative, int: color.int)
|
|
||||||
|
|
||||||
suite "CBOR deserialization with Questionable":
|
|
||||||
test "fromCborQ2 with primitive types":
|
|
||||||
# Test with integer
|
|
||||||
block:
|
|
||||||
var intValue: int
|
|
||||||
let node = CborNode(kind: cborUnsigned, uint: 42.uint64)
|
|
||||||
let result = fromCborQ2(intValue, node)
|
|
||||||
|
|
||||||
check result.isSuccess
|
|
||||||
check intValue == 42
|
|
||||||
|
|
||||||
# Test with string
|
|
||||||
block:
|
|
||||||
var strValue: string
|
|
||||||
let node = CborNode(kind: cborText, text: "hello")
|
|
||||||
let result = fromCborQ2(strValue, node)
|
|
||||||
|
|
||||||
check result.isSuccess
|
|
||||||
check strValue == "hello"
|
|
||||||
|
|
||||||
# Test with error case
|
|
||||||
block:
|
|
||||||
var intValue: int
|
|
||||||
let node = CborNode(kind: cborText, text: "not an int")
|
|
||||||
let result = fromCborQ2(intValue, node)
|
|
||||||
|
|
||||||
check result.isFailure
|
|
||||||
check $result.error.msg == "deserialization to int failed: expected {cborUnsigned, cborNegative} but got cborText"
|
|
||||||
|
|
||||||
test "parseCborAs with valid input":
|
|
||||||
# Create a valid CBOR object for a Person
|
|
||||||
var mapNode = CborNode(kind: cborMap)
|
|
||||||
mapNode.map = initOrderedTable[CborNode, CborNode]()
|
|
||||||
mapNode.map[CborNode(kind: cborText, text: "a")] = CborNode(
|
|
||||||
kind: cborText, text: "John Doe")
|
|
||||||
mapNode.map[CborNode(kind: cborText, text: "b")] = CborNode(
|
|
||||||
kind: cborUnsigned, uint: 30)
|
|
||||||
mapNode.map[CborNode(kind: cborText, text: "c")] = CborNode(
|
|
||||||
kind: cborSimple, simple: 21) # true
|
|
||||||
var p1: Person
|
|
||||||
p1.name = "John Doe"
|
|
||||||
p1.age = 30
|
|
||||||
p1.isActive = true
|
|
||||||
|
|
||||||
let stream = newStringStream()
|
|
||||||
stream.writeCbor(p1)
|
|
||||||
let cborData = stream.data
|
|
||||||
|
|
||||||
# var cborNode = parseCbor(cborData)
|
|
||||||
# check cborNode.isSuccess
|
|
||||||
# echo cborNode.tryError.msg
|
|
||||||
|
|
||||||
without parsedNode =? parseCbor(cborData), error:
|
|
||||||
echo error.msg
|
|
||||||
|
|
||||||
# Parse directly to Person object
|
|
||||||
var person: Person
|
|
||||||
let result = fromCborQ2(person, parsedNode)
|
|
||||||
|
|
||||||
check result.isSuccess
|
|
||||||
check person.name == "John Doe"
|
|
||||||
check person.age == 30
|
|
||||||
check person.isActive == true
|
|
||||||
|
|
||||||
test "fromCborQ2 with custom hook":
|
|
||||||
# Test with valid point data
|
|
||||||
block:
|
|
||||||
var point: CustomPoint
|
|
||||||
let node = createPointCbor(10, 20)
|
|
||||||
let result = fromCborQ2(point, node)
|
|
||||||
|
|
||||||
check result.isSuccess
|
|
||||||
check point.x == 10
|
|
||||||
check point.y == 20
|
|
||||||
|
|
||||||
# Test with invalid point data
|
|
||||||
block:
|
|
||||||
var point: CustomPoint
|
|
||||||
let elements = @[toCbor(10)]
|
|
||||||
let node = toCbor(elements)
|
|
||||||
let result = fromCborQ2(point, node)
|
|
||||||
|
|
||||||
check result.isFailure
|
|
||||||
# check "Expected array of length 2" in $result.error.msg
|
|
||||||
|
|
||||||
test "fromCborQ2 with complex object":
|
|
||||||
# Create a complex object
|
|
||||||
let point = CustomPoint(x: 15, y: 25)
|
|
||||||
# let obj = CustomObject(name: "Test Object", point: point, color: Green)
|
|
||||||
|
|
||||||
# Create CBOR representation
|
|
||||||
let node = createObjectCbor("Test Object", point, Green)
|
|
||||||
|
|
||||||
# Deserialize
|
|
||||||
var deserializedObj: CustomObject
|
|
||||||
# Check result
|
|
||||||
let result = fromCborQ2(deserializedObj, node)
|
|
||||||
check result.isSuccess
|
|
||||||
check deserializedObj.name == "Test Object"
|
|
||||||
check deserializedObj.point.x == 15
|
|
||||||
check deserializedObj.point.y == 25
|
|
||||||
check deserializedObj.color == Green
|
|
||||||
|
|
||||||
suite "CBOR round-trip for nested composite object":
|
|
||||||
test "serialize and parse nested composite type":
|
|
||||||
var refObj = new Inner
|
|
||||||
refObj.s = "refInner"
|
|
||||||
refObj.nums = @[30, 40]
|
|
||||||
var original = CompositeNested(
|
|
||||||
u: 42,
|
|
||||||
n: -99,
|
|
||||||
b: @[byte 1, byte 2],
|
|
||||||
t: "hi",
|
|
||||||
arr: @[1, 2, 3],
|
|
||||||
tag: 1.5,
|
|
||||||
flag: true,
|
|
||||||
inner: Inner(s: "inner!", nums: @[10, 20]),
|
|
||||||
innerArr: @[
|
|
||||||
Inner(s: "first", nums: @[1, 2]),
|
|
||||||
Inner(s: "second", nums: @[3, 4, 5])
|
|
||||||
],
|
|
||||||
coordinates: (x: 10, y: 20, label: "test"),
|
|
||||||
refInner: refObj
|
|
||||||
)
|
|
||||||
|
|
||||||
# Serialize to CBOR
|
|
||||||
let stream = newStringStream()
|
|
||||||
stream.writeCbor(original)
|
|
||||||
let cborData = stream.data
|
|
||||||
# Parse CBOR back to CborNode
|
|
||||||
let parseResult = parseCbor(cborData)
|
|
||||||
check parseResult.isSuccess
|
|
||||||
let node = parseResult.tryValue
|
|
||||||
|
|
||||||
# Deserialize to CompositeNested object
|
|
||||||
var roundtrip: CompositeNested
|
|
||||||
let deserResult = fromCborQ2(roundtrip, node)
|
|
||||||
check deserResult.isSuccess
|
|
||||||
|
|
||||||
# Check top-level fields
|
|
||||||
check roundtrip.u == original.u
|
|
||||||
check roundtrip.n == original.n
|
|
||||||
check roundtrip.b == original.b
|
|
||||||
check roundtrip.t == original.t
|
|
||||||
check roundtrip.arr == original.arr
|
|
||||||
check abs(roundtrip.tag - original.tag) < 1e-6
|
|
||||||
check roundtrip.flag == original.flag
|
|
||||||
|
|
||||||
# Check nested object
|
|
||||||
check roundtrip.inner.s == original.inner.s
|
|
||||||
check roundtrip.inner.nums == original.inner.nums
|
|
||||||
|
|
||||||
# Check nested array of objects
|
|
||||||
check roundtrip.innerArr.len == original.innerArr.len
|
|
||||||
for i in 0..<roundtrip.innerArr.len:
|
|
||||||
check roundtrip.innerArr[i].s == original.innerArr[i].s
|
|
||||||
check roundtrip.innerArr[i].nums == original.innerArr[i].nums
|
|
||||||
|
|
||||||
check roundtrip.coordinates.x == original.coordinates.x
|
|
||||||
check roundtrip.coordinates.y == original.coordinates.y
|
|
||||||
check roundtrip.coordinates.label == original.coordinates.label
|
|
||||||
|
|
||||||
|
|
||||||
check not roundtrip.refInner.isNil
|
|
||||||
check roundtrip.refInner.s == original.refInner.s
|
|
||||||
check roundtrip.refInner.nums == original.refInner.nums
|
|
||||||
177
tests/cbor/testObjects.nim
Normal file
177
tests/cbor/testObjects.nim
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
# File: /Users/rahul/Work/repos/nim-serde/tests/cbor_questionable.nim
|
||||||
|
|
||||||
|
import std/unittest
|
||||||
|
import std/options
|
||||||
|
import std/streams
|
||||||
|
import pkg/serde
|
||||||
|
import pkg/questionable
|
||||||
|
import pkg/questionable/results
|
||||||
|
|
||||||
|
# Custom type for testing
|
||||||
|
type
|
||||||
|
CustomPoint = object
|
||||||
|
x: int
|
||||||
|
y: int
|
||||||
|
|
||||||
|
CustomColor = enum
|
||||||
|
Red, Green, Blue
|
||||||
|
|
||||||
|
CustomObject = object
|
||||||
|
name: string
|
||||||
|
point: CustomPoint
|
||||||
|
color: CustomColor
|
||||||
|
|
||||||
|
Person = object
|
||||||
|
name: string
|
||||||
|
age: int
|
||||||
|
isActive: bool
|
||||||
|
|
||||||
|
Inner = object
|
||||||
|
s: string
|
||||||
|
nums: seq[int]
|
||||||
|
|
||||||
|
CompositeNested = object
|
||||||
|
u: uint64
|
||||||
|
n: int
|
||||||
|
b: seq[byte]
|
||||||
|
t: string
|
||||||
|
arr: seq[int]
|
||||||
|
tag: float
|
||||||
|
flag: bool
|
||||||
|
inner: Inner
|
||||||
|
innerArr: seq[Inner]
|
||||||
|
coordinates: tuple[x: int, y: int, label: string]
|
||||||
|
refInner: ref Inner
|
||||||
|
|
||||||
|
proc fromCborHook*(v: var CustomColor, n: CborNode): ?!void =
|
||||||
|
if n.kind == cborNegative:
|
||||||
|
v = CustomColor(n.int)
|
||||||
|
result = success()
|
||||||
|
else:
|
||||||
|
result = failure(newSerdeError("Expected signed integer, got " & $n.kind))
|
||||||
|
|
||||||
|
# Custom fromCborHook for CustomPoint
|
||||||
|
proc fromCborHook*(v: var CustomPoint, n: CborNode): ?!void =
|
||||||
|
if n.kind == cborArray and n.seq.len == 2:
|
||||||
|
var x, y: int
|
||||||
|
let xResult = fromCbor(x, n.seq[0])
|
||||||
|
if xResult.isFailure:
|
||||||
|
return failure(xResult.error)
|
||||||
|
|
||||||
|
let yResult = fromCbor(y, n.seq[1])
|
||||||
|
if yResult.isFailure:
|
||||||
|
return failure(yResult.error)
|
||||||
|
|
||||||
|
v = CustomPoint(x: x, y: y)
|
||||||
|
result = success()
|
||||||
|
else:
|
||||||
|
result = failure(newSerdeError("Expected array of length 2 for CustomPoint"))
|
||||||
|
|
||||||
|
# Helper function to create CBOR data for testing
|
||||||
|
proc createPointCbor(x, y: int): CborNode =
|
||||||
|
result = CborNode(kind: cborArray)
|
||||||
|
result.seq = @[
|
||||||
|
CborNode(kind: cborUnsigned, uint: x.uint64),
|
||||||
|
CborNode(kind: cborUnsigned, uint: y.uint64)
|
||||||
|
]
|
||||||
|
|
||||||
|
proc createObjectCbor(name: string, point: CustomPoint,
|
||||||
|
color: CustomColor): CborNode =
|
||||||
|
result = CborNode(kind: cborMap)
|
||||||
|
result.map = initOrderedTable[CborNode, CborNode]()
|
||||||
|
|
||||||
|
# Add name field
|
||||||
|
result.map[CborNode(kind: cborText, text: "name")] =
|
||||||
|
CborNode(kind: cborText, text: name)
|
||||||
|
|
||||||
|
# Add point field
|
||||||
|
result.map[CborNode(kind: cborText, text: "point")] =
|
||||||
|
createPointCbor(point.x, point.y)
|
||||||
|
|
||||||
|
# Add color field
|
||||||
|
result.map[CborNode(kind: cborText, text: "color")] =
|
||||||
|
CborNode(kind: cborNegative, int: color.int)
|
||||||
|
|
||||||
|
suite "CBOR deserialization":
|
||||||
|
|
||||||
|
test "deserializes object with custom types":
|
||||||
|
# Create a complex object
|
||||||
|
let point = CustomPoint(x: 15, y: 25)
|
||||||
|
# let obj = CustomObject(name: "Test Object", point: point, color: Green)
|
||||||
|
|
||||||
|
# Create CBOR representation
|
||||||
|
let node = createObjectCbor("Test Object", point, Green)
|
||||||
|
|
||||||
|
# Deserialize
|
||||||
|
var deserializedObj: CustomObject
|
||||||
|
# Check result
|
||||||
|
let result = fromCbor(deserializedObj, node)
|
||||||
|
check result.isSuccess
|
||||||
|
check deserializedObj.name == "Test Object"
|
||||||
|
check deserializedObj.point.x == 15
|
||||||
|
check deserializedObj.point.y == 25
|
||||||
|
check deserializedObj.color == Green
|
||||||
|
|
||||||
|
|
||||||
|
test "serialize and deserialize object with all supported wire types":
|
||||||
|
var refObj = new Inner
|
||||||
|
refObj.s = "refInner"
|
||||||
|
refObj.nums = @[30, 40]
|
||||||
|
var original = CompositeNested(
|
||||||
|
u: 42,
|
||||||
|
n: -99,
|
||||||
|
b: @[byte 1, byte 2],
|
||||||
|
t: "hi",
|
||||||
|
arr: @[1, 2, 3],
|
||||||
|
tag: 1.5,
|
||||||
|
flag: true,
|
||||||
|
inner: Inner(s: "inner!", nums: @[10, 20]),
|
||||||
|
innerArr: @[
|
||||||
|
Inner(s: "first", nums: @[1, 2]),
|
||||||
|
Inner(s: "second", nums: @[3, 4, 5])
|
||||||
|
],
|
||||||
|
coordinates: (x: 10, y: 20, label: "test"),
|
||||||
|
refInner: refObj
|
||||||
|
)
|
||||||
|
|
||||||
|
# Serialize to CBOR
|
||||||
|
let stream = newStringStream()
|
||||||
|
stream.writeCbor(original)
|
||||||
|
let cborData = stream.data
|
||||||
|
# Parse CBOR back to CborNode
|
||||||
|
let parseResult = parseCbor(cborData)
|
||||||
|
check parseResult.isSuccess
|
||||||
|
let node = parseResult.tryValue
|
||||||
|
|
||||||
|
# Deserialize to CompositeNested object
|
||||||
|
var roundtrip: CompositeNested
|
||||||
|
let deserResult = fromCbor(roundtrip, node)
|
||||||
|
check deserResult.isSuccess
|
||||||
|
|
||||||
|
# Check top-level fields
|
||||||
|
check roundtrip.u == original.u
|
||||||
|
check roundtrip.n == original.n
|
||||||
|
check roundtrip.b == original.b
|
||||||
|
check roundtrip.t == original.t
|
||||||
|
check roundtrip.arr == original.arr
|
||||||
|
check abs(roundtrip.tag - original.tag) < 1e-6
|
||||||
|
check roundtrip.flag == original.flag
|
||||||
|
|
||||||
|
# Check nested object
|
||||||
|
check roundtrip.inner.s == original.inner.s
|
||||||
|
check roundtrip.inner.nums == original.inner.nums
|
||||||
|
|
||||||
|
# Check nested array of objects
|
||||||
|
check roundtrip.innerArr.len == original.innerArr.len
|
||||||
|
for i in 0..<roundtrip.innerArr.len:
|
||||||
|
check roundtrip.innerArr[i].s == original.innerArr[i].s
|
||||||
|
check roundtrip.innerArr[i].nums == original.innerArr[i].nums
|
||||||
|
|
||||||
|
check roundtrip.coordinates.x == original.coordinates.x
|
||||||
|
check roundtrip.coordinates.y == original.coordinates.y
|
||||||
|
check roundtrip.coordinates.label == original.coordinates.label
|
||||||
|
|
||||||
|
|
||||||
|
check not roundtrip.refInner.isNil
|
||||||
|
check roundtrip.refInner.s == original.refInner.s
|
||||||
|
check roundtrip.refInner.nums == original.refInner.nums
|
||||||
@ -98,3 +98,11 @@ test "sorting":
|
|||||||
check not map.isSorted
|
check not map.isSorted
|
||||||
sort(map)
|
sort(map)
|
||||||
check map.isSorted
|
check map.isSorted
|
||||||
|
|
||||||
|
test "invalid wire type":
|
||||||
|
var intValue: int
|
||||||
|
let node = CborNode(kind: cborText, text: "not an int")
|
||||||
|
let result = fromCbor(intValue, node)
|
||||||
|
|
||||||
|
check result.isFailure
|
||||||
|
check $result.error.msg == "deserialization to int failed: expected {cborUnsigned, cborNegative} but got cborText"
|
||||||
@ -3,7 +3,7 @@ import ./json/testDeserializeModes
|
|||||||
import ./json/testPragmas
|
import ./json/testPragmas
|
||||||
import ./json/testSerialize
|
import ./json/testSerialize
|
||||||
import ./json/testSerializeModes
|
import ./json/testSerializeModes
|
||||||
import ./cbor/testDeserialize
|
import ./cbor/testPrimitives
|
||||||
import ./cbor/test
|
import ./cbor/testObjects
|
||||||
|
|
||||||
{.warning[UnusedImport]: off.}
|
{.warning[UnusedImport]: off.}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user