From 17ba688368eb75e59b8632405caf0907a8ec685d Mon Sep 17 00:00:00 2001 From: jackdewinter Date: Sat, 17 Feb 2024 07:27:10 -0800 Subject: [PATCH] Issue 990 (#1002) * https://github.com/jackdewinter/pymarkdown/issues/1001 --- changelog.md | 2 + publish/coverage.json | 8 +- publish/test-results.json | 6 +- pymarkdown/plugins/rule_md_019.py | 27 +-- pymarkdown/plugins/rule_md_021.py | 69 ++++++-- test/api/test_api_scan.py | 10 +- test/rules/test_md005.py | 4 +- test/rules/test_md006.py | 6 +- test/rules/test_md007.py | 8 +- test/rules/test_md019.py | 200 +++++++++++++++++++++- test/rules/test_md021.py | 269 +++++++++++++++++++++++++++++- test/test_main.py | 6 +- 12 files changed, 555 insertions(+), 60 deletions(-) diff --git a/changelog.md b/changelog.md index 495ba11e7..e27c2792d 100644 --- a/changelog.md +++ b/changelog.md @@ -15,6 +15,8 @@ - [Issue 994](https://github.com/jackdewinter/pymarkdown/issues/994) - Verified behavior of Rule Md029, adding configuration for starting ordered lists from integers greater than 1 +- [Issue 1001](https://github.com/jackdewinter/pymarkdown/issues/1001) + - Verified behavior of rules Md019 and Md021, fixing issues with Md021 ### Changed diff --git a/publish/coverage.json b/publish/coverage.json index 7f029692f..0b266580a 100644 --- a/publish/coverage.json +++ b/publish/coverage.json @@ -2,12 +2,12 @@ "projectName": "pymarkdown", "reportSource": "pytest", "branchLevel": { - "totalMeasured": 4823, - "totalCovered": 4823 + "totalMeasured": 4831, + "totalCovered": 4831 }, "lineLevel": { - "totalMeasured": 19417, - "totalCovered": 19417 + "totalMeasured": 19442, + "totalCovered": 19442 } } diff --git a/publish/test-results.json b/publish/test-results.json index 401c15563..6d3f8dd0f 100644 --- a/publish/test-results.json +++ b/publish/test-results.json @@ -1220,7 +1220,7 @@ }, { "name": "test.rules.test_md019", - "totalTests": 21, + "totalTests": 47, "failedTests": 0, "errorTests": 0, "skippedTests": 0, @@ -1236,7 +1236,7 @@ }, { "name": "test.rules.test_md021", - "totalTests": 20, + "totalTests": 53, "failedTests": 0, "errorTests": 0, "skippedTests": 0, @@ -1604,7 +1604,7 @@ }, { "name": "test.test_markdown_extra", - "totalTests": 114, + "totalTests": 115, "failedTests": 0, "errorTests": 0, "skippedTests": 0, diff --git a/pymarkdown/plugins/rule_md_019.py b/pymarkdown/plugins/rule_md_019.py index bfecaa03c..4b215ba51 100644 --- a/pymarkdown/plugins/rule_md_019.py +++ b/pymarkdown/plugins/rule_md_019.py @@ -72,18 +72,19 @@ def next_token(self, context: PluginScanContext, token: MarkdownToken) -> None: self.__atx_heading_token = None elif token.is_text: text_token = cast(TextMarkdownToken, token) - resolved_extracted_whitespace = ParserHelper.remove_all_from_text( - text_token.extracted_whitespace - ) - if self.__atx_heading_token and "\t" in resolved_extracted_whitespace: - start_index = ( - self.__atx_heading_token.column_number - - 1 - + self.__atx_heading_token.hash_count - ) - resolved_extracted_whitespace = TabHelper.detabify_string( - resolved_extracted_whitespace, start_index + if self.__atx_heading_token: + resolved_extracted_whitespace = ParserHelper.remove_all_from_text( + text_token.extracted_whitespace ) - if self.__atx_heading_token and len(resolved_extracted_whitespace) > 1: - self.__report(context, text_token) + if "\t" in resolved_extracted_whitespace: + start_index = ( + self.__atx_heading_token.column_number + - 1 + + self.__atx_heading_token.hash_count + ) + resolved_extracted_whitespace = TabHelper.detabify_string( + resolved_extracted_whitespace, start_index + ) + if len(resolved_extracted_whitespace) > 1: + self.__report(context, text_token) self.__atx_heading_token = None diff --git a/pymarkdown/plugins/rule_md_021.py b/pymarkdown/plugins/rule_md_021.py index 153347c53..be6bc7d21 100644 --- a/pymarkdown/plugins/rule_md_021.py +++ b/pymarkdown/plugins/rule_md_021.py @@ -5,6 +5,8 @@ from typing import Optional, cast +from pymarkdown.general.parser_helper import ParserHelper +from pymarkdown.general.tab_helper import TabHelper from pymarkdown.plugin_manager.plugin_details import PluginDetailsV2 from pymarkdown.plugin_manager.plugin_scan_context import PluginScanContext from pymarkdown.plugin_manager.rule_plugin import RulePlugin @@ -21,9 +23,10 @@ class RuleMd021(RulePlugin): def __init__(self) -> None: super().__init__() - self.__atx_heading_token: Optional[MarkdownToken] = None + self.__atx_heading_token: Optional[AtxHeadingMarkdownToken] = None self.__is_left_in_error = False self.__first_text_token: Optional[TextMarkdownToken] = None + self.__last_token: Optional[TextMarkdownToken] = None def get_details(self) -> PluginDetailsV2: """ @@ -45,13 +48,11 @@ def starting_new_file(self) -> None: """ self.__atx_heading_token = None self.__first_text_token = None + self.__last_token = None self.__is_left_in_error = False def __report( - self, - context: PluginScanContext, - token: MarkdownToken, - end_token: EndMarkdownToken, + self, context: PluginScanContext, token: MarkdownToken, extra_end_data: str ) -> None: assert self.__atx_heading_token is not None if context.in_fix_mode: @@ -64,10 +65,7 @@ def __report( "extracted_whitespace", " ", ) - if ( - end_token.extra_end_data is not None - and len(end_token.extra_end_data) > 1 - ): + if len(extra_end_data) > 1: self.register_fix_token_request( context, token, @@ -78,6 +76,32 @@ def __report( else: self.report_next_token_error(context, self.__atx_heading_token) + def __handle_atx_end( + self, context: PluginScanContext, token: MarkdownToken + ) -> None: + end_token = cast(EndMarkdownToken, token) + assert end_token.extra_end_data is not None + extra_end_data = end_token.extra_end_data + if "\t" in extra_end_data: + assert self.__last_token is not None + assert self.__last_token.is_text + resolved_token_text = ParserHelper.remove_all_from_text( + self.__last_token.token_text + ) + start_index = self.__last_token.column_number - 1 + resolved_token_text = TabHelper.detabify_string( + resolved_token_text, start_index + ) + start_index_after_last_text_token = start_index + len(resolved_token_text) + extra_end_data = TabHelper.detabify_string( + extra_end_data, start_index_after_last_text_token + ) + if self.__is_left_in_error or len(extra_end_data) > 1: + self.__report(context, token, extra_end_data) + self.__atx_heading_token = None + self.__first_text_token = None + self.__last_token = None + def next_token(self, context: PluginScanContext, token: MarkdownToken) -> None: """ Event that a new token is being processed. @@ -85,17 +109,28 @@ def next_token(self, context: PluginScanContext, token: MarkdownToken) -> None: if token.is_atx_heading: atx_token = cast(AtxHeadingMarkdownToken, token) if atx_token.remove_trailing_count: - self.__atx_heading_token = token + self.__atx_heading_token = atx_token self.__is_left_in_error = False elif token.is_paragraph_end: self.__atx_heading_token = None elif token.is_atx_heading_end: - end_token = cast(EndMarkdownToken, token) - assert end_token.extra_end_data is not None - if self.__is_left_in_error or len(end_token.extra_end_data) > 1: - self.__report(context, token, end_token) + self.__handle_atx_end(context, token) elif token.is_text: text_token = cast(TextMarkdownToken, token) - self.__first_text_token = text_token - if self.__atx_heading_token and len(text_token.extracted_whitespace) > 1: - self.__is_left_in_error = True + if not self.__first_text_token and self.__atx_heading_token: + resolved_extracted_whitespace = ParserHelper.remove_all_from_text( + text_token.extracted_whitespace + ) + if "\t" in resolved_extracted_whitespace: + start_index = ( + self.__atx_heading_token.column_number + - 1 + + self.__atx_heading_token.hash_count + ) + resolved_extracted_whitespace = TabHelper.detabify_string( + resolved_extracted_whitespace, start_index + ) + if len(resolved_extracted_whitespace) > 1: + self.__is_left_in_error = True + self.__first_text_token = text_token + self.__last_token = text_token diff --git a/test/api/test_api_scan.py b/test/api/test_api_scan.py index 8797ebcd2..1ee8612ad 100644 --- a/test/api/test_api_scan.py +++ b/test/api/test_api_scan.py @@ -268,7 +268,8 @@ def test_api_scan_with_multiple_scan_issues(): # Assert assert scan_result - assert len(scan_result.scan_failures) == 5 + assert len(scan_result.scan_failures) == 6 + print(scan_result.scan_failures) assert scan_result.scan_failures[0].partial_equals( PyMarkdownScanFailure(source_path, 1, 1, "MD022", "", "", None) ) @@ -276,12 +277,15 @@ def test_api_scan_with_multiple_scan_issues(): PyMarkdownScanFailure(source_path, 1, 12, "MD010", "", "", None) ) assert scan_result.scan_failures[2].partial_equals( - PyMarkdownScanFailure(source_path, 2, 2, "MD022", "", "", None) + PyMarkdownScanFailure(source_path, 2, 2, "MD021", "", "", None) ) assert scan_result.scan_failures[3].partial_equals( - PyMarkdownScanFailure(source_path, 2, 2, "MD023", "", "", None) + PyMarkdownScanFailure(source_path, 2, 2, "MD022", "", "", None) ) assert scan_result.scan_failures[4].partial_equals( + PyMarkdownScanFailure(source_path, 2, 2, "MD023", "", "", None) + ) + assert scan_result.scan_failures[5].partial_equals( PyMarkdownScanFailure(source_path, 2, 14, "MD010", "", "", None) ) diff --git a/test/rules/test_md005.py b/test/rules/test_md005.py index 9a91aa2f2..7eb91bd11 100644 --- a/test/rules/test_md005.py +++ b/test/rules/test_md005.py @@ -780,7 +780,7 @@ ), pluginRuleTest( "mix_md005_md007_only_md005_1", - disable_rules="md007", + disable_rules=__plugin_disable_md007, source_file_contents=""" + first + second + third @@ -803,7 +803,7 @@ ), pluginRuleTest( "mix_md005_md007_only_md005_2", - disable_rules="md007", + disable_rules=__plugin_disable_md007, source_file_contents=""" + first + second + third diff --git a/test/rules/test_md006.py b/test/rules/test_md006.py index aa52f041a..2d900802e 100644 --- a/test/rules/test_md006.py +++ b/test/rules/test_md006.py @@ -188,8 +188,8 @@ pluginRuleTest( "mix_md006_md004", is_mix_test=True, - enable_rules="MD006", - disable_rules="MD007", + enable_rules=plugin_enable_this_rule, + disable_rules=__plugin_disable_md007, source_file_contents=""" + first * second - third @@ -225,7 +225,7 @@ def test_md006_scan(test: pluginRuleTest) -> None: """ Execute a parameterized scan test for plugin md001. """ - execute_scan_test(test, "md006") + execute_scan_test(test, plugin_enable_this_rule) @pytest.mark.parametrize("test", fixTests, ids=id_test_plug_rule_fn) diff --git a/test/rules/test_md007.py b/test/rules/test_md007.py index c09a678c1..8625d5b72 100644 --- a/test/rules/test_md007.py +++ b/test/rules/test_md007.py @@ -530,7 +530,7 @@ ), pluginRuleTest( "mix_md007_md005_only_md007_1", - disable_rules="md005", + disable_rules=__plugin_disable_md005, source_file_contents=""" + first + second + third @@ -553,7 +553,7 @@ ), pluginRuleTest( "mix_md007_md005_only_md007_2", - disable_rules="md005", + disable_rules=__plugin_disable_md005, source_file_contents=""" + first + second + third @@ -621,7 +621,7 @@ ), pluginRuleTest( "mix_md007_md030_xx", - disable_rules="MD030", + disable_rules=__plugin_disable_md030, source_file_contents=""" * First first paragraph @@ -646,7 +646,7 @@ ), pluginRuleTest( "mix_md007_md030", - disable_rules="md005", + disable_rules=__plugin_disable_md005, source_file_contents=""" * First first paragraph diff --git a/test/rules/test_md019.py b/test/rules/test_md019.py index a20a94f86..eae9a7f8a 100644 --- a/test/rules/test_md019.py +++ b/test/rules/test_md019.py @@ -17,13 +17,20 @@ source_path = os.path.join("test", "resources", "rules", "md019") + os.sep __plugin_disable_md010 = "md010" -__plugin_disable_md023 = "md023" __plugin_disable_md013_md033 = "md013,md033" +__plugin_disable_md023 = "md023" +__plugin_disable_md026 = "md026" +__plugin_disable_md033 = "md033" +__plugin_disable_md037 = "md037" scanTests = [ pluginRuleTest( "good_single_spacing", source_file_name=f"{source_path}single_spacing.md", + source_file_contents="""# Heading 1 + +## Heading 2 +""", ), pluginRuleTest( "bad_multiple_spacing", @@ -38,6 +45,13 @@ fix_expected_file_contents="""# Heading 1 ## Heading 2 +""", + ), + pluginRuleTest( + "good_multiple_spacing_with_inline", + source_file_contents="""# Heading *number* 1 + +## Heading *number* 2 """, ), pluginRuleTest( @@ -53,6 +67,21 @@ fix_expected_file_contents="""# Heading *number* 1 ## Heading *number* 2 +""", + ), + pluginRuleTest( + "bad_multiple_spacing_with_inline_only", + source_file_contents="""# *number 1* + +## *number 2* +""", + disable_rules=__plugin_disable_md037, + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx) +{temp_source_path}:3:1: MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx)""", + fix_expected_file_contents="""# *number 1* + +## *number 2* """, ), pluginRuleTest( @@ -147,6 +176,175 @@ source_file_contents="""# empty +""", + ), + pluginRuleTest( + "good_empty_heading_with_empty_text", + source_file_contents="""# + +empty +""", + ), + pluginRuleTest( + "bad_extra_space_only_raw_html", + source_file_contents="""## + +just some text +""", + disable_rules=__plugin_disable_md033, + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx) +""", + fix_expected_file_contents="""## + +just some text +""", + ), + pluginRuleTest( + "good_extra_space_only_raw_html", + disable_rules=__plugin_disable_md033, + source_file_contents="""## + +just some text +""", + ), + pluginRuleTest( + "bad_extra_space_only_emphasis", + source_file_contents="""# *Heading 1#* + +## *Heading 2#* +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx) +{temp_source_path}:3:1: MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx)""", + fix_expected_file_contents="""# *Heading 1#* + +## *Heading 2#* +""", + ), + pluginRuleTest( + "good_extra_space_only_emphasis", + source_file_contents="""# *Heading 1#* + +## *Heading 2#* +""", + ), + pluginRuleTest( + "bad_extra_space_only_autolink", + source_file_contents="""# + +just some text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx) +""", + fix_expected_file_contents="""# + +just some text +""", + ), + pluginRuleTest( + "good_extra_space_only_autolink", + source_file_contents="""# + +just some text +""", + ), + pluginRuleTest( + "bad_extra_space_only_link", + source_file_contents="""# [google](https://google.com) + +just some text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx) +""", + fix_expected_file_contents="""# [google](https://google.com) + +just some text +""", + ), + pluginRuleTest( + "good_extra_space_only_link", + source_file_contents="""# [google](https://google.com) + +just some text +""", + ), + pluginRuleTest( + "bad_extra_space_only_codespan", + source_file_contents="""# `codespan` + +just some text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx) +""", + fix_expected_file_contents="""# `codespan` + +just some text +""", + ), + pluginRuleTest( + "good_extra_space_only_codepsan", + source_file_contents="""# `codespan` + +just some text +""", + ), + pluginRuleTest( + "bad_extra_space_only_reference", + source_file_contents="""# & + +just some text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx) +""", + fix_expected_file_contents="""# & + +just some text +""", + ), + pluginRuleTest( + "good_extra_space_only_reference", + source_file_contents="""# & + +just some text +""", + ), + pluginRuleTest( + "bad_extra_space_only_backslash", + disable_rules=__plugin_disable_md026, + source_file_contents="""# \\! + +just some text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx) +""", + fix_expected_file_contents="""# \\! + +just some text +""", + ), + pluginRuleTest( + "good_extra_space_only_backslash", + source_file_contents="""# \\! + +just some text +""", + disable_rules=__plugin_disable_md026, + ), + pluginRuleTest( + "bad_extra_space_tab_backslash_reference", + source_file_contents="""#\t\\!  + +just some text +""", + disable_rules="md010", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD019: Multiple spaces are present after hash character on Atx Heading. (no-multiple-space-atx) """, ), pluginRuleTest( diff --git a/test/rules/test_md021.py b/test/rules/test_md021.py index 9d3a8544f..46d3f09fe 100644 --- a/test/rules/test_md021.py +++ b/test/rules/test_md021.py @@ -17,12 +17,18 @@ source_path = os.path.join("test", "resources", "rules", "md021") + os.sep __plugin_disable_md010 = "md010" +__plugin_disable_md023 = "md023" +__plugin_disable_md026 = "md026" __plugin_disable_md033 = "md033" scanTests = [ pluginRuleTest( "good_single_spacing", source_file_name=f"{source_path}single_spacing.md", + source_file_contents="""# Heading 1 # + +## Heading 2 ## +""", ), pluginRuleTest( "bad_multiple_spacing_both", @@ -73,21 +79,58 @@ pluginRuleTest( "good_multiple_spacing_with_inline", source_file_name=f"{source_path}multiple_spacing_with_inline.md", + source_file_contents="""# Heading *number* 1 ## + +## Heading *number* 2 ## +""", ), pluginRuleTest( - "bad_multiple_spacing_with_indent", - source_file_name=f"{source_path}multiple_spacing_left.md", - source_file_contents="""# Heading 1 # + "bad_multiple_spacing_with_inline", + source_file_contents="""# Heading *number* 1 # -## Heading 2 ## +## Heading *number* 2 ## """, scan_expected_return_code=1, scan_expected_output="""{temp_source_path}:1:1: MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. (no-multiple-space-closed-atx) -{temp_source_path}:3:1: MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. (no-multiple-space-closed-atx) +{temp_source_path}:3:1: MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. (no-multiple-space-closed-atx)""", + fix_expected_file_contents="""# Heading *number* 1 # + +## Heading *number* 2 ## """, - fix_expected_file_contents="""# Heading 1 # + ), + pluginRuleTest( + "bad_multiple_spacing_with_inline_only", + source_file_contents="""# *number 1* # -## Heading 2 ## +## *number 2* ## +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. (no-multiple-space-closed-atx) +{temp_source_path}:3:1: MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. (no-multiple-space-closed-atx)""", + fix_expected_file_contents="""# *number 1* # + +## *number 2* ## +""", + ), + pluginRuleTest( + "bad_multiple_spacing_with_indent", + disable_rules=__plugin_disable_md023, + source_file_contents=""" # Heading 1 # + + ## Heading 2 ## + + ## Heading 3 ## +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:2: MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. (no-multiple-space-closed-atx) +{temp_source_path}:3:2: MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. (no-multiple-space-closed-atx) +{temp_source_path}:5:2: MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. (no-multiple-space-closed-atx) +""", + fix_expected_file_contents=""" # Heading 1 # + + ## Heading 2 ## + + ## Heading 3 ## """, ), pluginRuleTest( @@ -170,6 +213,218 @@ scan_expected_return_code=1, scan_expected_output="{temp_source_path}:1:1: MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. (no-multiple-space-closed-atx)", ), + pluginRuleTest( + "bad_extra_space_only_raw_html", + source_file_contents="""## ## + +just some text +""", + disable_rules=__plugin_disable_md033, + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. (no-multiple-space-closed-atx) +""", + fix_expected_file_contents="""## ## + +just some text +""", + ), + pluginRuleTest( + "good_extra_space_only_raw_html", + disable_rules=__plugin_disable_md033, + source_file_contents="""## ## + +just some text +""", + ), + pluginRuleTest( + "bad_extra_space_only_emphasis", + source_file_contents="""# *Heading 1#* # + +## *Heading 2#* ## +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. (no-multiple-space-closed-atx) +{temp_source_path}:3:1: MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. (no-multiple-space-closed-atx)""", + fix_expected_file_contents="""# *Heading 1#* # + +## *Heading 2#* ## +""", + ), + pluginRuleTest( + "good_extra_space_only_emphasis", + source_file_contents="""# *Heading 1#* # + +## *Heading 2#* ## +""", + ), + pluginRuleTest( + "bad_extra_space_only_autolink", + source_file_contents="""# # + +just some text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. (no-multiple-space-closed-atx) +""", + fix_expected_file_contents="""# # + +just some text +""", + ), + pluginRuleTest( + "good_extra_space_only_autolink", + source_file_contents="""# # + +just some text +""", + ), + pluginRuleTest( + "bad_extra_space_only_link", + source_file_contents="""# [google](https://google.com) # + +just some text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. (no-multiple-space-closed-atx) +""", + fix_expected_file_contents="""# [google](https://google.com) # + +just some text +""", + ), + pluginRuleTest( + "good_extra_space_only_link", + source_file_contents="""# [google](https://google.com) # + +just some text +""", + ), + pluginRuleTest( + "bad_extra_space_only_codespan", + source_file_contents="""# `codespan` # + +just some text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. (no-multiple-space-closed-atx) +""", + fix_expected_file_contents="""# `codespan` # + +just some text +""", + ), + pluginRuleTest( + "good_extra_space_only_codepsan", + source_file_contents="""# `codespan` # + +just some text +""", + ), + pluginRuleTest( + "bad_extra_space_only_reference", + source_file_contents="""# & # + +just some text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. (no-multiple-space-closed-atx) +""", + fix_expected_file_contents="""# & # + +just some text +""", + ), + pluginRuleTest( + "good_extra_space_only_reference", + source_file_contents="""# & # + +just some text +""", + ), + pluginRuleTest( + "bad_extra_space_only_backslash", + disable_rules=__plugin_disable_md026, + source_file_contents="""# \\! # + +just some text +""", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. (no-multiple-space-closed-atx) +""", + fix_expected_file_contents="""# \\! # + +just some text +""", + ), + pluginRuleTest( + "good_extra_space_only_backslash", + source_file_contents="""# \\! # + +just some text +""", + disable_rules=__plugin_disable_md026, + ), + pluginRuleTest( + "good_extra_space_backslash_reference", + source_file_contents="""# \\!  # + +just some text +""", + disable_rules=__plugin_disable_md026, + ), + pluginRuleTest( + "bad_extra_space_tab_before_backslash_reference", + source_file_contents="""#\t\\!  # + +just some text +""", + disable_rules="md010", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. (no-multiple-space-closed-atx) +""", + fix_expected_file_contents="""# \\!  # + +just some text +""", + ), + pluginRuleTest( + "bad_extra_space_tab_after_backslash_reference", + source_file_contents="""# \\! \t# + +just some text +""", + disable_rules="md010", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. (no-multiple-space-closed-atx) +""", + fix_expected_file_contents="""# \\!  # + +just some text +""", + ), + pluginRuleTest( + "good_extra_space_tab_after_backslash_reference_with_extra_inner_space", + source_file_contents="""# \\! \t# + +just some text +""", + disable_rules="md010", + ), + pluginRuleTest( + "bad_extra_space_tab_both_backslash_reference", + source_file_contents="""#\t\\! \t# + +just some text +""", + disable_rules="md010", + scan_expected_return_code=1, + scan_expected_output="""{temp_source_path}:1:1: MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. (no-multiple-space-closed-atx) +""", + fix_expected_file_contents="""# \\!  # + +just some text +""", + ), pluginRuleTest( "mix_md021_md010", source_file_contents="""# Heading\t1 # diff --git a/test/test_main.py b/test/test_main.py index bb01e502c..9891d0fe6 100644 --- a/test/test_main.py +++ b/test/test_main.py @@ -476,9 +476,9 @@ def test_markdown_with_multiple_errors_reported(): + f"{source_path}:1:12: " + "MD010: Hard tabs " + "[Column: 12] (no-hard-tabs)\n" - # + f"{source_path}:2:2: " - # + "MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. " - # + "(no-multiple-space-closed-atx)\n" + + f"{source_path}:2:2: " + + "MD021: Multiple spaces are present inside hash characters on Atx Closed Heading. " + + "(no-multiple-space-closed-atx)\n" + f"{source_path}:2:2: " + "MD022: Headings should be surrounded by blank lines. " + "[Expected: 1; Actual: 0; Above] (blanks-around-headings,blanks-around-headers)\n"