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