Source code for robot.model.tagstatistics

#  Copyright 2008-2015 Nokia Networks
#  Copyright 2016-     Robot Framework Foundation
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

from itertools import chain
import re

from robot.utils import NormalizedDict, unicode

from .stats import CombinedTagStat, CriticalTagStat, TagStat
from .tags import SingleTagPattern, TagPatterns


[docs]class TagStatistics(object): """Container for tag statistics.""" def __init__(self, critical_stats, non_critical_stats, combined_stats): #: Dictionary, where key is the name of the tag as a string and value #: is an instance of :class:`~robot.model.stats.TagStat`. self.tags = NormalizedDict(ignore='_') #: List of :class:`~robot.model.stats.CriticalTagStat` objects. self.critical = critical_stats #: List of :class:`~robot.model.stats.CriticalTagStat` objects. self.non_critical = non_critical_stats #: List of :class:`~robot.model.stats.CombinedTagStat` objects. self.combined = combined_stats
[docs] def visit(self, visitor): visitor.visit_tag_statistics(self)
def __iter__(self): crits = self._get_critical_and_non_critical_matcher() tags = [t for t in self.tags.values() if t.name not in crits] return iter(sorted(chain(self.critical, self.non_critical, self.combined, tags))) def _get_critical_and_non_critical_matcher(self): crits = [stat for stat in self.critical + self.non_critical if isinstance(stat.pattern, SingleTagPattern)] return NormalizedDict([(unicode(stat.pattern), None) for stat in crits], ignore='_')
[docs]class TagStatisticsBuilder(object): def __init__(self, criticality=None, included=None, excluded=None, combined=None, docs=None, links=None): self._included = TagPatterns(included) self._excluded = TagPatterns(excluded) self._info = TagStatInfo(docs, links) self.stats = TagStatistics( self._info.get_critical_stats(criticality), self._info.get_critical_stats(criticality, critical=False), self._info.get_combined_stats(combined) )
[docs] def add_test(self, test): self._add_tags_to_statistics(test) self._add_to_critical_and_combined_statistics(test)
def _add_tags_to_statistics(self, test): for tag in test.tags: if self._is_included(tag): if tag not in self.stats.tags: self.stats.tags[tag] = self._info.get_stat(tag) self.stats.tags[tag].add_test(test) def _is_included(self, tag): if self._included and not self._included.match(tag): return False return not self._excluded.match(tag) def _add_to_critical_and_combined_statistics(self, test): stats = self.stats for stat in stats.critical + stats.non_critical + stats.combined: if stat.match(test.tags): stat.add_test(test)
[docs]class TagStatInfo(object): def __init__(self, docs=None, links=None): self._docs = [TagStatDoc(*doc) for doc in docs or []] self._links = [TagStatLink(*link) for link in links or []]
[docs] def get_stat(self, tag): return TagStat(tag, self.get_doc(tag), self.get_links(tag))
[docs] def get_critical_stats(self, criticality, critical=True): if not criticality: return [] tag_patterns = (criticality.critical_tags if critical else criticality.non_critical_tags) return [self._get_critical_stat(p, critical) for p in tag_patterns]
def _get_critical_stat(self, pattern, critical): name = unicode(pattern) return CriticalTagStat(pattern, name, critical, self.get_doc(name), self.get_links(name))
[docs] def get_combined_stats(self, combined=None): return [self._get_combined_stat(*comb) for comb in combined or []]
def _get_combined_stat(self, pattern, name=None): name = name or pattern return CombinedTagStat(pattern, name, self.get_doc(name), self.get_links(name))
[docs] def get_doc(self, tag): return ' & '.join(doc.text for doc in self._docs if doc.match(tag))
[docs]class TagStatDoc(object): def __init__(self, pattern, doc): self._matcher = TagPatterns(pattern) self.text = doc
[docs] def match(self, tag): return self._matcher.match(tag)