Пример #1
0
def test_wrapper_deserialization_error():
    xml = '''<?xml version="1.0" encoding="utf-8"?>
    <test_model>
        <wrapper>
            <wrapper>
                <element1>value</element1>
            </wrapper>
        </wrapper>
    </test_model>
    '''

    @pb.model(name='test_model')
    class TestModel:
        element = pb.wrap('wrapper', pb.wrap('wrapper', pb.field()))

    with pytest.raises(
            exc.DeserializationError,
            match=
            r"required element '/test_model\[1\]/wrapper\[1\]/wrapper\[1\]/element\[1\]' not found"
    ):
        pb.from_xml(TestModel, xml)

    @pb.model(name='test_model')
    class TestModel:
        element = pb.wrap('wrapper1', pb.wrap('wrapper', pb.field()))

    with pytest.raises(
            exc.DeserializationError,
            match=r"required element '/test_model\[1\]/wrapper1\[1\]' not found"
    ):
        pb.from_xml(TestModel, xml)
Пример #2
0
def test_attribute_deserialization_error():
    xml = '''<?xml version="1.0" encoding="utf-8"?>
    <test_model attribute1="value1"/>
    '''

    @pb.model(name='test_model')
    class TestModel:
        attribute = pb.attr()

    with pytest.raises(
            exc.DeserializationError,
            match=r"required attribute '/test_model\[1\]/attribute' not found"
    ):
        pb.from_xml(TestModel, xml)
Пример #3
0
def test_inheritance_deserialization():
    xml = '''<?xml version="1.0" encoding="utf-8"?>
    <TestRootModel>
        <TestBaseModel>
            <element1>value1</element1>
        </TestBaseModel>
        <TestExtendedModel>
            <element1>value2</element1>
            <element2>value3</element2>
        </TestExtendedModel>
    </TestRootModel>
    '''

    @pb.model
    class TestBaseModel:
        element1 = pb.field()

    @pb.model
    class TestExtendedModel(TestBaseModel):
        element2 = pb.field()

    @pb.model
    class TestRootModel:
        model1 = pb.nested(TestBaseModel)
        model2 = pb.nested(TestExtendedModel)

    model = pb.from_xml(TestRootModel, xml)

    assert model.model1.element1 == 'value1'
    assert model.model2.element1 == 'value2'
    assert model.model2.element2 == 'value3'
Пример #4
0
def test_field_deserialization_error():
    xml = '''<?xml version="1.0" encoding="utf-8"?>
    <test_model>
        <element1/>
    </test_model>
    '''

    @pb.model(name='test_model')
    class TestModel:
        element = pb.field()

    with pytest.raises(
            exc.DeserializationError,
            match=r"required element '/test_model\[1\]/element\[1\]' not found"
    ):
        pb.from_xml(TestModel, xml)
Пример #5
0
def test_list_of_list_deserialization():
    xml = '''<?xml version="1.0" encoding="utf-8"?>
    <TestModel>
        <element1>
            <element2>value1</element2>
            <element2>value2</element2>
        </element1>
        <element1>
            <element2>value3</element2>
            <element2>value4</element2>
        </element1>
    </TestModel>
    '''

    @pb.model
    class TestModel:
        elements = pb.as_list(
            pb.wrap('element1', pb.as_list(pb.field('element2'))))

    model = pb.from_xml(TestModel, xml)

    assert model.elements[0][0] == 'value1'
    assert model.elements[0][1] == 'value2'
    assert model.elements[1][0] == 'value3'
    assert model.elements[1][1] == 'value4'
Пример #6
0
def test_nested_list_deserialization():
    xml = '''<?xml version="1.0" encoding="utf-8"?>
    <TestModel>
        <NestedModel>
            <element>value1</element>
        </NestedModel>
        <NestedModel>
            <element>value2</element>
        </NestedModel>
    </TestModel>
    '''

    @pb.model
    class NestedModel:
        element = pb.field()

    @pb.model
    class TestModel:
        elements = pb.as_list(pb.nested(NestedModel))

    model = pb.from_xml(TestModel, xml)

    assert len(model.elements) == 2
    assert model.elements[0].element == 'value1'
    assert model.elements[1].element == 'value2'
