Merge pull request #5 from kentonv/develop

Various improvements to test code.
This commit is contained in:
Jason Paryani
2013-08-31 18:55:27 -07:00
8 changed files with 569 additions and 30 deletions

View File

@@ -9,7 +9,7 @@
cimport cython cimport cython
cimport capnp_cpp as capnp cimport capnp_cpp as capnp
cimport schema_cpp cimport schema_cpp
from capnp_cpp cimport Schema as C_Schema, StructSchema as C_StructSchema, DynamicStruct as C_DynamicStruct, DynamicValue as C_DynamicValue, Type as C_Type, DynamicList as C_DynamicList, fixMaybe, SchemaParser as C_SchemaParser, ParsedSchema as C_ParsedSchema, VOID, ArrayPtr, StringPtr, DynamicOrphan as C_DynamicOrphan from capnp_cpp cimport Schema as C_Schema, StructSchema as C_StructSchema, DynamicStruct as C_DynamicStruct, DynamicValue as C_DynamicValue, Type as C_Type, DynamicList as C_DynamicList, fixMaybe, SchemaParser as C_SchemaParser, ParsedSchema as C_ParsedSchema, VOID, ArrayPtr, StringPtr, String, StringTree, DynamicOrphan as C_DynamicOrphan
from schema_cpp cimport Node as C_Node, EnumNode as C_EnumNode from schema_cpp cimport Node as C_Node, EnumNode as C_EnumNode
from cython.operator cimport dereference as deref from cython.operator cimport dereference as deref
@@ -30,14 +30,11 @@ ctypedef bint Bool
ctypedef float Float32 ctypedef float Float32
ctypedef double Float64 ctypedef double Float64
from libc.stdlib cimport malloc, free from libc.stdlib cimport malloc, free
from libcpp cimport bool as cbool
ctypedef fused valid_values: ctypedef fused _DynamicStructReaderOrBuilder:
int _DynamicStructReader
long _DynamicStructBuilder
float
double
bint
cython.p_char
def _make_enum(enum_name, *sequential, **named): def _make_enum(enum_name, *sequential, **named):
enums = dict(zip(sequential, range(len(sequential))), **named) enums = dict(zip(sequential, range(len(sequential))), **named)
@@ -73,6 +70,18 @@ cdef extern from "capnp/list.h" namespace " ::capnp":
cdef extern from "<utility>" namespace "std": cdef extern from "<utility>" namespace "std":
C_DynamicOrphan moveOrphan"std::move"(C_DynamicOrphan) C_DynamicOrphan moveOrphan"std::move"(C_DynamicOrphan)
cdef extern from "<capnp/pretty-print.h>" namespace " ::capnp":
StringTree printStructReader" ::capnp::prettyPrint"(C_DynamicStruct.Reader)
StringTree printStructBuilder" ::capnp::prettyPrint"(C_DynamicStruct.Builder)
StringTree printListReader" ::capnp::prettyPrint"(C_DynamicList.Reader)
StringTree printListBuilder" ::capnp::prettyPrint"(C_DynamicList.Builder)
cdef extern from "<kj/string.h>" namespace " ::kj":
String strStructReader" ::kj::str"(C_DynamicStruct.Reader)
String strStructBuilder" ::kj::str"(C_DynamicStruct.Builder)
String strListReader" ::kj::str"(C_DynamicList.Reader)
String strListBuilder" ::kj::str"(C_DynamicList.Builder)
cdef class _NodeReader: cdef class _NodeReader:
cdef C_Node.Reader thisptr cdef C_Node.Reader thisptr
cdef init(self, C_Node.Reader other): cdef init(self, C_Node.Reader other):
@@ -144,6 +153,13 @@ cdef class _DynamicListReader:
def __len__(self): def __len__(self):
return self.thisptr.size() return self.thisptr.size()
def __str__(self):
return printListReader(self.thisptr).flatten().cStr()
def __repr__(self):
# TODO: Print the list type.
return '<capnp list reader %s>' % strListReader(self.thisptr).cStr()
cdef class _DynamicResizableListBuilder: cdef class _DynamicResizableListBuilder:
"""Class for building growable Cap'n Proto Lists """Class for building growable Cap'n Proto Lists
@@ -225,18 +241,15 @@ cdef class _DynamicListBuilder:
for phone in phones: for phone in phones:
print phone.number print phone.number
""" """
cdef C_DynamicList.Builder * thisptr cdef C_DynamicList.Builder thisptr
cdef public object _parent cdef public object _parent
cdef _init(self, C_DynamicList.Builder other, object parent): cdef _init(self, C_DynamicList.Builder other, object parent):
self.thisptr = new C_DynamicList.Builder(other) self.thisptr = other
self._parent = parent self._parent = parent
return self return self
def __dealloc__(self):
del self.thisptr
cdef _get(self, index) except +ValueError: cdef _get(self, index) except +ValueError:
return toPython(deref(self.thisptr)[index], self._parent) return toPython(self.thisptr[index], self._parent)
def __getitem__(self, index): def __getitem__(self, index):
size = self.thisptr.size() size = self.thisptr.size()
@@ -245,31 +258,76 @@ cdef class _DynamicListBuilder:
index = index % size index = index % size
return self._get(index) return self._get(index)
def _setitem(self, index, valid_values value): cdef _setitemInt(self, index, value):
cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(value) cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(<long long>value)
self.thisptr.set(index, temp) self.thisptr.set(index, temp)
cdef _setattrDynamicStructBuilder(self, index, _DynamicStructBuilder value): cdef _setitemLong(self, index, value):
cdef C_DynamicValue.Reader temp
if value < 0:
temp = C_DynamicValue.Reader(<long long>value)
else:
temp = C_DynamicValue.Reader(<unsigned long long>value)
self.thisptr.set(index, temp)
cdef _setitemDouble(self, index, value):
cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(<double>value)
self.thisptr.set(index, temp)
cdef _setitemBool(self, index, value):
cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(<cbool>value)
self.thisptr.set(index, temp)
cdef _setitemString(self, index, value):
cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(<char*>value)
self.thisptr.set(index, temp)
cdef _setitemVoid(self, index):
cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(VOID)
self.thisptr.set(index, temp)
cdef _setitemList(self, index, value):
builder = toPython(self.thisptr.init(index, len(value)), self._parent)
for (i, v) in enumerate(value):
builder[i] = v
cdef _setitemDynamicStructBuilder(self, index, _DynamicStructBuilder value):
cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(value.thisptr.asReader()) cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(value.thisptr.asReader())
self.thisptr.set(index, temp) self.thisptr.set(index, temp)
cdef _setattrDynamicStructReader(self, index, _DynamicStructReader value): cdef _setitemDynamicStructReader(self, index, _DynamicStructReader value):
cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(value.thisptr) cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(value.thisptr)
self.thisptr.set(index, temp) self.thisptr.set(index, temp)
def __setitem__(self, index, value): def __setitem__(self, index, value):
# TODO: share code with _DynamicStructBuilder.__setattr__
size = self.thisptr.size() size = self.thisptr.size()
if index >= size: if index >= size:
raise IndexError('Out of bounds') raise IndexError('Out of bounds')
index = index % size index = index % size
value_type = type(value) value_type = type(value)
if value_type is _DynamicStructBuilder: if value_type is int:
self._setitemInt(index, value)
elif value_type is long:
self._setitemLong(index, value)
elif value_type is float:
self._setitemDouble(index, value)
elif value_type is bool:
self._setitemBool(index, value)
elif value_type is str:
self._setitemString(index, value)
elif value_type is list:
self._setitemList(index, value)
elif value is None:
self._setitemVoid(index)
elif value_type is _DynamicStructBuilder:
self._setattrDynamicStructBuilder(index, value) self._setattrDynamicStructBuilder(index, value)
elif value_type is _DynamicStructReader: elif value_type is _DynamicStructReader:
self._setattrDynamicStructReader(index, value) self._setattrDynamicStructReader(index, value)
else: else:
self._setitem(index, value) raise ValueError("Non primitive type")
def __len__(self): def __len__(self):
return self.thisptr.size() return self.thisptr.size()
@@ -315,6 +373,13 @@ cdef class _DynamicListBuilder:
""" """
return _DynamicOrphan()._init(self.thisptr.disown(index), self._parent) return _DynamicOrphan()._init(self.thisptr.disown(index), self._parent)
def __str__(self):
return printListBuilder(self.thisptr).flatten().cStr()
def __repr__(self):
# TODO: Print the list type.
return '<capnp list builder %s>' % strListBuilder(self.thisptr).cStr()
cdef class _List_NestedNode_Reader: cdef class _List_NestedNode_Reader:
cdef List[C_Node.NestedNode].Reader thisptr cdef List[C_Node.NestedNode].Reader thisptr
cdef _init(self, List[C_Node.NestedNode].Reader other): cdef _init(self, List[C_Node.NestedNode].Reader other):
@@ -347,7 +412,6 @@ cdef toPythonReader(C_DynamicValue.Reader self, object parent):
temp = self.asData() temp = self.asData()
return (<char*>temp.begin())[:temp.size()] return (<char*>temp.begin())[:temp.size()]
elif type == capnp.TYPE_LIST: elif type == capnp.TYPE_LIST:
print 'list'
return list(_DynamicListReader()._init(self.asList(), parent)) return list(_DynamicListReader()._init(self.asList(), parent))
elif type == capnp.TYPE_STRUCT: elif type == capnp.TYPE_STRUCT:
return _DynamicStructReader()._init(self.asStruct(), parent) return _DynamicStructReader()._init(self.asStruct(), parent)
@@ -440,6 +504,12 @@ cdef class _DynamicStructReader:
def __dir__(self): def __dir__(self):
return list(self.schema.fieldnames) return list(self.schema.fieldnames)
def __str__(self):
return printStructReader(self.thisptr).flatten().cStr()
def __repr__(self):
return '<%s reader %s>' % (self.schema.node.displayName, strStructReader(self.thisptr).cStr())
cdef class _DynamicStructBuilder: cdef class _DynamicStructBuilder:
"""Builds Cap'n Proto structs """Builds Cap'n Proto structs
@@ -453,15 +523,48 @@ cdef class _DynamicStructBuilder:
setattr(person, 'field-with-hyphens', 'foo') # for names that are invalid for python, use setattr setattr(person, 'field-with-hyphens', 'foo') # for names that are invalid for python, use setattr
print getattr(person, 'field-with-hyphens') # for names that are invalid for python, use getattr print getattr(person, 'field-with-hyphens') # for names that are invalid for python, use getattr
""" """
cdef C_DynamicStruct.Builder * thisptr cdef C_DynamicStruct.Builder thisptr
cdef public object _parent cdef public object _parent
cdef _init(self, C_DynamicStruct.Builder other, object parent): cdef bint _isRoot
self.thisptr = new C_DynamicStruct.Builder(other) cdef _init(self, C_DynamicStruct.Builder other, object parent, bint isRoot = False):
self.thisptr = other
self._parent = parent self._parent = parent
self._isRoot = isRoot
return self return self
def __dealloc__(self): def writeTo(self, file):
del self.thisptr """Writes the struct's containing message to the given file object in unpacked binary format.
This is a shortcut for calling capnp.writeMessageToFd(). This can only be called on the
message's root struct.
:type file: file
:param file: A file or socket object (or anything with a fileno() method), open for write.
:rtype: void
:Raises: :exc:`exceptions.ValueError` if this isn't the message's root struct.
"""
if not self._isRoot:
raise ValueError("You can only call writeTo() on the message's root struct.")
writeMessageToFd(file.fileno(), self._parent)
def writePackedTo(self, file):
"""Writes the struct's containing message to the given file object in packed binary format.
This is a shortcut for calling capnp.writePackedMessageToFd(). This can only be called on
the message's root struct.
:type file: file
:param file: A file or socket object (or anything with a fileno() method), open for write.
:rtype: void
:Raises: :exc:`exceptions.ValueError` if this isn't the message's root struct.
"""
if not self._isRoot:
raise ValueError("You can only call writeTo() on the message's root struct.")
writePackedMessageToFd(file.fileno(), self._parent)
cdef _get(self, field) except +ValueError: cdef _get(self, field) except +ValueError:
return toPython(self.thisptr.get(field), self._parent) return toPython(self.thisptr.get(field), self._parent)
@@ -473,12 +576,20 @@ cdef class _DynamicStructBuilder:
cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(<long long>value) cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(<long long>value)
self.thisptr.set(field, temp) self.thisptr.set(field, temp)
cdef _setattrLong(self, field, value):
cdef C_DynamicValue.Reader temp
if value < 0:
temp = C_DynamicValue.Reader(<long long>value)
else:
temp = C_DynamicValue.Reader(<unsigned long long>value)
self.thisptr.set(field, temp)
cdef _setattrDouble(self, field, value): cdef _setattrDouble(self, field, value):
cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(<double>value) cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(<double>value)
self.thisptr.set(field, temp) self.thisptr.set(field, temp)
cdef _setattrBool(self, field, value): cdef _setattrBool(self, field, value):
cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(<bint>value) cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(<cbool>value)
self.thisptr.set(field, temp) self.thisptr.set(field, temp)
cdef _setattrString(self, field, value): cdef _setattrString(self, field, value):
@@ -489,6 +600,11 @@ cdef class _DynamicStructBuilder:
cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(VOID) cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(VOID)
self.thisptr.set(field, temp) self.thisptr.set(field, temp)
cdef _setattrList(self, field, value):
builder = toPython(self.thisptr.init(field, len(value)), self._parent)
for (i, v) in enumerate(value):
builder[i] = v
cdef _setattrDynamicStructBuilder(self, field, _DynamicStructBuilder value): cdef _setattrDynamicStructBuilder(self, field, _DynamicStructBuilder value):
cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(value.thisptr.asReader()) cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(value.thisptr.asReader())
self.thisptr.set(field, temp) self.thisptr.set(field, temp)
@@ -498,16 +614,21 @@ cdef class _DynamicStructBuilder:
self.thisptr.set(field, temp) self.thisptr.set(field, temp)
def __setattr__(self, field, value): def __setattr__(self, field, value):
# TODO: share code with _DynamicListBuilder.__setitem__
value_type = type(value) value_type = type(value)
if value_type is int: if value_type is int:
self._setattrInt(field, value) self._setattrInt(field, value)
elif value_type is long:
self._setattrLong(field, value)
elif value_type is float: elif value_type is float:
self._setattrDouble(field, value) self._setattrDouble(field, value)
elif value_type is bool: elif value_type is bool:
self._setattrBool(field, value) self._setattrBool(field, value)
elif value_type is str: elif value_type is str:
self._setattrString(field, value) self._setattrString(field, value)
elif value_type is list:
self._setattrList(field, value)
elif value is None: elif value is None:
self._setattrVoid(field) self._setattrVoid(field)
elif value_type is _DynamicStructBuilder: elif value_type is _DynamicStructBuilder:
@@ -639,6 +760,12 @@ cdef class _DynamicStructBuilder:
def __dir__(self): def __dir__(self):
return list(self.schema.fieldnames) return list(self.schema.fieldnames)
def __str__(self):
return printStructBuilder(self.thisptr).flatten().cStr()
def __repr__(self):
return '<%s builder %s>' % (self.schema.node.displayName, strStructBuilder(self.thisptr).cStr())
cdef class _DynamicOrphan: cdef class _DynamicOrphan:
cdef C_DynamicOrphan thisptr cdef C_DynamicOrphan thisptr
cdef public object _parent cdef public object _parent
@@ -657,6 +784,12 @@ cdef class _DynamicOrphan:
""" """
return toPython(self.thisptr.get(), self._parent) return toPython(self.thisptr.get(), self._parent)
def __str__(self):
return str(self.get())
def __repr__(self):
return repr(self.get())
cdef class _Schema: cdef class _Schema:
cdef C_Schema thisptr cdef C_Schema thisptr
cdef _init(self, C_Schema other): cdef _init(self, C_Schema other):
@@ -699,6 +832,9 @@ cdef class _StructSchema:
def __get__(self): def __get__(self):
return _DynamicStructReader()._init(self.thisptr.getProto(), None) return _DynamicStructReader()._init(self.thisptr.getProto(), None)
def __repr__(self):
return '<schema for %s>' % self.node.displayName
cdef class _ParsedSchema: cdef class _ParsedSchema:
cdef C_ParsedSchema thisptr cdef C_ParsedSchema thisptr
cdef _init(self, C_ParsedSchema other): cdef _init(self, C_ParsedSchema other):
@@ -792,6 +928,18 @@ cdef class SchemaParser:
proto = schema.getProto() proto = schema.getProto()
if proto.isStruct: if proto.isStruct:
local_module.schema = schema.asStruct() local_module.schema = schema.asStruct()
def readFrom(file):
reader = StreamFdMessageReader(file.fileno())
return reader.getRoot(local_module)
def readPackedFrom(file):
reader = PackedFdMessageReader(file.fileno())
return reader.getRoot(local_module)
def newMessage():
builder = MallocMessageBuilder()
return builder.initRoot(local_module)
local_module.readFrom = readFrom
local_module.readPackedFrom = readPackedFrom
local_module.newMessage = newMessage
elif proto.isConst: elif proto.isConst:
module.__dict__[node.name] = schema.asConstValue() module.__dict__[node.name] = schema.asConstValue()
@@ -843,7 +991,7 @@ cdef class MessageBuilder:
s = schema.schema s = schema.schema
else: else:
s = schema s = schema
return _DynamicStructBuilder()._init(self.thisptr.initRootDynamicStruct(s.thisptr), self) return _DynamicStructBuilder()._init(self.thisptr.initRootDynamicStruct(s.thisptr), self, True)
cpdef getRoot(self, schema): cpdef getRoot(self, schema):
"""A method for instantiating Cap'n Proto structs, from an already pre-written buffer """A method for instantiating Cap'n Proto structs, from an already pre-written buffer
@@ -868,7 +1016,20 @@ cdef class MessageBuilder:
s = schema.schema s = schema.schema
else: else:
s = schema s = schema
return _DynamicStructBuilder()._init(self.thisptr.getRootDynamicStruct(s.thisptr), self) return _DynamicStructBuilder()._init(self.thisptr.getRootDynamicStruct(s.thisptr), self, True)
cpdef setRoot(self, value):
"""A method for instantiating Cap'n Proto structs by copying from an existing struct
:type value: :class:`_DynamicStructReader`
:param value: A Cap'n Proto struct value to copy
:rtype: void
"""
if type(value) is _DynamicStructBuilder:
value = value.asReader();
self.thisptr.setRootDynamicStruct((<_DynamicStructReader>value).thisptr)
cpdef newOrphan(self, schema): cpdef newOrphan(self, schema):
"""A method for instantiating Cap'n Proto orphans """A method for instantiating Cap'n Proto orphans

