예제 #1
0
def test_user_object_parse_aliased():
    """Parse an aliased user object"""
    xml_string = """
    <root>
        <book>Harry Potter</book>
        <person>
            <name>Ron</name>
            <age>18</age>
        </person>
    </root>
    """

    processor = xml.dictionary('root', [
        xml.string('book'),
        xml.user_object('person',
                        Person, [xml.string('name'),
                                 xml.integer('age')],
                        alias='character')
    ])

    expected = {
        'book': 'Harry Potter',
        'character': Person().set_values(name='Ron', age=18)
    }

    actual = xml.parse_from_string(processor, xml_string)

    assert expected == actual
예제 #2
0
def test_user_object_serialize_aliased():
    """Serializes an aliased user object"""
    value = {
        'book': 'Harry Potter',
        'character': Person().set_values(name='Malfoy', age=17)
    }

    processor = xml.dictionary('root', [
        xml.string('book'),
        xml.user_object('person',
                        Person, [xml.string('name'),
                                 xml.integer('age')],
                        alias='character')
    ])

    expected = strip_xml("""
    <root>
        <book>Harry Potter</book>
        <person>
            <name>Malfoy</name>
            <age>17</age>
        </person>
    </root>
    """)

    actual = xml.serialize_to_string(processor, value)

    assert expected == actual
예제 #3
0
def test_user_object_parse_nested():
    """Parse a user object as a nested element in the document"""
    xml_string = """
    <root>
        <position>quarterback</position>
        <person>
            <name>Bob</name>
            <pet>Fluffy</pet>
            <pet>Spots</pet>
        </person>
    </root>
    """

    processor = xml.dictionary('root', [
        xml.string('position'),
        xml.user_object('person', Person, [
            xml.string('name'),
            xml.array(xml.string('pet'), alias='pets'),
        ])
    ])

    expected = {
        'position': 'quarterback',
        'person': Person().set_values(name='Bob', pets=['Fluffy', 'Spots'])
    }

    actual = xml.parse_from_string(processor, xml_string)

    assert expected == actual
예제 #4
0
def test_named_tuple_serialize():
    """Serialize a namedtuple value"""
    value = Author(name='Robert A. Heinlein',
                   books=[
                       Book(title='Starship Troopers', year_published=1959),
                       Book(title='Stranger in a Strange Land',
                            year_published=1961)
                   ])

    processor = xml.named_tuple('author', Author, [
        xml.string('name'),
        xml.array(xml.named_tuple('book', Book, [
            xml.string('title'),
            xml.integer('year-published', alias='year_published')
        ]),
                  alias='books')
    ])

    expected = strip_xml("""
    <author>
        <name>Robert A. Heinlein</name>
        <book>
            <title>Starship Troopers</title>
            <year-published>1959</year-published>
        </book>
        <book>
            <title>Stranger in a Strange Land</title>
            <year-published>1961</year-published>
        </book>
    </author>
    """)

    actual = xml.serialize_to_string(processor, value)

    assert expected == actual
예제 #5
0
def test_user_object_serialize_nested():
    """Serializes a nested user object"""
    value = {
        'position': 'quarterback',
        'person': Person().set_values(name='Bob', pets=['Fluffy', 'Spots'])
    }

    processor = xml.dictionary('root', [
        xml.string('position'),
        xml.user_object('person', Person, [
            xml.string('name'),
            xml.array(xml.string('pet'), alias='pets'),
        ])
    ])

    expected = strip_xml("""
    <root>
        <position>quarterback</position>
        <person>
            <name>Bob</name>
            <pet>Fluffy</pet>
            <pet>Spots</pet>
        </person>
    </root>
    """)

    actual = xml.serialize_to_string(processor, value)

    assert expected == actual
예제 #6
0
def test_parse_dictionary_aliased():
    """Parses a dictionary value that is aliased"""
    xml_string = """
    <person>
        <name>John Doe</name>
        <demographics>
            <age>25</age>
            <gender>male</gender>
        </demographics>
    </person>
    """

    stats = xml.dictionary('demographics', [
        xml.integer('age'),
        xml.string('gender'),
    ],
                           alias='stats')

    person = xml.dictionary('person', [
        xml.string('name'),
        stats,
    ])

    expected = {
        'name': 'John Doe',
        'stats': {
            'age': 25,
            'gender': 'male',
        },
    }

    actual = xml.parse_from_string(person, xml_string)

    assert expected == actual