Пример #7
0
def test_nested_deserialization():
    xml = '''<?xml version="1.0" encoding="utf-8"?>
    <TestModel>
        <NestedModel1>
            <NestedModel2>
                <element>value</element>
            </NestedModel2>
        </NestedModel1>
    </TestModel>
    '''

    @pb.model
    class NestedModel2:
        element = pb.field()

    @pb.model
    class NestedModel1:
        nested = pb.nested(NestedModel2)

    @pb.model
    class TestModel:
        nested = pb.nested(NestedModel1)

    model = pb.from_xml(TestModel, xml)

    assert model.nested.nested.element == 'value'
Пример #8
0
def test_attribute_default():
    xml = '''<?xml version="1.0" encoding="utf-8"?>
    <test_model>
    </test_model>
    '''

    @pb.model(name='test_model')
    class TestModel:
        attrib = pb.attr(default=None)

    obj = pb.from_xml(TestModel, xml)
    assert obj.attrib is None
Пример #9
0
def test_field_default():
    xml = '''<?xml version="1.0" encoding="utf-8"?>
    <test_model>
    </test_model>
    '''

    @pb.model(name='test_model')
    class TestModel:
        field = pb.field(default=None)

    obj = pb.from_xml(TestModel, xml)
    assert obj.field is None
Пример #10
0
def test_nested_deserialization_error():
    xml = '''<?xml version="1.0" encoding="utf-8"?>
    <test_model>
        <nested_model/>
    </test_model>
    '''

    @pb.model(name='nested_model1')
    class NestedModel:
        pass

    @pb.model(name='test_model')
    class TestModel:
        element = pb.nested(NestedModel)

    with pytest.raises(
            exc.DeserializationError,
            match=
            r"required element '/test_model\[1\]/nested_model1\[1\]' not found"
    ):
        pb.from_xml(TestModel, xml)
Пример #11
0
def test_attribute_deserialization_with_name():
    xml = '''<?xml version="1.0" encoding="utf-8"?>
    <TestModel attribute1="value1" attribute2="value2"/>
    '''

    @pb.model
    class TestModel:
        attrib1 = pb.attr(name='attribute1')
        attrib2 = pb.attr(name='attribute2')

    model = pb.from_xml(TestModel, xml)

    assert model.attrib1 == 'value1'
    assert model.attrib2 == 'value2'
Пример #12
0
def test_root_deserialization():
    xml = '''<?xml version="1.0" encoding="utf-8"?>
    <test_model>
        <element1>value1</element1>
    </test_model>
    '''

    @pb.model(name='test_model')
    class TestModel:
        element1 = pb.field()

    model = pb.from_xml(TestModel, xml)

    assert model.element1 == 'value1'
Пример #13
0
def test_element_list_deserialization():
    xml = '''<?xml version="1.0" encoding="utf-8"?>
    <TestModel>
        <element1>value1</element1>
        <element1>value2</element1>
    </TestModel>
    '''

    @pb.model
    class TestModel:
        element1 = pb.as_list(pb.field())

    model = pb.from_xml(TestModel, xml)

    assert model.element1 == ['value1', 'value2']
Пример #14
0
def test_element_deserialization_with_name():
    xml = '''<?xml version="1.0" encoding="utf-8"?>
    <TestModel>
        <element1>value1</element1>
        <element2>value2</element2>
    </TestModel>
    '''

    @pb.model
    class TestModel:
        elem1 = pb.field(name='element1')
        elem2 = pb.field(name='element2')

    model = pb.from_xml(TestModel, xml)

    assert model.elem1 == 'value1'
    assert model.elem2 == 'value2'
