def test_SrvSpec(): from genmsg import MsgSpec, SrvSpec types = ['int32'] names = ['a'] constants = [] text = 'int32 a' msg_a = MsgSpec(types, names, constants, text, 'a/Int') assert msg_a.full_name == 'a/Int' assert msg_a.package == 'a' assert msg_a.short_name == 'Int' types = ['int64'] names = ['b'] constants = [] text = 'int64 b' msg_b = MsgSpec(types, names, constants, text, 'b/Int') assert msg_b.full_name == 'b/Int' assert msg_b.package == 'b' assert msg_b.short_name == 'Int' text = msg_a.text + '\n---\n' + msg_b.text spec = SrvSpec(msg_a, msg_b, text) assert msg_a == spec.request assert msg_b == spec.response assert text == spec.text assert '' == spec.full_name assert '' == spec.short_name assert '' == spec.package # tripwire assert repr(spec) assert str(spec) # exercise eq assert spec != 'spec' assert not spec == 'spec' spec2 = SrvSpec(msg_a, msg_b, text) assert spec == spec2 assert not spec != spec2 # - full_name spec2.full_name = 'something' assert spec != spec2 spec2.full_name = '' assert spec == spec2 # - short_name spec2.short_name = 'something' assert spec != spec2 spec2.short_name = '' assert spec == spec2 # - package spec2.package = 'something' assert spec != spec2 spec2.package = '' assert spec == spec2
def sub_test_MsgSpec(types, names, constants, text, full_name, has_header): m = MsgSpec(types, names, constants, text, full_name) assert m.types == types assert m.names == names assert m.text == text assert has_header == m.has_header() assert m.constants == constants assert list(zip(types, names)) == m.fields() assert m == MsgSpec(types, names, constants, text, full_name) return m
def sub_test_MsgSpec(types, names, constants, text, full_name, has_header): m = MsgSpec(types, names, constants, text, full_name) assert m.types == types assert m.names == names assert m.text == text assert has_header == m.has_header() assert m.constants == constants assert list(zip(types, names)) == m.fields() assert m == MsgSpec(types, names, constants, text, full_name) return m
def flatten(msg_context, msg): """ Flattens the msg spec so that embedded message fields become direct references. The resulting MsgSpec isn't a true/legal :class:`MsgSpec` and should only be used for serializer generation. :param msg: MsgSpec to flatten :returns: flattened MsgSpec message """ new_types = [] new_names = [] for t, n in zip(msg.types, msg.names): # Parse type to make sure we don't flatten an array msg_type, is_array, _ = genmsg.msgs.parse_type(t) #flatten embedded types - note: bug #59 if not is_array and msg_context.is_registered(t): msg_spec = flatten(msg_context, msg_context.get_registered(t)) new_types.extend(msg_spec.types) for n2 in msg_spec.names: new_names.append(n+'.'+n2) else: #I'm not sure if it's a performance win to flatten fixed-length arrays #as you get n __getitems__ method calls vs. a single *array call new_types.append(t) new_names.append(n) return MsgSpec(new_types, new_names, msg.constants, msg.text, msg.full_name)
def make_python_safe(spec): """ Remap field/constant names in spec to avoid collision with Python reserved words. :param spec: msg spec to map to new, python-safe field names, ``MsgSpec`` :returns: python-safe message specification, ``MsgSpec`` """ new_c = [genmsg.Constant(c.type, _remap_reserved(c.name), c.val, c.val_text) for c in spec.constants] return MsgSpec(spec.types, [_remap_reserved(n) for n in spec.names], new_c, spec.text, spec.full_name)
def test_MsgSpec(): def sub_test_MsgSpec(types, names, constants, text, full_name, has_header): m = MsgSpec(types, names, constants, text, full_name) assert m.types == types assert m.names == names assert m.text == text assert has_header == m.has_header() assert m.constants == constants assert list(zip(types, names)) == m.fields() assert m == MsgSpec(types, names, constants, text, full_name) return m from genmsg import MsgSpec, InvalidMsgSpec from genmsg.msgs import Field # don't allow duplicate fields try: MsgSpec(['int32', 'int64'], ['x', 'x'], [], 'int32 x\nint64 x', 'x/DupFields') assert False, "should have raised" except InvalidMsgSpec: pass # don't allow invalid fields try: MsgSpec(['string['], ['x'], [], 'int32 x\nint64 x', 'x/InvalidFields') assert False, "should have raised" except InvalidMsgSpec: pass # allow empty msg empty = sub_test_MsgSpec([], [], [], '', 'x/Nothing', False) assert [] == empty.fields() assert [] == empty.parsed_fields() assert 'x/Nothing' == empty.full_name assert 'x' == empty.package assert 'Nothing' == empty.short_name # one-field one_field = sub_test_MsgSpec(['int32'], ['x'], [], 'int32 x', 'x/OneInt', False) # make sure that equals tests every declared field assert one_field == MsgSpec(['int32'], ['x'], [], 'int32 x', 'x/OneInt') assert one_field != MsgSpec(['uint32'], ['x'], [], 'int32 x', 'x/OneInt') assert one_field != MsgSpec(['int32'], ['y'], [], 'int32 x', 'x/OneInt') assert one_field != MsgSpec(['int32'], ['x'], [], 'uint32 x', 'x/OneInt') assert one_field != MsgSpec(['int32'], ['x'], [], 'int32 x', 'x/OneIntBad') # test against __ne__ as well assert one_field != MsgSpec(['int32'], ['x'], [], 'uint32 x', 'x/OneInt') assert [ Field('x', 'int32') ] == one_field.parsed_fields(), "%s vs %s" % ([Field( 'x', 'int32')], one_field.parsed_fields()) #test str assert "int32 x" == str(one_field).strip() # test variations of multiple fields and headers two_fields = sub_test_MsgSpec(['int32', 'string'], ['x', 'str'], [], 'int32 x\nstring str', 'x/TwoFields', False) assert [Field('x', 'int32'), Field('str', 'string')] == two_fields.parsed_fields() one_header = sub_test_MsgSpec(['std_msgs/Header'], ['header'], [], 'Header header', 'x/OneHeader', True) header_and_fields = sub_test_MsgSpec( ['std_msgs/Header', 'int32', 'string'], ['header', 'x', 'str'], [], 'Header header\nint32 x\nstring str', 'x/HeaderAndFields', True) embed_types = sub_test_MsgSpec( ['std_msgs/Header', 'std_msgs/Int32', 'string'], ['header', 'x', 'str'], [], 'Header header\nstd_msgs/Int32 x\nstring str', 'x/EmbedTypes', True) #test strify assert "int32 x\nstring str" == str(two_fields).strip() # types and names mismatch try: MsgSpec(['int32', 'int32'], ['intval'], [], 'int32 intval\nint32 y', 'x/Mismatch') assert False, "types and names must align" except: pass # test (not) equals against non msgspec assert not (one_field == 1) assert one_field != 1 # test constants from genmsg.msgs import Constant msgspec = MsgSpec(['int32'], ['x'], [Constant('int8', 'c', 1, '1')], 'int8 c=1\nuint32 x', 'x/Constants') assert msgspec.constants == [Constant('int8', 'c', 1, '1')] # tripwire str(msgspec) repr(msgspec) # test that repr doesn't throw an error [repr(x) for x in [empty, one_field, one_header, two_fields, embed_types]]