'''Verify that xml.sax.saxutil.prepare_input_source(), when preparing an xml.sax.xmlreader.InputSource object, chooses properly between using the character stream, using the byte stream, or opening the file or URL specified in the system ID.''' from __future__ import with_statement import unittest import xml.sax.saxutils import xml.sax.xmlreader import StringIO import tempfile import os class TestPrepareInputSource(unittest.TestCase): # Fixture methods def setUp(self): self.file = tempfile.mktemp() with open(self.file, "w") as tmp: tmp.write("This was read from a file.") def tearDown(self): os.remove(self.file) def make_byte_stream(self): return StringIO.StringIO("This is a byte stream.") def make_character_stream(self): return StringIO.StringIO(u"This is a character stream.") # The tests def testUseCharacterStream(self): '''If the source is an InputSource with a character stream, use it.''' src = xml.sax.xmlreader.InputSource(self.file) src.setCharacterStream(self.make_character_stream()) prep = xml.sax.saxutils.prepare_input_source(src) self.failIf(prep.getCharacterStream() is None, "ignored character stream") self.verify_system_ID_not_used(prep) self.assertEqual(prep.getCharacterStream().read(), "This is a character stream.") def testUseByteStream(self): '''If the source is an InputSource that does not have a character stream but does have a byte stream, use the byte stream.''' src = xml.sax.xmlreader.InputSource(self.file) src.setByteStream(self.make_byte_stream()) prep = xml.sax.saxutils.prepare_input_source(src) self.verify_no_character_stream(prep) self.failIf(prep.getByteStream() is None, "ignored byte stream") self.verify_system_ID_not_used(prep) self.assertEqual(prep.getByteStream().read(), "This is a byte stream.") def testUseSystemID(self): '''If the source is an InputSource that has neither a character stream nor a byte stream, open the system ID.''' src = xml.sax.xmlreader.InputSource(self.file) prep = xml.sax.saxutils.prepare_input_source(src) self.verify_no_character_stream(prep) self.verify_used_temp(prep) def testUseString(self): '''If the source is a string, use it as a system ID and open it.''' prep = xml.sax.saxutils.prepare_input_source(self.file) self.verify_no_character_stream(prep) self.verify_used_temp(prep) def testUseFileObject(self): '''If the source is a file-like object, use it as a byte stream.''' prep = xml.sax.saxutils.prepare_input_source(self.make_byte_stream()) self.verify_no_character_stream(prep) self.failIf(prep.getByteStream() is None, "ignored file-like source") self.assertEqual(prep.getByteStream().read(), "This is a byte stream.") # Common assertions used above that need to ensure that any # handles to the temp file are closed before we delete it def verify_system_ID_not_used(self, prep): '''Verify that the file named by the system ID was not opened.''' stream = prep.getByteStream() if stream is not None and not isinstance(stream, StringIO.StringIO): self.try_close(stream) self.fail("gratuitously opened sysid") def verify_no_character_stream(self, prep): '''Verify that the InputSource object as no character stream.''' stream = prep.getCharacterStream() if stream is not None: self.try_close(stream) self.fail("where did that character stream come from?") def verify_used_temp(self, prep): '''Verify that our temp file is being used as the byte stream.''' stream = prep.getByteStream() try: self.assertEqual(stream.read(), "This was read from a file.") finally: self.try_close(stream) def try_close(self, stream): try: stream.close() except: pass