cleanup test files

This commit is contained in:
munna0908 2025-05-21 03:41:35 +05:30
parent f1ec805ec0
commit beac0e2a32
No known key found for this signature in database
GPG Key ID: 2FFCD637E937D3E6
5 changed files with 193 additions and 347 deletions

View File

@ -580,86 +580,7 @@ func getFloat*(n: CborNode; default = 0.0): float =
default
proc fromCbor*[T](v: var T; n: CborNode): bool =
## 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 =
proc fromCbor*[T](v: var T; n: CborNode): ?!void =
## Return a Result containing the value if `v` can be converted from a given `CborNode`,
## or an error if conversion fails.
## 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)):
return fromCborHook(v, n)
elif T is distinct:
return fromCborQ2(distinctBase v, n)
return fromCbor(distinctBase v, n)
elif T is SomeUnsignedInt:
exceptCborKind(T, {cborUnsigned}, n)
v = T n.uint
@ -714,7 +635,7 @@ proc fromCborQ2*[T](v: var T; n: CborNode): ?!void =
exceptCborKind(T, {cborArray}, n)
v.setLen n.seq.len
for i, e in n.seq:
let itemResult = fromCborQ2(v[i], e)
let itemResult = fromCbor(v[i], e)
if itemResult.isFailure:
v.setLen 0
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))
var i: int
for f in fields(v):
let itemResult = fromCborQ2(f, n.seq[i])
let itemResult = fromCbor(f, n.seq[i])
if itemResult.isFailure:
return failure(itemResult.error)
inc i
@ -736,7 +657,7 @@ proc fromCborQ2*[T](v: var T; n: CborNode): ?!void =
return success()
else:
if isNil(v): new(v)
return fromCborQ2(v[], n)
return fromCbor(v[], n)
elif T is object:
exceptCborKind(T, {cborMap}, n)
var
@ -747,7 +668,7 @@ proc fromCborQ2*[T](v: var T; n: CborNode): ?!void =
if not n.map.hasKey key:
return failure(newCborError("Missing field: " & s))
else:
let fieldResult = fromCborQ2(v.dot(s), n.map[key])
let fieldResult = fromCbor(v.dot(s), n.map[key])
if fieldResult.isFailure:
return failure(fieldResult.error)
inc i

View File

@ -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
View 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

View File

@ -98,3 +98,11 @@ test "sorting":
check not map.isSorted
sort(map)
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"

View File

@ -3,7 +3,7 @@ import ./json/testDeserializeModes
import ./json/testPragmas
import ./json/testSerialize
import ./json/testSerializeModes
import ./cbor/testDeserialize
import ./cbor/test
import ./cbor/testPrimitives
import ./cbor/testObjects
{.warning[UnusedImport]: off.}