Hook up addSuccess with a details parameter.
authorRobert Collins <robertc@robertcollins.net>
Sun, 4 Oct 2009 18:22:14 +0000 (05:22 +1100)
committerRobert Collins <robertc@robertcollins.net>
Sun, 4 Oct 2009 18:22:14 +0000 (05:22 +1100)
README
python/subunit/__init__.py
python/subunit/tests/test_test_protocol.py

diff --git a/README b/README
index a3997651731acc4c6dc501714fbc6598196b7b7a..3f15c03d01c7ba05f4f7925356dbd3299e756da5 100644 (file)
--- a/README
+++ b/README
@@ -162,9 +162,9 @@ time: YYYY-MM-DD HH:MM:SSZ
 
 DETAILS ::= BRACKETED | MULTIPART
 BRACKETED ::= '[' CR lines ']' CR
-MULTIPART ::= '[ multiparent' CR PART* ']' CR
-PART ::= PART_TYPE CR PART_BYTES CR
-PART_TYPE ::= Content-Type: type/sub-type(;parameter=label)
+MULTIPART ::= '[ multipart' CR PART* ']' CR
+PART ::= PART_TYPE CR NAME CR PART_BYTES CR
+PART_TYPE ::= Content-Type: type/sub-type(;parameter=value,parameter=value)
 PART_BYTES ::= (DIGITS CR BYTE{DIGITS})* '0' CR
 
 unexpected output on stdout -> stdout.
index d92e1bd304c128d10e5b38cf8fd0b2cf31580bdc..4edd69d584ba12b266f24cba79df9644562dc269 100644 (file)
@@ -41,10 +41,18 @@ Twisted. See the ``TestProtocolServer`` parser class for more details.
 
 Subunit includes extensions to the Python ``TestResult`` protocol. These are
 all done in a compatible manner: ``TestResult`` objects that do not implement
-the extension methods will not cause errors to be raised, instead the extesion
+the extension methods will not cause errors to be raised, instead the extension
 will either lose fidelity (for instance, folding expected failures to success
-in Python versions < 2.7 or 3.1), or discard the extended data (for tags,
-timestamping and progress markers).
+in Python versions < 2.7 or 3.1), or discard the extended data (for extra
+details, tags, timestamping and progress markers).
+
+The test outcome methods ``addSuccess`` take an optional keyword parameter
+``details`` which can be used instead of the usual python unittest parameter.
+When used the value of details should be a dict from ``string`` to 
+``subunit.content.Content`` objects. This is a draft API being worked on with
+the Python Testing In Python mail list, with the goal of permitting a common
+way to provide additional data beyond a traceback, such as captured data from
+disk, logging messages etc.
 
 The ``tags(new_tags, gone_tags)`` method is called (if present) to add or
 remove tags in the test run that is currently executing. If called when no
@@ -484,9 +492,21 @@ class TestProtocolClient(unittest.TestResult):
         self._stream.write("%s\n" % reason)
         self._stream.write("]\n")
 
-    def addSuccess(self, test):
+    def addSuccess(self, test, details=None):
         """Report a success in a test."""
-        self._stream.write("successful: %s\n" % test.id())
+        self._stream.write("successful: %s" % test.id())
+        if not details:
+            self._stream.write("\n")
+        else:
+            self._stream.write(" [ multipart\n")
+            for name, content in details.iteritems():
+                self._stream.write("Content-Type: %s/%s\n" %
+                    (content.content_type.type, content.content_type.subtype))
+                self._stream.write("%s\n" % name)
+                for bytes in content.iter_bytes():
+                    self._stream.write("%d\n%s" % (len(bytes), bytes))
+                self._stream.write("0\n")
+            self._stream.write("]\n")
 
     def startTest(self, test):
         """Mark a test as starting its test run."""
index 00a21ed9a24b07e63313028c5bde8e0ecac9db5c..f505626b254359cc49d89319a61b16245ee9467b 100644 (file)
@@ -18,9 +18,11 @@ import datetime
 import unittest
 from StringIO import StringIO
 import os
-import subunit
 import sys
 
+import subunit
+from subunit.content import Content
+from subunit.content_type import ContentType
 import subunit.iso8601 as iso8601
 
 
@@ -1052,6 +1054,8 @@ class TestTestProtocolClient(unittest.TestCase):
         self.io = StringIO()
         self.protocol = subunit.TestProtocolClient(self.io)
         self.test = TestTestProtocolClient("test_start_test")
+        self.sample_details = {'something':Content(
+            ContentType('text', 'plain'), lambda:['serialised\nform'])}
 
     def test_start_test(self):
         """Test startTest on a TestProtocolClient."""
@@ -1069,6 +1073,15 @@ class TestTestProtocolClient(unittest.TestCase):
         self.assertEqual(
             self.io.getvalue(), "successful: %s\n" % self.test.id())
 
+    def test_add_success_details(self):
+        """Test addSuccess on a TestProtocolClient."""
+        self.protocol.addSuccess(self.test, details=self.sample_details)
+        self.assertEqual(
+            self.io.getvalue(), "successful: %s [ multipart\n"
+                "Content-Type: text/plain\n"
+                "something\n"
+                "15\nserialised\nform0\n]\n"% self.test.id())
+
     def test_add_failure(self):
         """Test addFailure on a TestProtocolClient."""
         self.protocol.addFailure(