Add JsonValueRef compare operation (#89)
This commit is contained in:
parent
7516a92eb8
commit
1ac1d69f95
|
@ -1,5 +1,5 @@
|
|||
# json-serialization
|
||||
# Copyright (c) 2023 Status Research & Development GmbH
|
||||
# Copyright (c) 2023-2024 Status Research & Development GmbH
|
||||
# Licensed under either of
|
||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
||||
|
@ -79,4 +79,60 @@ proc delete*(obj: JsonValueRef, key: string) =
|
|||
raise newException(IndexDefect, "key not in object")
|
||||
obj.objVal.del(key)
|
||||
|
||||
func compare*(lhs, rhs: JsonValueRef): bool
|
||||
|
||||
func compareObject(lhs, rhs: JsonValueRef): bool =
|
||||
## assume lhs.len >= rhs.len
|
||||
## null field and no field are treated equals
|
||||
for k, v in lhs.objVal:
|
||||
let rhsVal = rhs.objVal.getOrDefault(k, nil)
|
||||
if rhsVal.isNil:
|
||||
if v.kind != JsonValueKind.Null:
|
||||
return false
|
||||
else:
|
||||
continue
|
||||
if not compare(rhsVal, v):
|
||||
return false
|
||||
true
|
||||
|
||||
func compare*(lhs, rhs: JsonValueRef): bool =
|
||||
## The difference between `==` and `compare`
|
||||
## lies in the object comparison. Null field `compare`
|
||||
## to non existent field will return true.
|
||||
## On the other hand, `==` will return false.
|
||||
|
||||
if lhs.isNil and rhs.isNil:
|
||||
return true
|
||||
|
||||
if not lhs.isNil and rhs.isNil:
|
||||
return false
|
||||
|
||||
if lhs.isNil and not rhs.isNil:
|
||||
return false
|
||||
|
||||
if lhs.kind != rhs.kind:
|
||||
return false
|
||||
|
||||
case lhs.kind
|
||||
of JsonValueKind.String:
|
||||
lhs.strVal == rhs.strVal
|
||||
of JsonValueKind.Number:
|
||||
lhs.numVal == rhs.numVal
|
||||
of JsonValueKind.Object:
|
||||
if lhs.objVal.len >= rhs.objVal.len:
|
||||
compareObject(lhs, rhs)
|
||||
else:
|
||||
compareObject(rhs, lhs)
|
||||
of JsonValueKind.Array:
|
||||
if lhs.arrayVal.len != rhs.arrayVal.len:
|
||||
return false
|
||||
for i, x in lhs.arrayVal:
|
||||
if not compare(x, rhs.arrayVal[i]):
|
||||
return false
|
||||
true
|
||||
of JsonValueKind.Bool:
|
||||
lhs.boolVal == rhs.boolVal
|
||||
of JsonValueKind.Null:
|
||||
true
|
||||
|
||||
{.pop.}
|
||||
|
|
|
@ -9,35 +9,130 @@
|
|||
|
||||
import
|
||||
unittest2,
|
||||
../json_serialization
|
||||
../json_serialization,
|
||||
../json_serialization/value_ops
|
||||
|
||||
func jsonBool(x: bool): JsonValueRef[uint64] =
|
||||
JsonValueRef[uint64](kind: JsonValueKind.Bool, boolVal: x)
|
||||
|
||||
func jsonNull(): JsonValueRef[uint64] =
|
||||
JsonValueRef[uint64](kind: JsonValueKind.Null)
|
||||
|
||||
suite "Test JsonValueRef":
|
||||
let objA = JsonValueRef[uint64](
|
||||
kind: JsonValueKind.Object,
|
||||
objVal: [
|
||||
("a", jsonBool(true)),
|
||||
].toOrderedTable
|
||||
)
|
||||
|
||||
let objA2 = JsonValueRef[uint64](
|
||||
kind: JsonValueKind.Object,
|
||||
objVal: [
|
||||
("a", jsonBool(true)),
|
||||
].toOrderedTable
|
||||
)
|
||||
|
||||
let objABNull = JsonValueRef[uint64](
|
||||
kind: JsonValueKind.Object,
|
||||
objVal: [
|
||||
("a", jsonBool(true)),
|
||||
("b", jsonNull())
|
||||
].toOrderedTable
|
||||
)
|
||||
|
||||
let objAB = JsonValueRef[uint64](
|
||||
kind: JsonValueKind.Object,
|
||||
objVal: [
|
||||
("a", jsonBool(true)),
|
||||
("b", jsonBool(true))
|
||||
].toOrderedTable
|
||||
)
|
||||
|
||||
let objInArrayA = JsonValueRef[uint64](
|
||||
kind: JsonValueKind.Array,
|
||||
arrayVal: @[
|
||||
objA
|
||||
]
|
||||
)
|
||||
|
||||
let objInArrayA2 = JsonValueRef[uint64](
|
||||
kind: JsonValueKind.Array,
|
||||
arrayVal: @[
|
||||
objA2
|
||||
]
|
||||
)
|
||||
|
||||
let objInArrayAB = JsonValueRef[uint64](
|
||||
kind: JsonValueKind.Array,
|
||||
arrayVal: @[
|
||||
objAB
|
||||
]
|
||||
)
|
||||
|
||||
let objInArrayABNull = JsonValueRef[uint64](
|
||||
kind: JsonValueKind.Array,
|
||||
arrayVal: @[
|
||||
objABNull
|
||||
]
|
||||
)
|
||||
|
||||
let objInObjA = JsonValueRef[uint64](
|
||||
kind: JsonValueKind.Object,
|
||||
objVal: [
|
||||
("x", objA)
|
||||
].toOrderedTable
|
||||
)
|
||||
|
||||
let objInObjA2 = JsonValueRef[uint64](
|
||||
kind: JsonValueKind.Object,
|
||||
objVal: [
|
||||
("x", objA2)
|
||||
].toOrderedTable
|
||||
)
|
||||
|
||||
let objInObjAB = JsonValueRef[uint64](
|
||||
kind: JsonValueKind.Object,
|
||||
objVal: [
|
||||
("x", objAB)
|
||||
].toOrderedTable
|
||||
)
|
||||
|
||||
let objInObjABNull = JsonValueRef[uint64](
|
||||
kind: JsonValueKind.Object,
|
||||
objVal: [
|
||||
("x", objABNull)
|
||||
].toOrderedTable
|
||||
)
|
||||
|
||||
test "Test table keys equality":
|
||||
let a = JsonValueRef[uint64](
|
||||
kind: JsonValueKind.Object,
|
||||
objVal: [
|
||||
("a", jsonBool(true)),
|
||||
].toOrderedTable
|
||||
)
|
||||
check objA != objAB
|
||||
check objA == objA2
|
||||
check objA != objABNull
|
||||
check objAB != objABNull
|
||||
|
||||
let a2 = JsonValueRef[uint64](
|
||||
kind: JsonValueKind.Object,
|
||||
objVal: [
|
||||
("a", jsonBool(true)),
|
||||
].toOrderedTable
|
||||
)
|
||||
check objInArrayA != objInArrayAB
|
||||
check objInArrayA != objInArrayABNull
|
||||
check objInArrayA == objInArrayA2
|
||||
check objInArrayAB != objInArrayABNull
|
||||
|
||||
let b = JsonValueRef[uint64](
|
||||
kind: JsonValueKind.Object,
|
||||
objVal: [
|
||||
("a", jsonBool(true)),
|
||||
("b", jsonBool(true))
|
||||
].toOrderedTable
|
||||
)
|
||||
check objInObjA != objInObjAB
|
||||
check objInObjA != objInObjABNull
|
||||
check objInObjA == objInObjA2
|
||||
check objInObjAB != objInObjABNull
|
||||
|
||||
check a != b
|
||||
check a == a2
|
||||
test "Test compare":
|
||||
check compare(objA, objAB) == false
|
||||
check compare(objA, objA2) == true
|
||||
check compare(objA, objABNull) == true
|
||||
check compare(objAB, objABNull) == false
|
||||
|
||||
check compare(objInArrayA, objInArrayAB) == false
|
||||
check compare(objInArrayA, objInArrayABNull) == true
|
||||
check compare(objInArrayA, objInArrayA2) == true
|
||||
check compare(objInArrayAB, objInArrayABNull) == false
|
||||
|
||||
check compare(objInObjA, objInObjAB) == false
|
||||
check compare(objInObjA, objInObjABNull) == true
|
||||
check compare(objInObjA, objInObjA2) == true
|
||||
check compare(objInObjAB, objInObjABNull) == false
|
||||
|
|
Loading…
Reference in New Issue