View File

@@ -6,6 +6,7 @@ from schema_cpp cimport Node, Data, StructNode, EnumNode
from libc.stdint cimport * from libc.stdint cimport *
ctypedef unsigned int uint ctypedef unsigned int uint
from libcpp cimport bool as cbool
cdef extern from "capnp/common.h" namespace " ::capnp": cdef extern from "capnp/common.h" namespace " ::capnp":
enum Void: enum Void:
@@ -14,6 +15,12 @@ cdef extern from "capnp/common.h" namespace " ::capnp":
cdef extern from "kj/string.h" namespace " ::kj": cdef extern from "kj/string.h" namespace " ::kj":
cdef cppclass StringPtr: cdef cppclass StringPtr:
StringPtr(char *) StringPtr(char *)
cdef cppclass String:
char* cStr()
cdef extern from "kj/string-tree.h" namespace " ::kj":
cdef cppclass StringTree:
String flatten()
cdef extern from "kj/common.h" namespace " ::kj": cdef extern from "kj/common.h" namespace " ::kj":
cdef cppclass Maybe[T]: cdef cppclass Maybe[T]:
@@ -92,6 +99,7 @@ cdef extern from "capnp/dynamic.h" namespace " ::capnp":
StructSchema getSchema() StructSchema getSchema()
Maybe[StructSchema.Field] which() Maybe[StructSchema.Field] which()
cppclass Builder: cppclass Builder:
Builder()
Builder(Builder &) Builder(Builder &)
DynamicValueForward.Builder get(char *) DynamicValueForward.Builder get(char *)
bint has(char *) except +ValueError bint has(char *) except +ValueError
@@ -118,6 +126,7 @@ cdef extern from "capnp/dynamic.h" namespace " ::capnp":
DynamicValueForward.Reader operator[](uint) except +ValueError DynamicValueForward.Reader operator[](uint) except +ValueError
uint size() uint size()
cppclass Builder: cppclass Builder:
Builder()
Builder(Builder &) Builder(Builder &)
DynamicValueForward.Builder operator[](uint) DynamicValueForward.Builder operator[](uint)
uint size() uint size()
@@ -131,7 +140,7 @@ cdef extern from "capnp/dynamic.h" namespace " ::capnp":
cppclass Reader: cppclass Reader:
Reader() Reader()
Reader(Void value) Reader(Void value)
Reader(bint value) Reader(cbool value)
Reader(char value) Reader(char value)
Reader(short value) Reader(short value)
Reader(int value) Reader(int value)
@@ -160,6 +169,7 @@ cdef extern from "capnp/dynamic.h" namespace " ::capnp":
Data.Reader asData"as< ::capnp::Data>"() Data.Reader asData"as< ::capnp::Data>"()
cppclass Builder: cppclass Builder:
Builder()
Type getType() Type getType()
int64_t asInt"as<int64_t>"() int64_t asInt"as<int64_t>"()
uint64_t asUint"as<uint64_t>"() uint64_t asUint"as<uint64_t>"()

