# -*- coding: utf-8 -*- # Copyright (C) 2014 Yahoo! Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import tempfile import testtools from doc8 import checks from doc8 import parser class TestTrailingWhitespace(testtools.TestCase): def test_trailing(self): lines = ["a b ", "ab"] check = checks.CheckTrailingWhitespace({}) errors = [] for line in lines: errors.extend(check.report_iter(line)) self.assertEqual(1, len(errors)) (code, msg) = errors[0] self.assertIn(code, check.REPORTS) class TestTabIndentation(testtools.TestCase): def test_tabs(self): lines = [" b", "\tabc", "efg", "\t\tc"] check = checks.CheckIndentationNoTab({}) errors = [] for line in lines: errors.extend(check.report_iter(line)) self.assertEqual(2, len(errors)) (code, msg) = errors[0] self.assertIn(code, check.REPORTS) class TestCarriageReturn(testtools.TestCase): def test_cr(self): lines = ["\tabc", "efg", "\r\n"] check = checks.CheckCarriageReturn({}) errors = [] for line in lines: errors.extend(check.report_iter(line)) self.assertEqual(1, len(errors)) (code, msg) = errors[0] self.assertIn(code, check.REPORTS) class TestLineLength(testtools.TestCase): def test_over_length(self): content = b""" === aaa === ---- test ---- """ content += b"\n\n" content += (b"a" * 60) + b" " + (b"b" * 60) content += b"\n" conf = { 'max_line_length': 79, 'allow_long_titles': True, } for ext in ['.rst', '.txt']: with tempfile.NamedTemporaryFile(suffix=ext) as fh: fh.write(content) fh.flush() parsed_file = parser.ParsedFile(fh.name) check = checks.CheckMaxLineLength(conf) errors = list(check.report_iter(parsed_file)) self.assertEqual(1, len(errors)) (line, code, msg) = errors[0] self.assertIn(code, check.REPORTS) def test_correct_length(self): conf = { 'max_line_length': 79, 'allow_long_titles': True, } with tempfile.NamedTemporaryFile(suffix='.rst') as fh: fh.write(b'known exploit in the wild, for example' b' \xe2\x80\x93 the time' b' between advance notification') fh.flush() parsed_file = parser.ParsedFile(fh.name, encoding='utf-8') check = checks.CheckMaxLineLength(conf) errors = list(check.report_iter(parsed_file)) self.assertEqual(0, len(errors)) def test_ignore_code_block(self): conf = { 'max_line_length': 79, 'allow_long_titles': True, } with tempfile.NamedTemporaryFile(suffix='.rst') as fh: fh.write(b'List which contains items with code-block\n' b'- this is a list item\n\n' b' .. code-block:: ini\n\n' b' this line exceeds 80 chars but should be ignored' b'this line exceeds 80 chars but should be ignored' b'this line exceeds 80 chars but should be ignored') fh.flush() parsed_file = parser.ParsedFile(fh.name, encoding='utf-8') check = checks.CheckMaxLineLength(conf) errors = list(check.report_iter(parsed_file)) self.assertEqual(0, len(errors)) def test_unsplittable_length(self): content = b""" === aaa === ---- test ---- """ content += b"\n\n" content += b"a" * 100 content += b"\n" conf = { 'max_line_length': 79, 'allow_long_titles': True, } # This number is different since rst parsing is aware that titles # are allowed to be over-length, while txt parsing is not aware of # this fact (since it has no concept of title sections). extensions = [(0, '.rst'), (1, '.txt')] for expected_errors, ext in extensions: with tempfile.NamedTemporaryFile(suffix=ext) as fh: fh.write(content) fh.flush() parsed_file = parser.ParsedFile(fh.name) check = checks.CheckMaxLineLength(conf) errors = list(check.report_iter(parsed_file)) self.assertEqual(expected_errors, len(errors)) class TestNewlineEndOfFile(testtools.TestCase): def test_newline(self): tests = [(1, b"testing"), (1, b"testing\ntesting"), (0, b"testing\n"), (0, b"testing\ntesting\n")] for expected_errors, line in tests: with tempfile.NamedTemporaryFile() as fh: fh.write(line) fh.flush() parsed_file = parser.ParsedFile(fh.name) check = checks.CheckNewlineEndOfFile({}) errors = list(check.report_iter(parsed_file)) self.assertEqual(expected_errors, len(errors))