Style checker for sphinx (or other) rst documentation.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_checks.py 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. # -*- coding: utf-8 -*-
  2. # Copyright (C) 2014 Yahoo! Inc. All Rights Reserved.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  5. # not use this file except in compliance with the License. You may obtain
  6. # a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. # License for the specific language governing permissions and limitations
  14. # under the License.
  15. import tempfile
  16. import testtools
  17. from doc8 import checks
  18. from doc8 import parser
  19. class TestTrailingWhitespace(testtools.TestCase):
  20. def test_trailing(self):
  21. lines = ["a b ", "ab"]
  22. check = checks.CheckTrailingWhitespace({})
  23. errors = []
  24. for line in lines:
  25. errors.extend(check.report_iter(line))
  26. self.assertEqual(1, len(errors))
  27. (code, msg) = errors[0]
  28. self.assertIn(code, check.REPORTS)
  29. class TestTabIndentation(testtools.TestCase):
  30. def test_tabs(self):
  31. lines = [" b", "\tabc", "efg", "\t\tc"]
  32. check = checks.CheckIndentationNoTab({})
  33. errors = []
  34. for line in lines:
  35. errors.extend(check.report_iter(line))
  36. self.assertEqual(2, len(errors))
  37. (code, msg) = errors[0]
  38. self.assertIn(code, check.REPORTS)
  39. class TestCarriageReturn(testtools.TestCase):
  40. def test_cr(self):
  41. lines = ["\tabc", "efg", "\r\n"]
  42. check = checks.CheckCarriageReturn({})
  43. errors = []
  44. for line in lines:
  45. errors.extend(check.report_iter(line))
  46. self.assertEqual(1, len(errors))
  47. (code, msg) = errors[0]
  48. self.assertIn(code, check.REPORTS)
  49. class TestLineLength(testtools.TestCase):
  50. def test_over_length(self):
  51. content = """
  52. ===
  53. aaa
  54. ===
  55. ----
  56. test
  57. ----
  58. """
  59. content += "\n\n"
  60. content += ("a" * 60) + " " + ("b" * 60)
  61. content += "\n"
  62. conf = {
  63. 'max_line_length': 79,
  64. 'allow_long_titles': True,
  65. }
  66. for ext in ['.rst', '.txt']:
  67. with tempfile.NamedTemporaryFile(suffix=ext) as fh:
  68. fh.write(content)
  69. fh.flush()
  70. parsed_file = parser.ParsedFile(fh.name)
  71. check = checks.CheckMaxLineLength(conf)
  72. errors = list(check.report_iter(parsed_file))
  73. self.assertEqual(1, len(errors))
  74. (line, code, msg) = errors[0]
  75. self.assertIn(code, check.REPORTS)
  76. def test_correct_length(self):
  77. conf = {
  78. 'max_line_length': 79,
  79. 'allow_long_titles': True,
  80. }
  81. with tempfile.NamedTemporaryFile(suffix='.rst') as fh:
  82. fh.write(b'known exploit in the wild, for example'
  83. ' \xe2\x80\x93 the time'
  84. ' between advance notification')
  85. fh.flush()
  86. parsed_file = parser.ParsedFile(fh.name, encoding='utf-8')
  87. check = checks.CheckMaxLineLength(conf)
  88. errors = list(check.report_iter(parsed_file))
  89. self.assertEqual(0, len(errors))
  90. def test_unsplittable_length(self):
  91. content = """
  92. ===
  93. aaa
  94. ===
  95. ----
  96. test
  97. ----
  98. """
  99. content += "\n\n"
  100. content += "a" * 100
  101. content += "\n"
  102. conf = {
  103. 'max_line_length': 79,
  104. 'allow_long_titles': True,
  105. }
  106. # This number is different since rst parsing is aware that titles
  107. # are allowed to be over-length, while txt parsing is not aware of
  108. # this fact (since it has no concept of title sections).
  109. extensions = [(0, '.rst'), (1, '.txt')]
  110. for expected_errors, ext in extensions:
  111. with tempfile.NamedTemporaryFile(suffix=ext) as fh:
  112. fh.write(content)
  113. fh.flush()
  114. parsed_file = parser.ParsedFile(fh.name)
  115. check = checks.CheckMaxLineLength(conf)
  116. errors = list(check.report_iter(parsed_file))
  117. self.assertEqual(expected_errors, len(errors))
  118. class TestNewlineEndOfFile(testtools.TestCase):
  119. def test_newline(self):
  120. tests = [(1, "testing"),
  121. (1, "testing\ntesting"),
  122. (0, "testing\n"),
  123. (0, "testing\ntesting\n")]
  124. for expected_errors, line in tests:
  125. with tempfile.NamedTemporaryFile() as fh:
  126. fh.write(line)
  127. fh.flush()
  128. parsed_file = parser.ParsedFile(fh.name)
  129. check = checks.CheckNewlineEndOfFile({})
  130. errors = list(check.report_iter(parsed_file))
  131. self.assertEqual(expected_errors, len(errors))