diff --git a/asciidoc_linter/rules/whitespace_rules.py b/asciidoc_linter/rules/whitespace_rules.py index 3ea8359..ceb6f8e 100644 --- a/asciidoc_linter/rules/whitespace_rules.py +++ b/asciidoc_linter/rules/whitespace_rules.py @@ -41,6 +41,9 @@ def check_line( findings = [] line_content = self.get_line_content(line) + # Debug output to see why the whitespace_rules got triggered + print(f"Checking line {line_number + 1}: {line_content}") + # Check for multiple consecutive empty lines if not line_content.strip(): self.consecutive_empty_lines += 1 @@ -121,7 +124,7 @@ def check_line( # Check for blank line before section title (except for first line) if line_number > 0: prev_content = self.get_line_content(context[line_number - 1]) - if prev_content.strip(): + if prev_content.strip() and not prev_content.strip().startswith(("[.", "[[")): findings.append( Finding( rule_id=self.id, @@ -135,7 +138,7 @@ def check_line( # Check for blank line after section title (except for last line) if line_number < len(context) - 1: next_content = self.get_line_content(context[line_number + 1]) - if next_content.strip(): + if next_content.strip() and not next_content.strip().startswith(":"): findings.append( Finding( rule_id=self.id, diff --git a/tests/rules/test_heading_rules.py b/tests/rules/test_heading_rules.py old mode 100755 new mode 100644 index c577188..2866fc6 --- a/tests/rules/test_heading_rules.py +++ b/tests/rules/test_heading_rules.py @@ -308,5 +308,61 @@ def test_multiple_top_level(self): ) +class TestHeadingAttributesAndRoles(unittest.TestCase): + """Tests for headings with attributes or roles. + This rule ensures that headings followed by attributes or roles are handled correctly. + """ + + def setUp(self): + """ + Given a HeadingFormatRule instance + """ + self.rule = HeadingFormatRule() + + def test_heading_with_attribute(self): + """ + Given a document with headings followed by attributes + When the heading format rule is checked + Then no findings should be reported + """ + # Given: A document with headings followed by attributes + content = """ += Level 1 +:attribute: value + +== Level 2 +:another-attribute: value +""" + # When: We check the heading format + findings = self.rule.check(content) + + # Then: No findings should be reported + self.assertEqual( + len(findings), 0, "Headings followed by attributes should not produce findings" + ) + + def test_heading_with_role(self): + """ + Given a document with headings followed by roles + When the heading format rule is checked + Then no findings should be reported + """ + # Given: A document with headings followed by roles + content = """ +[.role] += Level 1 + +[[target]] +== Level 2 +""" + # When: We check the heading format + findings = self.rule.check(content) + + # Then: No findings should be reported + self.assertEqual( + len(findings), 0, "Headings followed by roles should not produce findings" + ) + + if __name__ == "__main__": unittest.main() diff --git a/tests/test_linter.py b/tests/test_linter.py index 79156f4..a22eb9f 100644 --- a/tests/test_linter.py +++ b/tests/test_linter.py @@ -184,3 +184,27 @@ def test_lint_with_config_file(tmp_path, sample_asciidoc): # Ensure that the WS001 rule is disabled and no findings are reported assert len(report.findings) == 0 + + +def test_lint_string_with_attributes_and_roles(mock_parser, mock_rule): + """Test linting a string with headings followed by attributes or roles""" + content = """ += Title +:attribute: value + +[.role] +== Section 1 + +[[target]] +== Section 2 +""" + + with patch("asciidoc_linter.linter.AsciiDocParser", return_value=mock_parser): + linter = AsciiDocLinter() + linter.rules = [mock_rule] + + findings = linter.lint_string(content) + + assert len(findings) == 0 + mock_parser.parse.assert_called_once_with(content) + mock_rule.check.assert_called_once() diff --git a/tests/test_reporter.py b/tests/test_reporter.py old mode 100755 new mode 100644 index 3e51b2a..b676ce3 --- a/tests/test_reporter.py +++ b/tests/test_reporter.py @@ -171,3 +171,29 @@ def test_html_reporter_styling(sample_report): assert "