def test_duplicated_identifiers_union(): with pytest.raises(model.ModelError, match="Duplicated 'field_name' identifier in union U"): model.Union("U", [ model.UnionMember('field_name', 'u32', 0), model.UnionMember('field_name', 'u16', 1), ])
def test_definitions_union(): nodes = process([ model.Struct("Composite", [model.StructMember("x", "u32")]), model.Union("Union", [model.UnionMember("a", "u32", 1)]), model.Union("UnionPadded", [ model.UnionMember("a", "u8", 1), model.UnionMember("b", "u64", 2), model.UnionMember("c", "Composite", 3) ]) ]) assert generate_definitions([nodes[1]]) == """\ PROPHY_STRUCT(4) Union { enum _discriminator { discriminator_a = 1 } discriminator; union { uint32_t a; }; }; """ assert generate_definitions([nodes[2]]) == """\
def test_definitions_union(): nodes = [ model.Union("Union", [(model.UnionMember("a", "u8", 1)), (model.UnionMember("b", "u64", 2)), (model.UnionMember("c", "Composite", 3))]) ] assert generate_definitions(nodes) == """\
def test_union_repr(): union = model.Union("MyUnion", [ model.UnionMember("a", "u8", 1), model.UnionMember("b", "u16", 2), model.UnionMember("c", "u32", 3, docstring="deff") ]) assert_repr_reproduces(union) assert str(union) == """\
def test_swap_union(): nodes = [ model.Union("X", [(model.UnionMember("a", "u8", 1)), (model.UnionMember("b", "u64", 2)), (model.UnionMember("c", "C", 3))]) ] assert generate_swap(nodes) == """\
def test_union_repr(): union = model.Union("MyStruct", [ model.UnionMember("a", "u8", 1), model.UnionMember("b", "u16", 2), model.UnionMember("c", "u32", 3) ]) assert str(union.members[0]) == "1: u8 a" assert str(union.members[1]) == "2: u16 b" assert str(union.members[2]) == "3: u32 c"
def test_model_sort_union(): nodes = [model.Typedef("C", "B"), model.Union("B", [model.UnionMember("a", "A", "0"), model.UnionMember("b", "A", "1")]), model.Struct("A", [model.StructMember("a", "X")])] model.topological_sort(nodes) assert ["A", "B", "C"] == [node.name for node in nodes]
def test_swap_union(): nodes = process([ model.Typedef('C', 'u32'), model.Union("X", [(model.UnionMember("a", "u8", 1)), (model.UnionMember("b", "u64", 2)), (model.UnionMember("c", "C", 3))]) ]) assert generate_swap(nodes[-1:]) == """\
def test_change_union_to_struct_excessive_params(): nodes = [ model.Union("MyUnion", [ model.UnionMember("field1", "u32", 1), model.UnionMember("field2", "u32", 2) ]) ] patches = {'MyUnion': [patch.Action('struct', ['surplus_param'])]} with pytest.raises(Exception) as e: patch.patch(nodes, patches) assert 'Change union to struct takes no params: MyUnion' in str(e.value)
def test_union_rendering_2(): nodes = [ model.Union("U", [ model.UnionMember("a", "i8", "0"), model.UnionMember("b", "u32", "1"), model.UnionMember("c", "r64", "2") ]) ] ref = """\ class U(prophy.with_metaclass(prophy.union_generator, prophy.union)): _descriptor = [('a', prophy.i8, 0), ('b', prophy.u32, 1), ('c', prophy.r64, 2)] """ assert ref == serialize(nodes)
def test_union_rendering(): nodes = [ model.Union("U", [ model.UnionMember("a", "A", "0"), model.UnionMember("b", "B", "1"), model.UnionMember("c", "C", "2") ]) ] ref = """\ class U(prophy.with_metaclass(prophy.union_generator, prophy.union)): _descriptor = [('a', A, 0), ('b', B, 1), ('c', C, 2)] """ assert ref == serialize(nodes)
def test_evaluate_sizes_unknown(): nodes, warnings = process_with_warnings([ model.Struct('X', [ model.StructMember('x', 'u8'), model.StructMember('y', 'U'), model.StructMember('z', 'u32'), ]), model.Union('Y', [ model.UnionMember('x', 'u32', '1'), model.UnionMember('y', 'U', '2'), model.UnionMember('z', 'u32', '3'), ]), model.Typedef('U16', 'U'), model.Struct('Z', [ model.StructMember('x', 'U16'), model.StructMember('y', 'Unknown'), ]), ]) assert warnings == [ 'X::y has unknown type "U"', 'Y::y has unknown type "U"', 'Z::x has unknown type "U"', 'Z::y has unknown type "Unknown"', ] assert list(map(get_size_alignment_padding, get_members_and_node(nodes[0]))) == [ (1, 1, None), (None, None, None), (4, 4, None), (None, None), ] assert list(map(get_size_alignment_padding, get_members_and_node(nodes[1]))) == [ (4, 4), (None, None), (4, 4), (None, None), ] assert list(map(get_size_alignment_padding, get_members_and_node(nodes[3]))) == [ (None, None, None), (None, None, None), (None, None), ]
def test_change_union_to_struct(): nodes = [model.Union("MyUnion", [model.UnionMember("field1", "u32", 1)])] patches = {'MyUnion': [patch.Action('struct', [])]} patch.patch(nodes, patches) assert [model.Struct('MyUnion', [model.StructMember('field1', 'u32')])] == nodes
def test_union_parsing(): xml = """\ <x> <union name="Union"> <member type="A" name="a" discriminatorValue="0"/> <member type="B" name="b" discriminatorValue="1"/> <member type="C" name="c" discriminatorValue="5"/> </union> </x> """ nodes = parse(xml) assert ["Union"] == [node.name for node in nodes] assert nodes[0].members == [ model.UnionMember("a", "A", "0"), model.UnionMember("b", "B", "1"), model.UnionMember("c", "C", "5") ]
def test_swap_enum_in_union(): nodes = process([ model.Enum("E1", [model.EnumMember("E1_A", "0")]), model.Union("EnumUnion", [ (model.UnionMember("x", "E1", 1)), ]) ]) assert generate_swap(nodes) == """\
def test_evaluate_sizes_union_with_padding(): nodes = process([ model.Union('X', [ model.UnionMember('x', 'u8', '1') ]), model.Union('Y', [ model.UnionMember('x', 'u8', '1'), model.UnionMember('y', 'u64', '2') ]) ]) assert list(map(get_size_alignment_padding, get_members_and_node(nodes[0]))) == [ (1, 1), (8, 4) ] assert list(map(get_size_alignment_padding, get_members_and_node(nodes[1]))) == [ (1, 1), (8, 8), (16, 8) ]
def test_unions_parsing(): content = """\ const three = 3; typedef u32 z_t; union test { 1: u32 x; 2: u32 y; three: z_t z; }; """ assert parse(content) == [ model.Constant('three', '3'), model.Typedef('z_t', 'u32'), model.Union('test', [ model.UnionMember('x', 'u32', '1'), model.UnionMember('y', 'u32', '2'), model.UnionMember('z', 'z_t', '3') ]) ]
def test_generate_swap_declarations(): nodes = process([ model.Struct("A", [ (model.StructMember("x", "u32")), ]), model.Union("B", [ (model.UnionMember("x", "u32", 1)), ]), model.Enum("C", [model.EnumMember("E1_A", "0")]) ]) assert generate_swap_declarations(nodes) == """\
def test_wrong_struct_member_type(): expected_msg = "Each member of struct 'A' has to be a StructMember instance. Got str at index 1." with pytest.raises(model.ModelError, match=expected_msg): model.Struct("A", [ model.StructMember('field_name', 'u32'), "string", ]) expected_msg = "Each member of struct 'A' has to be a StructMember instance. Got UnionMember at index 0." with pytest.raises(model.ModelError, match=expected_msg): model.Struct("A", [ model.UnionMember('field_name', 'u32', 2), ])
def test_evaluate_sizes_union(): nodes = process([ model.Union('X', [ model.UnionMember('x', 'u32', '1'), model.UnionMember('y', 'u32', '2'), model.UnionMember('z', 'u32', '3') ]), model.Union('Y', [ model.UnionMember('x', 'u64', '1') ]), model.Union('Z', [ model.UnionMember('x', 'X', '1'), model.UnionMember('y', 'Y', '2') ]) ]) assert list(map(get_size_alignment_padding, get_members_and_node(nodes[0]))) == [ (4, 4), (4, 4), (4, 4), (8, 4) ] assert list(map(get_size_alignment_padding, get_members_and_node(nodes[1]))) == [ (8, 8), (16, 8) ] assert list(map(get_size_alignment_padding, get_members_and_node(nodes[2]))) == [ (8, 4), (16, 8), (24, 8) ]
def test_wrong_union_member_type(): expected_msg = "Each member of union 'U' has to be a UnionMember instance. Got str at index 1." with pytest.raises(model.ModelError, match=expected_msg): model.Union("U", [ model.UnionMember('field_name', 'u32', 0), "string", ]) expected_msg = "Each member of union 'U' has to be a UnionMember instance. Got StructMember at index 0." with pytest.raises(model.ModelError, match=expected_msg): model.Union("U", [ model.StructMember('field_name', 'u32'), ])
def test_union(): hpp = """\ #include <stdint.h> union Union { uint8_t a; uint16_t b; uint32_t c; }; struct X { Union a; }; """ assert parse(hpp) == [ model.Union("Union", [ model.UnionMember("a", "u8", "0"), model.UnionMember("b", "u16", "1"), model.UnionMember("c", "u32", "2") ]), model.Struct("X", [model.StructMember("a", "Union")]) ]
def test_change_union_to_struct_and_remove_field(): nodes = [ model.Union("MyUnion", [ model.UnionMember("field1", "u32", 1), model.UnionMember("field2", "u32", 2), model.UnionMember("field3", "u32", 3) ]) ] patches = { 'MyUnion': [patch.Action('struct', []), patch.Action('remove', ['field2'])] } patch.patch(nodes, patches) assert [ model.Struct('MyUnion', [ model.StructMember('field1', 'u32'), model.StructMember('field3', 'u32') ]) ] == nodes
def make_union(xml_elem): if len(xml_elem): members = [] for member in xml_elem: members.append( model.UnionMember( member.get("name"), member.get("type"), member.get("discriminatorValue"), docstring=get_docstr(member), )) return model.Union(xml_elem.get('name'), members, docstring=get_docstr(xml_elem))
def test_typedefed_union(): hpp = """\ #include <stdint.h> typedef union { uint8_t a; } Union; struct X { Union a; }; """ assert parse(hpp) == [ model.Union("Union", [model.UnionMember("a", "u8", "0")]), model.Struct("X", [model.StructMember("a", "Union")]) ]
def _build_union_member(self, cursor, disc): name = cursor.spelling.decode() type_name = self._build_field_type_name(cursor.type) return model.UnionMember(name, type_name, str(disc))
def make_union_member(elem): return model.UnionMember(elem.get("name"), elem.get("type"), elem.get("discriminatorValue"))
def test_cross_reference_union_warnings(): nodes = [model.Union('X', [model.UnionMember('x', 'TypeUnknown', '42')])] warn = WarnFake() model.cross_reference(nodes, warn) assert warn.msgs == ["type 'TypeUnknown' not found"]
def larger_model(lorem_with_breaks): return [ model.Typedef('a', 'i16'), model.Typedef('c', 'a'), model.Include('some_defs', [ model.Struct('IncludedStruct', [ model.StructMember( 'member1', 'r32', docstring='doc for member1'), model.StructMember( 'member2', 'u64', docstring='docstring for member1') ]), model.Typedef('c', 'a'), ]), model.Include('cplx', [ model.Struct('cint16_t', [ model.StructMember('re', 'i16', docstring='real'), model.StructMember('im', 'i16', docstring='imaginary') ]), model.Struct('cint32_t', [ model.StructMember('re', 'i32', docstring='real'), model.StructMember('im', 'i32', docstring='imaginary') ]), ]), model.Union('the_union', [ model.UnionMember('a', 'IncludedStruct', 0), model.UnionMember( 'field_with_a_long_name', 'cint16_t', 1, docstring="Shorter"), model.UnionMember('field_with_a_longer_name', 'cint32_t', 2, docstring="Longer description"), model.UnionMember('other', 'i32', 4090, docstring='This one has larger discriminator'), ], "spec for that union"), model.Enum( 'E1', [ model.EnumMember('E1_A', '0', 'enum1 constant value A'), model.EnumMember('E1_B_has_a_long_name', '1', 'enum1 constant va3lue B'), model.EnumMember('E1_C_desc', '2', lorem_with_breaks[:150]), ], "Enumerator is a model type that is not supposed to be serialized. Its definition represents yet another " "syntax variation for typing a constant. Of course elements of it's type are serializable " "(as int32)"), model.Enum('E2', [ model.EnumMember('E2_A', '0', "Short\nmultiline\ndoc"), ]), model.Constant('CONST_A', '6'), model.Constant('CONST_B', '0'), model.Struct('StructMemberKinds', [ model.StructMember('member_without_docstring', 'i16'), model.StructMember('ext_size', 'i16', docstring='arbitrary sizer for dynamic arrays'), model.StructMember('optional_element', 'cint16_t', optional=True, docstring='optional array'), model.StructMember('fixed_array', 'cint16_t', size=3, docstring='Array with static size.'), model.StructMember('samples', 'cint16_t', bound='ext_size', docstring='dynamic (ext.sized) array'), model.StructMember('limited_array', 'r64', size=4, bound='ext_size', docstring='Has statically ' 'evaluable maximum size.'), model.StructMember('greedy', 'cint16_t', greedy=True, docstring='Represents array of arbitrary ' 'number of elements. Buffer size ' 'must be multiply of element size.'), ], lorem_with_breaks[:400]), ]