Пример #15
0
def test_private_attributes():
    xml = '''<?xml version="1.0" encoding="utf-8"?>
    <TestModel>
        <field1>value1</field1>
        <field2>value2</field2>
    </TestModel>
    '''

    @pb.model()
    class TestModel:
        _field1 = pb.field(name='field1')
        __field2 = pb.field(name='field2')

    obj = pb.from_xml(TestModel, xml)

    assert obj._field1 == 'value1'
    assert obj._TestModel__field2 == 'value2'
Пример #16
0
def test_indexes_deserialization():
    xml = '''<?xml version="1.0" encoding="utf-8"?>
    <root>
        <element>value1</element>
        <element>value2</element>

        <wrapper>
            <element>value3</element>
        </wrapper>
        <wrapper>
            <element>value4</element>
        </wrapper>

        <nested>
            <element>value5</element>
        </nested>
        <nested>
            <element>value6</element>
        </nested>
    </root>
    '''

    @pb.model(name='nested')
    class Nested:
        field = pb.field('element')

    @pb.model(name='root')
    class TestModel:
        field1 = pb.field('element', idx=1)
        field2 = pb.field('element', idx=2)

        field3 = pb.wrap('wrapper', pb.field('element'), idx=1)
        field4 = pb.wrap('wrapper', pb.field('element'), idx=2)

        nested1 = pb.nested(Nested, idx=1)
        nested2 = pb.nested(Nested, idx=2)

    model = pb.from_xml(TestModel, xml)

    assert model.field1 == 'value1'
    assert model.field2 == 'value2'
    assert model.field3 == 'value3'
    assert model.field4 == 'value4'
    assert model.nested1.field == 'value5'
    assert model.nested2.field == 'value6'
Пример #17
0
def test_wrapper_deserialization():
    xml = '''<?xml version="1.0" encoding="utf-8"?>
    <TestModel>
        <wrapper1>
            <wrapper2>
                <element1>value1</element1>
            </wrapper2>
        </wrapper1>
    </TestModel>
    '''

    @pb.model
    class TestModel:
        element1 = pb.wrap('wrapper1', pb.wrap('wrapper2', pb.field()))

    model = pb.from_xml(TestModel, xml)

    assert model.element1 == 'value1'
Пример #18
0
def test_wrapper_list_deserialization():
    xml = '''<?xml version="1.0" encoding="utf-8"?>
    <TestModel>
        <wrapper>
            <element>value1</element>
        </wrapper>
        <wrapper>
            <element>value2</element>
        </wrapper>
    </TestModel>
    '''

    @pb.model
    class TestModel:
        elements = pb.as_list(pb.wrap('wrapper', pb.field('element')))

    model = pb.from_xml(TestModel, xml)

    assert model.elements == ['value1', 'value2']
Пример #19
0
def test_namespaces_deserialization():
    xml = '''<?xml version="1.0" encoding="utf-8"?>
    <testns1:TestModel xmlns:testns1="http://www.test1.org"
                   xmlns:testns2="http://www.test2.org"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://www.test.com schema.xsd">
        <element1>value1</element1>
        <testns1:element2>value2</testns1:element2>
        <testns2:element3>value3</testns2:element3>
        <testns1:element4 xmlns:testns2="http://www.test22.org">
            <element5>value5</element5>
            <testns2:element6>value6</testns2:element6>
        </testns1:element4>
    </testns1:TestModel>
    '''

    @pb.model(ns='testns1', ns_map={'testns2': 'http://www.test2.org'})
    class TestModel:
        schema = pb.attribute('schemaLocation', ns='xsi')
        element1 = pb.field(ns='')
        element2 = pb.field()
        element3 = pb.field(ns='testns2')
        element5 = pb.wrap('element4', pb.field(ns=''))
        element6 = pb.wrap('element4',
                           pb.field(ns='testns2'),
                           ns_map={'testns2': 'http://www.test22.org'})

    model = pb.from_xml(TestModel,
                        xml,
                        ns_map={
                            'testns1': 'http://www.test1.org',
                            'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
                        })

    assert model.schema == 'http://www.test.com schema.xsd'
    assert model.element1 == 'value1'
    assert model.element2 == 'value2'
    assert model.element3 == 'value3'
    assert model.element5 == 'value5'
    assert model.element6 == 'value6'
