Home | History | Annotate | Download | only in test
      1 # Tests StringIO and cStringIO
      2 
      3 import unittest
      4 import StringIO
      5 import cStringIO
      6 import types
      7 import array
      8 import sys
      9 from test import test_support
     10 
     11 
     12 class TestGenericStringIO(unittest.TestCase):
     13     # use a class variable MODULE to define which module is being tested
     14 
     15     # Line of data to test as string
     16     _line = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!'
     17 
     18     # Constructor to use for the test data (._line is passed to this
     19     # constructor)
     20     constructor = str
     21 
     22     def setUp(self):
     23         self._lines = self.constructor((self._line + '\n') * 5)
     24         self._fp = self.MODULE.StringIO(self._lines)
     25 
     26     def test_reads(self):
     27         eq = self.assertEqual
     28         self.assertRaises(TypeError, self._fp.seek)
     29         eq(self._fp.read(10), self._line[:10])
     30         eq(self._fp.read(0), '')
     31         eq(self._fp.readline(0), '')
     32         eq(self._fp.readline(), self._line[10:] + '\n')
     33         eq(len(self._fp.readlines(60)), 2)
     34         self._fp.seek(0)
     35         eq(self._fp.readline(-1), self._line + '\n')
     36 
     37     def test_writes(self):
     38         f = self.MODULE.StringIO()
     39         self.assertRaises(TypeError, f.seek)
     40         f.write(self._line[:6])
     41         f.seek(3)
     42         f.write(self._line[20:26])
     43         f.write(self._line[52])
     44         self.assertEqual(f.getvalue(), 'abcuvwxyz!')
     45 
     46     def test_writelines(self):
     47         f = self.MODULE.StringIO()
     48         f.writelines([self._line[0], self._line[1], self._line[2]])
     49         f.seek(0)
     50         self.assertEqual(f.getvalue(), 'abc')
     51 
     52     def test_writelines_error(self):
     53         def errorGen():
     54             yield 'a'
     55             raise KeyboardInterrupt()
     56         f = self.MODULE.StringIO()
     57         self.assertRaises(KeyboardInterrupt, f.writelines, errorGen())
     58 
     59     def test_truncate(self):
     60         eq = self.assertEqual
     61         f = self.MODULE.StringIO()
     62         f.write(self._lines)
     63         f.seek(10)
     64         f.truncate()
     65         eq(f.getvalue(), 'abcdefghij')
     66         f.truncate(5)
     67         eq(f.getvalue(), 'abcde')
     68         f.write('xyz')
     69         eq(f.getvalue(), 'abcdexyz')
     70         self.assertRaises(IOError, f.truncate, -1)
     71         f.close()
     72         self.assertRaises(ValueError, f.write, 'frobnitz')
     73 
     74     def test_closed_flag(self):
     75         f = self.MODULE.StringIO()
     76         self.assertEqual(f.closed, False)
     77         f.close()
     78         self.assertEqual(f.closed, True)
     79         f = self.MODULE.StringIO("abc")
     80         self.assertEqual(f.closed, False)
     81         f.close()
     82         self.assertEqual(f.closed, True)
     83 
     84     def test_isatty(self):
     85         f = self.MODULE.StringIO()
     86         self.assertRaises(TypeError, f.isatty, None)
     87         self.assertEqual(f.isatty(), False)
     88         f.close()
     89         self.assertRaises(ValueError, f.isatty)
     90 
     91     def test_iterator(self):
     92         eq = self.assertEqual
     93         unless = self.assertTrue
     94         eq(iter(self._fp), self._fp)
     95         # Does this object support the iteration protocol?
     96         unless(hasattr(self._fp, '__iter__'))
     97         unless(hasattr(self._fp, 'next'))
     98         i = 0
     99         for line in self._fp:
    100             eq(line, self._line + '\n')
    101             i += 1
    102         eq(i, 5)
    103         self._fp.close()
    104         self.assertRaises(ValueError, self._fp.next)
    105 
    106     def test_getvalue(self):
    107         self._fp.close()
    108         self.assertRaises(ValueError, self._fp.getvalue)
    109 
    110     @test_support.bigmemtest(test_support._2G + 2**26, memuse=2.001)
    111     def test_reads_from_large_stream(self, size):
    112         linesize = 2**26 # 64 MiB
    113         lines = ['x' * (linesize - 1) + '\n'] * (size // linesize) + \
    114                 ['y' * (size % linesize)]
    115         f = self.MODULE.StringIO(''.join(lines))
    116         for i, expected in enumerate(lines):
    117             line = f.read(len(expected))
    118             self.assertEqual(len(line), len(expected))
    119             self.assertEqual(line, expected)
    120         self.assertEqual(f.read(), '')
    121         f.seek(0)
    122         for i, expected in enumerate(lines):
    123             line = f.readline()
    124             self.assertEqual(len(line), len(expected))
    125             self.assertEqual(line, expected)
    126         self.assertEqual(f.readline(), '')
    127         f.seek(0)
    128         self.assertEqual(f.readlines(), lines)
    129         self.assertEqual(f.readlines(), [])
    130         f.seek(0)
    131         self.assertEqual(f.readlines(size), lines)
    132         self.assertEqual(f.readlines(), [])
    133 
    134     # In worst case cStringIO requires 2 + 1 + 1/2 + 1/2**2 + ... = 4
    135     # bytes per input character.
    136     @test_support.bigmemtest(test_support._2G, memuse=4)
    137     def test_writes_to_large_stream(self, size):
    138         s = 'x' * 2**26 # 64 MiB
    139         f = self.MODULE.StringIO()
    140         n = size
    141         while n > len(s):
    142             f.write(s)
    143             n -= len(s)
    144         s = None
    145         f.write('x' * n)
    146         self.assertEqual(len(f.getvalue()), size)
    147 
    148 
    149 class TestStringIO(TestGenericStringIO):
    150     MODULE = StringIO
    151 
    152     def test_unicode(self):
    153 
    154         if not test_support.have_unicode: return
    155 
    156         # The StringIO module also supports concatenating Unicode
    157         # snippets to larger Unicode strings. This is tested by this
    158         # method. Note that cStringIO does not support this extension.
    159 
    160         f = self.MODULE.StringIO()
    161         f.write(self._line[:6])
    162         f.seek(3)
    163         f.write(unicode(self._line[20:26]))
    164         f.write(unicode(self._line[52]))
    165         s = f.getvalue()
    166         self.assertEqual(s, unicode('abcuvwxyz!'))
    167         self.assertEqual(type(s), types.UnicodeType)
    168 
    169 class TestcStringIO(TestGenericStringIO):
    170     MODULE = cStringIO
    171 
    172     def test_array_support(self):
    173         # Issue #1730114: cStringIO should accept array objects
    174         a = array.array('B', [0,1,2])
    175         f = self.MODULE.StringIO(a)
    176         self.assertEqual(f.getvalue(), '\x00\x01\x02')
    177 
    178     def test_unicode(self):
    179 
    180         if not test_support.have_unicode: return
    181 
    182         # The cStringIO module converts Unicode strings to character
    183         # strings when writing them to cStringIO objects.
    184         # Check that this works.
    185 
    186         f = self.MODULE.StringIO()
    187         f.write(u'abcde')
    188         s = f.getvalue()
    189         self.assertEqual(s, 'abcde')
    190         self.assertEqual(type(s), str)
    191 
    192         f = self.MODULE.StringIO(u'abcde')
    193         s = f.getvalue()
    194         self.assertEqual(s, 'abcde')
    195         self.assertEqual(type(s), str)
    196 
    197         self.assertRaises(UnicodeEncodeError, self.MODULE.StringIO, u'\xf4')
    198 
    199 
    200 import sys
    201 if sys.platform.startswith('java'):
    202     # Jython doesn't have a buffer object, so we just do a useless
    203     # fake of the buffer tests.
    204     buffer = str
    205 
    206 class TestBufferStringIO(TestStringIO):
    207     constructor = buffer
    208 
    209 class TestBuffercStringIO(TestcStringIO):
    210     constructor = buffer
    211 
    212 class TestMemoryviewcStringIO(TestcStringIO):
    213     constructor = memoryview
    214 
    215 
    216 def test_main():
    217     test_support.run_unittest(TestStringIO, TestcStringIO)
    218     with test_support.check_py3k_warnings(("buffer.. not supported",
    219                                              DeprecationWarning)):
    220         test_support.run_unittest(TestBufferStringIO, TestBuffercStringIO)
    221     test_support.run_unittest(TestMemoryviewcStringIO)
    222 
    223 if __name__ == '__main__':
    224     test_main()
    225