From 1a210d219be89e0697be09349546910eeb5c571a Mon Sep 17 00:00:00 2001 From: Jack De Winter Date: Wed, 6 Nov 2024 20:32:35 -0800 Subject: [PATCH] https://github.com/jackdewinter/pymarkdown/issues/1208 --- publish/coverage.json | 8 +- publish/test-results.json | 2 +- pymarkdown/plugins/rule_md_012.py | 6 + test/rules/test_md012.py | 462 ++++++++---------------------- 4 files changed, 130 insertions(+), 348 deletions(-) diff --git a/publish/coverage.json b/publish/coverage.json index ef9a15f3..aa8022ae 100644 --- a/publish/coverage.json +++ b/publish/coverage.json @@ -2,12 +2,12 @@ "projectName": "pymarkdown", "reportSource": "pytest", "branchLevel": { - "totalMeasured": 5431, - "totalCovered": 5428 + "totalMeasured": 5433, + "totalCovered": 5430 }, "lineLevel": { - "totalMeasured": 21194, - "totalCovered": 21193 + "totalMeasured": 21197, + "totalCovered": 21196 } } diff --git a/publish/test-results.json b/publish/test-results.json index 979e1298..95d51a6e 100644 --- a/publish/test-results.json +++ b/publish/test-results.json @@ -1204,7 +1204,7 @@ }, { "name": "test.rules.test_md012", - "totalTests": 12, + "totalTests": 15, "failedTests": 0, "errorTests": 0, "skippedTests": 0, diff --git a/pymarkdown/plugins/rule_md_012.py b/pymarkdown/plugins/rule_md_012.py index 03a2a50c..2dae700d 100644 --- a/pymarkdown/plugins/rule_md_012.py +++ b/pymarkdown/plugins/rule_md_012.py @@ -87,6 +87,12 @@ def next_token(self, context: PluginScanContext, token: MarkdownToken) -> None: Event that a new token is being processed. """ if token.is_blank_line: + if ( + self.__last_blank_line is not None + and (token.line_number - self.__last_blank_line.line_number) != 1 + ): + self.__check_for_excess_blank_lines(context) + self.__blank_line_count = 0 self.__last_blank_line = token self.__blank_line_count += 1 else: diff --git a/test/rules/test_md012.py b/test/rules/test_md012.py index 7ce920b8..81eca582 100644 --- a/test/rules/test_md012.py +++ b/test/rules/test_md012.py @@ -3,370 +3,146 @@ """ import os -from test.markdown_scanner import MarkdownScanner -from test.rules.utils import execute_query_configuration_test, pluginQueryConfigTest +from test.rules.utils import ( + execute_configuration_test, + execute_query_configuration_test, + execute_scan_test, + id_test_plug_rule_fn, + pluginConfigErrorTest, + pluginQueryConfigTest, + pluginRuleTest, +) import pytest +source_path = os.path.join("test", "resources", "rules", "md012") + os.sep + +configTests = [ + pluginConfigErrorTest( + "bad_configuration_maximum", + use_strict_config=True, + set_args=["plugins.md012.maximum=$#-2"], + expected_error="""BadPluginError encountered while configuring plugins: +The value for property 'plugins.md012.maximum' is not valid: Allowable values are any non-negative integers.""", + ), +] + +scanTests = [ + pluginRuleTest( + "good_simple_paragraphs_single_blanks", + source_file_name=f"{source_path}good_simple_paragraphs_single_blanks.md", + ), + pluginRuleTest( + "bad_simple_paragraphs_double_blanks", + source_file_name=f"{source_path}good_simple_paragraphs_double_blanks.md", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:1: MD012: Multiple consecutive blank lines [Expected: 1, Actual: 2] (no-multiple-blanks)""", + ), + pluginRuleTest( + "good_simple_paragraphs_double_blanks", + source_file_name=f"{source_path}good_simple_paragraphs_double_blanks.md", + set_args=["plugins.md012.maximum=$#2"], + ), + pluginRuleTest( + "good_simple_paragraphs_triple_blanks", + source_file_name=f"{source_path}good_simple_paragraphs_triple_blanks.md", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:4:1: MD012: Multiple consecutive blank lines [Expected: 1, Actual: 3] (no-multiple-blanks)""", + ), + pluginRuleTest( + "bad_double_blanks_at_end", + source_file_name=f"{source_path}bad_double_blanks_at_end.md", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:1: MD012: Multiple consecutive blank lines [Expected: 1, Actual: 2] (no-multiple-blanks)""", + ), + pluginRuleTest( + "bad_multiple_blanks_in_block_quote", + source_file_name=f"{source_path}bad_multiple_blanks_in_block_quote.md", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:2: MD012: Multiple consecutive blank lines [Expected: 1, Actual: 2] (no-multiple-blanks)""", + ), + pluginRuleTest( + "bad_multiple_blanks_in_list", + source_file_name=f"{source_path}bad_multiple_blanks_in_list.md", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:1: MD012: Multiple consecutive blank lines [Expected: 1, Actual: 2] (no-multiple-blanks)""", + disable_rules="md009", + ), + pluginRuleTest( + "good_multiple_blanks_in_fenced", + source_file_name=f"{source_path}good_multiple_blanks_in_fenced.md", + scan_expected_return_code=0, + ), + pluginRuleTest( + "good_multiple_blanks_in_indented", + source_file_name=f"{source_path}good_multiple_blanks_in_indented.md", + scan_expected_return_code=0, + ), + pluginRuleTest( + "bad_multiple_blanks_in_html", + source_file_name=f"{source_path}bad_multiple_blanks_in_html.md", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:1: MD012: Multiple consecutive blank lines [Expected: 1, Actual: 2] (no-multiple-blanks)""", + ), + pluginRuleTest( + "good_blanks_around_single_pragma", + source_file_contents="""Some markdown here + + + +My 10 lines +""", + scan_expected_return_code=0, + ), + pluginRuleTest( + "bad_blanks_double_around_single_pragma", + source_file_contents="""Some markdown here -@pytest.mark.rules -def test_md012_bad_configuration_maximum(): - """ - Test to verify that a configuration error is thrown when supplying the - maximum value with an integer that is negative. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md012", "good_simple_paragraphs_single_blanks.md" - ) - supplied_arguments = [ - "--set", - "plugins.md012.maximum=$#-2", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = "" - expected_error = ( - "BadPluginError encountered while configuring plugins:\n" - + "The value for property 'plugins.md012.maximum' is not valid: Allowable values are any non-negative integers." - ) - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - - -@pytest.mark.rules -def test_md012_good_simple_paragraphs_single_blanks(): - """ - Test to make sure this rule does not trigger with a document that - contains only paragraphs with a single blank line between them. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md012", "good_simple_paragraphs_single_blanks.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 0 - expected_output = "" - expected_error = "" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - - -@pytest.mark.rules -def test_md012_bad_simple_paragraphs_double_blanks(): - """ - Test to make sure this rule does trigger with a document that - contains only paragraphs with two blank lines between them. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md012", "good_simple_paragraphs_double_blanks.md" - ) - supplied_arguments = [ - # "--log-level", "DEBUG", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:1: " - + "MD012: Multiple consecutive blank lines [Expected: 1, Actual: 2] (no-multiple-blanks)" - ) - expected_error = "" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - - -@pytest.mark.rules -def test_md012_good_simple_paragraphs_double_blanks(): - """ - Test to make sure this rule does not trigger with a document that - contains only paragraphs with two blank lines between them and - the configuration to make that correct. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md012", "good_simple_paragraphs_double_blanks.md" - ) - supplied_arguments = [ - "--set", - "plugins.md012.maximum=$#2", - "--strict-config", - "scan", - source_path, - ] - - expected_return_code = 0 - expected_output = "" - expected_error = "" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - - -@pytest.mark.rules -def test_md012_good_simple_paragraphs_triple_blanks(): - """ - Test to make sure this rule does trigger with a document that - contains only paragraphs with three blank lines between them. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md012", "good_simple_paragraphs_triple_blanks.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:4:1: " - + "MD012: Multiple consecutive blank lines [Expected: 1, Actual: 3] (no-multiple-blanks)" - ) - expected_error = "" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - - -@pytest.mark.rules -def test_md012_bad_double_blanks_at_end(): - """ - Test to make sure this rule does trigger with a document that - contains a paragraph followed by two blank lines. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md012", "bad_double_blanks_at_end.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:1: " - + "MD012: Multiple consecutive blank lines [Expected: 1, Actual: 2] (no-multiple-blanks)" - ) - expected_error = "" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - - -@pytest.mark.rules -def test_md012_bad_multiple_blanks_in_block_quote(): - """ - Test to make sure this rule does not trigger with a document that - contains two paragraphs separated by two blank lines, all within a block quote. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md012", "bad_multiple_blanks_in_block_quote.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:2: " - + "MD012: Multiple consecutive blank lines [Expected: 1, Actual: 2] (no-multiple-blanks)" - ) - expected_error = "" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) - - -@pytest.mark.rules -def test_md012_bad_multiple_blanks_in_list(): - """ - Test to make sure this rule does trigger with a document that - contains a paragraph followed by two blank lines, in a list item. - """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md012", "bad_multiple_blanks_in_list.md" - ) - supplied_arguments = [ - "--disable-rules", - "md009", - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:1: " - + "MD012: Multiple consecutive blank lines [Expected: 1, Actual: 2] (no-multiple-blanks)" - ) - expected_error = "" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) + -@pytest.mark.rules -def test_md012_good_multiple_blanks_in_fenced(): - """ - Test to make sure this rule does not trigger with a document that - contains a two blank lines within a fenced code block. - """ +My 10 lines +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:3:1: MD012: Multiple consecutive blank lines [Expected: 1, Actual: 2] (no-multiple-blanks) +{temp_source_path}:6:1: MD012: Multiple consecutive blank lines [Expected: 1, Actual: 2] (no-multiple-blanks)""", + ), + pluginRuleTest( + "bad_blanks_double_within_pragmas", + source_file_contents="""Some markdown here - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md012", "good_multiple_blanks_in_fenced.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] + - expected_return_code = 0 - expected_output = "" - expected_error = "" - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) + - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) +My 10 lines +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:5:1: MD012: Multiple consecutive blank lines [Expected: 1, Actual: 2] (no-multiple-blanks)""", + ), +] -@pytest.mark.rules -def test_md012_good_multiple_blanks_in_indented(): +@pytest.mark.parametrize("test", scanTests, ids=id_test_plug_rule_fn) +def test_md012_scan(test: pluginRuleTest) -> None: """ - Test to make sure this rule does not trigger with a document that - contains a two blank lines within a indented code block. + Execute a parameterized scan test for plugin md001. """ + execute_scan_test(test, "md007") - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md012", "good_multiple_blanks_in_indented.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 0 - expected_output = "" - expected_error = "" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code - ) +# Fix? -@pytest.mark.rules -def test_md012_bad_multiple_blanks_in_html(): +@pytest.mark.parametrize("test", configTests, ids=id_test_plug_rule_fn) +def test_md012_config(test: pluginRuleTest) -> None: """ - Test to make sure this rule does not trigger with a document that - contains a two blank lines within a HTML block. + Execute a parameterized fix test for plugin md001. """ - - # Arrange - scanner = MarkdownScanner() - source_path = os.path.join( - "test", "resources", "rules", "md012", "bad_multiple_blanks_in_html.md" - ) - supplied_arguments = [ - "scan", - source_path, - ] - - expected_return_code = 1 - expected_output = ( - f"{source_path}:3:1: " - + "MD012: Multiple consecutive blank lines [Expected: 1, Actual: 2] (no-multiple-blanks)" - ) - expected_error = "" - - # Act - execute_results = scanner.invoke_main(arguments=supplied_arguments) - - # Assert - execute_results.assert_results( - expected_output, expected_error, expected_return_code + execute_configuration_test( + test, f"{source_path}good_simple_paragraphs_single_blanks.md" )