1# Tests universal newline support for both reading and parsing files.
2import io
3import _pyio as pyio
4import unittest
5import os
6import sys
7from test import support
8
9if not hasattr(sys.stdin, 'newlines'):
10    raise unittest.SkipTest(
11        "This Python does not have universal newline support")
12
13FATX = 'x' * (2**14)
14
15DATA_TEMPLATE = [
16    "line1=1",
17    "line2='this is a very long line designed to go past any default " +
18        "buffer limits that exist in io.py but we also want to test " +
19        "the uncommon case, naturally.'",
20    "def line3():pass",
21    "line4 = '%s'" % FATX,
22    ]
23
24DATA_LF = "\n".join(DATA_TEMPLATE) + "\n"
25DATA_CR = "\r".join(DATA_TEMPLATE) + "\r"
26DATA_CRLF = "\r\n".join(DATA_TEMPLATE) + "\r\n"
27
28# Note that DATA_MIXED also tests the ability to recognize a lone \r
29# before end-of-file.
30DATA_MIXED = "\n".join(DATA_TEMPLATE) + "\r"
31DATA_SPLIT = [x + "\n" for x in DATA_TEMPLATE]
32
33class CTest:
34    open = io.open
35
36class PyTest:
37    open = staticmethod(pyio.open)
38
39class TestGenericUnivNewlines:
40    # use a class variable DATA to define the data to write to the file
41    # and a class variable NEWLINE to set the expected newlines value
42    READMODE = 'r'
43    WRITEMODE = 'wb'
44
45    def setUp(self):
46        data = self.DATA
47        if "b" in self.WRITEMODE:
48            data = data.encode("ascii")
49        with self.open(support.TESTFN, self.WRITEMODE) as fp:
50            fp.write(data)
51
52    def tearDown(self):
53        try:
54            os.unlink(support.TESTFN)
55        except:
56            pass
57
58    def test_read(self):
59        with self.open(support.TESTFN, self.READMODE) as fp:
60            data = fp.read()
61        self.assertEqual(data, DATA_LF)
62        self.assertEqual(repr(fp.newlines), repr(self.NEWLINE))
63
64    def test_readlines(self):
65        with self.open(support.TESTFN, self.READMODE) as fp:
66            data = fp.readlines()
67        self.assertEqual(data, DATA_SPLIT)
68        self.assertEqual(repr(fp.newlines), repr(self.NEWLINE))
69
70    def test_readline(self):
71        with self.open(support.TESTFN, self.READMODE) as fp:
72            data = []
73            d = fp.readline()
74            while d:
75                data.append(d)
76                d = fp.readline()
77        self.assertEqual(data, DATA_SPLIT)
78        self.assertEqual(repr(fp.newlines), repr(self.NEWLINE))
79
80    def test_seek(self):
81        with self.open(support.TESTFN, self.READMODE) as fp:
82            fp.readline()
83            pos = fp.tell()
84            data = fp.readlines()
85            self.assertEqual(data, DATA_SPLIT[1:])
86            fp.seek(pos)
87            data = fp.readlines()
88        self.assertEqual(data, DATA_SPLIT[1:])
89
90
91class TestCRNewlines(TestGenericUnivNewlines):
92    NEWLINE = '\r'
93    DATA = DATA_CR
94class CTestCRNewlines(CTest, TestCRNewlines, unittest.TestCase): pass
95class PyTestCRNewlines(PyTest, TestCRNewlines, unittest.TestCase): pass
96
97class TestLFNewlines(TestGenericUnivNewlines):
98    NEWLINE = '\n'
99    DATA = DATA_LF
100class CTestLFNewlines(CTest, TestLFNewlines, unittest.TestCase): pass
101class PyTestLFNewlines(PyTest, TestLFNewlines, unittest.TestCase): pass
102
103class TestCRLFNewlines(TestGenericUnivNewlines):
104    NEWLINE = '\r\n'
105    DATA = DATA_CRLF
106
107    def test_tell(self):
108        with self.open(support.TESTFN, self.READMODE) as fp:
109            self.assertEqual(repr(fp.newlines), repr(None))
110            data = fp.readline()
111            pos = fp.tell()
112        self.assertEqual(repr(fp.newlines), repr(self.NEWLINE))
113class CTestCRLFNewlines(CTest, TestCRLFNewlines, unittest.TestCase): pass
114class PyTestCRLFNewlines(PyTest, TestCRLFNewlines, unittest.TestCase): pass
115
116class TestMixedNewlines(TestGenericUnivNewlines):
117    NEWLINE = ('\r', '\n')
118    DATA = DATA_MIXED
119class CTestMixedNewlines(CTest, TestMixedNewlines, unittest.TestCase): pass
120class PyTestMixedNewlines(PyTest, TestMixedNewlines, unittest.TestCase): pass
121
122if __name__ == '__main__':
123    unittest.main()
124