test_stripspace.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. # test_stripspace.py -- Tests for stripspace functionality
  2. # Copyright (C) 2025 Jelmer Vernooij <jelmer@jelmer.uk>
  3. #
  4. # Dulwich is dual-licensed under the Apache License, Version 2.0 and the GNU
  5. # General Public License as public by the Free Software Foundation; version 2.0
  6. # or (at your option) any later version. You can redistribute it and/or
  7. # modify it under the terms of either of these two licenses.
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. #
  15. # You should have received a copy of the licenses; if not, see
  16. # <http://www.gnu.org/licenses/> for a copy of the GNU General Public License
  17. # and <http://www.apache.org/licenses/LICENSE-2.0> for a copy of the Apache
  18. # License, Version 2.0.
  19. """Tests for stripspace functionality."""
  20. import unittest
  21. from dulwich.stripspace import stripspace
  22. class StripspaceTests(unittest.TestCase):
  23. """Tests for the stripspace function."""
  24. def test_empty_input(self):
  25. """Test that empty input returns empty output."""
  26. self.assertEqual(stripspace(b""), b"")
  27. def test_simple_text(self):
  28. """Test simple text with no issues."""
  29. self.assertEqual(stripspace(b"hello\nworld\n"), b"hello\nworld\n")
  30. def test_trailing_whitespace(self):
  31. """Test that trailing whitespace is removed."""
  32. self.assertEqual(stripspace(b"hello \nworld\t\n"), b"hello\nworld\n")
  33. def test_multiple_blank_lines(self):
  34. """Test that multiple blank lines are collapsed to one."""
  35. self.assertEqual(
  36. stripspace(b"hello\n\n\n\nworld\n"),
  37. b"hello\n\nworld\n",
  38. )
  39. def test_leading_blank_lines(self):
  40. """Test that leading blank lines are removed."""
  41. self.assertEqual(
  42. stripspace(b"\n\n\nhello\nworld\n"),
  43. b"hello\nworld\n",
  44. )
  45. def test_trailing_blank_lines(self):
  46. """Test that trailing blank lines are removed."""
  47. self.assertEqual(
  48. stripspace(b"hello\nworld\n\n\n"),
  49. b"hello\nworld\n",
  50. )
  51. def test_leading_and_trailing_blank_lines(self):
  52. """Test that both leading and trailing blank lines are removed."""
  53. self.assertEqual(
  54. stripspace(b"\n\nhello\nworld\n\n"),
  55. b"hello\nworld\n",
  56. )
  57. def test_adds_final_newline(self):
  58. """Test that a final newline is added if missing."""
  59. self.assertEqual(stripspace(b"hello\nworld"), b"hello\nworld\n")
  60. def test_complex_whitespace(self):
  61. """Test complex whitespace cleanup."""
  62. input_text = b" hello \n\n\n\n world \n\n"
  63. expected = b"hello\n\nworld\n"
  64. self.assertEqual(stripspace(input_text), expected)
  65. def test_strip_comments(self):
  66. """Test stripping lines that start with comment character."""
  67. input_text = b"# comment\nhello\n# another comment\nworld\n"
  68. expected = b"hello\nworld\n"
  69. self.assertEqual(stripspace(input_text, strip_comments=True), expected)
  70. def test_strip_comments_indented(self):
  71. """Test that indented comments are also stripped."""
  72. input_text = b" # comment\nhello\n\t# another comment\nworld\n"
  73. expected = b"hello\nworld\n"
  74. self.assertEqual(stripspace(input_text, strip_comments=True), expected)
  75. def test_strip_comments_custom_char(self):
  76. """Test stripping comments with custom comment character."""
  77. input_text = b"; comment\nhello\n; another comment\nworld\n"
  78. expected = b"hello\nworld\n"
  79. self.assertEqual(
  80. stripspace(input_text, strip_comments=True, comment_char=b";"),
  81. expected,
  82. )
  83. def test_comment_lines(self):
  84. """Test prepending comment character to each line."""
  85. input_text = b"hello\nworld\n"
  86. expected = b"# hello\n# world\n"
  87. self.assertEqual(stripspace(input_text, comment_lines=True), expected)
  88. def test_comment_lines_custom_char(self):
  89. """Test prepending custom comment character to each line."""
  90. input_text = b"hello\nworld\n"
  91. expected = b"; hello\n; world\n"
  92. self.assertEqual(
  93. stripspace(input_text, comment_lines=True, comment_char=b";"),
  94. expected,
  95. )
  96. def test_only_whitespace(self):
  97. """Test input that contains only whitespace."""
  98. self.assertEqual(stripspace(b" \n\t\n \n"), b"")
  99. def test_only_blank_lines(self):
  100. """Test input that contains only blank lines."""
  101. self.assertEqual(stripspace(b"\n\n\n"), b"")
  102. def test_crlf_line_endings(self):
  103. """Test handling of Windows-style line endings."""
  104. self.assertEqual(
  105. stripspace(b"hello \r\nworld\t\r\n"),
  106. b"hello\r\nworld\r\n",
  107. )
  108. def test_mixed_line_endings(self):
  109. """Test handling of mixed line endings."""
  110. self.assertEqual(
  111. stripspace(b"hello \r\nworld\t\n"),
  112. b"hello\r\nworld\n",
  113. )
  114. def test_commit_message_example(self):
  115. """Test a realistic commit message cleanup."""
  116. input_text = b"""
  117. Add new feature
  118. This commit adds a new feature to the project.
  119. Signed-off-by: Alice <alice@example.com>
  120. """
  121. expected = b"""Add new feature
  122. This commit adds a new feature to the project.
  123. Signed-off-by: Alice <alice@example.com>
  124. """
  125. self.assertEqual(stripspace(input_text), expected)
  126. def test_strip_comments_preserves_non_comment_hash(self):
  127. """Test that # in the middle of a line is not treated as a comment."""
  128. input_text = b"# comment\nhello # world\n"
  129. expected = b"hello # world\n"
  130. self.assertEqual(stripspace(input_text, strip_comments=True), expected)
  131. def test_comment_lines_then_strip_whitespace(self):
  132. """Test that comment_lines works correctly with whitespace stripping."""
  133. input_text = b"hello \n\n\nworld \n"
  134. expected = b"# hello\n\n# world\n"
  135. self.assertEqual(stripspace(input_text, comment_lines=True), expected)
  136. def test_only_comments(self):
  137. """Test input that contains only comments."""
  138. input_text = b"# comment 1\n# comment 2\n# comment 3\n"
  139. self.assertEqual(stripspace(input_text, strip_comments=True), b"")
  140. def test_blank_line_between_content(self):
  141. """Test that a single blank line between content is preserved."""
  142. input_text = b"hello\n\nworld\n"
  143. expected = b"hello\n\nworld\n"
  144. self.assertEqual(stripspace(input_text), expected)