View File

@@ -664,6 +664,7 @@ cdef extern from "capnp/message.h" namespace " ::capnp":
DynamicStruct.Builder getRootDynamicStruct'getRoot< ::capnp::DynamicStruct>'(StructSchema) DynamicStruct.Builder getRootDynamicStruct'getRoot< ::capnp::DynamicStruct>'(StructSchema)
DynamicStruct.Builder initRootDynamicStruct'initRoot< ::capnp::DynamicStruct>'(StructSchema) DynamicStruct.Builder initRootDynamicStruct'initRoot< ::capnp::DynamicStruct>'(StructSchema)
void setRootDynamicStruct'setRoot< ::capnp::DynamicStruct::Reader>'(DynamicStruct.Reader)
DynamicOrphan newOrphan'getOrphanage().newOrphan'(StructSchema) DynamicOrphan newOrphan'getOrphanage().newOrphan'(StructSchema)

BIN
test/all-types.binary Normal file

Binary file not shown.

52
test/all-types.capnp Normal file
View File

@@ -0,0 +1,52 @@
# This is copied from test.capnp in the Cap'n Proto C++ code.
@0xcaa67a26d16950d9;
enum TestEnum {
foo @0;
bar @1;
baz @2;
qux @3;
quux @4;
corge @5;
grault @6;
garply @7;
}
struct TestAllTypes {
voidField @0 : Void;
boolField @1 : Bool;
int8Field @2 : Int8;
int16Field @3 : Int16;
int32Field @4 : Int32;
int64Field @5 : Int64;
uInt8Field @6 : UInt8;
uInt16Field @7 : UInt16;
uInt32Field @8 : UInt32;
uInt64Field @9 : UInt64;
float32Field @10 : Float32;
float64Field @11 : Float64;
textField @12 : Text;
dataField @13 : Data;
structField @14 : TestAllTypes;
enumField @15 : TestEnum;
interfaceField @16 : Void; # TODO
voidList @17 : List(Void);
boolList @18 : List(Bool);
int8List @19 : List(Int8);
int16List @20 : List(Int16);
int32List @21 : List(Int32);
int64List @22 : List(Int64);
uInt8List @23 : List(UInt8);
uInt16List @24 : List(UInt16);
uInt32List @25 : List(UInt32);
uInt64List @26 : List(UInt64);
float32List @27 : List(Float32);
float64List @28 : List(Float64);
textList @29 : List(Text);
dataList @30 : List(Data);
structList @31 : List(TestAllTypes);
enumList @32 : List(TestEnum);
interfaceList @33 : List(Void); # TODO
}

