class Thing(dictobj.PacketSpec): fields = [ ("one", T.Uint8.enum(E).multiple(3).default(E.ZERO)), ("two", T.Int32.multiple(3).default(0)), ("three", T.String(32).multiple(3).default(lambda pkt: "")), ("four", T.Bytes(40).multiple(3, kls=Other)), ]
class Thing(dictobj.PacketSpec): fields = [ ("one", T.Uint8.enum(E).multiple(4).default(E.ZERO)), ("two", T.Int32.multiple(3).default(0)), ("three", T.String(32).multiple(3)), ("four", T.Bytes(8).multiple(1, kls=Other)), ("five", T.Uint8.enum(E, allow_unknown=False).multiple(3).default(E.ZERO)), ]
class M(Messages): # fmt:off One = msg(78, ("one", T.String(16))) Two = msg(99) Three = msg( 98, ("three", T.Int8.transform(lambda _, v: v + 5, lambda _, v: v - 5)))
def mocked_spec(self, name, conversion): struct_format = mock.Mock(name="struct_format") size_bits = mock.Mock(name="size_bits") t = Type(struct_format, conversion).S(size_bits) spec = mock.Mock(name="spec") spec_maker = mock.Mock(name=name, return_value=spec) with mock.patch("photons_protocol.types.{0}".format(name), spec_maker): yield t, spec_maker, spec, size_bits
class V: other_typ = T.Int16.transform(lambda _, v: v + 5, lambda _, v: v - 5) two_typ = T.String(20 * 8).allow_callable() thing_typ = T.Reserved(lambda p: p.other * 8) @hp.memoized_property def G1(s): class G1(dictobj.PacketSpec): fields = [("other", s.other_typ), ("thing", s.thing_typ)] return G1 @hp.memoized_property def P(s): class P(dictobj.PacketSpec): fields = [("one", T.Bool), ("two", s.two_typ), ("g1", s.G1)] return P
class Group2(dictobj.PacketSpec): fields = [ ( "two", T.Int16.transform( lambda _, v: (int(str(v).split(".")[0]) << 0x10) + int(str(v).split(".")[1]), lambda _, v: float("{0}.{1}".format(v >> 0x10, v & 0xFF)), ), ), ("mod", T.String.default(lambda p: "{0}.modified".format(p["two"]))), ("sb", T.Int8), ("bts", T.Bytes(lambda p: p["sb"])), ]
it "complains about things that aren't json like objects, callables and non string keys": for val in (type("adf", (object,), {}), any, json, lambda: 1): with assertRaises(BadSpecValue): json_spec.normalise(Meta.empty(), val) try: json_spec.normalise(Meta.empty(), {"one": {1: 2}}) assert False, "Expected an error" except BadSpecValue as error: assert error.errors[0].errors[0].message == "Expected a string" describe "Type": it "takes in struct_format and conversion": struct_format = mock.Mock(name="struct_format") conversion = mock.Mock(name="conversion") t = Type(struct_format, conversion) assert t.struct_format is struct_format assert t.conversion is conversion describe "Adding size_bits": @pytest.fixture() def V(self): class V: struct_format = mock.Mock(name="struct_format") conversion = mock.Mock(name="conversion") @hp.memoized_property def t(s): return Type(s.struct_format, s.conversion)
group = mock.Mock(name="group") info = FieldInfo(name, typ, val, size_bits, group) assert info.name is name assert info.typ is typ assert info.val is val assert info.size_bits is size_bits assert info.group is group describe "value": it "returns value as is", info, val: assert info.value is val it "returns value as 0 bits if our typ is Reserved and val is NotSpecified", info: info.typ = T.Reserved(8) info.size_bits = 8 info.val = sb.NotSpecified assert info.value == bitarray("0" * 8) it "returns value as is if typ is Reserved but value is not NotSpecified", info, val: info.typ = T.Reserved(8) assert info.value == val describe "to_sized_bitarray": it "removes from the right if no left_cut", info: info.typ.left_cut = False info.size_bits = 3 to_bitarray = mock.Mock(name="to_bitarray") to_bitarray.return_value = bitarray("110000", endian="little")
def spec(self): return T.Bytes(20)
class Group2(dictobj.PacketSpec): fields = [("three", T.Bytes(100).multiple(3, kls=three_typ)), ("four", four_typ)]
class Other(dictobj.PacketSpec): fields = [("other", T.BoolInt), ("another", T.String(64).default(""))]
class Payload(dictobj.PacketSpec): message_type = 52 represents_ack = True fields = [("one", T.Bytes(16))]
class Other(dictobj.PacketSpec): fields = [ ("one", T.BoolInt), ("five", T.Bytes(16).multiple(2).default(lambda pkt: b"")), ]
class Thing(dictobj.PacketSpec): fields = [ ("one", T.BoolInt), ("two", T.Int32.multiple(2).default(0)), ("three", T.Bytes(4).multiple(2, kls=Other)), ]
class Chooser(dictobj.PacketSpec): fields = [ ("choice", T.String(64)), ("amount", T.Uint8), ("val", T.Bytes(32).multiple(lambda pkt: pkt.amount, kls=choose_kls)), ]
class Two(dictobj.PacketSpec): fields = [("two", T.String(32))]
class Thing(dictobj.PacketSpec): fields = [("thing", T.Bytes(72).multiple(3, kls=Other))]
def t(s): t = Type(s.struct_format, int) t._allow_float = s.allow_float t._unknown_enum_values = s.unknown_enum_values return t
def t(s): return Type(s.struct_format, s.conversion)
thing.four[0] = {"one": "asdf"} self.assertProperties(thing, partial(test_thing, UnknownEnum(6))) it "can set as bytes": class E(enum.Enum): ZERO = 0 MEH = 1 BLAH = 2 class Other(dictobj.PacketSpec): fields = [("other", T.BoolInt), ("another", T.String(64).default(""))] one_fields = [("one", T.Uint8.enum(E).multiple(3).default(E.ZERO))] two_fields = [("two", T.Bytes(72).multiple(3, kls=Other))] class One(dictobj.PacketSpec): fields = one_fields class Two(dictobj.PacketSpec): fields = two_fields class Thing(dictobj.PacketSpec): fields = [*one_fields, *two_fields] one = One(one=[1, "BLAH", repr(E.ZERO)]) two = Two( two=[ {"other": False, "another": "wat"}, {"other": True},
class M(Messages): P = msg(1) P2 = msg(2, ("thing", T.String(32 * 8)))
class P(dictobj.PacketSpec): fields = [("g", T.String(32))]
class Q(dictobj.PacketSpec): fields = [("things", T.Bytes(16).multiple(3, kls=lambda pkt: P))]
class Group1(dictobj.PacketSpec): fields = [("one", one_typ), ("two", T.Bytes(1).multiple(3, kls=two_typ))]