diff --git a/tests/test_formatting.py b/tests/test_formatting.py index 9fe6475..7513a27 100755 --- a/tests/test_formatting.py +++ b/tests/test_formatting.py @@ -5,6 +5,7 @@ import pathlib import sys import unittest +import textwrap # Sets up sys.path and provides helpers import testutils as tu @@ -62,6 +63,34 @@ def test_index_slice(self): self.assertEqual(self._format(b"data[1 :1-1];").rstrip(), b"data[1 : 1 - 1];") self.assertEqual(self._format(b"data[f(): ];").rstrip(), b"data[f() :];") + def test_format_comment_separator(self): + """Validates that we preserve the separator before a comment. This is a + regression test for #62.""" + + self.assertEqual( + self._format(b"global x = 42; # Inline.\n"), b"global x = 42; # Inline.\n" + ) + + code = textwrap.dedent( + """\ + event zeek_init() {} + # Comment on next line. + """ + ) + + expected = textwrap.dedent( + """\ + event zeek_init() + \t{ } + # Comment on next line. + """ + ) + + # We split out lines here to work around different line endings on Windows. + self.assertEqual( + self._format(code.encode()).decode().splitlines(), expected.splitlines() + ) + class TestFormattingErrors(unittest.TestCase): def _format(self, content): diff --git a/zeekscript/formatter.py b/zeekscript/formatter.py index f6d3b50..33718e1 100644 --- a/zeekscript/formatter.py +++ b/zeekscript/formatter.py @@ -1336,10 +1336,15 @@ def __init__(self, script, node, ostream, indent=0, hints=None): class MinorCommentFormatter(CommentFormatter): def format(self): node = self.node - # There's something before us and it's not a newline, then - # separate this comment from it with a space: - if node.prev_cst_sibling and not node.prev_cst_sibling.is_nl(): - self._write_sp() + + # Preserve separator to previous node if any. + if node.prev_cst_sibling: + if node.prev_cst_sibling.is_nl(): + # Keep newlines verbatim. + self._write_nl() + else: + # If we are on the same line, normalize to exactly one space. + self._write_sp() self._format_token() # Write comment itself