diff --git a/MANIFEST.in b/MANIFEST.in index 59a31962..71bee650 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -11,3 +11,4 @@ recursive-include src *.png recursive-include src *.pt recursive-include src *.zcml recursive-include src *.rst +recursive-include src *.txt diff --git a/src/zope/app/apidoc/codemodule/.gitattributes b/src/zope/app/apidoc/codemodule/.gitattributes new file mode 100644 index 00000000..3e2f6a8d --- /dev/null +++ b/src/zope/app/apidoc/codemodule/.gitattributes @@ -0,0 +1,3 @@ +# make sure git doesn't normalize these files. +_test_crlf.txt text=false +_test_cr.txt text=false diff --git a/src/zope/app/apidoc/codemodule/_test_cr.txt b/src/zope/app/apidoc/codemodule/_test_cr.txt new file mode 100644 index 00000000..72a020d4 --- /dev/null +++ b/src/zope/app/apidoc/codemodule/_test_cr.txt @@ -0,0 +1 @@ +This file uses Mac line endings. \ No newline at end of file diff --git a/src/zope/app/apidoc/codemodule/_test_crlf.txt b/src/zope/app/apidoc/codemodule/_test_crlf.txt new file mode 100644 index 00000000..13fce246 --- /dev/null +++ b/src/zope/app/apidoc/codemodule/_test_crlf.txt @@ -0,0 +1,4 @@ +This file +uses +Windows +line endings. \ No newline at end of file diff --git a/src/zope/app/apidoc/codemodule/tests.py b/src/zope/app/apidoc/codemodule/tests.py index 60284e45..33724785 100644 --- a/src/zope/app/apidoc/codemodule/tests.py +++ b/src/zope/app/apidoc/codemodule/tests.py @@ -14,17 +14,43 @@ """Tests for the Code Documentation Module """ - +import os.path import unittest import doctest from zope.component import testing +from zope.app.apidoc.codemodule.text import TextFile + from zope.app.apidoc.tests import standard_checker from zope.app.apidoc.tests import standard_option_flags from zope.app.apidoc.tests import LayerDocFileSuite import zope.app.apidoc.codemodule +here = os.path.dirname(__file__) + +class TestText(unittest.TestCase): + + def _read_via_text(self, path): + return TextFile(os.path.join(here, path), path, None).getContent() + + def _read_bytes(self, path): + with open(os.path.join(here, path), 'rb') as f: + return f.read() + + def test_crlf(self): + self.assertEqual(self._read_bytes('_test_crlf.txt'), + b'This file\r\nuses \r\nWindows \r\nline endings.') + + self.assertEqual(self._read_via_text('_test_crlf.txt'), + u'This file\nuses \nWindows \nline endings.') + + def test_cr(self): + self.assertEqual(self._read_bytes('_test_cr.txt'), + b'This file\ruses \rMac \rline endings.') + + self.assertEqual(self._read_via_text('_test_cr.txt'), + u'This file\nuses \nMac \nline endings.') def test_suite(): checker = standard_checker() @@ -39,6 +65,7 @@ def test_suite(): tearDown=testing.tearDown, checker=checker, optionflags=standard_option_flags), + unittest.defaultTestLoader.loadTestsFromName(__name__), )) if __name__ == '__main__': diff --git a/src/zope/app/apidoc/codemodule/text.py b/src/zope/app/apidoc/codemodule/text.py index fdc446a7..5a1c3deb 100644 --- a/src/zope/app/apidoc/codemodule/text.py +++ b/src/zope/app/apidoc/codemodule/text.py @@ -15,6 +15,7 @@ """ __docformat__ = 'restructuredtext' + from zope.interface import implementer from zope.location.interfaces import ILocation @@ -31,6 +32,11 @@ def __init__(self, path, name, package): self.__name__ = name def getContent(self): - with open(self.path, 'rUb') as f: + with open(self.path, 'rb') as f: content = f.read() + + # Make newlines universal + content = content.replace(b'\r\n', b'\n') + content = content.replace(b'\r', b'\n') + return content.decode('utf-8')