diff options
| author | Robert Collins <robertc@robertcollins.net> | 2009-10-13 16:43:05 +1100 |
|---|---|---|
| committer | Robert Collins <robertc@robertcollins.net> | 2009-10-13 16:43:05 +1100 |
| commit | 39b7a1cc39710acc6ed0deff19d1dcaaa46970a8 (patch) | |
| tree | e5376e264ca95c82afc1dff257c8b90477fb9be8 /python | |
| parent | 236a0392e2d4ae550addac6bea02c7edb093c75f (diff) | |
| download | subunit-git-39b7a1cc39710acc6ed0deff19d1dcaaa46970a8.tar.gz | |
Gather multipart details.
Diffstat (limited to 'python')
| -rw-r--r-- | python/subunit/details.py | 36 | ||||
| -rw-r--r-- | python/subunit/tests/test_details.py | 20 |
2 files changed, 55 insertions, 1 deletions
diff --git a/python/subunit/details.py b/python/subunit/details.py index 4f121cc..1460170 100644 --- a/python/subunit/details.py +++ b/python/subunit/details.py @@ -16,6 +16,11 @@ """Handlers for outcome details.""" +from cStringIO import StringIO + +import chunked, content, content_type + + class DetailsParser(object): """Base class/API reference for details parsing.""" @@ -50,9 +55,40 @@ class MultipartDetailsParser(DetailsParser): def __init__(self, state): self._state = state self._details = {} + self._parse_state = self._look_for_content + + def _look_for_content(self, line): + if line == "]\n": + self._state.endDetails() + return + # TODO error handling + field, value = line[:-1].split(' ', 1) + main, sub = value.split('/') + self._content_type = content_type.ContentType(main, sub) + self._parse_state = self._get_name + + def _get_name(self, line): + self._name = line[:-1] + self._body = StringIO() + self._chunk_parser = chunked.Decoder(self._body) + self._parse_state = self._feed_chunks + + def _feed_chunks(self, line): + residue = self._chunk_parser.write(line) + if residue is not None: + # Line based use always ends on no residue. + assert residue == '' + body = self._body + self._details[self._name] = content.Content( + self._content_type, lambda:[body.getvalue()]) + self._chunk_parser.close() + self._parse_state = self._look_for_content def get_details(self): return self._details def get_message(self): return None + + def lineReceived(self, line): + self._parse_state(line) diff --git a/python/subunit/tests/test_details.py b/python/subunit/tests/test_details.py index bc0930a..f76d505 100644 --- a/python/subunit/tests/test_details.py +++ b/python/subunit/tests/test_details.py @@ -18,7 +18,7 @@ from cStringIO import StringIO import unittest import subunit.tests -from subunit import details +from subunit import content, content_type, details def test_suite(): @@ -60,3 +60,21 @@ class TestMultipartDetails(unittest.TestCase): def test_get_details(self): parser = details.MultipartDetailsParser(None) self.assertEqual({}, parser.get_details()) + + def test_parts(self): + parser = details.MultipartDetailsParser(None) + parser.lineReceived("Content-Type: text/plain\n") + parser.lineReceived("something\n") + parser.lineReceived("F\r\n") + parser.lineReceived("serialised\n") + parser.lineReceived("form0\r\n") + expected = {} + expected['something'] = content.Content( + content_type.ContentType("text", "plain"), + lambda:["serialised\nform"]) + found = parser.get_details() + self.assertEqual(expected.keys(), found.keys()) + self.assertEqual(expected['something'].content_type, + found['something'].content_type) + self.assertEqual(''.join(expected['something'].iter_bytes()), + ''.join(found['something'].iter_bytes())) |