예제 #7
0
def test_parse_dictionary_missing():
    """Parse a missing dictionary"""
    xml_string = """
    <person>
        <name>John Doe</name>
        <demographics>
            <age>25</age>
            <gender>male</gender>
        </demographics>
    </person>
    """

    demographics = xml.dictionary('demographics', [
        xml.integer('age'),
        xml.string('gender'),
    ])

    address = xml.dictionary('address', [
        xml.string('street'),
        xml.integer('zip'),
        xml.string('state'),
    ])

    person = xml.dictionary('person', [
        xml.string('name'),
        demographics,
        address,
    ])

    with pytest.raises(xml.MissingValue):
        xml.parse_from_string(person, xml_string)
예제 #8
0
class TestSlashFromRootArray(_ProcessorTestCase):
    """Process with a slash starting from the root element"""

    xml_string = strip_xml("""
    <locations>
        <cities>
            <city name="Kansas City" state="MO" />
            <city name="Lincoln" state="NE" />
            <city name="Salt Lake City" state="UT" />
        </cities>
    </locations>
    """)

    value = [{
        'name': 'Kansas City',
        'state': 'MO'
    }, {
        'name': 'Lincoln',
        'state': 'NE'
    }, {
        'name': 'Salt Lake City',
        'state': 'UT'
    }]

    processor = xml.array(xml.dictionary('city', [
        xml.string('.', attribute='name'),
        xml.string('.', attribute='state'),
    ]),
                          nested='locations/cities',
                          alias='cities')
예제 #9
0
    def _plays_to_games(self, data):
        def after_players_hook(_, status):
            return status["name"] if "name" in status else "Unknown"

        plays_processor = xml.dictionary("plays", [
            xml.array(
                xml.dictionary('play', [
                    xml.integer(".", attribute="id", alias="playid"),
                    xml.dictionary('item', [
                        xml.string(".", attribute="name", alias="gamename"),
                        xml.integer(".", attribute="objectid", alias="gameid")
                    ],
                                   alias='game'),
                    xml.array(
                        xml.dictionary(
                            'players/player', [
                                xml.string(".",
                                           attribute="name",
                                           required=False,
                                           default="Unknown")
                            ],
                            required=False,
                            alias='players',
                            hooks=xml.Hooks(after_parse=after_players_hook)))
                ],
                               required=False,
                               alias="plays"))
        ])

        plays = xml.parse_from_string(plays_processor, data)
        plays = plays["plays"]
        return plays
예제 #10
0
def test_dictionary_serialize_nested_missing_optional():
    """Serializes nested dictionaries"""
    value = {
        'name': 'John Doe',
        'demographics': {
            'age': 27,
            'gender': 'male',
        },
    }

    processor = xml.dictionary('root', [
        xml.string('name'),
        xml.dictionary(
            'demographics',
            [xml.integer('age'), xml.string('gender')]),
        xml.dictionary('favorites', [xml.string('food'),
                                     xml.string('color')],
                       required=False)
    ])

    expected = strip_xml("""
    <root>
        <name>John Doe</name>
        <demographics>
            <age>27</age>
            <gender>male</gender>
        </demographics>
    </root>
    """)

    actual = xml.serialize_to_string(processor, value)

    assert expected == actual
예제 #11
0
def test_dictionary_serialize_nested_aliased():
    """Serializes nested aliased dictionaries"""
    value = {
        'name': 'John Doe',
        'stats': {
            'age': 27,
            'gender': 'male',
        }
    }

    processor = xml.dictionary('root', [
        xml.string('name'),
        xml.dictionary(
            'demographics',
            [xml.integer('age'), xml.string('gender')],
            alias='stats')
    ])

    expected = strip_xml("""
    <root>
        <name>John Doe</name>
        <demographics>
            <age>27</age>
            <gender>male</gender>
        </demographics>
    </root>
    """)

    actual = xml.serialize_to_string(processor, value)

    assert expected == actual
