summaryrefslogtreecommitdiff
path: root/python/subunit
diff options
context:
space:
mode:
authorRobert Collins <robertc@robertcollins.net>2008-12-08 18:02:15 +1100
committerRobert Collins <robertc@robertcollins.net>2008-12-08 18:02:15 +1100
commit0ed5a16cc89aef319cfc2d4bb66c1ac1ced10f5f (patch)
treeaacbc7251c1446466c3d33e5d2c25524fb7de070 /python/subunit
parent852b598c58186f44178fa78f80f54faf98168101 (diff)
downloadsubunit-git-0ed5a16cc89aef319cfc2d4bb66c1ac1ced10f5f.tar.gz
Add subunit-tags to alter the tags on a test stream.
Diffstat (limited to 'python/subunit')
-rw-r--r--python/subunit/__init__.py63
-rw-r--r--python/subunit/tests/__init__.py2
-rw-r--r--python/subunit/tests/test_subunit_tags.py70
3 files changed, 128 insertions, 7 deletions
diff --git a/python/subunit/__init__.py b/python/subunit/__init__.py
index 84d9428..ff2ad66 100644
--- a/python/subunit/__init__.py
+++ b/python/subunit/__init__.py
@@ -43,6 +43,18 @@ def join_dir(base_path, path):
return os.path.join(os.path.dirname(os.path.abspath(base_path)), path)
+def tags_to_new_gone(tags):
+ """Split a list of tags into a new_set and a gone_set."""
+ new_tags = set()
+ gone_tags = set()
+ for tag in tags:
+ if tag[0] == '-':
+ gone_tags.add(tag[1:])
+ else:
+ new_tags.add(tag)
+ return new_tags, gone_tags
+
+
class TestProtocolServer(object):
"""A class for receiving results from a TestProtocol client.
@@ -173,13 +185,7 @@ class TestProtocolServer(object):
def _handleTags(self, offset, line):
"""Process a tags command."""
tags = line[offset:].split()
- new_tags = set()
- gone_tags = set()
- for tag in tags:
- if tag[0] == '-':
- gone_tags.add(tag[1:])
- else:
- new_tags.add(tag)
+ new_tags, gone_tags = tags_to_new_gone(tags)
if self.state == TestProtocolServer.OUTSIDE_TEST:
update_tags = self.tags
else:
@@ -568,3 +574,46 @@ def TAP2SubUnit(tap, subunit):
# record missed tests
plan_start = _skipped_test(subunit, plan_start)
return 0
+
+
+def tag_stream(original, filtered, tags):
+ """Alter tags on a stream.
+
+ :param original: The input stream.
+ :param filtered: The output stream.
+ :param tags: The tags to apply. As in a normal stream - a list of 'TAG' or
+ '-TAG' commands.
+ A 'TAG' command will add the tag to the output stream,
+ and override any existing '-TAG' command in that stream.
+ Specifically:
+ * A global 'tags: TAG' will be added to the start of the stream.
+ * Any tags commands with -TAG will have the -TAG removed.
+ A '-TAG' command will remove the TAG command from the stream.
+ Specifically:
+ * A 'tags: -TAG' command will be added to the start of the stream.
+ * Any 'tags: TAG' command will have 'TAG' removed from it.
+ Additionally, any redundant tagging commands (adding a tag globally
+ present, or removing a tag globally removed) are stripped as a
+ by-product of the filtering.
+ :return: 0
+ """
+ new_tags, gone_tags = tags_to_new_gone(tags)
+ def write_tags(new_tags, gone_tags):
+ if new_tags or gone_tags:
+ filtered.write("tags: " + ' '.join(new_tags))
+ if gone_tags:
+ for tag in gone_tags:
+ filtered.write("-" + tag)
+ filtered.write("\n")
+ write_tags(new_tags, gone_tags)
+ # TODO: use the protocol parser and thus don't mangle test comments.
+ for line in original:
+ if line.startswith("tags:"):
+ line_tags = line[5:].split()
+ line_new, line_gone = tags_to_new_gone(line_tags)
+ line_new = line_new - gone_tags
+ line_gone = line_gone - new_tags
+ write_tags(line_new, line_gone)
+ else:
+ filtered.write(line)
+ return 0
diff --git a/python/subunit/tests/__init__.py b/python/subunit/tests/__init__.py
index 7f501c7..6703514 100644
--- a/python/subunit/tests/__init__.py
+++ b/python/subunit/tests/__init__.py
@@ -19,6 +19,7 @@
from subunit.tests import (
TestUtil,
+ test_subunit_tags,
test_tap2subunit,
test_test_protocol,
)
@@ -27,4 +28,5 @@ def test_suite():
result = TestUtil.TestSuite()
result.addTest(test_test_protocol.test_suite())
result.addTest(test_tap2subunit.test_suite())
+ result.addTest(test_subunit_tags.test_suite())
return result
diff --git a/python/subunit/tests/test_subunit_tags.py b/python/subunit/tests/test_subunit_tags.py
new file mode 100644
index 0000000..66cff68
--- /dev/null
+++ b/python/subunit/tests/test_subunit_tags.py
@@ -0,0 +1,70 @@
+#
+# subunit: extensions to python unittest to get test results from subprocesses.
+# Copyright (C) 2005 Robert Collins <robertc@robertcollins.net>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+"""Tests for subunit.tag_stream."""
+
+import unittest
+from StringIO import StringIO
+
+import subunit
+
+
+class TestSubUnitTags(unittest.TestCase):
+
+ def setUp(self):
+ self.original = StringIO()
+ self.filtered = StringIO()
+
+ def test_add_tag(self):
+ self.original.write("tags: foo\n")
+ self.original.write("test: test\n")
+ self.original.write("tags: bar -quux\n")
+ self.original.write("success: test\n")
+ self.original.seek(0)
+ result = subunit.tag_stream(self.original, self.filtered, ["quux"])
+ self.assertEqual([
+ "tags: quux",
+ "tags: foo",
+ "test: test",
+ "tags: bar",
+ "success: test",
+ ],
+ self.filtered.getvalue().splitlines())
+
+ def test_remove_tag(self):
+ self.original.write("tags: foo\n")
+ self.original.write("test: test\n")
+ self.original.write("tags: bar -quux\n")
+ self.original.write("success: test\n")
+ self.original.seek(0)
+ result = subunit.tag_stream(self.original, self.filtered, ["-bar"])
+ self.assertEqual([
+ "tags: -bar",
+ "tags: foo",
+ "test: test",
+ "tags: -quux",
+ "success: test",
+ ],
+ self.filtered.getvalue().splitlines())
+
+
+def test_suite():
+ loader = subunit.tests.TestUtil.TestLoader()
+ result = loader.loadTestsFromName(__name__)
+ return result