Пример #20
0
    phone = pb.wrap('contacts', pb.field())
    emails = pb.wrap('contacts', pb.as_list(pb.field(name='email')))

    passport_series = pb.wrap('documents/passport', pb.attr('series'))
    passport_number = pb.wrap('documents/passport', pb.attr('number'))

    occupations = pb.wrap('occupations',
                          pb.lst(pb.nested(Occupation)),
                          ns='data',
                          ns_map={'data': 'http://www.test2.org'})

    citizenship = pb.field(default='RU')

    @phone.validator
    def check(self, attribute, value):
        if not re.match(r'\+\d{11,13}', value):
            raise ValueError("phone number is incorrect")


try:
    user = pb.from_xml(User,
                       xml,
                       envelope='doc:envelope',
                       ns_map={'doc': 'http://www.test1.org'})
    user.birthdate = user.birthdate.replace(year=1993)

    pprint.pprint(attr.asdict(user))

except (pb.exc.DeserializationError, ValueError) as e:
    print(f"deserialization error: {e}")
Пример #21
0
def test_complex_xml_deserialization():
    xml = '''<?xml version="1.0" encoding="utf-8"?>
    <envelope xmlns="http://www.test.org"
                  xmlns:doc="http://www.test1.org"
                  xmlns:data="http://www.test2.org">
        <doc:user name="Alexey" surname="Ivanov" age="26">

            <doc:contacts>
                <doc:phone>+79204563539</doc:phone>
                <doc:email>[email protected]</doc:email>
                <doc:email>[email protected]</doc:email>
            </doc:contacts>

            <doc:documents>
                <doc:passport series="3127" number="836815"/>
            </doc:documents>

            <data:occupations xmlns:data="http://www.test22.org">
                <data:occupation title="yandex">
                    <data:address>Moscow</data:address>
                    <data:employees>8854</data:employees>
                </data:occupation>
                <data:occupation title="skbkontur">
                    <data:address>Yekaterinburg</data:address>
                    <data:employees>7742</data:employees>
                </data:occupation>
            </data:occupations>

        </doc:user>
    </envelope>
    '''

    @pb.model(name='occupation',
              ns='data',
              ns_map={'data': 'http://www.test22.org'})
    class Occupation:
        title = pb.attr()
        address = pb.field()
        employees = pb.field(converter=int)

    @pb.model(name='user', ns='doc', ns_map={'doc': 'http://www.test1.org'})
    class User:
        name = pb.attr()
        surname = pb.attr()
        age = pb.attr(converter=int)

        phone = pb.wrap('contacts', pb.field())
        emails = pb.wrap('contacts', pb.as_list(pb.field(name='email')))

        passport_series = pb.wrap('documents/passport', pb.attr('series'))
        passport_number = pb.wrap('documents/passport', pb.attr('number'))

        occupations = pb.wrap('occupations',
                              pb.lst(pb.nested(Occupation)),
                              ns='data',
                              ns_map={'data': 'http://www.test22.org'})

        citizenship = pb.field(default='RU')

    xml = et.fromstring(xml)
    user = pb.from_xml(User, xml)

    assert user.name == 'Alexey'
    assert user.surname == 'Ivanov'
    assert user.age == 26

    assert user.phone == '+79204563539'
    assert user.emails == ['*****@*****.**', '*****@*****.**']

    assert user.passport_series == '3127'
    assert user.passport_number == '836815'

    assert len(user.occupations) == 2

    assert user.occupations[0].title == 'yandex'
    assert user.occupations[0].address == 'Moscow'
    assert user.occupations[0].employees == 8854

    assert user.occupations[1].title == 'skbkontur'
    assert user.occupations[1].address == 'Yekaterinburg'
    assert user.occupations[1].employees == 7742

    assert user.citizenship == 'RU'