예제 #12
0
def test_attribute_serialize_multiple():
    """Serializing multiple attributes to the same element"""
    value = {
        'attribute_a': 'Hello, World',
        'attribute_b': True,
        'data': 1,
        'message': 'Hello, World'
    }

    processor = xml.dictionary('root', [
        xml.integer('data'),
        xml.string('data', attribute='attribute_a'),
        xml.boolean('data', attribute='attribute_b'),
        xml.string('message')
    ])

    expected = strip_xml("""
    <root>
        <data attribute_a="Hello, World" attribute_b="True">1</data>
        <message>Hello, World</message>
    </root>
    """)

    actual = xml.serialize_to_string(processor, value)

    assert expected == actual
예제 #13
0
 def __init__(self):
     self.processor = xml.user_object(
         "annotation", Annotation, [
             xml.user_object("size", Size, [
                 xml.integer("width"),
                 xml.integer("height"),
             ]),
             xml.array(
                 xml.user_object(
                     "object", Object, [
                         xml.string("name"),
                         xml.user_object(
                             "bndbox",
                             Box, [
                                 xml.floating_point("xmin"),
                                 xml.floating_point("ymin"),
                                 xml.floating_point("xmax"),
                                 xml.floating_point("ymax"),
                             ],
                             alias="box"
                         )
                     ]
                 ),
                 alias="objects"
             ),
             xml.string("filename")
         ]
     )
예제 #14
0
def test_parse_missing_non_required_namedtuple_issue_24():
    """Parse XML with a non-required namedtuple value."""
    Author = namedtuple('Author', [
        'name',
        'genre',
    ])
    Genre = namedtuple('Genre', [
        'name',
    ])

    processor = xml.named_tuple('author', Author, [
        xml.string('name'),
        xml.named_tuple('genre', Genre, [
            xml.string('name')
        ], required=False)
    ])

    author_xml = """
    <author>
        <name>Robert A. Heinlein</name>
    </author>
    """

    expected_value = Author(name='Robert A. Heinlein', genre=None)

    actual_value = xml.parse_from_string(processor, author_xml)

    assert expected_value == actual_value
예제 #15
0
 def update(self):
     logging.debug('ExecutorEntryBuilder')
     executor_proc = xml.user_object('PASSPORT/EXECUTOR', Executor, [
         xml.string('EXECUTORNAME',  alias='name'),
         xml.string('EXECUTORPHONE', alias='phone')
     ])
     executor = xml.parse_from_file(executor_proc, self.xml_data)
     super(ExecutorEntryBuilder, self).replace_bookmark(self.doc, 'EXECUTORNAME',  executor.name)
     super(ExecutorEntryBuilder, self).replace_bookmark(self.doc, 'EXECUTORPHONE', executor.phone)
예제 #16
0
    def _collection_to_games(self, data):
        def after_status_hook(_, status):
            return [tag for tag, value in status.items() if value == "1"]

        game_in_collection_processor = xml.dictionary("items", [
            xml.array(
                xml.dictionary('item', [
                    xml.integer(".", attribute="objectid", alias="id"),
                    xml.string("name"),
                    xml.dictionary("status", [
                        xml.string(".", attribute="fortrade"),
                        xml.string(".", attribute="own"),
                        xml.string(".", attribute="preordered"),
                        xml.string(".", attribute="prevowned"),
                        xml.string(".", attribute="want"),
                        xml.string(".", attribute="wanttobuy"),
                        xml.string(".", attribute="wanttoplay"),
                        xml.string(".", attribute="wishlist"),
                    ],
                                   alias='tags',
                                   hooks=xml.Hooks(
                                       after_parse=after_status_hook)),
                    xml.integer("numplays"),
                ],
                               required=False,
                               alias="items"), )
        ])
        collection = xml.parse_from_string(game_in_collection_processor, data)
        collection = collection["items"]
        return collection
예제 #17
0
def test_can_parse_and_serialize_frozen_attrs_class():
    """Parse and serialize a frozen attrs class."""
    processor = xml.user_object('book', _FrozenBook, [
        xml.string('title'),
        xml.string('author'),
    ])

    value = _FrozenBook(
        title='The Three Body Problem',
        author='Liu Cixin'
    )

    assert_can_roundtrip_xml_value(processor, value)
