add test cases and fix counting function

This commit is contained in:
chirag-parmar 2024-10-25 14:36:32 +05:30
parent 6a73a9d8b0
commit ec253456f9
3 changed files with 75 additions and 3 deletions

View File

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

View File

@ -2,4 +2,5 @@ import
./test_api_usage,
./test_json_suite,
./test_empty_string,
./test_object_serialization
./test_object_serialization,
./test_optional_fields

View File

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