def get_errors(self): """ Report why the element has not been found or booking its id failed """ if (self.element_found() or (self._book_errors is not None and not self._book_errors)): raise AssertionError( "Improper usage: cannot report errors when there are none") element = get_root( self._context_element).find(f'.//*[@id="{self._element_id}"]') if element is not None: if element.tag in self._tag_list: return [ reports.object_with_id_in_unexpected_context( element.tag, self._element_id, self._context_element.tag, self._context_element.attrib.get("id", "")) ] return [ reports.id_belongs_to_unexpected_type( self._element_id, expected_types=self._expected_types, current_type=element.tag) ] if self._book_errors is None: return [ reports.id_not_found( self._element_id, self._expected_types, self._context_element.tag, self._context_element.attrib.get("id", "")) ] return self._book_errors
def find_element_by_tag_and_id( tag, context_element, element_id, none_if_id_unused=False, id_description="" ): """ Return element with given tag and element_id under context_element. When element does not exists raises LibraryError or return None if specified in none_if_id_unused. etree.Element(Tree) context_element is part of tree for element scan string|list tag is expected tag (or list of tags) of search element string element_id is id of search element bool none_if_id_unused is flag, when is True and element with element_id does not exists function returns None string id_description optional description for id """ tag_list = [tag] if is_string(tag) else tag element_list = context_element.xpath( './/*[({0}) and @id="{1}"]'.format( " or ".join(["self::{0}".format(one_tag) for one_tag in tag_list]), element_id ) ) if element_list: return element_list[0] element = get_root(context_element).find( './/*[@id="{0}"]'.format(element_id) ) if element is not None: raise LibraryError( reports.id_belongs_to_unexpected_type( element_id, expected_types=tag_list, current_type=element.tag ) if element.tag not in tag_list else reports.object_with_id_in_unexpected_context( element.tag, element_id, context_element.tag, context_element.attrib.get("id", "") ) ) if none_if_id_unused: return None raise LibraryError( reports.id_not_found( element_id, id_description if id_description else "/".join(tag_list), context_element.tag, context_element.attrib.get("id", "") ) )
def find_element_by_tag_and_id( tag, context_element, element_id, none_if_id_unused=False, id_description="" ): """ Return element with given tag and element_id under context_element. When element does not exists raises LibraryError or return None if specified in none_if_id_unused. etree.Element(Tree) context_element is part of tree for element scan string|list tag is expected tag (or list of tags) of search element string element_id is id of search element bool none_if_id_unused if the element is not found then return None if True or raise a LibraryError if False string id_description optional description for id """ tag_list = [tag] if is_string(tag) else tag element_list = context_element.xpath( './/*[({0}) and @id="{1}"]'.format( " or ".join(["self::{0}".format(one_tag) for one_tag in tag_list]), element_id ) ) if element_list: return element_list[0] element = get_root(context_element).find( './/*[@id="{0}"]'.format(element_id) ) if element is not None: raise LibraryError( reports.id_belongs_to_unexpected_type( element_id, expected_types=tag_list, current_type=element.tag ) if element.tag not in tag_list else reports.object_with_id_in_unexpected_context( element.tag, element_id, context_element.tag, context_element.attrib.get("id", "") ) ) if none_if_id_unused: return None raise LibraryError( reports.id_not_found( element_id, id_description if id_description else "/".join(tag_list), context_element.tag, context_element.attrib.get("id", "") ) )
def get_errors(self): """ Report why the element has not been found or booking its id failed """ if ( self.element_found() or (self._book_errors is not None and not self._book_errors) ): raise AssertionError( "Improper usage: cannot report errors when there are none" ) element = get_root(self._context_element).find( f'.//*[@id="{self._element_id}"]' ) if element is not None: if element.tag in self._tag_list: return [ reports.object_with_id_in_unexpected_context( element.tag, self._element_id, self._context_element.tag, self._context_element.attrib.get("id", "") ) ] return [ reports.id_belongs_to_unexpected_type( self._element_id, expected_types=self._expected_types, current_type=element.tag ) ] if self._book_errors is None: return [ reports.id_not_found( self._element_id, self._expected_types, self._context_element.tag, self._context_element.attrib.get("id", "") ) ] return self._book_errors
def _validate_resource_elements(self, bad_or_missing_group_specified, bad_resources_specified, bad_adjacent_specified): report_list = [] # Check if the group element is really a group unless it has been # checked before. if (not bad_or_missing_group_specified and not group.is_group(self._group_element)): bad_or_missing_group_specified = True report_list.append( reports.id_belongs_to_unexpected_type( self._group_element.attrib.get("id"), expected_types=[group.TAG], current_type=self._group_element.tag)) # Report an error if no resources were specified. If resource ids have # been specified but they are not valid resource ids, then some # resources were specified, even though not valid ones. if not bad_resources_specified and not self._resource_element_list: report_list.append(reports.cannot_group_resource_no_resources()) resources_already_in_the_group = set() resources_count = defaultdict(int) for resource in self._resource_element_list: resource_id = resource.attrib.get("id") if not primitive.is_primitive(resource): report_list.append( reports.cannot_group_resource_wrong_type( resource_id, resource.tag)) continue resources_count[resource_id] = resources_count[resource_id] + 1 parent = resource.getparent() if parent is not None: if group.is_group(parent): # If no adjacent resource has been specified (either valid # or invalid), the resources must not already be in the # group, if the group already exists. if (not bad_or_missing_group_specified and not bad_adjacent_specified and self._adjacent_resource_element is None and (parent.attrib.get("id") == self._group_element.attrib.get("id"))): resources_already_in_the_group.add(resource_id) elif parent.tag != "resources": # If the primitive is not in a 'group' or 'resources' tag, # it is either in a clone, master, bundle or similar tag # and cannot be put into a group. report_list.append( reports.cannot_group_resource_wrong_type( resource_id, parent.tag)) if resources_already_in_the_group: report_list.append( reports.cannot_group_resource_already_in_the_group( resources_already_in_the_group, self._group_element.attrib.get("id"))) more_than_once_resources = [ resource for resource, count in resources_count.items() if count > 1 ] if more_than_once_resources: report_list.append( reports.cannot_group_resource_more_than_once( more_than_once_resources)) return report_list
def _validate_resource_elements( self, bad_or_missing_group_specified, bad_resources_specified, bad_adjacent_specified ): report_list = [] # Check if the group element is really a group unless it has been # checked before. if ( not bad_or_missing_group_specified and not group.is_group(self._group_element) ): bad_or_missing_group_specified = True report_list.append( reports.id_belongs_to_unexpected_type( self._group_element.attrib.get("id"), expected_types=[group.TAG], current_type=self._group_element.tag ) ) # Report an error if no resources were specified. If resource ids have # been specified but they are not valid resource ids, then some # resources were specified, even though not valid ones. if not bad_resources_specified and not self._resource_element_list: report_list.append(reports.cannot_group_resource_no_resources()) resources_already_in_the_group = set() resources_count = defaultdict(int) for resource in self._resource_element_list: resource_id = resource.attrib.get("id") if not primitive.is_primitive(resource): report_list.append( reports.cannot_group_resource_wrong_type( resource_id, resource.tag ) ) continue resources_count[resource_id] = resources_count[resource_id] + 1 parent = resource.getparent() if parent is not None: if group.is_group(parent): # If no adjacent resource has been specified (either valid # or invalid), the resources must not already be in the # group, if the group already exists. if ( not bad_or_missing_group_specified and not bad_adjacent_specified and self._adjacent_resource_element is None and ( parent.attrib.get("id") == self._group_element.attrib.get("id") ) ): resources_already_in_the_group.add(resource_id) elif parent.tag != "resources": # If the primitive is not in a 'group' or 'resources' tag, # it is either in a clone, master, bundle or similar tag # and cannot be put into a group. report_list.append( reports.cannot_group_resource_wrong_type( resource_id, parent.tag ) ) if resources_already_in_the_group: report_list.append( reports.cannot_group_resource_already_in_the_group( resources_already_in_the_group, self._group_element.attrib.get("id") ) ) more_than_once_resources = [ resource for resource, count in resources_count.items() if count > 1 ] if more_than_once_resources: report_list.append( reports.cannot_group_resource_more_than_once( more_than_once_resources ) ) return report_list