def test_attribute(self, value, required, is_content, ns_prefix, ns_uri): attr = ItemElementAttribute(value=value, required=required, is_content=is_content, ns_prefix=ns_prefix, ns_uri=ns_uri) six.assertRegex( self, repr(attr), r'^ItemElementAttribute\(value={}, serializer=[^,]+, required={}, is_content={}, ns_prefix={}, ns_uri={}\)$' .format(re.escape(repr(value)), re.escape(repr(required)), re.escape(repr(is_content)), re.escape(repr(ns_prefix or '')), re.escape(repr(ns_uri or ''))))
class NonStandardElement(ItemElement): first_attribute = ItemElementAttribute(required=True, is_content=True) second_attribute = ItemElementAttribute(required=True)
class Element1(ItemElement): attr10 = ItemElementAttribute(ns_prefix="prefix10", ns_uri="id10")
class Element0(ItemElement): attr00 = ItemElementAttribute(is_content=True)
class Element2(ItemElement): attr21 = ItemElementAttribute(ns_prefix="prefix21", ns_uri="id01") pseudo_prefix22__attr22 = ItemElementAttribute( ns_prefix="prefix22", ns_uri="id22")
class Element1(ItemElement): prefix11__attr11 = ItemElementAttribute(ns_uri="id11") prefix12__attr12 = ItemElementAttribute(ns_prefix="prefix12", ns_uri="id12")
class Element0(ItemElement): attr01 = ItemElementAttribute(ns_prefix="prefix01", ns_uri="id01")
def test_content_attr_namespace(self, ns_kwargs): with six.assertRaisesRegex(self, ValueError, "Content cannot have namespace"): ItemElementAttribute(is_content=True, **ns_kwargs)
class TestRepr(RssTestCase): @parameterized.expand( (value, required, is_content, ns_prefix, ns_uri) for value in values for required in (True, False) for is_content in (True, False) for ns_prefix in (None, '', 'prefix') for ns_uri in (('id', ) if ns_prefix else (None, '', 'id')) if not is_content or not ns_uri) def test_attribute(self, value, required, is_content, ns_prefix, ns_uri): attr = ItemElementAttribute(value=value, required=required, is_content=is_content, ns_prefix=ns_prefix, ns_uri=ns_uri) six.assertRegex( self, repr(attr), r'^ItemElementAttribute\(value={}, serializer=[^,]+, required={}, is_content={}, ns_prefix={}, ns_uri={}\)$' .format(re.escape(repr(value)), re.escape(repr(required)), re.escape(repr(is_content)), re.escape(repr(ns_prefix or '')), re.escape(repr(ns_uri or '')))) @parameterized.expand( (attr_name, attr, elem_kwargs) for attr_name, attr in chain([( "attr0", ItemElementAttribute())], ns_attrs.items()) for elem_kwargs in chain([{}], ns_elem_names.values())) def test_element_with_single_attr(self, attr_name, attr, elem_kwargs): elem_cls_name = "Element0" elem_cls = type(elem_cls_name, (ItemElement, ), {attr_name: attr}) elem = elem_cls(**elem_kwargs) full_elem_kwargs = {"ns_prefix": "", "ns_uri": ""} full_elem_kwargs.update(elem_kwargs) expected_kwargs_reprs = [ ", {}={!r}".format(k, v) for k, v in full_elem_kwargs.items() ] elem_reprs = [ "{}({}={!r}{})".format(elem_cls_name, attr_name, attr, "".join(expected_kwargs_repr)) for expected_kwargs_repr in permutations(expected_kwargs_reprs) ] assert any(repr(elem) == elem_repr for elem_repr in elem_reprs),\ "{!r}\nis not equal to one of:\n{}".format(elem, "\n".join(elem_reprs)) @parameterized.expand( product( combinations( chain([("attr0", ItemElementAttribute())], ns_attrs.items()), 3), chain([{}], ns_elem_names.values()))) def test_element_with_multiple_attrs(self, attrs, elem_kwargs): attrs = dict(attrs) elem_cls_name = "Element0" elem_cls = type(elem_cls_name, (ItemElement, ), deepcopy(attrs)) elem = elem_cls(**elem_kwargs) full_elem_kwargs = {"ns_prefix": "", "ns_uri": ""} full_elem_kwargs.update(elem_kwargs) for attr_name, attr in attrs.items(): if not attr.ns_prefix and "__" in attr_name: attr.ns_prefix = attr_name.split("__")[0] expected_kwargs_reprs = [ ", {}={!r}".format(k, v) for k, v in full_elem_kwargs.items() ] attrs_reprs = [ "{}={!r}".format(name, attr) for name, attr in attrs.items() ] elem_reprs = [ "{}({}{})".format(elem_cls_name, ", ".join(attrs_repr), "".join(expected_kwargs_repr)) for attrs_repr in permutations(attrs_reprs) for expected_kwargs_repr in permutations(expected_kwargs_reprs) ] assert any(repr(elem) == elem_repr for elem_repr in elem_reprs),\ "{!r}\nis not equal to one of:\n{}".format(elem, "\n".join(elem_reprs)) @parameterized.expand( (attr_name, attr, elem_name, elem_kwargs) for attr_name, attr in chain([( "attr0", ItemElementAttribute())], ns_attrs.items()) for elem_name, elem_kwargs in chain([('elem0', {})], ns_elem_names.items())) def test_item_with_single_elem(self, attr_name, attr, elem_name, elem_kwargs): elem_cls_name = "Element0" item_cls_name = "Item0" elem_cls = type(elem_cls_name, (ItemElement, ), {attr_name: attr}) elem = elem_cls(**elem_kwargs) item_cls = type(item_cls_name, (RssItem, ), {elem_name: elem}) item = item_cls() repr(item) if sys.version_info >= (3, 7): # insertion ordered dict default_elems_repr = ("{}={!r}".format( name, value) for name, value in chain(RssItem().elements.items(), [( elem_name, elem)])) assert repr(item) == "{}({})".format(item_cls_name, ", ".join(default_elems_repr)) @parameterized.expand( product( combinations( chain([("attr0", ItemElementAttribute())], ns_attrs.items()), 3), combinations(chain([("elem0", {})], ns_elem_names.items()), 3))) def test_item_with_multiple_elems(self, attrs, elems_descr): elems_names, elems_kwargs = zip(*elems_descr) item_cls_name = "Item0" elem_clses = [ type("Element{}".format(n), (ItemElement, ), dict(attrs)) for n in range(len(elems_descr)) ] elem_instances = [ elem_cls(**elems_kwargs[n]) for n, elem_cls in enumerate(elem_clses) ] item_cls = type(item_cls_name, (RssItem, ), dict(zip(elems_names, elem_instances))) item = item_cls() repr(item) if sys.version_info >= (3, 7): # insertion ordered dict elems_reprs = ( "{}={}".format(elem_name, elem) for elem_name, elem in chain(RssItem().elements.items(), zip(elems_names, elem_instances))) item_repr = "{}({})".format(item_cls_name, ", ".join(elems_reprs)) assert repr(item) == item_repr
class Element0(ItemElement): attr1 = ItemElementAttribute(is_content=True) attr2 = ItemElementAttribute(is_content=False) attr3 = ItemElementAttribute(is_content=True)
from itertools import chain, product, combinations, permutations import re from copy import deepcopy import six import sys from tests.utils import RssTestCase, get_dict_attr from scrapy_rss.items import RssItem from scrapy_rss.elements import * from scrapy_rss.meta import ItemElementAttribute, ItemElement, MultipleElements from scrapy_rss.exceptions import InvalidElementValueError ns_attrs = { 'attr1': ItemElementAttribute(ns_prefix='prefix1', ns_uri='id1'), 'prefix2__attr2': ItemElementAttribute(ns_uri='id2'), 'prefix3__attr3': ItemElementAttribute(ns_prefix='prefix3', ns_uri='id3'), 'pseudo_prefix4__attr4': ItemElementAttribute(ns_prefix='prefix4', ns_uri='id4') } ns_elem_names = { 'elem1': { 'ns_prefix': 'el_prefix1', 'ns_uri': 'el_id1' }, 'el_prefix2__elem2': { 'ns_uri': 'el_id2'
class NSElement4(ItemElement): attr41 = ItemElementAttribute() prefix42__attr41 = ItemElementAttribute(ns_uri="id42")
class NSElement3(ItemElement): attr31 = ItemElementAttribute(is_content=True) attr32 = ItemElementAttribute(ns_prefix="prefixa", ns_uri="id32")
class NSElement2(ItemElement): attr21 = ItemElementAttribute(is_content=True) pseudo_prefix22__attr22 = ItemElementAttribute( ns_prefix="prefix22", ns_uri="id22")