예제 #18
0
def test_can_parse_and_serialize_attrs_class_with_no_defaults():
    """Parse and serialize an attrs class."""
    processor = xml.user_object('book', _BookWithNoDefaults, [
        xml.string('title'),
        xml.string('author'),
    ])

    value = _BookWithNoDefaults(
        title='The Three Body Problem',
        author='Liu Cixin'
    )

    assert_can_roundtrip_xml_value(processor, value)
예제 #19
0
def test_parse_dictionary_nested():
    """Parse nested dictionaries"""
    xml_string = """
    <person>
        <name>John Doe</name>
        <demographics>
            <age>25</age>
            <gender>male</gender>
        </demographics>
        <address>
            <street>123 ABC Street</street>
            <zip>123456</zip>
            <state>NY</state>
        </address>
    </person>
    """

    demographics = xml.dictionary('demographics', [
        xml.integer('age'),
        xml.string('gender'),
    ])

    address = xml.dictionary('address', [
        xml.string('street'),
        xml.integer('zip'),
        xml.string('state'),
    ])

    person = xml.dictionary('person', [
        xml.string('name'),
        demographics,
        address,
    ])

    expected = {
        'name': 'John Doe',
        'demographics': {
            'age': 25,
            'gender': 'male',
        },
        'address': {
            'street': '123 ABC Street',
            'zip': 123456,
            'state': 'NY',
        },
    }

    actual = xml.parse_from_string(person, xml_string)

    assert expected == actual
예제 #20
0
 def json2cdata(input):
     author_processor = xml.dictionary('rows', [
         xml.array(xml.dictionary('row', [
             xml.string('qid'),
             xml.integer('code'),
             xml.string('answer'),
             xml.integer('sortorder'),
             xml.integer('assessment_value'),
             xml.integer('language'),
             xml.integer('scale_id'),
         ]),
                   alias='rows')
     ])
     xmlstr = xml.serialize_to_string(author_processor, input, indent='   ')
     return xmlstr
예제 #21
0
def test_named_tuple_transform():
    """Transform a named tuple value"""
    Person = namedtuple('Person', ['name', 'age'])

    xml_string = strip_xml("""
    <person>
        <name>John</name>
        <age>24</age>
    </person>
    """)

    value = {
        'name': 'John',
        'age': 24,
    }

    def _after_parse(_, tuple_value):
        return {
            'name': tuple_value.name,
            'age': tuple_value.age,
        }

    def _before_serialize(_, dict_value):
        return Person(name=dict_value['name'], age=dict_value['age'])

    processor = xml.named_tuple('person',
                                Person, [
                                    xml.string('name'),
                                    xml.integer('age'),
                                ],
                                hooks=xml.Hooks(
                                    after_parse=_after_parse,
                                    before_serialize=_before_serialize))

    _transform_test_case_run(processor, value, xml_string)
예제 #22
0
def test_parse_array_embedded_aliased():
    """Parse array embedded within its parent element"""
    xml_string = """
    <root>
        <message>Goodbye, World!</message>
        <value>765</value>
        <value>3456</value>
    </root>
    """

    values_array = xml.array(xml.integer('value'), alias='numbers')

    processor = xml.dictionary('root', [
        xml.string('message'),
        values_array,
    ])

    expected = {
        'message': 'Goodbye, World!',
        'numbers': [765, 3456],
    }

    actual = xml.parse_from_string(processor, xml_string)

    assert expected == actual
예제 #23
0
def test_parse_array_embedded():
    """Parse array embedded within its parent element"""
    xml_string = """
    <root>
        <message>Hello, World!</message>
        <value>21</value>
        <value>17</value>
        <value>90</value>
        <value>6</value>
    </root>
    """

    values_array = xml.array(xml.integer('value'))

    processor = xml.dictionary('root', [
        xml.string('message'),
        values_array,
    ])

    expected = {
        'message': 'Hello, World!',
        'value': [21, 17, 90, 6],
    }

    actual = xml.parse_from_string(processor, xml_string)

    assert expected == actual
