3 new revisions:
Revision: 8b4569246ce3
Author: Pekka Klärck
Date: Mon Nov 14 14:50:07 2011
Log: TagStatistice.__len__
http://code.google.com/p/robotframework/source/detail?r=8b4569246ce3
Revision: 4eb2a132d297
Author: Pekka Klärck
Date: Mon Nov 14 15:56:32 2011
Log: TagStatistics: Simplify handling combined statistics
http://code.google.com/p/robotframework/source/detail?r=4eb2a132d297
Revision: ddf735904e54
Author: Pekka Klärck
Date: Mon Nov 14 16:11:39 2011
Log: TagStatistics: explicit test for sorting
http://code.google.com/p/robotframework/source/detail?r=ddf735904e54
==============================================================================
Revision: 8b4569246ce3
Author: Pekka Klärck
Date: Mon Nov 14 14:50:07 2011
Log: TagStatistice.__len__
http://code.google.com/p/robotframework/source/detail?r=8b4569246ce3
Modified:
/src/robot/model/tagstatistics.py
/utest/model/test_statistics.py
=======================================
--- /src/robot/model/tagstatistics.py Mon Nov 14 13:07:07 2011
+++ /src/robot/model/tagstatistics.py Mon Nov 14 14:50:07 2011
@@ -65,6 +65,9 @@
def __iter__(self):
return iter(sorted(self.stats.values()))
+ def __len__(self):
+ return len(self.stats)
+
class TagStatInfo(object):
=======================================
--- /utest/model/test_statistics.py Mon Nov 14 13:07:07 2011
+++ /utest/model/test_statistics.py Mon Nov 14 14:50:07 2011
@@ -161,6 +161,22 @@
assert_equals(sorted(tagstats.stats.keys()),
exp, "Incls: %s, Excls: %s" % (incl, excl))
+ def test_len(self):
+ stats = TagStatistics(Criticality())
+ assert_equals(len(stats), 0)
+ stats.add_test(TestCase())
+ assert_equals(len(stats), 0)
+ stats.add_test(TestCase(tags=['a']))
+ assert_equals(len(stats), 1)
+ stats.add_test(TestCase(tags=['A', 'B']))
+ assert_equals(len(stats), 2)
+
+ def test_len_with_combine(self):
+ stats = TagStatistics(Criticality(), combine=[('x*', 'title')])
+ assert_equals(len(stats), 1)
+ stats.add_test(TestCase(tags=['xxx', 'yyy']))
+ assert_equals(len(stats), 3)
+
def test_combine_with_name(self):
for comb_tags, expected_name in [
([], '' ),
@@ -173,7 +189,7 @@
stats = TagStatistics(Criticality(), combine=comb_tags)
test = TestCase()
stats._add_combined_statistics(test)
- assert_equals(len(stats.stats), expected_name != '')
+ assert_equals(bool(stats), expected_name != '')
if expected_name:
assert_equals(stats.stats[expected_name].name,
expected_name)
==============================================================================
Revision: 4eb2a132d297
Author: Pekka Klärck
Date: Mon Nov 14 15:56:32 2011
Log: TagStatistics: Simplify handling combined statistics
http://code.google.com/p/robotframework/source/detail?r=4eb2a132d297
Modified:
/src/robot/model/stats.py
/src/robot/model/tagstatistics.py
/src/robot/result/jsondatamodelhandlers.py
/utest/model/test_statistics.py
=======================================
--- /src/robot/model/stats.py Mon Nov 14 13:07:07 2011
+++ /src/robot/model/stats.py Mon Nov 14 15:56:32 2011
@@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from .tags import TagPatterns
+
class Stat(object):
@@ -66,12 +68,12 @@
class TagStat(Stat):
type = 'tag'
- def __init__(self, name, doc='', links=[], critical=False,
+ def __init__(self, name, doc='', links=None, critical=False,
non_critical=False, combined=''):
Stat.__init__(self, name)
# TODO: Do we need all these attrs or could they me only in
self.attrs?
self.doc = doc
- self.links = links # TODO: Are both self.links and self._link_str
needed?
+ self.links = links or [] # TODO: Are both self.links and
self._link_str needed?
self.critical = critical
self.non_critical = non_critical
self.combined = combined
@@ -102,6 +104,16 @@
or cmp(self.name, other.name)
+class CombinedTagStat(TagStat):
+
+ def __init__(self, pattern, name=None, doc='', links=None):
+ TagStat.__init__(self, name or pattern, doc, links,
combined=pattern)
+ self._matcher = TagPatterns(pattern)
+
+ def match(self, tags):
+ return self._matcher.match(tags)
+
+
class TotalStat(Stat):
type = 'total'
=======================================
--- /src/robot/model/tagstatistics.py Mon Nov 14 14:50:07 2011
+++ /src/robot/model/tagstatistics.py Mon Nov 14 15:56:32 2011
@@ -14,91 +14,76 @@
import re
-from robot.model.tags import TagPatterns
-from robot.model.stats import TagStat
from robot import utils
+from .tags import TagPatterns
+from .stats import TagStat, CombinedTagStat
class TagStatistics(object):
def __init__(self, criticality, include=None, exclude=None,
combine=None,
docs=None, links=None):
- self.stats = utils.NormalizedDict(ignore=['_'])
- self._info = TagStatInfo(criticality, combine, docs, links)
+ # TODO: Check argument names
+ self._tags = utils.NormalizedDict(ignore=['_'])
self._include = TagPatterns(include)
self._exclude = TagPatterns(exclude)
- for tag in self._info.combined_tags:
- self.stats[tag.name] = TagStat(tag.name,
- self._info.get_doc(tag.name),
- self._info.get_links(tag.name),
- combined=tag.pattern)
+ self._info = TagStatInfo(criticality, docs, links)
+ self._combined = [self._info.get_combined_stat(pattern, name)
+ for pattern, name in combine or []]
def add_test(self, test):
- self._add_tags_statistics(test)
- self._add_combined_statistics(test)
-
- def _add_tags_statistics(self, test):
+ self._add_tags_to_statistics(test)
+ self._add_to_combined_statistics(test)
+
+ def _add_tags_to_statistics(self, test):
for tag in test.tags:
- if not self._is_included(tag):
- continue
- if tag not in self.stats:
- self.stats[tag] = TagStat(tag,
- self._info.get_doc(tag),
- self._info.get_links(tag),
- self._info.is_critical(tag),
- self._info.is_non_critical(tag))
- self.stats[tag].add_test(test)
+ if self._is_included(tag):
+ if tag not in self._tags:
+ self._tags[tag] = self._info.get_stat(tag)
+ self._tags[tag].add_test(test)
def _is_included(self, tag):
if self._include and not self._include.match(tag):
return False
return not self._exclude.match(tag)
- def _add_combined_statistics(self, test):
- for comb in self._info.combined_tags:
+ def _add_to_combined_statistics(self, test):
+ for comb in self._combined:
if comb.match(test.tags):
- self.stats[comb.name].add_test(test)
+ comb.add_test(test)
def visit(self, visitor):
visitor.visit_tag_statistics(self)
def __iter__(self):
- return iter(sorted(self.stats.values()))
+ return iter(sorted(self._tags.values() + self._combined))
def __len__(self):
- return len(self.stats)
+ return len(self._tags) + len(self._combined)
class TagStatInfo(object):
- def __init__(self, criticality, combines=None, docs=None, links=None):
- self.criticality = criticality
- self.combined_tags = [CombinedTag(*comb) for comb in combines or
[]]
- self.docs = [TagStatDoc(*doc) for doc in docs or []]
- self.links = [TagStatLink(*link) for link in links or []]
-
- def is_critical(self, tag):
- return self.criticality.tag_is_critical(tag)
-
- def is_non_critical(self, tag):
- return self.criticality.tag_is_non_critical(tag)
-
- def get_doc(self, tag):
- return ' & '.join(doc.text for doc in self.docs if doc.match(tag))
-
- def get_links(self, tag):
- return [link.get_link(tag) for link in self.links if
link.match(tag)]
-
-
-class CombinedTag(object):
-
- def __init__(self, pattern, name=None):
- self.pattern = pattern
- self._matcher = TagPatterns(pattern)
- self.name = name or pattern
-
- def match(self, tags):
- return self._matcher.match(tags)
+ def __init__(self, criticality, docs=None, links=None):
+ self._criticality = criticality
+ self._docs = [TagStatDoc(*doc) for doc in docs or []]
+ self._links = [TagStatLink(*link) for link in links or []]
+
+ def get_stat(self, tag):
+ return TagStat(tag, self._get_doc(tag), self._get_links(tag),
+ self._criticality.is_critical(tag),
+ self._criticality.is_non_critical(tag))
+
+ def get_combined_stat(self, pattern, name=None):
+ name = name or pattern
+ return CombinedTagStat(pattern, name, self._get_doc(name),
+ self._get_links(name))
+
+ def _get_doc(self, tag):
+ return ' & '.join(doc.text for doc in self._docs if doc.match(tag))
+
+ def _get_links(self, tag):
+ return [link.get_link(tag) for link in self._links if
link.match(tag)]
class TagStatDoc(object):
=======================================
--- /src/robot/result/jsondatamodelhandlers.py Mon Nov 14 03:46:38 2011
+++ /src/robot/result/jsondatamodelhandlers.py Mon Nov 14 15:56:32 2011
@@ -113,7 +113,7 @@
return [self._create_stat(total.critical),
self._create_stat(total.all)]
def _parse_tag(self, tags):
- return [self._create_stat(tag) for tag in tags.stats.values()]
+ return [self._create_stat(tag) for tag in tags]
def _parse_suite(self, suite):
stats = []
=======================================
--- /utest/model/test_statistics.py Mon Nov 14 14:50:07 2011
+++ /utest/model/test_statistics.py Mon Nov 14 15:56:32 2011
@@ -59,7 +59,7 @@
verify_suite(self.statistics.suite, 'Hello', 's1', 2, 1)
def test_tags(self):
- assert_equals(self.statistics.tags.stats, {})
+ assert_equals(list(self.statistics.tags), [])
class TestStatisticsNotSoSimple(unittest.TestCase):
@@ -89,14 +89,13 @@
def test_tags(self):
tags = self.statistics.tags
- keys = tags.stats.keys()
- assert_equals(len(keys), 4)
- keys.sort()
- assert_equals(keys, 'smoke t1 t2 t3'.split())
- verify_stat(tags.stats['smoke'], 'smoke', 2, 2, True, False)
- verify_stat(tags.stats['t1'], 't1', 3, 2, False, False)
- verify_stat(tags.stats['t2'], 't2', 2, 1, False, False)
- verify_stat(tags.stats['t3'], 't3', 0, 2, False, False)
+ assert_equals(len(tags), 4)
+ names = [t.name for t in tags]
+ assert_equals(names, 'smoke t1 t2 t3'.split())
+ verify_stat(tags._tags['smoke'], 'smoke', 2, 2, True, False)
+ verify_stat(tags._tags['t1'], 't1', 3, 2, False, False)
+ verify_stat(tags._tags['t2'], 't2', 2, 1, False, False)
+ verify_stat(tags._tags['t3'], 't3', 0, 2, False, False)
class TestSuiteStatLevel(unittest.TestCase):
@@ -112,39 +111,33 @@
assert_equals(len(s2.suites), 0)
-_incl_excl_data = [
- ([], []),
- ([], ['t1','t2']),
- (['t1'], ['t1','t2']),
- (['t1','t2'], ['t1','t2','t3','t4']),
- (['UP'], ['t1','t2','up']),
- (['not','not2'], ['t1','t2','t3']),
- (['t*'], ['t1','s1','t2','t3','s2','s3']),
- (['T*','r'], ['t1','t2','r','teeeeeeee']),
- (['*'], ['t1','t2','s1','tag']),
- (['t1','t2','t3','not'], ['t1','t2','t3','t4','s1','s2'])
-]
-
-
class TestTagStatistics(unittest.TestCase):
+ _incl_excl_data = [([], []),
+ ([], ['t1','t2']),
+ (['t1'], ['t1','t2']),
+ (['t1','t2'], ['t1','t2','t3','t4']),
+ (['UP'], ['t1','t2','up']),
+ (['not','not2'], ['t1','t2','t3']),
+ (['t*'], ['t1','s1','t2','t3','s2','s3']),
+ (['T*','r'], ['t1','t2','r','teeeeeeee']),
+ (['*'], ['t1','t2','s1','tag']),
+ (['t1','t2','t3','not'],
['t1','t2','t3','t4','s1','s2'])]
def test_include(self):
- for incl, tags in _incl_excl_data:
- tagstats = TagStatistics(Criticality(), incl, [])
- tagstats.add_test(TestCase(status='PASS', tags=tags))
- exp_keys = [tag for tag in sorted(tags)
- if incl == [] or utils.matches_any(tag, incl)]
- assert_equals(sorted(tagstats.stats.keys()),
- exp_keys, "Incls: %s " % incl)
+ for incl, tags in self._incl_excl_data:
+ stats = TagStatistics(Criticality(), incl, [])
+ stats.add_test(TestCase(status='PASS', tags=tags))
+ expected = [tag for tag in tags
+ if incl == [] or any(utils.matches(tag, i) for i
in incl)]
+ assert_equals([s.name for s in stats], sorted(expected))
def test_exclude(self):
- for excl, tags in _incl_excl_data:
- tagstats = TagStatistics(Criticality(), [], excl)
- tagstats.add_test(TestCase(status='PASS', tags=tags))
- exp_keys = [tag for tag in sorted(tags)
- if not utils.matches_any(tag, excl)]
- assert_equals(sorted(tagstats.stats.keys()),
- exp_keys, "Excls: %s" % excl)
+ for excl, tags in self._incl_excl_data:
+ stats = TagStatistics(Criticality(), [], excl)
+ stats.add_test(TestCase(status='PASS', tags=tags))
+ expected = [tag for tag in tags
+ if not any(utils.matches(tag, e) for e in excl)]
+ assert_equals([s.name for s in stats], sorted(expected))
def test_include_and_exclude(self):
for incl, excl, tags, exp in [
@@ -156,10 +149,9 @@
(['t1','t2','t3','not'], ['t2','t0'],
['t0','t1','t2','t3','x'], ['t1','t3'] )
]:
- tagstats = TagStatistics(Criticality(), incl, excl)
- tagstats.add_test(TestCase(status='PASS', tags=tags))
- assert_equals(sorted(tagstats.stats.keys()),
- exp, "Incls: %s, Excls: %s" % (incl, excl))
+ stats = TagStatistics(Criticality(), incl, excl)
+ stats.add_test(TestCase(status='PASS', tags=tags))
+ assert_equals([s.name for s in stats], exp),
def test_len(self):
stats = TagStatistics(Criticality())
@@ -187,11 +179,9 @@
([('4NOT5', 'Some new name')], 'Some new name')
]:
stats = TagStatistics(Criticality(), combine=comb_tags)
- test = TestCase()
- stats._add_combined_statistics(test)
assert_equals(bool(stats), expected_name != '')
if expected_name:
- assert_equals(stats.stats[expected_name].name,
expected_name)
+ assert_equals([s.name for s in stats], [expected_name])
def test_is_combined_with_and_statements(self):
for comb_tags, test_tags, expected_count in [
@@ -205,13 +195,12 @@
('t*&s', ['s','tee','t'], 1),
('t*&s&non', ['s','tee','t'], 0)
]:
- self._test_combined_statistics(comb_tags, test_tags,
expected_count)
-
- def _test_combined_statistics(self, comb_tags, test_tags,
expected_count):
- stats = TagStatistics(Criticality(),
combine=[(comb_tags, 'name')])
- test = TestCase(tags=test_tags)
- stats._add_combined_statistics(test)
- assert_equals(stats.stats['Name'].total, expected_count)
+ self._verify_combined_statistics(comb_tags, test_tags,
expected_count)
+
+ def _verify_combined_statistics(self, comb_tags, test_tags,
expected_count):
+ stats = TagStatistics(Criticality(), combine=[(comb_tags, 'name')])
+ stats._add_to_combined_statistics(TestCase(tags=test_tags))
+ assert_equals([s.total for s in stats if s.combined],
[expected_count])
def test_is_combined_with_not_statements(self):
for comb_tags, test_tags, expected_count in [
@@ -234,7 +223,13 @@
('tNOTs*NOTr', ['S','T'], 0),
('tNOTs*NOTr', ['R','T','s'], 1),
]:
- self._test_combined_statistics(comb_tags, test_tags,
expected_count)
+ self._verify_combined_statistics(comb_tags, test_tags,
expected_count)
+
+ def test_combine_with_same_name_as_existing_tag(self):
+ stats = TagStatistics(Criticality(), combine=[('x*', 'name')])
+ stats.add_test(TestCase(tags=['name', 'another']))
+ assert_equals([(s.name, s.combined) for s in stats],
+ [('name', 'x*'), ('another', ''), ('name', '')])
def test_combine(self):
# This is more like an acceptance test than a unit test ...
@@ -278,10 +273,7 @@
('t1 NOT t2', ''), ('none & t1', 'a
title')])
expected = [('smoke', 4), ('a title', 0), ('t1 & t2', 3),
('t1 NOT t2', 2), ('t? & smoke', 4), ('t1', 5), ('t2',
3)]
- assert_equals([stat.name for stat in statistics.tags],
- [name for name, _ in expected])
- for name, count in expected:
- assert_equals(statistics.tags.stats[name].total, count, name)
+ assert_equals([(t.name, t.total) for t in statistics.tags],
expected)
class TestTagStatLink(unittest.TestCase):
@@ -361,13 +353,5 @@
assert_equals(link.get_link('A-XXX-ABC-B'),
('B-XXX-XXX-B', 'Tracker'))
-class TestTagStatLinks(unittest.TestCase):
-
- def test_tag_stat_links_with_valid_tags(self):
- values = [('1', '2', '3'), ('tag', 'foo.html', 'bar')]
- tag_stat_links = TagStatInfo(Criticality(), links=values)
- assert_equals(len(tag_stat_links.links), 2)
-
-
if __name__ == "__main__":
unittest.main()
==============================================================================
Revision: ddf735904e54
Author: Pekka Klärck
Date: Mon Nov 14 16:11:39 2011
Log: TagStatistics: explicit test for sorting
http://code.google.com/p/robotframework/source/detail?r=ddf735904e54
Modified:
/utest/model/test_statistics.py
=======================================
--- /utest/model/test_statistics.py Mon Nov 14 15:56:32 2011
+++ /utest/model/test_statistics.py Mon Nov 14 16:11:39 2011
@@ -265,6 +265,18 @@
# 4) Verify names (match counts were already verified)
assert_equals(names, exp_names)
+ def test_sorting(self):
+ stats = TagStatistics(Criticality(['c2', 'c1'], ['n*']),
+ combine=[('c*', ''), ('xxx', 'a title')])
+ stats.add_test(TestCase(tags=['c1', 'c2', 't1']))
+ stats.add_test(TestCase(tags=['c1', 'n2', 't2']))
+ stats.add_test(TestCase(tags=['n1', 'n2', 't1', 't3']))
+ assert_equals([(s.name, s._info, s.total) for s in stats],
+ [('c1', 'critical', 2), ('c2', 'critical', 1),
+ ('n1', 'non-critical', 1), ('n2', 'non-critical',
2),
+ ('a title', 'combined', 0), ('c*', 'combined', 2),
+ ('t1', '', 2), ('t2', '', 1), ('t3', '', 1)])
+
def test_through_suite(self):
suite = generate_default_suite()
suite.set_criticality(critical_tags=['smoke'])