- added tests "test_tstruct_default_field" and "test_tstruct_const_field"

- added setattrs
This commit is contained in:
Tim Rid 2021-01-01 17:26:40 +01:00
parent 4aa3013a82
commit 944cf85797
5 changed files with 80 additions and 17 deletions

View file

@ -1,3 +1,11 @@
from .generic_wrapper import (
Construct,
Adapter,
ListContainer,
Context,
ConstantOrContextLambda,
PathType,
)
from .tarray import TArray
from .tenum import TEnum
from .tstruct import TStruct, TBitStruct, TStructField
@ -10,5 +18,11 @@ __all__ = [
"TEnum",
"TUnionField",
"TUnion",
"TArray"
"TArray",
"Construct",
"Adapter",
"ListContainer",
"Context",
"ConstantOrContextLambda",
"PathType",
]

View file

@ -21,16 +21,9 @@ def TStructField(
subcon = cs.Renamed(subcon, newdocs=doc, newparsed=parsed)
if subcon.flagbuildnone is True:
# some subcons have a predefined default value. all other have "None"
default: t.Any = None
if isinstance(subcon, (cs.Const, cs.Default)):
if callable(subcon.value): # type: ignore
raise ValueError("lamda as default is not supported")
default = subcon.value # type: ignore
# if subcon builds from "None", set default to "None"
field = dataclasses.field(
default=default,
default=None,
init=False,
metadata={"subcon": cs.Renamed(subcon, newdocs=doc)},
)

View file

@ -1,4 +1,5 @@
import pytest
xfail = pytest.mark.xfail
skip = pytest.mark.skip
skipif = pytest.mark.skipif
@ -8,16 +9,18 @@ import os, math, random, collections, itertools, io, hashlib, binascii
from construct import *
from construct.lib import *
class ZeroIO(io.BufferedIOBase):
def read(self, __size = None):
def read(self, __size=None):
if __size is not None:
return bytes(__size)
else:
return bytes(0)
def read1(self, __size = 0):
def read1(self, __size=0):
return bytes(__size)
ident = lambda x: x
devzero = ZeroIO()
@ -46,20 +49,26 @@ def common(format, datasample, objsample, sizesample=SizeofError, **kw):
assert size == sizesample
def setattrs(obj, **kwargs):
for name, value in kwargs.items():
setattr(obj, name, value)
return obj
def commonhex(format, hexdata):
commonbytes(format, binascii.unhexlify(hexdata))
def commondumpdeprecated(format, filename):
filename = "tests/deprecated_gallery/blobs/" + filename
with open(filename,'rb') as f:
with open(filename, "rb") as f:
data = f.read()
commonbytes(format, data)
def commondump(format, filename):
filename = "tests/gallery/blobs/" + filename
with open(filename,'rb') as f:
with open(filename, "rb") as f:
data = f.read()
commonbytes(format, data)

View file

@ -6,6 +6,7 @@ import construct_typed as cst
Buffer = t.Union[bytes, memoryview, bytearray]
ParsedType = t.TypeVar("ParsedType")
BuildTypes = t.TypeVar("BuildTypes")
T = t.TypeVar("T")
IdentType = t.TypeVar("IdentType")
@ -32,6 +33,7 @@ def common(
sizesample: t.Union[int, t.Type[Exception]] = ...,
**kw: t.Any
) -> None: ...
def setattrs(obj: T, **kwargs: t.Any) -> T: ...
def commonhex(format: Construct[ParsedType, BuildTypes], hexdata: str) -> None: ...
def commondumpdeprecated(
format: Construct[ParsedType, BuildTypes], filename: str

View file

@ -3,11 +3,12 @@
import enum
import dataclasses
import typing as t
from .declarativeunittest import common, raises
from .declarativeunittest import common, raises, setattrs
import construct as cs
import construct_typed as cst
def test_tstruct_1() -> None:
def test_tstruct() -> None:
@dataclasses.dataclass
class TestDataclass:
a: int = cst.TStructField(cs.Int16ub)
@ -50,6 +51,47 @@ def test_tstruct_nested() -> None:
)
def test_tstruct_default_field() -> None:
@dataclasses.dataclass
class Image:
width: int = cst.TStructField(cs.Int8ub)
height: int = cst.TStructField(cs.Int8ub)
pixels: t.Optional[bytes] = cst.TStructField(
cs.Default(
cs.Bytes(cs.this.width * cs.this.height),
lambda ctx: bytes(ctx.width * ctx.height),
)
)
common(
cst.TStruct(Image),
b"\x02\x03\x00\x00\x00\x00\x00\x00",
setattrs(Image(2, 3), pixels=bytes(6)),
sample_building=Image(2, 3),
)
def test_tstruct_const_field() -> None:
@dataclasses.dataclass
class TestDataclass:
const_field: t.Optional[bytes] = cst.TStructField(cs.Const(b"\x00"))
common(
cst.TStruct(TestDataclass),
bytes(1),
setattrs(TestDataclass(), const_field=b"\x00"),
1,
)
assert (
raises(
cst.TStruct(TestDataclass).build,
setattrs(TestDataclass(), const_field=b"\x01"),
)
== cs.ConstError
)
def test_tstruct_anonymus_fields_1() -> None:
@dataclasses.dataclass
class TestDataclass:
@ -61,7 +103,7 @@ def test_tstruct_anonymus_fields_1() -> None:
common(
cst.TStruct(TestDataclass),
bytes(2),
TestDataclass(),
setattrs(TestDataclass(), _1=b"\x00"),
cs.SizeofError,
)
@ -97,7 +139,10 @@ def test_tstruct_wrong_dataclass() -> None:
a: int = cst.TStructField(cs.Int16ub)
b: int = cst.TStructField(cs.Int8ub)
assert raises(cst.TStruct(TestDataclass1).build, TestDataclass2(a=1, b=2)) == TypeError
assert (
raises(cst.TStruct(TestDataclass1).build, TestDataclass2(a=1, b=2)) == TypeError
)
def test_tbitstruct() -> None:
assert False