def test_get_read_collection_path(self): path = get_read_collection_path(get_collection_class(IMyEntity), CsvMime, directory=self._data_dir) self.assert_false(path is None) tmp_dir = tempfile.mkdtemp() tmp_path = get_read_collection_path(get_collection_class(IMyEntity), CsvMime, directory=tmp_dir) self.assert_true(tmp_path is None)
def test_load_from_invalid_file(self): coll_cls = get_collection_class(IMyEntity) with self.assert_raises(ValueError) as cm: dummy = \ load_collection_from_file(coll_cls, 'my-entity-collection.foo') exc_msg = 'Could not infer MIME type' self.assert_true(cm.exception.message.startswith(exc_msg))
def test_add_resource_with_collection_title(self, simple_config, title): simple_config.add_resource(IFoo, FooMember, FooEntity, expose=False, collection_title=title) assert get_collection_class(IFoo).title == title
def __get_q_tag(self, attr): # FIXME: We should cache the namespace for each attribute. if not attr.namespace is None: q_tag = '{%s}%s' % (attr.namespace, attr.repr_name) else: if attr.kind == RESOURCE_ATTRIBUTE_KINDS.TERMINAL: xml_ns = \ self.mapping.configuration.get_option(XML_NAMESPACE_OPTION) else: if attr.kind == RESOURCE_ATTRIBUTE_KINDS.MEMBER: attr_type = get_member_class(attr.value_type) elif attr.kind == RESOURCE_ATTRIBUTE_KINDS.COLLECTION: attr_type = get_collection_class(attr.value_type) mp = self.mapping.mapping_registry.find_mapping(attr_type) if not mp is None: xml_ns = mp.configuration.get_option(XML_NAMESPACE_OPTION) else: # pragma: no cover # Not mapped. # FIXME This case is neither tested nor documented. xml_ns = None if not xml_ns is None: q_tag = '{%s}%s' % (xml_ns, attr.repr_name) else: q_tag = attr.repr_name return q_tag
def test_delete_member(self, view_app_creator, view_collection): # pylint:disable=W0621 assert len(view_collection) == 2 res = view_app_creator.delete("%s/0" % self.path, content_type=CsvMime.mime_type_string, status=200) assert not res is None assert len(view_collection) == 1 # Second delete triggers 404. view_app_creator.delete("%s/0" % self.path, content_type=CsvMime.mime_type_string, status=404) coll_cls = get_collection_class(IMyEntity) old_remove = coll_cls.__dict__.get('remove') def remove_with_exception(self): # pylint: disable=W0613 raise RuntimeError() coll_cls.remove = remove_with_exception try: view_app_creator.delete("%s/1" % self.path, content_type=CsvMime.mime_type_string, status=500) finally: if not old_remove is None: coll_cls.remove = old_remove
def set_up(self): FunctionalTestCase.set_up(self) self.config.load_zcml( 'everest.tests.complete_app:configure_no_rdb.zcml') self.config.add_view(context=get_collection_class(IMyEntity), view=ExceptionPostCollectionView, request_method='POST')
def test_add_resource_with_root_name(self, simple_config, root_name): simple_config.add_resource(IFoo, FooMember, FooEntity, expose=True, collection_root_name=root_name) assert get_collection_class(IFoo).root_name == root_name
def __get_q_tag(self, attr): # FIXME: We should cache the namespace for each attribute. if not attr.namespace is None: q_tag = '{%s}%s' % (attr.namespace, attr.repr_name) else: if attr.kind == RESOURCE_ATTRIBUTE_KINDS.TERMINAL: xml_ns = \ self.mapping.configuration.get_option(XML_NAMESPACE_OPTION) else: if attr.kind == RESOURCE_ATTRIBUTE_KINDS.MEMBER: attr_type = get_member_class(attr.value_type) elif attr.kind == RESOURCE_ATTRIBUTE_KINDS.COLLECTION: attr_type = get_collection_class(attr.value_type) mp = self.mapping.mapping_registry.find_mapping(attr_type) if not mp is None: xml_ns = mp.configuration.get_option(XML_NAMESPACE_OPTION) else: # pragma: no cover # Not mapped. # FIXME This case is neither tested nor documented. xml_ns = None if not xml_ns is None: q_tag = '{%s}%s' % (xml_ns, attr.repr_name) else: q_tag = '{}%s' % attr.repr_name return q_tag
def after(self): # Register resources eagerly so the various adapters and utilities are # available for other directives. discriminator = ('resource', self.interface) reg = get_current_registry() config = Configurator(reg, package=self.context.package) config.add_resource(self.interface, self.member, self.entity, collection=self.collection, collection_root_name=self.collection_root_name, collection_title=self.collection_title, repository=self.repository, expose=self.expose, _info=self.context.info) for key, value in iteritems_(self.representers): cnt_type, rc_kind = key opts, mp_opts = value if rc_kind == RESOURCE_KINDS.MEMBER: rc = get_member_class(self.interface) elif rc_kind == RESOURCE_KINDS.COLLECTION: rc = get_collection_class(self.interface) else: # None rc = self.interface discriminator = ('resource_representer', rc, cnt_type, rc_kind) self.action(discriminator=discriminator, # pylint: disable=E1101 callable=config.add_resource_representer, args=(rc, cnt_type), kw=dict(options=opts, attribute_options=mp_opts, _info=self.context.info), )
def test_invalid_xml(self): coll = object.__new__(get_collection_class(IMyEntity)) rpr = as_representer(coll, XmlMime) with self.assert_raises(SyntaxError) as cm: rpr.from_string('<?xml version="1.0" encoding="UTF-8"?><murks/>') exc_msg = 'Could not parse XML document for schema' self.assert_not_equal(cm.exception.message.find(exc_msg), -1)
def set_up(self): FunctionalTestCase.set_up(self) self.config.load_zcml( 'everest.tests.complete_app:configure_no_rdb.zcml') self.config.add_view(context=get_collection_class(IMyEntity), view=ExceptionPostCollectionView, request_method=RequestMethods.POST)
def _test_load(self, load_func, fn_func, is_into): member = _make_test_entity_member() tmp_dir = tempfile.mkdtemp() try: dump_resource_to_files(member, directory=tmp_dir) file_names = glob.glob1(tmp_dir, "*.csv") self.assert_equal(len(file_names), 4) for ifc in [IMyEntityParent, IMyEntity, IMyEntityChild, IMyEntityGrandchild]: coll_cls = get_collection_class(ifc) root_coll = get_root_collection(ifc) file_name = get_collection_filename(coll_cls) file_path = fn_func(os.path.join(tmp_dir, file_name)) if not is_into: coll = load_func(coll_cls, file_path) self.assert_equal(len(coll), 1) for mb in coll: root_coll.add(mb) else: load_func(root_coll, file_path) self.assert_equal(len(root_coll), 1) finally: shutil.rmtree(tmp_dir)
def test_mapping_polymorhpic(self): # pylint: disable=W0232 class IMyDerivedEntity(IMyEntity): pass class MyDerivedEntity(MyEntity): pass class MyDerivedEntityMember(MyEntityMember): pass class MyDerivedEntityCollection(get_collection_class(IMyEntity)): pass # pylint: enable=W0232 self.config.add_resource(IMyDerivedEntity, MyDerivedEntityMember, MyDerivedEntity, MyDerivedEntityCollection, expose=False) self.config.add_resource_representer( IMyDerivedEntity, XmlMime, attribute_options= {('parent',):dict(ignore=True)}) mp_reg = get_mapping_registry(XmlMime) mp = mp_reg.find_or_create_mapping(get_collection_class(IMyEntity)) for rc in (MyDerivedEntityMember, MyDerivedEntityCollection): attr = None for attr in mp.attribute_iterator(rc): if attr.name == 'parent': break self.assert_is_not_none(attr) self.assert_equal(attr.ignore_on_write, True) self.assert_equal(attr.ignore_on_read, True)
def set_up(self): _PlantScribeResourcesBaseTestCase.set_up(self) # data_dir = os.path.join(os.path.dirname(__file__), 'data') for coll_name, coll_cls in \ (('customer', get_collection_class(ICustomer)), ('project', get_collection_class(IProject)), ('site', get_collection_class(ISite)), ('species', get_collection_class(ISpecies)), ('incidence', get_collection_class(IIncidence)), ): url = 'file://%s' % os.path.join(data_dir, '%s-collection.csv' % coll_name) coll = get_root_collection(coll_cls) load_into_collection_from_url(coll, url, content_type=CsvMime)
def after(self): # Register resources eagerly so the various adapters and utilities are # available for other directives. discriminator = ('resource', self.interface) reg = get_current_registry() config = Configurator(reg, package=self.context.package) config.add_resource(self.interface, self.member, self.entity, collection=self.collection, collection_root_name=self.collection_root_name, collection_title=self.collection_title, repository=self.repository, expose=self.expose, _info=self.context.info) for key, value in self.representers.iteritems(): cnt_type, rc_kind = key opts, mp_opts = value if rc_kind == RESOURCE_KINDS.member: rc = get_member_class(self.interface) elif rc_kind == RESOURCE_KINDS.collection: rc = get_collection_class(self.interface) else: # None rc = self.interface discriminator = ('resource_representer', rc, cnt_type, rc_kind) self.action( discriminator=discriminator, # pylint: disable=E1101 callable=config.add_resource_representer, args=(rc, cnt_type), kw=dict(options=opts, attribute_options=mp_opts, _info=self.context.info), )
def wrn_with_exc_vw_app_creator(app_creator): app_creator.config.load_zcml( 'everest.tests.complete_app:configure_no_rdb.zcml') app_creator.config.add_view(context=get_collection_class(IMyEntity), view=ExceptionPostCollectionView, request_method=RequestMethods.POST) yield app_creator
def pred_view_app_creator(app_creator): app_creator.config.add_renderer('csv', RendererFactory) app_creator.config.add_view(context=get_collection_class(IMyEntity), view=GetCollectionView, renderer='csv', request_method=RequestMethods.GET, custom_predicates=(accept_csv_only, )) yield app_creator
def test_add_resource_with_collection_title(self): title = 'myfoos' self._config.add_resource(IFoo, FooMember, FooEntity, expose=False, collection_title=title) self.assert_equal(get_collection_class(IFoo).title, title)
def set_up(self): _PlantScribeResourcesBaseTestCase.set_up(self) # repo_mgr = get_repository_manager() repo = repo_mgr.get(REPOSITORY_TYPES.RDB) data_dir = os.path.join(os.path.dirname(__file__), 'data') for coll_name, coll_cls in \ (('customer', get_collection_class(ICustomer)), ('project', get_collection_class(IProject)), ('site', get_collection_class(ISite)), ('species', get_collection_class(ISpecies)), ('incidence', get_collection_class(IIncidence)), ): url = 'file://%s' % os.path.join(data_dir, '%s-collection.csv' % coll_name) repo.load_representation(coll_cls, url, content_type=CsvMime, resolve_urls=True)
def pred_view_app_creator(app_creator): app_creator.config.add_renderer('csv', RendererFactory) app_creator.config.add_view(context=get_collection_class(IMyEntity), view=GetCollectionView, renderer='csv', request_method=RequestMethods.GET, custom_predicates=(accept_csv_only,)) yield app_creator
def test_add_resource_with_root_name(self): root_name = 'myfoos' self._config.add_resource(IFoo, FooMember, FooEntity, expose=True, collection_root_name=root_name) self.assert_equal(get_collection_class(IFoo).root_name, root_name)
def set_up(self): FunctionalTestCase.set_up(self) self.config.load_zcml('everest.tests.complete_app:configure_rpr.zcml') self.config.add_renderer('csv', RendererFactory) self.config.add_view(context=get_collection_class(IMyEntity), view=GetCollectionView, renderer='csv', request_method=RequestMethods.GET, custom_predicates=(accept_csv_only,))
def test_mapping_duplicate_prefix(self): mp_reg = get_mapping_registry(XmlMime) mp = mp_reg.find_or_create_mapping(get_collection_class(IMyEntity)) ns = 'foo' mp.configuration.set_option(XML_NAMESPACE_OPTION, ns) with self.assert_raises(ValueError) as cm: mp.mapping_registry.set_mapping(mp) exc_msg = 'is already registered for namespace' self.assert_not_equal(cm.exception.message.find(exc_msg), -1)
def _create_link_data_element(self, attribute, member_node): if attribute.kind == RESOURCE_ATTRIBUTE_KINDS.MEMBER: kind = RESOURCE_KINDS.MEMBER rc_cls = get_member_class(attribute.value_type) else: kind = RESOURCE_KINDS.COLLECTION rc_cls = get_collection_class(attribute.value_type) return self._mapping.create_linked_data_element( member_node, kind, relation=rc_cls.relation, title=rc_cls.title)
def set_up(self): FunctionalTestCase.set_up(self) self.config.load_zcml('everest.tests.complete_app:configure_rpr.zcml') self.config.add_renderer('csv', RendererFactory) self.config.add_view(context=get_collection_class(IMyEntity), view=GetCollectionView, renderer='csv', request_method='GET', custom_predicates=(accept_csv_only,))
def test_mapping_duplicate_tag(self): mp_reg = get_mapping_registry(XmlMime) mp = mp_reg.find_or_create_mapping(get_collection_class(IMyEntity)) mb_mp = mp_reg.find_or_create_mapping(MyEntityMember) mb_tag = mb_mp.configuration.get_option(XML_TAG_OPTION) mp.configuration.set_option(XML_TAG_OPTION, mb_tag) mp.mapping_registry.set_mapping(mp) with self.assert_raises(ValueError) as cm: getattr(mp.mapping_registry, 'parsing_lookup') self.assert_true(str(cm.exception).startswith('Duplicate tag'))
def __collect(self, resource): ent_cls = get_entity_class(resource) coll_cls = get_collection_class(resource) cache = EntityCacheMap() agg = StagingAggregate(ent_cls, cache) coll = coll_cls.create_from_aggregate(agg) coll.add(resource) return dict([(get_member_class(ent_cls), coll.get_root_collection(ent_cls)) for ent_cls in cache.keys()])
def test_mapping_duplicate_tag(self): mp_reg = get_mapping_registry(XmlMime) mp = mp_reg.find_or_create_mapping(get_collection_class(IMyEntity)) mb_mp = mp_reg.find_or_create_mapping(MyEntityMember) mb_tag = mb_mp.configuration.get_option(XML_TAG_OPTION) mp.configuration.set_option(XML_TAG_OPTION, mb_tag) mp.mapping_registry.set_mapping(mp) with self.assert_raises(ValueError) as cm: getattr(mp.mapping_registry, 'parsing_lookup') exc_msg = 'Duplicate tag "%s" ' % mb_tag self.assert_not_equal(cm.exception.message.find(exc_msg), -1)
def get_root_collection(self, rc): """ Returns a root collection for the given resource. The root collection is created using a root aggregate fetched from the same repository that was used to create the root aggregate for this collection. """ root_agg = self.__aggregate.get_root_aggregate(rc) coll_cls = get_collection_class(rc) return coll_cls.create_from_aggregate(root_agg)
def test_load_from_zipfile_invalid_extension(self): strm = StringIO('w') zipf = zipfile.ZipFile(strm, 'w') coll_name = get_collection_name(get_collection_class(IMyEntity)) zipf.writestr('%s.foo' % coll_name, '') zipf.close() colls = [get_root_collection(IMyEntity)] with self.assert_raises(ValueError) as cm: dummy = load_into_collections_from_zipfile(colls, strm) exc_msg = 'Could not infer MIME type' self.assert_true(cm.exception.message.startswith(exc_msg))
def test_mapping_reset_lookup(self): mp_reg = get_mapping_registry(XmlMime) old_lookup = mp_reg.parsing_lookup mp = mp_reg.find_or_create_mapping(get_collection_class(IMyEntity)) new_tag = 'my-new-entities' mp.configuration.set_option(XML_TAG_OPTION, new_tag) mp_reg.set_mapping(mp) new_lookup = mp_reg.parsing_lookup self.assert_false(old_lookup is new_lookup) ns = mp.configuration.get_option(XML_NAMESPACE_OPTION) cls_map = new_lookup.get_namespace(ns) self.assert_equal(cls_map[new_tag], mp.data_element_class)
def __process_link(self, link, attr): if not self.__is_link(link): raise ValueError('Value for nested attribute "%s" ' 'is not a link.' % attr.repr_name) if attr.kind == RESOURCE_ATTRIBUTE_KINDS.MEMBER: kind = RESOURCE_KINDS.MEMBER rc_cls = get_member_class(attr.value_type) else: kind = RESOURCE_KINDS.COLLECTION rc_cls = get_collection_class(attr.value_type) return self._mapping.create_linked_data_element( link, kind, relation=rc_cls.relation, title=rc_cls.title)
def create_staging_collection(resource): """ Helper function to create a staging collection for the given registered resource. :param resource: registered resource :type resource: class implementing or instance providing or subclass of a registered resource interface. """ ent_cls = get_entity_class(resource) coll_cls = get_collection_class(resource) agg = StagingAggregate(ent_cls) return coll_cls.create_from_aggregate(agg)
def __load_entities(self, entity_class): coll_cls = get_collection_class(entity_class) fn = get_read_collection_path(coll_cls, self._config['content_type'], directory=self._config['directory']) if not fn is None: url = 'file://%s' % fn coll = load_collection_from_url(coll_cls, url, content_type= self._config['content_type']) ents = [mb.get_entity() for mb in coll] else: ents = [] return ents
def _data_callback(cls, value, options): # Set the default for the report directory. if options.report_directory is None: options.report_directory = os.path.dirname(value) coll_cls = get_collection_class(cls.registration_resource) rpr = as_representer(object.__new__(coll_cls), JsonMime) reg_items = rpr.from_stream(open(value, 'rU')) # FIXME: This should be treated properly in everest. if IMemberResource in provided_by(reg_items): ents = [reg_items.get_entity()] else: ents = [rc.get_entity() for rc in reg_items] return ents
def get_collection(self, resource): if not self.__is_initialized: raise RuntimeError('Repository needs to be initialized.') ent_cls = get_entity_class(resource) root_coll = self.__cache.get(ent_cls) if root_coll is None: # Create a new root aggregate. root_agg = self.__agg_cls.create(ent_cls, self.session_factory, self) # Create a new root collection. coll_cls = get_collection_class(resource) root_coll = coll_cls.create_from_aggregate(root_agg) self.__cache[ent_cls] = root_coll return root_coll.clone()
def __process_link(self, link, attr): if not self.__is_link(link): raise ValueError('Value for nested attribute "%s" ' 'is not a link.' % attr.repr_name) if attr.kind == RESOURCE_ATTRIBUTE_KINDS.MEMBER: kind = RESOURCE_KINDS.MEMBER rc_cls = get_member_class(attr.value_type) else: kind = RESOURCE_KINDS.COLLECTION rc_cls = get_collection_class(attr.value_type) return self._mapping.create_linked_data_element(link, kind, relation= rc_cls.relation, title=rc_cls.title)
def __dump_entities(self, entity_class): cache = self._get_cache(entity_class) coll_cls = get_collection_class(entity_class) mb_cls = get_member_class(entity_class) fn = get_write_collection_path(coll_cls, self._config['content_type'], directory=self._config['directory']) # Wrap the entities in a temporary collection. coll = create_staging_collection(coll_cls) for ent in cache.iterator(): coll.add(mb_cls.create_from_entity(ent)) # Open stream for writing and dump the collection. stream = file(fn, 'w') with stream: dump_resource(coll, stream, content_type=self._config['content_type'])
def __collect_mapped_attributes(self, mapped_class, key): if isinstance(key, MappedAttributeKey): names = key.names else: names = key collected_mp_attrs = OrderedDict() is_mapped_cls = mapped_class is self.__mapped_cls if len(names) == 0 and is_mapped_cls: # Bootstrapping: fetch resource attributes and create new # mapped attributes. rc_attrs = get_resource_class_attributes(self.__mapped_cls) for rc_attr in itervalues_(rc_attrs): attr_key = names + (rc_attr.resource_attr,) attr_mp_opts = \ self.__configurations[-1].get_attribute_options(attr_key) new_mp_attr = MappedAttribute(rc_attr, options=attr_mp_opts) collected_mp_attrs[new_mp_attr.resource_attr] = new_mp_attr else: # Indirect access - fetch mapped attributes from some other # class' mapping and clone. if is_mapped_cls: mp = self elif len(names) == 0 and self.__is_collection_mapping: if provides_member_resource(mapped_class): # Mapping a polymorphic member class. mapped_coll_cls = get_collection_class(mapped_class) else: # Mapping a derived collection class. mapped_coll_cls = mapped_class mp = self.__mp_reg.find_or_create_mapping(mapped_coll_cls) else: mp = self.__mp_reg.find_or_create_mapping(mapped_class) mp_attrs = mp.get_attribute_map() for mp_attr in itervalues_(mp_attrs): attr_key = names + (mp_attr.name,) attr_mp_opts = \ dict(((k, v) for (k, v) in iteritems_(self.__configurations[-1] .get_attribute_options(attr_key)) if not v is None)) clnd_mp_attr = mp_attr.clone(options=attr_mp_opts) collected_mp_attrs[mp_attr.resource_attr] = clnd_mp_attr return collected_mp_attrs
def __collect_mapped_attributes(self, mapped_class, key): if isinstance(key, MappedAttributeKey): names = key.names else: names = key collected_mp_attrs = OrderedDict() is_mapped_cls = mapped_class is self.__mapped_cls if len(names) == 0 and is_mapped_cls: # Bootstrapping: fetch resource attributes and create new # mapped attributes. rc_attrs = get_resource_class_attributes(self.__mapped_cls) for rc_attr in itervalues_(rc_attrs): attr_key = names + (rc_attr.resource_attr,) attr_mp_opts = \ self.__configurations[-1].get_attribute_options(attr_key) new_mp_attr = MappedAttribute(rc_attr, options=attr_mp_opts) collected_mp_attrs[new_mp_attr.resource_attr] = new_mp_attr else: # Indirect access - fetch mapped attributes from some other # class' mapping and clone. if is_mapped_cls: mp = self elif len(names) == 0 and self.__is_collection_mapping: if provides_member_resource(mapped_class): # Mapping a polymorphic member class. mapped_coll_cls = get_collection_class(mapped_class) else: # Mapping a derived collection class. mapped_coll_cls = mapped_class mp = self.__mp_reg.find_or_create_mapping(mapped_coll_cls) else: mp = self.__mp_reg.find_or_create_mapping(mapped_class) mp_attrs = mp.get_attribute_map() for mp_attr in itervalues_(mp_attrs): attr_key = names + (mp_attr.name,) attr_mp_opts = \ dict(((k, v) for (k, v) in iteritems_(self.__configurations[-1] .get_attribute_options(attr_key)) if not v is None)) clnd_mp_attr = mp_attr.clone(options=attr_mp_opts) collected_mp_attrs[mp_attr.name] = clnd_mp_attr return collected_mp_attrs
def get_collection(self, resource): """ Get a clone of the root collection for the given registered resource. :param resource: Registered resource. :raises RuntimeError: If the repository has not been initialized yet. """ if not self.__is_initialized: raise RuntimeError('Repository needs to be initialized.') ent_cls = get_entity_class(resource) root_coll = self.__cache.get(ent_cls) if root_coll is None: coll_cls = get_collection_class(resource) agg = self.__agg_cls.create(ent_cls, self.session_factory) root_coll = coll_cls.create_from_aggregate(agg) self.__cache[ent_cls] = root_coll clone = root_coll.clone() clone.__repository__ = self return clone
def __get_q_tag(self, attr): if not attr.namespace is None: q_tag = '{%s}%s' % (attr.namespace, attr.repr_name) else: if attr.kind == ResourceAttributeKinds.TERMINAL: xml_ns = \ self.mapping.configuration.get_option(XML_NAMESPACE_OPTION) else: if attr.kind == ResourceAttributeKinds.MEMBER: attr_type = get_member_class(attr.value_type) elif attr.kind == ResourceAttributeKinds.COLLECTION: attr_type = get_collection_class(attr.value_type) mp = self.mapping.mapping_registry.find_mapping(attr_type) if not mp is None: xml_ns = mp.configuration.get_option(XML_NAMESPACE_OPTION) else: # Not mapped. xml_ns = None if not xml_ns is None: q_tag = '{%s}%s' % (xml_ns, attr.repr_name) else: q_tag = attr.repr_name return q_tag