BIN
test/all-types.packed Normal file

Binary file not shown.

71
test/all-types.txt Normal file
View File

@@ -0,0 +1,71 @@
( boolField = true,
int8Field = -123,
int16Field = -12345,
int32Field = -12345678,
int64Field = -123456789012345,
uInt8Field = 234,
uInt16Field = 45678,
uInt32Field = 3456789012,
uInt64Field = 12345678901234567890,
float32Field = 1234.5,
float64Field = -1.23e47,
textField = "foo",
dataField = "bar",
structField = (
boolField = true,
int8Field = -12,
int16Field = 3456,
int32Field = -78901234,
int64Field = 56789012345678,
uInt8Field = 90,
uInt16Field = 1234,
uInt32Field = 56789012,
uInt64Field = 345678901234567890,
float32Field = -1.25e-10,
float64Field = 345,
textField = "baz",
dataField = "qux",
structField = (
textField = "nested",
structField = (
textField = "really nested" ) ),
enumField = baz,
voidList = [void, void, void],
boolList = [false, true, false, true, true],
int8List = [12, -34, -128, 127],
int16List = [1234, -5678, -32768, 32767],
int32List = [12345678, -90123456, -2147483648, 2147483647],
int64List = [123456789012345, -678901234567890, -9223372036854775808, 9223372036854775807],
uInt8List = [12, 34, 0, 255],
uInt16List = [1234, 5678, 0, 65535],
uInt32List = [12345678, 90123456, 0, 4294967295],
uInt64List = [123456789012345, 678901234567890, 0, 18446744073709551615],
float32List = [0, 1234567, 1e37, -1e37, 1e-37, -1e-37],
float64List = [0, 123456789012345, 1e306, -1e306, 1e-306, -1e-306],
textList = ["quux", "corge", "grault"],
dataList = ["garply", "waldo", "fred"],
structList = [
( textField = "x structlist 1" ),
( textField = "x structlist 2" ),
( textField = "x structlist 3" ) ],
enumList = [qux, bar, grault] ),
enumField = corge,
voidList = [void, void, void, void, void, void],
boolList = [true, false, false, true],
int8List = [111, -111],
int16List = [11111, -11111],
int32List = [111111111, -111111111],
int64List = [1111111111111111111, -1111111111111111111],
uInt8List = [111, 222],
uInt16List = [33333, 44444],
uInt32List = [3333333333],
uInt64List = [11111111111111111111],
float32List = [5555.5, inf, -inf, nan],
float64List = [7777.75, inf, -inf, nan],
textList = ["plugh", "xyzzy", "thud"],
dataList = ["oops", "exhausted", "rfc3092"],
structList = [
( textField = "structlist 1" ),
( textField = "structlist 2" ),
( textField = "structlist 3" ) ],
enumList = [foo, garply] )