예제 #24
0
def test_user_object_serialize_array():
    """Serializes an array of user objects"""
    value = [
        Person().set_values(name='Bob', age=33),
        Person().set_values(name='Jan', age=24),
        Person().set_values(name='Tom', age=29)
    ]

    processor = xml.array(xml.user_object(
        'person', Person,
        [xml.string('name'), xml.integer('age')]),
                          nested='people')

    expected = strip_xml("""
    <people>
        <person>
            <name>Bob</name>
            <age>33</age>
        </person>
        <person>
            <name>Jan</name>
            <age>24</age>
        </person>
        <person>
            <name>Tom</name>
            <age>29</age>
        </person>
    </people>
    """)

    actual = xml.serialize_to_string(processor, value)

    assert expected == actual
예제 #25
0
def test_parse_primitive_aliased():
    """Parses primitive values with aliases"""
    xml_string = """
    <root>
        <boolean>true</boolean>
        <float>3.14</float>
        <int>1</int>
        <string>Hello, World</string>
    </root>
    """

    processor = xml.dictionary('root', [
        xml.boolean('boolean', alias='b'),
        xml.floating_point('float', alias='f'),
        xml.integer('int', alias='i'),
        xml.string('string', alias='s'),
    ])

    expected = {
        'b': True,
        'f': 3.14,
        'i': 1,
        's': 'Hello, World',
    }

    actual = xml.parse_from_string(processor, xml_string)

    assert expected == actual
예제 #26
0
def test_primitive_default_present():
    """Parses primitive values with defaults specified"""
    xml_string = """
    <root>
        <boolean>false</boolean>
        <float>3.14</float>
        <int>1</int>
        <string>Hello, World</string>
    </root>
    """

    processor = xml.dictionary('root', [
        xml.boolean('boolean', required=False, default=True),
        xml.floating_point('float', required=False, default=0.0),
        xml.integer('int', required=False, default=0),
        xml.string('string', required=False, default=''),
    ])

    expected = {
        'boolean': False,
        'float': 3.14,
        'int': 1,
        'string': 'Hello, World',
    }

    actual = xml.parse_from_string(processor, xml_string)

    assert expected == actual
예제 #27
0
    def test_non_root_dictionary(self):
        """Apply a transform to a non-root dictionary"""
        xml_string = strip_xml("""
            <results>
                <name>Dataset 1</name>
                <data>
                    <a>17</a>
                    <b>42</b>
                    <c>23</c>
                </data>
            </results>
        """)

        value = {
            'name': 'Dataset 1',
            'data': [
                ('a', 17),
                ('b', 42),
                ('c', 23),
            ],
        }

        processor = xml.dictionary('results', [
            xml.string('name'),
            self._dict_processor,
        ])

        _transform_test_case_run(processor, value, xml_string)
예제 #28
0
    def test_user_object_non_root(self):
        """Custom error message for user object values."""
        processor = xml.dictionary('data', [
            xml.user_object('user',
                            _UserClass, [
                                xml.string('name'),
                                xml.integer('age'),
                            ],
                            hooks=self._hooks)
        ])

        xml_string = strip_xml("""
        <data>
            <user>
                <name>Bob</name>
                <age>24</age>
            </user>
        </data>
        """)

        value = {'user': _UserClass(name='Bob', age=24)}

        location = 'data/user'

        self._assert_error_message(processor, value, xml_string, location)
예제 #29
0
    def test_dictionary_non_root(self):
        """Custom error message for dictionary values."""
        processor = xml.dictionary('data', [
            xml.dictionary('user', [
                xml.string('name'),
                xml.integer('age'),
            ],
                           hooks=self._hooks)
        ])

        xml_string = strip_xml("""
        <data>
            <user>
                <name>Bob</name>
                <age>24</age>
            </user>
        </data>
        """)

        value = {
            'user': {
                'name': 'Bob',
                'age': 24,
            }
        }

        location = 'data/user'

        self._assert_error_message(processor, value, xml_string, location)
예제 #30
0
    def test_non_root_array(self):
        """Transform array values for non-root arrays"""
        xml_string = strip_xml("""
            <data>
                <name>Dataset 1</name>
                <value key="a">17</value>
                <value key="b">42</value>
                <value key="c">37</value>
            </data>
        """)

        value = {
            'name': 'Dataset 1',
            'values': OrderedDict([
                ('a', 17),
                ('b', 42),
                ('c', 37),
            ]),
        }

        processor = xml.dictionary('data', [
            xml.string('name'),
            xml.array(self._item_processor, alias='values', hooks=self._hooks)
        ])

        _transform_test_case_run(processor, value, xml_string)