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'])

Reply via email to