View File

@@ -1,6 +1,7 @@
import pytest import pytest
import capnp import capnp
import os import os
import math
this_dir = os.path.dirname(__file__) this_dir = os.path.dirname(__file__)
@@ -65,3 +66,246 @@ def test_addressbook(addressbook):
f = open('example', 'r') f = open('example', 'r')
printAddressBook(f.fileno()) printAddressBook(f.fileno())
@pytest.fixture
def all_types():
return capnp.load(os.path.join(this_dir, 'all-types.capnp'))
# TODO: These tests should be extended to:
# - Read each field in Python and assert that it is equal to the expected value.
# - Build an identical message using Python code and compare it to the golden.
#
def init_all_types(builder):
builder.voidField = None
builder.boolField = True
builder.int8Field = -123
builder.int16Field = -12345
builder.int32Field = -12345678
builder.int64Field = -123456789012345
builder.uInt8Field = 234
builder.uInt16Field = 45678
builder.uInt32Field = 3456789012
builder.uInt64Field = 12345678901234567890
builder.float32Field = 1234.5
builder.float64Field = -123e45
builder.textField = "foo"
builder.dataField = "bar"
subBuilder = builder.structField
subBuilder.voidField = None
subBuilder.boolField = True
subBuilder.int8Field = -12
subBuilder.int16Field = 3456
subBuilder.int32Field = -78901234
subBuilder.int64Field = 56789012345678
subBuilder.uInt8Field = 90
subBuilder.uInt16Field = 1234
subBuilder.uInt32Field = 56789012
subBuilder.uInt64Field = 345678901234567890
subBuilder.float32Field = -1.25e-10
subBuilder.float64Field = 345
subBuilder.textField = "baz"
subBuilder.dataField = "qux"
subSubBuilder = subBuilder.structField
subSubBuilder.textField = "nested"
subSubBuilder.structField.textField = "really nested"
subBuilder.enumField = "baz"
subBuilder.voidList = [None, None, None]
subBuilder.boolList = [False, True, False, True, True]
subBuilder.int8List = [12, -34, -0x80, 0x7f]
subBuilder.int16List = [1234, -5678, -0x8000, 0x7fff]
subBuilder.int32List = [12345678, -90123456, -0x80000000, 0x7fffffff]
subBuilder.int64List = [123456789012345, -678901234567890, -0x8000000000000000, 0x7fffffffffffffff]
subBuilder.uInt8List = [12, 34, 0, 0xff]
subBuilder.uInt16List = [1234, 5678, 0, 0xffff]
subBuilder.uInt32List = [12345678, 90123456, 0, 0xffffffff]
subBuilder.uInt64List = [123456789012345, 678901234567890, 0, 0xffffffffffffffff]
subBuilder.float32List = [0, 1234567, 1e37, -1e37, 1e-37, -1e-37]
subBuilder.float64List = [0, 123456789012345, 1e306, -1e306, 1e-306, -1e-306]
subBuilder.textList = ["quux", "corge", "grault"]
subBuilder.dataList = ["garply", "waldo", "fred"]
listBuilder = subBuilder.init('structList', 3)
listBuilder[0].textField = "x structlist 1"
listBuilder[1].textField = "x structlist 2"
listBuilder[2].textField = "x structlist 3"
subBuilder.enumList = ["qux", "bar", "grault"]
builder.enumField = "corge"
builder.init("voidList", 6)
builder.boolList = [True, False, False, True]
builder.int8List = [111, -111]
builder.int16List = [11111, -11111]
builder.int32List = [111111111, -111111111]
builder.int64List = [1111111111111111111, -1111111111111111111]
builder.uInt8List = [111, 222]
builder.uInt16List = [33333, 44444]
builder.uInt32List = [3333333333]
builder.uInt64List = [11111111111111111111]
builder.float32List = [5555.5, float("inf"), float("-inf"), float("nan")]
builder.float64List = [7777.75, float("inf"), float("-inf"), float("nan")]
builder.textList = ["plugh", "xyzzy", "thud"]
builder.dataList = ["oops", "exhausted", "rfc3092"]
listBuilder = builder.init('structList', 3)
listBuilder[0].textField = "structlist 1"
listBuilder[1].textField = "structlist 2"
listBuilder[2].textField = "structlist 3"
builder.enumList = ["foo", "garply"]
def assert_almost(float1, float2):
if float1 != float2:
assert abs((float1 - float2) / float1) < 0.00001
def check_list(reader, expected):
assert len(reader) == len(expected)
for (i, v) in enumerate(expected):
if type(v) is float:
assert_almost(reader[i], v)
else:
assert reader[i] == v
def check_all_types(reader):
assert reader.voidField == None
assert reader.boolField == True
assert reader.int8Field == -123
assert reader.int16Field == -12345
assert reader.int32Field == -12345678
assert reader.int64Field == -123456789012345
assert reader.uInt8Field == 234
assert reader.uInt16Field == 45678
assert reader.uInt32Field == 3456789012
assert reader.uInt64Field == 12345678901234567890
assert reader.float32Field == 1234.5
assert_almost(reader.float64Field, -123e45)
assert reader.textField == "foo"
assert reader.dataField == "bar"
subReader = reader.structField
assert subReader.voidField == None
assert subReader.boolField == True
assert subReader.int8Field == -12
assert subReader.int16Field == 3456
assert subReader.int32Field == -78901234
assert subReader.int64Field == 56789012345678
assert subReader.uInt8Field == 90
assert subReader.uInt16Field == 1234
assert subReader.uInt32Field == 56789012
assert subReader.uInt64Field == 345678901234567890
assert_almost(subReader.float32Field, -1.25e-10)
assert subReader.float64Field == 345
assert subReader.textField == "baz"
assert subReader.dataField == "qux"
subSubReader = subReader.structField
assert subSubReader.textField == "nested"
assert subSubReader.structField.textField == "really nested"
assert subReader.enumField == "baz"
check_list(subReader.voidList, [None, None, None])
check_list(subReader.boolList, [False, True, False, True, True])
check_list(subReader.int8List, [12, -34, -0x80, 0x7f])
check_list(subReader.int16List, [1234, -5678, -0x8000, 0x7fff])
check_list(subReader.int32List, [12345678, -90123456, -0x80000000, 0x7fffffff])
check_list(subReader.int64List, [123456789012345, -678901234567890, -0x8000000000000000, 0x7fffffffffffffff])
check_list(subReader.uInt8List, [12, 34, 0, 0xff])
check_list(subReader.uInt16List, [1234, 5678, 0, 0xffff])
check_list(subReader.uInt32List, [12345678, 90123456, 0, 0xffffffff])
check_list(subReader.uInt64List, [123456789012345, 678901234567890, 0, 0xffffffffffffffff])
check_list(subReader.float32List, [0.0, 1234567.0, 1e37, -1e37, 1e-37, -1e-37])
check_list(subReader.float64List, [0.0, 123456789012345.0, 1e306, -1e306, 1e-306, -1e-306])
check_list(subReader.textList, ["quux", "corge", "grault"])
check_list(subReader.dataList, ["garply", "waldo", "fred"])
listReader = subReader.structList
assert len(listReader) == 3
assert listReader[0].textField == "x structlist 1"
assert listReader[1].textField == "x structlist 2"
assert listReader[2].textField == "x structlist 3"
check_list(subReader.enumList, ["qux", "bar", "grault"])
assert reader.enumField == "corge"
assert len(reader.voidList) == 6
check_list(reader.boolList, [True, False, False, True])
check_list(reader.int8List, [111, -111])
check_list(reader.int16List, [11111, -11111])
check_list(reader.int32List, [111111111, -111111111])
check_list(reader.int64List, [1111111111111111111, -1111111111111111111])
check_list(reader.uInt8List, [111, 222])
check_list(reader.uInt16List, [33333, 44444])
check_list(reader.uInt32List, [3333333333])
check_list(reader.uInt64List, [11111111111111111111])
listReader = reader.float32List
assert len(listReader) == 4
assert listReader[0] == 5555.5
assert listReader[1] == float("inf")
assert listReader[2] == -float("inf")
assert math.isnan(listReader[3])
listReader = reader.float64List
len(listReader) == 4
assert listReader[0] == 7777.75
assert listReader[1] == float("inf")
assert listReader[2] == -float("inf")
assert math.isnan(listReader[3])
check_list(reader.textList, ["plugh", "xyzzy", "thud"])
check_list(reader.dataList, ["oops", "exhausted", "rfc3092"])
listReader = reader.structList
len(listReader) == 3
assert listReader[0].textField == "structlist 1"
assert listReader[1].textField == "structlist 2"
assert listReader[2].textField == "structlist 3"
check_list(reader.enumList, ["foo", "garply"])
def test_build(all_types):
root = all_types.TestAllTypes.newMessage()
init_all_types(root)
expectedText = open(os.path.join(this_dir, 'all-types.txt'), 'r').read()
assert str(root) + '\n' == expectedText
def test_binary_read(all_types):
f = open(os.path.join(this_dir, 'all-types.binary'), 'r')
root = all_types.TestAllTypes.readFrom(f)
check_all_types(root)
expectedText = open(os.path.join(this_dir, 'all-types.txt'), 'r').read()
assert str(root) + '\n' == expectedText
# Test setRoot().
builder = capnp.MallocMessageBuilder()
builder.setRoot(root)
check_all_types(builder.getRoot(all_types.TestAllTypes))
builder2 = capnp.MallocMessageBuilder()
builder2.setRoot(builder.getRoot(all_types.TestAllTypes))
check_all_types(builder2.getRoot(all_types.TestAllTypes))
def test_packed_read(all_types):
f = open(os.path.join(this_dir, 'all-types.packed'), 'r')
root = all_types.TestAllTypes.readPackedFrom(f)
check_all_types(root)
expectedText = open(os.path.join(this_dir, 'all-types.txt'), 'r').read()
assert str(root) + '\n' == expectedText
def test_binary_write(all_types):
root = all_types.TestAllTypes.newMessage()
init_all_types(root)
root.writeTo(open('example', 'w'))
check_all_types(all_types.TestAllTypes.readFrom(open('example', 'r')))
def test_packed_write(all_types):
root = all_types.TestAllTypes.newMessage()
init_all_types(root)
root.writePackedTo(open('example', 'w'))
check_all_types(all_types.TestAllTypes.readPackedFrom(open('example', 'r')))