mirror of https://github.com/status-im/nim-eth.git
add test cases and fix counting function
This commit is contained in:
parent
6a73a9d8b0
commit
ec253456f9
|
@ -156,7 +156,7 @@ proc appendImpl[T](self: var RlpWriter, listOrBlob: openArray[T]) =
|
|||
for i in 0 ..< listOrBlob.len:
|
||||
self.append listOrBlob[i]
|
||||
|
||||
proc countOptionalFields(T: type): int =
|
||||
proc countOptionalFields(T: type): int {.compileTime.} =
|
||||
mixin enumerateRlpFields
|
||||
|
||||
var dummy: T
|
||||
|
@ -165,6 +165,8 @@ proc countOptionalFields(T: type): int =
|
|||
template op(RT, fN, f) =
|
||||
when f is Option or f is Opt:
|
||||
inc result
|
||||
else: # this will count only optional fields at the end
|
||||
result = 0
|
||||
|
||||
enumerateRlpFields(dummy, op)
|
||||
|
||||
|
@ -205,14 +207,18 @@ macro genOptionalFieldsValidation(obj: untyped, T: type, num: static[int]): unty
|
|||
proc countFieldsRuntime(obj: object|tuple): int =
|
||||
mixin enumerateRlpFields
|
||||
|
||||
var numOptionals: int = 0
|
||||
|
||||
template op(RT, fN, f) {.used.} =
|
||||
when f is Option or f is Opt:
|
||||
if f.isSome: # if optional and non empty
|
||||
inc result
|
||||
inc numOptionals
|
||||
else: # if mandatory field
|
||||
inc result
|
||||
numOptionals = 0 # count only optionals at the end (after mandatory)
|
||||
|
||||
enumerateRlpFields(obj, op)
|
||||
result += numOptionals
|
||||
|
||||
proc appendRecordType*(self: var RlpWriter, obj: object|tuple, wrapInList = wrapObjsInList) =
|
||||
mixin enumerateRlpFields, append
|
||||
|
|
|
@ -2,4 +2,5 @@ import
|
|||
./test_api_usage,
|
||||
./test_json_suite,
|
||||
./test_empty_string,
|
||||
./test_object_serialization
|
||||
./test_object_serialization,
|
||||
./test_optional_fields
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
{.used.}
|
||||
|
||||
import
|
||||
../../eth/[rlp, common],
|
||||
unittest2
|
||||
|
||||
# Optionals in between mandatory fields for the convenience of
|
||||
# implementation. According to the spec all optionals appear
|
||||
# after mandatory fields. Moreover, an empty optional field
|
||||
# cannot and will not appear before a non-empty optional field
|
||||
|
||||
type ObjectWithOptionals = object
|
||||
a* : uint64
|
||||
b* : uint64
|
||||
c* : Opt[uint64] # should not count this as optional
|
||||
d* : Opt[uint64] # should not count this as optional
|
||||
e* : uint64
|
||||
f* : uint64
|
||||
g* : uint64
|
||||
h* : Opt[uint64] # should not count this as optional
|
||||
i* : Opt[uint64] # should not count this as optional
|
||||
j* : Opt[uint64] # should not count this as optional
|
||||
k* : uint64
|
||||
l* : Opt[uint64] # should count this as an optional
|
||||
m* : Opt[uint64] # should count this as an optional
|
||||
n* : Opt[uint64] # should count this as an optional
|
||||
|
||||
var
|
||||
objWithEmptyOptional: ObjectWithOptionals
|
||||
objWithNonEmptyOptional: ObjectWithOptionals
|
||||
objWithNonEmptyTrailingOptionals: ObjectWithOptionals
|
||||
objWithEmptyTrailingOptionals: ObjectWithOptionals
|
||||
|
||||
objWithNonEmptyOptional.c = Opt.some(0'u64)
|
||||
objWithNonEmptyOptional.d = Opt.some(0'u64)
|
||||
objWithNonEmptyOptional.h = Opt.some(0'u64)
|
||||
objWithNonEmptyOptional.i = Opt.some(0'u64)
|
||||
objWithNonEmptyOptional.j = Opt.some(0'u64)
|
||||
objWithNonEmptyOptional.l = Opt.some(0'u64)
|
||||
objWithNonEmptyOptional.m = Opt.some(0'u64)
|
||||
objWithNonEmptyOptional.n = Opt.some(0'u64)
|
||||
|
||||
objWithNonEmptyTrailingOptionals.l = Opt.some(0'u64)
|
||||
objWithNonEmptyTrailingOptionals.m = Opt.some(0'u64)
|
||||
objWithNonEmptyTrailingOptionals.n = Opt.some(0'u64)
|
||||
|
||||
objWithEmptyTrailingOptionals.c = Opt.some(0'u64)
|
||||
objWithEmptyTrailingOptionals.d = Opt.some(0'u64)
|
||||
objWithEmptyTrailingOptionals.h = Opt.some(0'u64)
|
||||
objWithEmptyTrailingOptionals.i = Opt.some(0'u64)
|
||||
objWithEmptyTrailingOptionals.j = Opt.some(0'u64)
|
||||
|
||||
suite "test optional fields":
|
||||
test "all optionals are empty":
|
||||
let bytes = rlp.encode(objWithEmptyOptional)
|
||||
|
||||
test "all optionals are non empty":
|
||||
let bytes = rlp.encode(objWithNonEmptyOptional)
|
||||
|
||||
test "Only trailing optionals are non empty":
|
||||
let bytes = rlp.encode(objWithNonEmptyTrailingOptionals)
|
||||
|
||||
test "Only trailing optionals are empty":
|
||||
let bytes = rlp.encode(objWithEmptyTrailingOptionals)
|
||||
|
Loading…
Reference in New Issue